Programming - Games - OpenGL and C++

This tutorial was written for me by Imran Khan (imranahmedkhan82@hotmail.com, iak1982@yahoo.com).
Copyright (c) 2004 is owned by Martin Baker

Moving in 3D-World:

As we have learned basic things of OpenGL. Now we will create 3D World and will Move in it. In this Section we will use "Texture Mapping " , " KeyBoard / Mouse Interaction ".

First of all we will define 3 structures , 'Sector ' , ' Triangle ' , ' Vertex ' .

typedef struct tagVERTEX
{
float x, y, z;
float u, v;
} VERTEX;

typedef struct tagTRIANGLE
{
VERTEX vertex[3];
} TRIANGLE;

typedef struct tagSECTOR
{
int numtriangles;
TRIANGLE* triangle;
} SECTOR;

SECTOR sector1;

A Sector can be any enclosed volume.So a 3d World is consisits of Sectors and Sectors is consists of Traingle and Triangle is consists of Vertex.Thats why Sector structure contains Triangle structure variable with ' number of triangles ' .

TRIANGLE* triangle;

we take triangle array because one sector can contain many Triangle.Then Triangle Structure contains Vertex Structure Variable.As a triable has only 3 Vertex thats why the array size is " 3 " . In the Last Vertext. it contains 5 variable,"x,y,z,u,v".

If you making a big 3d-World then it will be very difficult and complex to write all the vertices in the program. It is better to write all the vertices in a Text File and we will read that text file. In this way , we don't have to recompile our program everytime.Now we will write a Method which get the values from text file and set the 3D world according to data.

void SetupWorld()
{
float x, y, z, u, v;
int numtriangles;
FILE *filein;
char oneline[255];
filein = fopen("data/track.txt", "rt");

readstr(filein,oneline);
sscanf(oneline, "TRIANGLES %d\n", &numtriangles);

sector1.triangle = new TRIANGLE[numtriangles];
sector1.numtriangles = numtriangles;
for (int loop = 0; loop < numtriangles; loop++)
{
for (int vert = 0; vert < 3; vert++)
{
readstr(filein,oneline);
sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v);
sector1.triangle[loop].vertex[vert].x = x;
sector1.triangle[loop].vertex[vert].y = y;
sector1.triangle[loop].vertex[vert].z = z;
sector1.triangle[loop].vertex[vert].u = u;
sector1.triangle[loop].vertex[vert].v = v;
}
}
fclose(filein);
return;
}

"filein = fopen("data/track.txt", "rt"); " -- In this method we just get Lines from textfile

readstr(filein,oneline); -- we will write a method which will check for empty line and comments so that this method won't read those lines.

sscanf(oneline, "TRIANGLES %d\n", &numtriangles); -- We read number of Traingles from textfile and put its value in numtriangle.

sector1.triangle = new TRIANGLE[numtriangles]; -- We create that much triangles which are required.

Next we have a nested loop. Uper Loop will run till number of triangles in sector is reached .Inner loop for vertices will run till 3 because each triangle got 3 vertices. In the loop we again use these 2 lines :

readstr(filein,oneline);
sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v);

firtline read the spaces and comments. and next line get the values from the Text file.Actually the format which is used in the file is like :

X1 Y1 Z1 U1 V1
X2 Y2 Z2 U2 V2
X3 Y3 Z3 U3 V3

So thats why we are getting values like : " sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v); "

Now we will show you the function which checks empty lines and comments.

void readstr(FILE *f,char *string)
{
do
{
fgets(string, 255, f);
} while ((string[0] == '/') || (string[0] == '\n'));
return;
}

Its easy to Understand.Its just get the line and check for Comment " / " and empty line " /n ".

Then we have the same functions for LoadBmp and LoadGLTextures to load the BMP and convert it to textture. We have done this in Tutorial 6. Now in the InitGL method we will call "SetupWorld" . So that it will load our track in the beginning of the execution.

int InitGL(GLvoid)
{
if (!LoadGLTextures())
{
return FALSE;
}

glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

SetupWorld();
Position_Camera(0, 0, 6,0, 0, 0, 0, 1, 0);

return TRUE;

}

All the things are same Except the call for " SetupWorld ( ) ". At the end we set the initial position of the Camera .

Also we got some changes in "DrawGLScene" method because we have to draw triangles which we have just save in structures.

int DrawGLScene(GLvoid)
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

GLfloat x_m, y_m, z_m, u_m, v_m;
GLfloat xtrans = -xpos;
GLfloat ztrans = -zpos;
GLfloat ytrans = -walkbias-0.25f;

int numtriangles;

gluLookAt(mPos.x, mPos.y, mPos.z,
mView.x, mView.y, mView.z,
mUp.x, mUp.y, mUp.z);


glTranslatef(xtrans, ytrans, ztrans);
glBindTexture(GL_TEXTURE_2D, texture[filter]);

numtriangles = sector1.numtriangles;

// Process Each Triangle
for (int loop_m = 0; loop_m < numtriangles; loop_m++)
{
glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
x_m = sector1.triangle[loop_m].vertex[0].x;
y_m = sector1.triangle[loop_m].vertex[0].y;
z_m = sector1.triangle[loop_m].vertex[0].z;
u_m = sector1.triangle[loop_m].vertex[0].u;
v_m = sector1.triangle[loop_m].vertex[0].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);

x_m = sector1.triangle[loop_m].vertex[1].x;
y_m = sector1.triangle[loop_m].vertex[1].y;
z_m = sector1.triangle[loop_m].vertex[1].z;
u_m = sector1.triangle[loop_m].vertex[1].u;
v_m = sector1.triangle[loop_m].vertex[1].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);

x_m = sector1.triangle[loop_m].vertex[2].x;
y_m = sector1.triangle[loop_m].vertex[2].y;
z_m = sector1.triangle[loop_m].vertex[2].z;
u_m = sector1.triangle[loop_m].vertex[2].u;
v_m = sector1.triangle[loop_m].vertex[2].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
glEnd();
}

return TRUE;
}

First 2 lines are familiar. Next we define some variables. Next we place the camera at the desired position. Next 2 lines are similar . Then we have For loop. Which loaded each vertex from the structure and draw triangle according to it.

Now when u run the , its like you are playing some game.

Download the Source Code.


metadata block
see also:
Correspondence about this page

This site may have errors. Don't use for critical systems.

Copyright (c) 1998-2023 Martin John Baker - All rights reserved - privacy policy.