PDA

View Full Version : loading tga textures



Riuzaki90
02-18-2012, 09:16 AM
I'm having problem during the apply of textures to my objects in a project...The textures don't appairs in the scene...

here my code


#include <math.h>
#include <GL/glut.h>
#include "Terrain.h"
#include "VectorR3.h"
#include "tga.h"
#include <iostream>

using namespace std;

#define TEXTURE_COUNT 2
#define BAR_SCALE 0
#define SAT_TEXTURE 1
GLuint textures[TEXTURE_COUNT];
const char *textureFile[TEXTURE_COUNT] = { "temp.tga", "sat.tga" };

int width = 0, height = 0;
int precx, precy;
int zoomFactor = 5;
VectorR3 eye;
VectorR3 focus;
VectorR3 normal;
VectorR3 rotation;
VectorR3 translate;
int anglex = 0, angley = 0, anglez = 0, angle = 0;
static GLenum filling = GL_FILL;
bool rotationX = false;
bool rotationY = false;
bool rotationZ = false;
bool zoomIn = false, zoomOut = false;
bool buttonLeftDawn = false, buttonRightDawn = false, buttonMiddleDawn = false;
bool transl = false, trasla = false;
using namespace std;

// function prototypes
void disp(void);
void reshape(int w, int h);
void init();
void createAxis();
void writeNumAxis();
void mouse(int, int, int, int);
void mousemotion(int x, int y);
void keyboard(unsigned char key, int x, int y);
void ShutdownTextures();


GLuint legenda_temperatura;
GLuint texture_satellite;

Terrain* terreno;
Terrain* colata;
Terrain* temperature;

int x, y;

int main(int argc, char **argv) {
terreno = new Terrain(argv[1]);

glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Visualizzatore terreno");
init();
glutDisplayFunc(disp);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMotionFunc(mousemotion);
glutKeyboardFunc(keyboard);
glutMainLoop();
terreno->~Terrain();

if (argv[2] != NULL)
colata->~Terrain();

if (argv[3] != NULL)
temperature->~Terrain();

ShutdownTextures();

return 0;
}

void mousemotion(int x, int y) {
x = x - (width / 2);
y = y - (height / 2);

if (trasla) {
translate.set(translate.getX() + (x - precx),
translate.getY() + (-y + precy), 0);

glutPostRedisplay();
} else {
if (buttonLeftDawn) {
anglex = (anglex + (y - precy)) % 360;
glutPostRedisplay();
}
if (buttonRightDawn) {
angley = (angley + (x - precx)) % 360;
glutPostRedisplay();
}
if (buttonMiddleDawn) {
anglex = (anglex + (y - precy)) % 360;
angley = (angley + (x - precx)) % 360;
glutPostRedisplay();
}
}
precx = x;
precy = y;
}

void mouse(int button, int state, int x1, int y1) {
x1 = x1 - (width / 2);
y1 = y1 - (height / 2);

if (button == GLUT_LEFT_BUTTON) {
if (state == GLUT_DOWN)
buttonLeftDawn = true;
else
buttonLeftDawn = false;
} else
buttonLeftDawn = false;

if (button == GLUT_RIGHT_BUTTON) {
if (state == GLUT_DOWN)
buttonRightDawn = true;
else
buttonRightDawn = false;
} else
buttonRightDawn = false;

if (button == GLUT_MIDDLE_BUTTON) {
if (state == GLUT_DOWN)
buttonMiddleDawn = true;
else
buttonMiddleDawn = false;
} else
buttonMiddleDawn = false;

if (button == 3 &amp;&amp; state == GLUT_UP)
eye.set(0, 0, eye.getZ() + 85);

if (button == 4 &amp;&amp; state == GLUT_UP)
eye.set(0, 0, eye.getZ() - 85);

if (button == GLUT_MIDDLE_BUTTON &amp;&amp; state == GLUT_DOWN &amp;&amp; transl)
trasla = true;
else {
transl = false;
trasla = false;
}
precx = x1;
precy = y1;

keyboard('/', 0, 0);
}

