### OpenGL Tutorial - 3

##### Render a Triangular Model in OpenGL? or how to use glBegin(GL_TRIANGLES) in OpenGL? or How to use "for loop" for rendering a big triangular model? or How to make a data structure for 3D model rendering? or How to use a header file?

**How to render a triangle?**

**How to render a triangular model?**

**How to use "for loop" for rendering a big triangular model?**

**How to make a data structure for 3D model rendering? (very important)**

**How to declare a array pointer?**

**How to use declared pointers for rendering 3D model?**

**How to make a header file?**

**How to use a header file?**

**How to make a function with local variables?**

I am assuming that you have successfully compiled your first and second program using my OpenGLTest_Animation.cpp file or using my Visual Studio project. In this tutorial, we are going to use a header file for data structure and short math algorithms. Data structure is very important in 3D graphics programming, if you have a proper data structure, only then you can extend your application or software further for new ideas and algorithms. But if you were made a data structure improper, improper means that will not be perfect for many algorithms, then you can't use your data structure with those algorithms. You can convert their (Google) algorithms same as your data structure demands, but it will take so much time, and it's very complicated, sometime you give up and through away. I had the same problem when I was working on my softwares, then I realized that what if I had made a perfect data structure before, and now I could save my so much time which I have wasted on just data structure conversion.

Anyways, let's start to make a new header file. In order to create a new header file, just follow the steps which we have done for creating a *.cpp file in the first tutorial. In this header file, we are going to make a data structure for the triangular model. Here we will render a triangular cube which will be composed of 8 vertices and 12 indices. By creating two structures one for vertices and second for indices of the model, we create some pointers to those structures, and we allocate arrays memory to 12 and 8 for triangles and vertices, respectively.

The header file for rendering a triangular model can be downloaded from here. The file contains data structure, some pointers to sturcture, and veriables, etc.

File Name | Type | Size | Release Date |

myMath | *.h | 1.09 KB | 2012.06.23 |

```
/********************************************************************
Created: 2012/06/23
Created: 23:6:2012 2:48
Filename: myMath.h
Author: Furqan Ullah
Website: www.real3d.pk
Disclaimer: This tutorial has been written for learning purposes only.
*********************************************************************/
#ifndef __myMath_H__
#define __myMath_H__
#include < math.h>
struct GLpoint // A Structure To Hold Point Data of triangles
{
GLfloat x, y, z; // The Components Of The GLpoint
};
struct GLFace // A Structure To Hold Face Data of triangles
{
unsigned int v1, v2, v3; // The Components Of The GLFace
};
GLpoint p_VERTICES[8]; // pointer to vertices of the main model
GLpoint FaceNormals[12]; // pointer to face normals (triangle normal) of the main model
int nb_Vertices = 0; // number of total vertices of main model
GLFace p_indices[12]; // pointer to indices (vertex index) of the main model
int nb_Faces = 0; // number of total triangles of main model
#endif
```

**Note: **I am not including normals in this tutorial, because for rendering normals, we also need to know about 3D lights of OpenGL, first I will describe about lights in the next tutorial and then I will include normals rendering. In this tutorial, you will find a wireframe rendering of a cube.

In the *.cpp file, You will also find one function name Draw_One_Triangle(void). I just wanted to make your concept clear by including this function. You will find that how can we apply colors to triangles of a 3D model.

If you have successfully done your previous tutorial, then it will be very easy to understand this tutorial. Just follow the code. I didn't change anything in the *.cpp file of the previous tutorials, I just added some functions, use them wherever you want.

**Note:** Actually, whenever we use pointers it means you are allocating some memory, but you should know between static and dynamic memory. When you will study about it then you will know that we do not need to de-allocate the arrays memory, array will automatically be de-allocated whenever you exit your application. The system will release all the allocated memory by your application just after your press exit. But in case of dynamic memory, de-allocation of memory is very important, there must not be any kind of leak in your application or software, otherwise you will find some bugs, instability in your software, etc. In our case, in this tutorial we only allocated the arrays memory, so we don't need any kind of de-allocation.

The code and *.cpp file for the 3rd tutorial can be found below.

File Name | Type | Size | Release Date |

OpenGLTest_Rendering_A_Triangular_Model | *.cpp | 9.73 KB | 2012.06.23 |