void createAxis() {

glColor3f(1, 0, 0);
glBegin(GL_LINES); //Start drawing the X asse

glVertex3f(0, 0, 0); //draw first coordinate

glVertex3f(10000, 0, 0); //second coordinate

glEnd(); //Stop drawing

glColor3f(0, 1, 0);

glBegin(GL_LINES); //Start drawing the Y asse

glVertex3f(0, 0, 0); //draw first coordinate

glVertex3f(0, 10000, 0); //second coordinate

glEnd(); //Stop drawing

glColor3f(0, 0, 1);

glBegin(GL_LINES); //Start drawing the Z asse

glVertex3f(0, 0, 0); //draw first coordinate

glVertex3f(0, 0, 10000); //second coordinate

glEnd();
}

GLint terrain;

void init() {

GLbyte *pBytes;
GLint iWidth, iHeight, iComponents;
GLenum eFormat;
GLubyte i;

glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW);

terrain = glGenLists(1);
glNewList(terrain, GL_COMPILE);
terreno->drawTerrain();
glEndList();

glClearColor(0.0, 0.99, 0.01, 0.1);
glEnable(GL_COLOR_MATERIAL);

//Set Material properties to follow glColor values
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_NORMALIZE); //Have OpenGL automatically normalize our normals
glShadeModel(GL_SMOOTH); //Enable smooth shading

glEnable(GL_LIGHTING); //Enable lighting
glEnable(GL_LIGHT0); //Enable light #0

GLfloat AmbientLight[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat DiffuseLight[] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat SpecularLight[] = { 0.0, 0.0, 0.0, 1.0 };

glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight);

GLfloat LightPosition[] = { 0.0, 0.0, 300.0, 0.0 };
GLfloat LightDirection[] = { 0.0, 0.0, -1.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
glLightfv(GL_LIGHT0, GL_POSITION, LightDirection);

normal.setX(0);
normal.setY(1);
normal.setZ(0);
precx = precy = 0;
eye.setX(0);
eye.setY(0);
focus.setX(0);
focus.setY(0);
focus.setZ(0);
translate.setY(0);
translate.setZ(0);

eye.setZ(terreno->getLenght() * terreno->getCellSize() * 16);

// Enable textur mapping and mode
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glGenTextures(TEXTURE_COUNT, textures);

// Load texture
for (i = 0; i < TEXTURE_COUNT; i++)
{

glBindTexture(GL_TEXTURE_2D, textures[i]);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
pBytes = gltLoadTGA(textureFile[i], &amp;iWidth, &amp;iHeight, &amp;iComponents, &amp;eFormat);
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
delete [] pBytes;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
}

void ShutdownTextures(void)
{
glDeleteTextures(TEXTURE_COUNT, textures);
}

void reshape(int x, int y) {
width = x;
height = y;
glViewport(0, 0, x, y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

GLfloat z_near = 0.5f;
GLfloat z_far = 150000;
GLfloat angle_perspective = 45.0f;

gluPerspective(angle_perspective / zoomFactor, (GLdouble) x / (GLdouble) y, z_near,
z_far);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye.getX(), eye.getY(), eye.getZ(), focus.getX(), focus.getY(),
focus.getZ(), normal.getX(), normal.getY(), normal.getZ());
}

void writeNumAxis() {
for (int i = 0; i <= 10000; i += 100) {
glRasterPos3f(i, 0, 0);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, '/');
glRasterPos3f(0, i, 0);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, '-');
glRasterPos3f(0, 0, i);
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, '\\');
}
}

void keyboard(unsigned char key, int x, int y) {

switch (key) {
case ' ':
transl = true;
break;
case 'f':
filling == GL_FILL ? filling = GL_LINE : filling = GL_FILL;
glPolygonMode(GL_FRONT_AND_BACK, filling);
break;
case 27:
exit(0);
break;
default:
break;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eye.getX(), eye.getY(), eye.getZ(), focus.getX(), focus.getY(),
focus.getZ(), normal.getX(), normal.getY(), normal.getZ());
glutPostRedisplay();
}

void disp() {
//size del terreno
int size = terreno->getCellSize();

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();

glBindTexture(GL_TEXTURE_2D, textures[BAR_SCALE]);
glRectf(2000, 2000, 2300, 1400);

glTranslatef(translate.getX(), translate.getY(), 0);
//lo rimetto nella posizione di partenza
glTranslatef(((terreno->getCol() * size) / 2), (terreno->getMax() + terreno->getMin()) / 2,
(terreno->getRow() * size) / 2);
glRotatef(anglex, 1, 0, 0);
glRotatef(angley, 0, 1, 0);
glRotatef(anglez, 0, 0, 1);
//lo sposto con il centro in zero e applico le 3 rotazioni
glTranslatef(-((terreno->getCol() * size) / 2), -(terreno->getMax() + terreno->getMin()) / 2,
-(terreno->getRow() * size) / 2);

glPushMatrix();
glTranslatef(terreno->getLenght()*size/2,
(terreno->getMax() + terreno->getMin())/2,
terreno->getLenght()*size/2);

glutWireCube(terreno->getLenght() * size);
glPopMatrix();

glBindTexture(GL_TEXTURE_2D, textures[SAT_TEXTURE]);
glCallList(terrain);

createAxis();

writeNumAxis();

glPopMatrix();
glutSwapBuffers();
}


and here my class that load the tga images:


#include <GL/glut.h>
#include <iostream>
#include <fstream>

using namespace std;

// Define targa header.
#pragma pack(1)
typedef struct
{
GLbyte identsize; // Size of ID field that follows header (0)
GLbyte colorMapType; // 0 = None, 1 = paletted
GLbyte imageType; // 0 = none, 1 = indexed, 2 = rgb, 3 = grey, +8=rle
unsigned short colorMapStart; // First colour map entry
unsigned short colorMapLength; // Number of colors
unsigned char colorMapBits; // bits per palette entry
unsigned short xstart; // image x origin
unsigned short ystart; // image y origin
unsigned short width; // width in pixels
unsigned short height; // height in pixels
GLbyte bits; // bits per pixel (8 16, 24, 32)
GLbyte descriptor; // image descriptor
} TGAHEADER;
#pragma pack(8)



////////////////////////////////////////////////////////////////////
// Allocate memory and load targa bits. Returns pointer to new buffer,
// height, and width of texture, and the OpenGL format of data.
// Call free() on buffer when finished!
// This only works on pretty vanilla targas... 8, 24, or 32 bit color
// only, no palettes, no RLE encoding.
GLbyte *gltLoadTGA(const char *szFileName, GLint *iWidth, GLint *iHeight, GLint *iComponents, GLenum *eFormat)
{
FILE *pFile; // File pointer
TGAHEADER tgaHeader; // TGA file header
unsigned long lImageSize; // Size in bytes of image
short sDepth; // Pixel depth;
GLbyte *pBits = NULL; // Pointer to bits

// Default/Failed values
*iWidth = 0;
*iHeight = 0;
*eFormat = GL_BGR_EXT;
*iComponents = GL_RGB8;

// Attempt to open the fil
pFile = fopen(szFileName, "rb");
if(pFile == NULL)
return NULL;

// Read in header (binary)
fread(&amp;tgaHeader, 18/* sizeof(TGAHEADER)*/, 1, pFile);

// Do byte swap for big vs little endian
#ifdef __APPLE__
BYTE_SWAP(tgaHeader.colorMapStart);
BYTE_SWAP(tgaHeader.colorMapLength);
BYTE_SWAP(tgaHeader.xstart);
BYTE_SWAP(tgaHeader.ystart);
BYTE_SWAP(tgaHeader.width);
BYTE_SWAP(tgaHeader.height);
#endif


// Get width, height, and depth of texture
*iWidth = tgaHeader.width;
*iHeight = tgaHeader.height;
sDepth = tgaHeader.bits / 8;

// Put some validity checks here. Very simply, I only understand
// or care about 8, 24, or 32 bit targa's.
if(tgaHeader.bits != 8 &amp;&amp; tgaHeader.bits != 24 &amp;&amp; tgaHeader.bits != 32)
return NULL;

// Calculate size of image buffer
lImageSize = tgaHeader.width * tgaHeader.height * sDepth;

// Allocate memory and check for success
pBits = new GLbyte[(lImageSize * sizeof(GLbyte))];
if(pBits == NULL)
return NULL;

// Read in the bits
// Check for read error. This should catch RLE or other
// weird formats that I don't want to recognize
if(fread(pBits, lImageSize, 1, pFile) != 1)
{
delete [](pBits);
return NULL;
}

// Set OpenGL format expected
switch(sDepth)
{
case 3: // Most likely case
*eFormat = GL_BGR_EXT;
*iComponents = GL_RGB8;
break;
case 4:
*eFormat = GL_BGRA_EXT;
*iComponents = GL_RGBA8;
break;
case 1:
*eFormat = GL_LUMINANCE;
*iComponents = GL_LUMINANCE8;
break;
};


// Done with File
fclose(pFile);

for(int i = 0; i < sizeof(*pBits); i++)
cout << pBits[i];

// Return pointer to image data
return pBits;
}