```
/********************************************************************
Created: 2012/06/23
Created: 23:6:2012 2:48
Filename: OpenGLTest_Rendering_A_Triangular_Model.cpp
Author: Furqan Ullah
Website: www.real3d.pk
Disclaimer: This tutorial has been written for learning purposes only.
*********************************************************************/
#include "myMath.h" // declaration of header file
/************************************************************************/
/* I made this data set myself for rendering a Cube. A Cube contains 8 vertices and 12 triangles. */
/* You can change size of the cube by changing xsize, ysize, zsize variables. */
/************************************************************************/
void getTriangularModelData()
{
float xsize = 20.0; float ysize = 20.0; float zsize = 20.0;
// cube vertices positions in x, y, z
p_VERTICES[0].x = xsize; p_VERTICES[0].y = ysize; p_VERTICES[0].z = -zsize; // position of 1st vertex (x, y, z)
p_VERTICES[1].x = xsize; p_VERTICES[1].y = ysize; p_VERTICES[1].z = zsize; // position of 2nd vertex (x, y, z)
p_VERTICES[2].x = xsize; p_VERTICES[2].y = -ysize; p_VERTICES[2].z = -zsize; // position of 3rd vertex (x, y, z)
p_VERTICES[3].x = xsize; p_VERTICES[3].y = -ysize; p_VERTICES[3].z = zsize; // position of 4th vertex (x, y, z)
p_VERTICES[4].x = -xsize; p_VERTICES[4].y = -ysize; p_VERTICES[4].z = -zsize; // position of 5th vertex (x, y, z)
p_VERTICES[5].x = -xsize; p_VERTICES[5].y = -ysize; p_VERTICES[5].z = zsize; // position of 6th vertex (x, y, z)
p_VERTICES[6].x = -xsize; p_VERTICES[6].y = ysize; p_VERTICES[6].z = -zsize; // position of 7th vertex (x, y, z)
p_VERTICES[7].x = -xsize; p_VERTICES[7].y = ysize; p_VERTICES[7].z = zsize; // position of 8th vertex (x, y, z)
nb_Vertices = 8; // total number of vertices
// cube indices
p_indices[0].v1 = 0; p_indices[0].v2 = 1; p_indices[0].v3 = 2; // 1st triangle
p_indices[1].v1 = 3; p_indices[1].v2 = 2; p_indices[1].v3 = 1; // 2nd triangle
p_indices[2].v1 = 2; p_indices[2].v2 = 3; p_indices[2].v3 = 4; // 3rd triangle
p_indices[3].v1 = 5; p_indices[3].v2 = 4; p_indices[3].v3 = 3; // and so on
p_indices[4].v1 = 4; p_indices[4].v2 = 5; p_indices[4].v3 = 6;
p_indices[5].v1 = 7; p_indices[5].v2 = 6; p_indices[5].v3 = 5;
p_indices[6].v1 = 6; p_indices[6].v2 = 7; p_indices[6].v3 = 0;
p_indices[7].v1 = 1; p_indices[7].v2 = 0; p_indices[7].v3 = 7;
p_indices[8].v1 = 0; p_indices[8].v2 = 2; p_indices[8].v3 = 4;
p_indices[9].v1 = 4; p_indices[9].v2 = 6; p_indices[9].v3 = 0;
p_indices[10].v1 = 1; p_indices[10].v2 = 5; p_indices[10].v3 = 3;
p_indices[11].v1 = 5; p_indices[11].v2 = 1; p_indices[11].v3 = 7;
nb_Faces = 12; // total number of indices
}
/************************************************************************/
/* This function will render only one triangle with 3 colors of each side.*/
/************************************************************************/
void Draw_One_Triangle(void)
{
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0, 0); // apply color on 1st vertex
glVertex3f(0, 0, 0);
glColor3f(0.0, 1.0, 0); // apply color on 2nd vertex
glVertex3f(15, 0, 0);
glColor3f(0.0, 0, 1.0); // apply color on 3rd vertex
glVertex3f(15, 15, 0);
glEnd();
}
/************************************************************************/
/* This function will render a triangular model. You will realize that here I am using float pointer for rendering vertices of triangle.*/
/* This is optimized and efficient way, do use it.*/
/* GLpoint *P is a pointer to vertices of model */
/* GLpoint *Fn is a pointer to face normals of model (face normal means normal vector of a triangle)*/
/* GLFace *T is a pointer to indices of model. Indices means triangles corners i.e., v1, v2, v3 */
/* int nbF = total number of triangles of model */
/************************************************************************/
void Draw_TriangularModel(GLpoint *P, GLpoint *Fn, GLFace *T, int nbF)
{
glBegin(GL_TRIANGLES);
for (int i=0; i < nbF; i++)
{
//glNormal3fv((float *)&Fn[i]); we are not using face normals in this tutorial
glVertex3fv((float *)&P[T[i].v1]);
glVertex3fv((float *)&P[T[i].v2]);
glVertex3fv((float *)&P[T[i].v3]);
}
glEnd();
}
/************************************************************************/
/* This is the main OpenGL function. Whatever you want to draw in your OpenGL application, you will need to write in this function only. */
/* This is a real-time activated function, this function operates like a loop function, */
/************************************************************************/
void display(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // you can apply background color by setting RBG values here.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(15.0, 1.0, 0.0, 0.0);
glRotatef(30.0, 0.0, 1.0, 0.0);
glRotatef(0, 0.0, 0.0, 1.0);
glutIdleFunc(ModelRotation); // Idle function of OpenGL, idle function means it will never stop until the application is terminated or your stop by your self.
glRotatef(Rot_Cangle_animate, 1.0f, 0.0f, 0.0f); // apply rotation around X-axis
glRotatef(Rot_Cangle_animate, 0.0f, 0.0f, 1.0f); // rotation around Z-axis
//glutWireCube(30.0); // render a wire cube with size 30
//glutWireTeapot(15.0); // if you want to render a teapot, just uncomment it.
//glutWireTorus(5.0, 20.0, 20.0, 20.0); // how about to render a torus, have fun
Draw_One_Triangle(); // rendering a triangle
glColor3f(1.0f, 1.0f, 1.0f); // apply color to object (Cube)
Draw_TriangularModel(p_VERTICES, FaceNormals, p_indices, nb_Faces); // rendering a triangular model
glPopMatrix();
glutSwapBuffers();
}
```