can someone help me? thanks in advance.

carsten neumann
02-18-2012, 11:47 AM
Please try to post only relevant code parts.
I don't see you specify texture coordinates anywhere, without them texturing does not really work.

Riuzaki90
02-19-2012, 12:48 PM
I've solved the loading problem that I had...now I'm tryng to set the texture coords of my terrain



//versione del terreno con i GL_TRIANGLES e l'altezza al centro della cella
void Terrain::drawTerrain() {

Terrain *lava;
Terrain *temperature;

if(!created &amp;&amp; file_name == "topografia.dat")
{
created = true;
lava = new Terrain("lava.dat");
temperature = new Terrain("temperature.dat");

glBindTexture(GL_TEXTURE_2D, texture);

// glNormal3f(0,0,1);
// glBegin( GL_QUADS );
//
// glTexCoord2d(1.0, 0.0); glVertex3f((COLUMN - 1)*CELLSIZE, heights[ROW - 1][COLUMN - 1], (ROW - 1)*CELLSIZE);
// glTexCoord2d(1.0, 1.0); glVertex3f((COLUMN - 1)*CELLSIZE, heights[0][COLUMN - 1], 0);
// glTexCoord2d(0.0, 1.0); glVertex3f(0, heights[0][0], 0);
// glTexCoord2d(0.0, 0.0); glVertex3f(0, heights[ROW - 1][0], (ROW - 1)*CELLSIZE);
// glEnd();
}

float** vertex_matrix = new float*[ROW + 1];

for (int i = 0; i < ROW + 1; i++)
vertex_matrix[i] = new float[COLUMN + 1];

getVertexMatrix(vertex_matrix);

for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COLUMN; j++) {
if (heights[i][j] == NODATA
|| vertex_matrix[i + 1][j + 1] == NODATA
|| vertex_matrix[i + 1][j] == NODATA
|| vertex_matrix[i][j + 1] == NODATA
|| vertex_matrix[i][j] == NODATA)
continue;

//calcolo le normali dei 4 triangoli del quadrato

VectorR3 center(-(j * CELLSIZE + CELLSIZE / 2), -(heights[i][j]),
-(i * CELLSIZE + CELLSIZE / 2));

VectorR3 north_west(j * CELLSIZE, vertex_matrix[i][j], i * CELLSIZE);

VectorR3 south_west(j * CELLSIZE, vertex_matrix[i + 1][j],
i * CELLSIZE + CELLSIZE);

VectorR3 north_est(j * CELLSIZE + CELLSIZE, vertex_matrix[i][j + 1],
i * CELLSIZE);

VectorR3 south_est(j * CELLSIZE + CELLSIZE, vertex_matrix[i + 1][j + 1],
i * CELLSIZE + CELLSIZE);

VectorR3 west_normal = calculateNormal(
center.getX() + north_west.getX(),
center.getY() + north_west.getY(),
center.getZ() + north_west.getZ(),
center.getX() + south_west.getX(),
center.getY() + south_west.getY(),
center.getZ() + south_west.getZ(), 1);

VectorR3 est_normal = calculateNormal(
center.getX() + south_est.getX(),
center.getY() + south_est.getY(),
center.getZ() + south_est.getZ(),
center.getX() + north_est.getX(),
center.getY() + north_est.getY(),
center.getZ() + north_est.getZ(), 1);

VectorR3 up_normal = calculateNormal(
center.getX() + north_est.getX(),
center.getY() + north_est.getY(),
center.getZ() + north_est.getZ(),
center.getX() + north_west.getX(),
center.getY() + north_west.getY(),
center.getZ() + north_west.getZ(), 1);

VectorR3 down_normal = calculateNormal(
center.getX() + south_west.getX(),
center.getY() + south_west.getY(),
center.getZ() + south_west.getZ(),
center.getX() + south_est.getX(),
center.getY() + south_est.getY(),
center.getZ() + south_est.getZ(), 1);

if(file_name == "topografia.dat" &amp;&amp; temperature->getHeight(i,j) != 0)
changeColor(temperature->getHeight(i,j), "red", temperature->getMax(),
temperature->getMin());
else
glColor3f(1,1,1);

glNormal3f(west_normal.getX(), west_normal.getY(), west_normal.getZ());
glBegin(GL_TRIANGLES);

glVertex3f(j * CELLSIZE, vertex_matrix[i][j], i * CELLSIZE);

glVertex3f(j * CELLSIZE + CELLSIZE / 2, heights[i][j],
i * CELLSIZE + CELLSIZE / 2);

glVertex3f(j * CELLSIZE, vertex_matrix[i + 1][j],
i * CELLSIZE + CELLSIZE);
glEnd();

glNormal3f(up_normal.getX(), up_normal.getY(), up_normal.getZ());
glBegin(GL_TRIANGLES);

glVertex3f(j * CELLSIZE, vertex_matrix[i][j], i * CELLSIZE);

glVertex3f(j * CELLSIZE + CELLSIZE / 2, heights[i][j],
i * CELLSIZE + CELLSIZE / 2);

glVertex3f(j * CELLSIZE + CELLSIZE, vertex_matrix[i][j + 1],
i * CELLSIZE);
glEnd();

glNormal3f(est_normal.getX(), est_normal.getY(), est_normal.getZ());
glBegin(GL_TRIANGLES);

glVertex3f(j * CELLSIZE + CELLSIZE, vertex_matrix[i + 1][j + 1],
i * CELLSIZE + CELLSIZE);

glVertex3f(j * CELLSIZE + CELLSIZE / 2, heights[i][j],
i * CELLSIZE + CELLSIZE / 2);
glTexCoord2d(1,1);
glVertex3f(j * CELLSIZE + CELLSIZE, vertex_matrix[i][j + 1],
i * CELLSIZE);
glEnd();

glNormal3f(down_normal.getX(), down_normal.getY(), down_normal.getZ());
glBegin(GL_TRIANGLES);

glVertex3f(j * CELLSIZE + CELLSIZE, vertex_matrix[i + 1][j + 1],
i * CELLSIZE + CELLSIZE);

glVertex3f(j * CELLSIZE + CELLSIZE / 2, heights[i][j],
i * CELLSIZE + CELLSIZE / 2);

glVertex3f(j * CELLSIZE, vertex_matrix[i + 1][j],
i * CELLSIZE + CELLSIZE);
glEnd();

glTexCoord2d(i/ROW, j/COLUMN);
glTexCoord2d(i/ROW, (j+1)/COLUMN);
glTexCoord2d((i+1)/ROW, j/COLUMN);
glTexCoord2d((i+1)/ROW, (j+1)/COLUMN);
}

}

for (int i = 0; i < ROW + 1; i++)
delete[] vertex_matrix[i];

delete[] vertex_matrix;
}


this way I havent the result that I want because the texture isnt shown ... I see some little textures in each triangles of the terrain...How can I do properly?

thanks a lot.

carsten neumann
02-19-2012, 01:33 PM
OpenGL is a state machine. When you specify vertices, the currently set vertex attributes (normal, color, tex coord, etc.) at the time you call glVertex*() are used.

So to specify a triangle with texture coordinates and normals in immediate mode, the order of calls should look something like this:



glBegin(GL_TRIANGLES)

glTexCoord2d( ... );
glNormalf( ... );
glVertex3f( ... );

glTexCoord2d( ... );
glNormalf( ... );
glVertex3f( ... );

glTexCoord2d( ... );
glNormalf( ... );
glVertex3f( ... );

glEnd();


Also, if ROW, COL are integers in C/C++ the division i/ROW is an integer division, you probably want to write float(i)/ROW and use glTexCoord2f, unless you really need double precision.

Riuzaki90
02-19-2012, 02:01 PM
thanks so much now it works :-) what I've to do if I want to color above the texture?

Riuzaki90
02-20-2012, 10:16 AM
Now I've this problem, the result after loading and applyng the texture on the terrain is this:

http://i.imgur.com/pkdQC.png
http://i.imgur.com/fhIFa.jpg

but the image has colors and is different:

http://i.imgur.com/IDzya.jpg

now I set the coords texture this way:


void Terrain::drawTerrain() {

Terrain *lava;
Terrain *temperature;

if (!created &amp;&amp; file_name == "topografia.dat") {
created = true;
lava = new Terrain("lava.dat");
temperature = new Terrain("temperature.dat");
}

float** vertex_matrix = new float*[ROW + 1];

for (int i = 0; i < ROW + 1; i++)
vertex_matrix[i] = new float[COLUMN + 1];

getVertexMatrix(vertex_matrix);

for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COLUMN; j++) {
if (heights[i][j] == NODATA || vertex_matrix[i + 1][j + 1] == NODATA
|| vertex_matrix[i + 1][j] == NODATA
|| vertex_matrix[i][j + 1] == NODATA
|| vertex_matrix[i][j] == NODATA)
continue;

//calcolo le normali dei 4 triangoli del quadrato

VectorR3 center(-(j * CELLSIZE + CELLSIZE / 2), -(heights[i][j]),
-(i * CELLSIZE + CELLSIZE / 2));

VectorR3 north_west(j * CELLSIZE, vertex_matrix[i][j],
i * CELLSIZE);

VectorR3 south_west(j * CELLSIZE, vertex_matrix[i + 1][j],
i * CELLSIZE + CELLSIZE);

VectorR3 north_est(j * CELLSIZE + CELLSIZE, vertex_matrix[i][j + 1],
i * CELLSIZE);

VectorR3 south_est(j * CELLSIZE + CELLSIZE,
vertex_matrix[i + 1][j + 1], i * CELLSIZE + CELLSIZE);

VectorR3 west_normal = calculateNormal(
center.getX() + north_west.getX(),
center.getY() + north_west.getY(),
center.getZ() + north_west.getZ(),
center.getX() + south_west.getX(),
center.getY() + south_west.getY(),
center.getZ() + south_west.getZ(), 1);

VectorR3 est_normal = calculateNormal(
center.getX() + south_est.getX(),
center.getY() + south_est.getY(),
center.getZ() + south_est.getZ(),
center.getX() + north_est.getX(),
center.getY() + north_est.getY(),
center.getZ() + north_est.getZ(), 1);

VectorR3 up_normal = calculateNormal(
center.getX() + north_est.getX(),
center.getY() + north_est.getY(),
center.getZ() + north_est.getZ(),
center.getX() + north_west.getX(),
center.getY() + north_west.getY(),
center.getZ() + north_west.getZ(), 1);

VectorR3 down_normal = calculateNormal(
center.getX() + south_west.getX(),
center.getY() + south_west.getY(),
center.getZ() + south_west.getZ(),
center.getX() + south_est.getX(),
center.getY() + south_est.getY(),
center.getZ() + south_est.getZ(), 1);

if (file_name == "topografia.dat"
&amp;&amp; temperature->getHeight(i, j) != 0)
changeColor(temperature->getHeight(i, j), "red",
temperature->getMax(), temperature->getMin());
else {
glColor4f(1, 1, 1, 1);
}
glBegin(GL_TRIANGLES);
glTexCoord2d(float(i + 1) / float(ROW),
float(j + 1) / float(COLUMN));
glNormal3f(est_normal.getX(), est_normal.getY(), est_normal.getZ());
glVertex3f(j * CELLSIZE + CELLSIZE, vertex_matrix[i + 1][j + 1],
i * CELLSIZE + CELLSIZE);

glTexCoord2d(float(i + 1 / 2) / float(ROW),
float(j + 1 / 2) / float(COLUMN));
glNormal3f(est_normal.getX(), est_normal.getY(), est_normal.getZ());
glVertex3f(j * CELLSIZE + CELLSIZE / 2, heights[i][j],
i * CELLSIZE + CELLSIZE / 2);

glTexCoord2d(float(i) / float(ROW), float(j + 1) / float(COLUMN));
glNormal3f(est_normal.getX(), est_normal.getY(), est_normal.getZ());
glVertex3f(j * CELLSIZE + CELLSIZE, vertex_matrix[i][j + 1],
i * CELLSIZE);
glEnd();

glBegin(GL_TRIANGLES);
glTexCoord2d(float(i) / float(ROW), float(j) / float(COLUMN));
glNormal3f(up_normal.getX(), up_normal.getY(), up_normal.getZ());
glVertex3f(j * CELLSIZE, vertex_matrix[i][j], i * CELLSIZE);

glTexCoord2d(float(i + 1 / 2) / float(ROW),
float(j + 1 / 2) / float(COLUMN));
glNormal3f(up_normal.getX(), up_normal.getY(), up_normal.getZ());
glVertex3f(j * CELLSIZE + CELLSIZE / 2, heights[i][j],
i * CELLSIZE + CELLSIZE / 2);

glTexCoord2d(float(i) / float(ROW), float(j + 1) / float(COLUMN));
glNormal3f(up_normal.getX(), up_normal.getY(), up_normal.getZ());
glVertex3f(j * CELLSIZE + CELLSIZE, vertex_matrix[i][j + 1],
i * CELLSIZE);
glEnd();

glBegin(GL_TRIANGLES);
glTexCoord2d(float(i + 1) / float(ROW),
float(j + 1) / float(COLUMN));
glNormal3f(down_normal.getX(), down_normal.getY(),
down_normal.getZ());
glVertex3f(j * CELLSIZE + CELLSIZE, vertex_matrix[i + 1][j + 1],
i * CELLSIZE + CELLSIZE);

glTexCoord2d(float(i + 1 / 2) / float(ROW),
float(j + 1 / 2) / float(COLUMN));
glNormal3f(down_normal.getX(), down_normal.getY(),
down_normal.getZ());
glVertex3f(j * CELLSIZE + CELLSIZE / 2, heights[i][j],
i * CELLSIZE + CELLSIZE / 2);

glTexCoord2d(float(i + 1) / float(ROW), float(j) / float(COLUMN));
glNormal3f(down_normal.getX(), down_normal.getY(),
down_normal.getZ());
glVertex3f(j * CELLSIZE, vertex_matrix[i + 1][j],
i * CELLSIZE + CELLSIZE);
glEnd();

glBegin(GL_TRIANGLES);
glTexCoord2d(float(i) / float(ROW), float(j) / float(COLUMN));
glNormal3f(west_normal.getX(), west_normal.getY(),
west_normal.getZ());
glVertex3f(j * CELLSIZE, vertex_matrix[i][j], i * CELLSIZE);

glTexCoord2d(float(i + 1 / 2) / float(ROW),
float(j + 1 / 2) / float(COLUMN));
glNormal3f(west_normal.getX(), west_normal.getY(),
west_normal.getZ());
glVertex3f(j * CELLSIZE + CELLSIZE / 2, heights[i][j],
i * CELLSIZE + CELLSIZE / 2);

glTexCoord2d(float(i + 1) / float(ROW), float(j) / float(COLUMN));
glNormal3f(west_normal.getX(), west_normal.getY(),
west_normal.getZ());
glVertex3f(j * CELLSIZE, vertex_matrix[i + 1][j],
i * CELLSIZE + CELLSIZE);
glEnd();

}

}

for (int i = 0; i < ROW + 1; i++)
delete[] vertex_matrix[i];

delete[] vertex_matrix;
}