www.pudn.com > 3dterrain.zip > Terrain.cpp


// Terrain.cpp: implementation of the Terrain class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "Terrain.h" 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
Terrain::Terrain() 
{ 
	height_map = NULL;			// pole obsahujuce informacie o vyske 
	texture_map = NULL;			// pole obsahujuce informacie o texture 
	texture_map_x = 256; texture_map_z = 256; 
	texture = NULL;				// pole cisel textur 
	pocet_textur = 0; 
	vertex = NULL;				// pole bodov 
	normal = NULL; 
	colors = NULL; 
	fog = NULL; 
	pasy = NULL; 
	prechod = NULL; 
	OcTree = NULL; 
 
	error=1; 
} 
 
Terrain::Terrain(char *subor) 
{ 
	FILE *sub=NULL; 
	char temp[300]; 
	 
	english ? load->Add("Loading terrain") : load->Add("Nacitavam teren"); 
	height_map = NULL;			// pole obsahujuce informacie o vyske 
	texture_map = NULL;			// pole obsahujuce informacie o texture 
	texture_map_x = 256; texture_map_z = 256; 
	split_x = 256; split_z = 256 ; 
	texture = NULL;				// pole cisel textur 
	pocet_textur = 0; 
	vertex = NULL;				// pole bodov 
	normal = NULL; 
	colors = NULL; 
	fog = NULL; 
	pasy = NULL; 
	prechod = NULL; 
	OcTree = NULL; 
	Diffuse = 0.8f; 
	Ambient = 0.2f; 
 
	sub = fopen(subor,"r"); 
	if(sub==NULL){error=1; return;} 
	GetString(temp, 300, sub); 
	while(temp[0] != NULL || !strcmp(temp,"ENDFILE") ) 
	{ 
		if(!strcmp(temp,"HEIGHT_MAP")) 
		{ 
			unsigned char water; 
			FILE* sub2; 
			GetString(temp, 300, sub); 
			sub2 = fopen(temp,"r"); 
			if(sub2 == NULL) {MessageBox(NULL,"Nemozem otvorit subor !",temp,MB_OK | MB_ICONERROR); error=1; fclose(sub);return;} 
			GetString(temp, 300, sub); 
			height_map_x = atoi(temp); 
			GetString(temp, 300, sub); 
			height_map_z = atoi(temp); 
			english ? load->Add("Loading height map") : load->Add("Nacitavam vyskovu mapu"); 
			height_map = new unsigned char[height_map_x*height_map_z]; 
			if(height_map==NULL){MessageBox(NULL,"Chyba","Malo pamete pri alokovani vyskovej mapy",MB_OK | MB_ICONERROR); error=1; fclose(sub); fclose(sub2); return;} 
			fread( height_map, height_map_x*height_map_z, 1, sub2 ); 
			fclose(sub2); 
			GetString(temp, 300, sub); 
			water = (unsigned char) atoi(temp); 
			for(int z=0; zAdd("Loading texture map") : load->Add("Nacitavam texturovu mapu"); 
			sub2 = fopen(meno_sub,"r"); 
			if(sub2 == NULL) {MessageBox(NULL,"Nemozem otvorit subor !",meno_sub,MB_OK | MB_ICONERROR); error=1; fclose(sub);return;} 
			texture_map = new unsigned char[texture_map_x*texture_map_z]; 
			if(texture_map==NULL){MessageBox(NULL,"Chyba","Malo pamete pre texturovu mapu",MB_OK | MB_ICONERROR); error=1; fclose(sub); fclose(sub2); return;} 
			fread( texture_map, texture_map_x*texture_map_z, 1, sub2 ); 
			fclose(sub2); 
			continue; 
		} 
		if(!strcmp(temp,"TEXTURE")) 
		{ 
			int num; 
			GetString(temp, 300, sub); 
			pocet_textur = atoi(temp); 
			pocet_textur++; 
			if(pocet_textur>255)continue; 
			texture = new unsigned int[pocet_textur]; 
			ZeroMemory( texture, pocet_textur*sizeof(unsigned int) ); 
			GetString(temp, 300, sub); 
 
			english ? load->Add("Loading textures of terrain") : load->Add("Nacitavam textury terenu"); 
			while( strcmp(temp,"END") && temp[0] != NULL) 
			{ 
				num = atoi(temp); 
				GetString(temp, 300, sub); 
				if(numAdd("Generating texture map from entered intervals") : 
						load->Add("Generujem texturovu mapu zo zadanych intervalov"); 
			texture_map = new unsigned char[texture_map_x*texture_map_z]; 
			if(texture_map==NULL){MessageBox(NULL,"Chyba","Malo pamete pre generovanu texturovu mapu",MB_OK | MB_ICONERROR); error=1; fclose(sub); return;} 
			 
			GetString(temp, 300, sub); 
			while( strcmp(temp,"END") && temp[0] != NULL) 
			{ 
				for(i=0; temp[i]!='-' && i<299; i++);		// presunieme i na poziciu '-' 
				temp[i] = NULL;								// nahradime '-' NULL 
				i++; 
				for(j=0; temp[i]!=NULL && i<299; j++) 
				{ 
					temp2[j] = temp[i];						// skopirujeme od '-' do NULL 
					i++; 
				} 
				temp2[j]=NULL; 
 
				horna = (float) atof(temp); 
				textura_akt = (unsigned int) atoi( temp2); 
				for(int z=0; zdolna && height_map[zi*height_map_x+xi]<=horna) 
						{ 
							texture_map[z*texture_map_x+x] = textura_akt; 
						} 
					} 
				} 
				dolna = horna; 
				GetString(temp, 300, sub); 
			} 
			continue; 
		} 
		GetString(temp, 300, sub); 
	} 
	fclose(sub); 
 
	if(height_map==NULL || texture_map==NULL || texture==NULL) 
	{ 
		MessageBox( NULL, "Chyba pri inicializacii terenu", "Chyba", MB_OK); 
		error = 1; 
		return; 
	} 
 
	english ? load->Add("Computing point of terrain") : load->Add("Vypocitavam body terenu"); 
	if( split_x != texture_map_x || split_z != texture_map_z)		// prisposobime texture_map velkosti delenia 
	{ 
		unsigned char* texture_map_pom = new unsigned char[split_x*split_z]; 
		if(texture_map_pom == NULL ) {MessageBox(NULL,"Chyba","Malo pamete pre pomocnu vyskovu mapu",MB_OK | MB_ICONERROR); error=1;return;} 
 
		for(int z=0; zAdd("Computing normal vectors") : load->Add("Vypocitavam normalove vektory"); 
	colors = new float[3*(split_x+1)*(split_z+1)]; 
	if(colors == NULL ) {MessageBox(NULL,"Chyba","Malo pamete pre colors",MB_OK | MB_ICONERROR); error=1;return;} 
	Vypocitaj_normalove_vektory(); 
	GLfloat LightPosition[4]=	{ -0.5477225575f, 0.83666f, 0.0f, 0.0f };		//smer difuzneho svetla - ak je 4 zlozka 0 - smerove svetlo, ak nie je 0 potom s jedna o bodove svetlo so suradnicami x,y,z 
	Vypocitaj_osvetlenie( &LightPosition[0] ); 
	 
	pasy   = new vector[split_z]; 
 
	cast_pasu p; 
	p.left = 0; 
	p.right = split_x-1; 
 
	for( int i = 0; iAdd("Computing transition") : load->Add("Vypocitavam prechody"); 
	prechod = new vector[split_z*pocet_textur]; 
	Vypln_prechody_stvorcov(); 
 
	float velkost; 
	if(size_OpenGL_x>size_OpenGL_z) velkost = size_OpenGL_x; 
	else velkost = size_OpenGL_z; 
	if(velkostAdd("Loading octree from file.") : load->Add("Nacitavam oktanovy strom zo subora."); 
	english ? load->Add("Count of nodes") : load->Add("Pocet listov"); 
	load->Add("0"); 
	OcTree = new OcTree_Terrain( vertex, pasy, velkost, split_x, split_z); 
	if(!OcTree->Load("data/teren.oct")) 
	{ 
		english ?	load->Update("Creating octree",load->index-2) :  
					load->Update("Vytvaram oktanovy strom",load->index-2); 
		delete OcTree; 
		OcTree = new OcTree_Terrain( vertex, pasy, velkost, split_x, split_z); 
		OcTree->Vytvor_vrchol(); 
		english ? load->Add("SAving octree to file") : load->Add("Ukladam oktanovy strom do suboru"); 
		OcTree->Save("data/teren.oct"); 
	} 
 
	fog = new float[(split_x+1)*(split_z+1)]; 
	if(fog == NULL ) {MessageBox(NULL,"Chyba","Malo pamete pre fog",MB_OK | MB_ICONERROR); error=1;return;} 
	for( i=0; i<(split_x+1)*(split_z+1); i++) fog[i] = 0; 
 
	volumetric_sphere s; 
 
/*	s.p[0] = 0; 
	s.p[2] = 8; 
	s.p[1] = Height( s.p[0], s.p[2]); 
	s.r = 20; 
	s.hustota = 0.05f; 
	volum_fog.push_back(s); 
*//*	s.p[0] = 50; 
	s.p[2] = 50; 
	s.p[1] = Height( s.p[0], s.p[2]); 
	s.r = 30; 
	s.hustota = 0.02f; 
	volum_fog.push_back(s); 
*/ 
	for( i=0; i<10; i++) 
	{ 
		s.p[0] = size_OpenGL_x*(-0.5f + (float)rand()/(float)RAND_MAX ); 
		s.p[2] = size_OpenGL_z*(-0.5f + (float)rand()/(float)RAND_MAX ); 
		s.p[1] = 8.f*(float)rand()/(float)RAND_MAX+Height( s.p[0], s.p[2]); 
		s.r = 10.f*(float)rand()/(float)RAND_MAX+4.f; 
		s.hustota = 0.3f/s.r; 
		volum_fog.push_back(s); 
	} 
 
	volumetric_plate pla; 
 
	pla.low[3] = -30.f*scale_height; 
	pla.high[3]= -50.f*scale_height; 
	pla.hustota= 0.4f/(25.f*scale_height); 
	volum_fog_plate.push_back(pla); 
 
	pla.low[3] = -50.f*scale_height; 
	pla.high[3]= -75.f*scale_height; 
	pla.hustota= 0.4f*0.75f/(25.f*scale_height); 
	volum_fog_plate.push_back(pla); 
 
	pla.low[3] = -75.f*scale_height; 
	pla.high[3]= -100.f*scale_height; 
	pla.hustota= 0.4f*0.5f/(25.f*scale_height); 
	volum_fog_plate.push_back(pla); 
 
	pla.low[3] = -100.f*scale_height; 
	pla.high[3]= -125.f*scale_height; 
	pla.hustota= 0.4f*0.25f/(25.f*scale_height); 
	volum_fog_plate.push_back(pla); 
	 
	pla.low[3] = -210.f*scale_height; 
	pla.high[3]= -255.f*scale_height; 
	pla.hustota= 0.4f/(45.f*scale_height); 
	volum_fog_plate.push_back(pla); 
 
//	pla.low[3] = -40.f*scale_height; 
//	pla.high[3]= -80.f*scale_height; 
//	pla.hustota= 0.5f/(40.f*scale_height); 
//	volum_fog_plate.push_back(pla); 
} 
 
Terrain::~Terrain() 
{ 
	if(height_map != NULL) delete[] height_map;			// pole obsahujuce informacie o vyske 
	if(texture_map != NULL) delete[] texture_map;			// pole obsahujuce informacie o texture 
	for(int i=0; i  pre polohu v terene 
	j = (z+size_OpenGL_z/2.0)/size_OpenGL_z; 
 
	i = (height_map_x-1)*fabs(i); 
	j = (height_map_z-1)*fabs(j); 
 
	x0_ = (int) floor(i);	// vrati mensiu celu cast 2.8 -> 2.0 
	y0_ = (int) floor(j);	// -2.8  -> -3.0 
 
	if(x0_ > height_map_x-1)x0_=0; 
	if(y0_ > height_map_z-1)y0_=0; 
 
	zx = fmod(i,1.0); 
	zz = fmod(j,1.0); 
 
	x0 = height_map[y0_*height_map_z + x0_]; 
	x1 = height_map[y0_*height_map_z + x0_ + 1]; 
	y0 = height_map[(y0_+1)*height_map_z + x0_]; 
	y1 = height_map[(y0_+1)*height_map_z + x0_ + 1]; 
 
	i = zx*(float)(x1-x0) + (float)x0;  
	j =	zx*(float)(y1-y0) + (float)y0; 
	i = zz*(j-i)+i; 
	return (float)i*scale_height; 
} 
 
unsigned int Terrain::Textura(int x, int z) 
{ 
	unsigned int temp; 
//	if( x >=texture_map_x) x %= texture_map_x; 
//	if( z >=texture_map_z) z %= texture_map_z; 
	 
//	temp = texture_map[z*texture_map_x+x]; 
//	if(temp >= POCET_TEXTUR)temp %= POCET_TEXTUR; 
//	if(temp==0)temp=1; 
 
	float xf,zf; 
 
	xf = x / (float)split_x; 
	zf = z / (float)split_z; 
 
	x = (int) (xf * (float)texture_map_x); 
	z = (int) (zf * (float)texture_map_z); 
	 
	temp = texture_map[z*texture_map_x+x]; 
	return temp; 
} 
 
void Terrain::SaveTextura_map(void) 
{ 
	FILE* sub; 
	unsigned char* textura = new unsigned char[texture_map_x*texture_map_z]; 
	if(textura==NULL){MessageBox(NULL,"Chyba","Malo pamete pre texturovu mapu",MB_OK | MB_ICONERROR); error=1;return;} 
	sub = fopen("data/textura.raw","w"); 
	if(sub == NULL) {MessageBox(NULL,"Nemozem otvorit data/textura.raw !","Chyba",MB_OK | MB_ICONERROR); error=1;return;} 
	for(int x=0; x 3*(2*split_x+2) 
	// potrebujeme o jeden pas a stlpec viac vrcholov ako mame pasov 3*(split_x+1)*(split_z+1) 
	vertex = new float[3*(split_x+1)*(split_z+1)]; 
 
	if(vertex == NULL ) {MessageBox(NULL,"Chyba","Malo pamete pre vertex !",MB_OK | MB_ICONERROR); error=1;return;} 
 
	ddx = dx / (float)split_x; 
	ddz = dz / (float)split_z; 
 
	for(z1 = 0; z1 < split_z+1 ; z1++)		// pre kazdy pas vrcholov 
	{ 
		z2 = z + z1 * ddz; 
		for(x1 = 0; x1 < split_x+1 ; x1++)	// pre vsetky vrcholy v danom pase 
		{ 
			x2 = x + x1 * ddx;				// vypocitame prislusne x 
			vertex[i++] = x2;				// ulozime x 
			vertex[i++] = Height(x2,z2);	// y 
			vertex[i++] = z2;				// z 
		} 
	} 
} 
 
static inline CROSSPROD( float *p1, float *p2, float *p3) 
{ 
	p3[0] = p1[1]*p2[2] - p1[2]*p2[1]; 
	p3[1] = p1[2]*p2[0] - p1[0]*p2[2]; 
	p3[2] = p1[0]*p2[1] - p1[1]*p2[0]; 
} 
 
static inline void Normalise(float *p) 
{	float length = (float) sqrt( p[0]*p[0] + p[1]*p[1] + p[2]*p[2]); 
	if (length != 0) {	p[0] /= length;		p[1] /= length;		p[2] /= length;	}  
	else {	p[2] = 0; p[1] = 0;	p[2] = 0;} 
} 
static inline void Odcitaj( float *c, float *a, float *b) 
{	c[0] = a[0] - b[0];	c[1] = a[1] - b[1];	c[2] = a[2] - b[2];	} 
static inline void Scitaj( float *c, float *a, float *b) 
{	c[0] = a[0] + b[0];	c[1] = a[1] + b[1];	c[2] = a[2] + b[2];	} 
static inline void Scitaj_a_del4( float *v, float *a, float *b, float *c, float *d) 
{	v[0] = a[0] + b[0] + c[0] + d[0]; 
	v[1] = a[1] + b[1] + c[1] + d[1]; 
	v[2] = a[2] + b[2] + c[2] + d[2]; 
	v[0] *= 0.25f; v[1] *= 0.25f; v[2] *= 0.25f;} 
static inline void Scitaj_a_del2( float *v, float *a, float *b) 
{	v[0] = a[0] + b[0];	v[1] = a[1] + b[1];	v[2] = a[2] + b[2]; 
	v[0] *= 0.25f; v[1] *= 0.25f; v[2] *= 0.25f;} 
static inline void Rovnasa( float *a, float *b)	{	memcpy( a, b, 3*sizeof(float) );} 
static inline void Nasob( float *c, float *a, float *b) 
{	c[0] = a[0] * b[0];	c[1] = a[1] * b[1];	c[2] = a[2] * b[2]; } 
static inline float Nasob( float *a, float *b) 
{	return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; } 
static inline float Velkost( float *p)	{	return (float) sqrt( p[0]*p[0] + p[1]*p[1] + p[2]*p[2]);} 
 
void Terrain::Vypocitaj_normalove_vektory() 
{ 
	float *n = NULL; 
	float a[3],b[3]; 
	int z,x; 
	int max_x = (split_x+1); 
 
	n = new float[3*split_z*split_x]; 
	if(n == NULL ) {MessageBox(NULL,"Malo pamete pre pomocne normalove vektory","Chyba",MB_OK | MB_ICONERROR); error=1;return;} 
	// vypocet normalovych vektorov pre plochy 
	for( z=0; z10.f) 
							{ 
							//	triangles++;triangles++; 
								s = -11.f; 
								glEnd(); 
								glBegin(GL_TRIANGLE_STRIP); 
								glTexCoord2f(s,1); 
								glVertex3fv(&vertex[3*(j*max_x+i)]); 
								glTexCoord2f(s,0); 
								glVertex3fv(&vertex[3*((j+1)*max_x+i)]); 
								s += 1.f; 
							}*/ 
						} 
					//	triangles++;triangles++; 
						glTexCoord2f(s,1); 
						glVertex3fv(&vertex[3*(j*max_x+i)]); 
						glTexCoord2f(s,0); 
						glVertex3fv(&vertex[3*((j+1)*max_x+i)]); 
						glEnd(); 
					} 
				} 
			} 
		} 
	} 
	glDisable(GL_FOG); 
	if(!keys['M'])//return; 
	for( textur=0; textur<(unsigned int)pocet_textur; textur++)	// pre kazdu texturu 
	{ 
		glBindTexture(GL_TEXTURE_2D, texture[textur]); 
		for( int z=0; z=0; i--) 
			{ 
				if(!(prechod[zi][i].typ % 2)) break; 
				if(!Je_v_pohlade( prechod[zi][i].x, &(pasy[z]) ) ) continue; 
				switch(prechod[zi][i].typ) 
				{ 
				case _10: 
					glBegin(GL_TRIANGLE_STRIP); 
					glColor3fv( w); 
					glTexCoord2f(0,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(0,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glColor3fv( b); 
					glTexCoord2f(1,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glTexCoord2f(1,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case __10: 
					glBegin(GL_TRIANGLE_STRIP); 
					glColor3fv( w); 
					glTexCoord2f(0,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glColor3fv( b); 
					glTexCoord2f(0,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glColor3fv( w); 
					glTexCoord2f(1,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glColor3fv( b); 
					glTexCoord2f(1,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1110: 
					glBegin(GL_TRIANGLE_STRIP); 
					glColor3fv( w); 
					glTexCoord2f(0,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(0,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(1,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glColor3fv( b); 
					glTexCoord2f(1,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1011: 
					glBegin(GL_TRIANGLE_STRIP); 
					glColor3fv( w); 
					glTexCoord2f(0,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(0,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glColor3fv( b); 
					glTexCoord2f(1,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glColor3fv( w); 
					glTexCoord2f(1,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1101: 
					glBegin(GL_TRIANGLE_STRIP); 
					glColor3fv( w); 
					glTexCoord2f(0,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glColor3fv( b); 
					glTexCoord2f(0,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glColor3fv( w); 
					glTexCoord2f(1,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glTexCoord2f(1,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _0111: 
					glBegin(GL_TRIANGLE_STRIP); 
					glColor3fv( b); 
					glTexCoord2f(0,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glColor3fv( w); 
					glTexCoord2f(0,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(1,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glTexCoord2f(1,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1001: 
					glBegin(GL_TRIANGLE_STRIP); 
					glColor3fv( w); 
					glTexCoord2f(0,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glColor3fv( b); 
					glTexCoord2f(0,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(1,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glColor3fv( w); 
					glTexCoord2f(1,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				} 
			} 
		} 
	} 
 
//	glBlendFunc(GL_ZERO, GL_SRC_COLOR); 
/*	if(fog)glEnable(GL_FOG); 
	if(fog && keys['I']) 
	{ 
		glDisable(GL_TEXTURE_2D); 
		glColor3fv( b); 
		for( int z=0; z parne; 
	vector neparne; 
 
	// usporiadnie tak, aby isli najprv prechody z parnym typom a potom z neparnym 
	for( int z=0; z *p) 
{ 
	for( int i=0; isize(); i++) 
	{ 
		if( x>=(*p)[i].left && x <= (*p)[i].right) return 1; 
	} 
	return 0; 
} 
 
void Terrain::Kresli_glBegin_normal() 
{ 
	int max_x,zi; 
	triangles=0; 
	float w[4] = {1,1,1,1}; 
	float b[4] = {0,0,0,1}; 
 
	max_x = (split_x+1); 
	for(unsigned int textur=0; textur<(unsigned int)pocet_textur; textur++)	// pre kazdu texturu 
	{ 
		glBindTexture(GL_TEXTURE_2D, texture[textur]); 
		if(!keys['Z']) 
		for(int j = 0; j < split_z; j++)						// pre vsetky pasy 
		{ 
			for(int cast=0; cast < pasy[j].size();cast ++) 
			{ 
				int right = pasy[j][cast].right; 
				//for(int i = pasy[j][cast].left; i <= pasy[j][cast].right; i++) 
				for(int i = pasy[j][cast].left; i <= right; i++) 
				{ 
					if(texture_map[(j*split_x+i)]==textur)		// ak textura stvorca je == ako aktualna textura 
					{ 
						float s = -11.f; 
						glBegin(GL_TRIANGLE_STRIP); 
						//for(; (i <= pasy[j][cast].right)&&(texture_map[(j*split_x+i)]==textur); i++)	// kreslime pokial neskonci pas a textura je == aktualnej 
						for(; (i <= right)&&(texture_map[(j*split_x+i)]==textur); i++)	// kreslime pokial neskonci pas a textura je == aktualnej 
						{ 
							glTexCoord2f(s,1);		// parne vrcholy 
							glNormal3fv(&normal[3*(j*max_x+i)]); 
							glVertex3fv(&vertex[3*(j*max_x+i)]); 
							glTexCoord2f(s,0);		// neparne vrcholy 
							glNormal3fv(&normal[3*((j+1)*max_x+i)]); 
							glVertex3fv(&vertex[3*((j+1)*max_x+i)]); 
							s += 1.f; 
 
							triangles++;triangles++; 
 
						/*	if(s>10.f) 
							{ 
							//	triangles++;triangles++; 
								s = -11.f; 
								glEnd(); 
								glBegin(GL_TRIANGLE_STRIP); 
								glTexCoord2f(s,1); 
								glNormal3fv(&normal[3*(j*max_x+i)]); 
								glVertex3fv(&vertex[3*(j*max_x+i)]); 
								glTexCoord2f(s,0); 
								glNormal3fv(&normal[3*((j+1)*max_x+i)]); 
								glVertex3fv(&vertex[3*((j+1)*max_x+i)]); 
								s += 1.f; 
							}*/ 
						} 
					//	triangles++;triangles++; 
						glTexCoord2f(s,1); 
						glNormal3fv(&normal[3*(j*max_x+i)]); 
						glVertex3fv(&vertex[3*(j*max_x+i)]); 
						glTexCoord2f(s,0); 
						glNormal3fv(&normal[3*((j+1)*max_x+i)]); 
						glVertex3fv(&vertex[3*((j+1)*max_x+i)]); 
						glEnd(); 
					} 
				} 
			} 
		} 
	} 
	if(keys['M']) return; 
	for( textur=0; textur<(unsigned int)pocet_textur; textur++)	// pre kazdu texturu 
	{ 
		glBindTexture(GL_TEXTURE_2D, texture[textur]); 
		for( int z=0; z=0; i--) 
			{ 
				if(!(prechod[zi][i].typ % 2)) break; 
				if(!Je_v_pohlade( prechod[zi][i].x, &(pasy[z]) ) ) continue; 
				switch(prechod[zi][i].typ) 
				{ 
				case _10: 
					glBegin(GL_TRIANGLE_STRIP); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
					glTexCoord2f(0,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(0,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , b); 
					glTexCoord2f(1,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glTexCoord2f(1,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case __10: 
					glBegin(GL_TRIANGLE_STRIP); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
					glTexCoord2f(0,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , b); 
					glTexCoord2f(0,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
					glTexCoord2f(1,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , b); 
					glTexCoord2f(1,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1110: 
					glBegin(GL_TRIANGLE_STRIP); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
					glTexCoord2f(0,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(0,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(1,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , b); 
					glTexCoord2f(1,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1011: 
					glBegin(GL_TRIANGLE_STRIP); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
					glTexCoord2f(0,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(0,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , b); 
					glTexCoord2f(1,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
					glTexCoord2f(1,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1101: 
					glBegin(GL_TRIANGLE_STRIP); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
					glTexCoord2f(0,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , b); 
					glTexCoord2f(0,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
					glTexCoord2f(1,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glTexCoord2f(1,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _0111: 
					glBegin(GL_TRIANGLE_STRIP); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , b); 
					glTexCoord2f(0,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
					glTexCoord2f(0,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(1,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glTexCoord2f(1,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1001: 
					glBegin(GL_TRIANGLE_STRIP); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
					glTexCoord2f(0,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , b); 
					glTexCoord2f(0,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(1,1); 
					glNormal3fv(&normal[3*(z*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
					glTexCoord2f(1,0); 
					glNormal3fv(&normal[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				} 
			} 
		} 
	} 
	glDisable(GL_BLEND); 
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE , w); 
} 
 
void Terrain::Kresli_normaly() 
{ 
	int max_x = (split_x+1); 
 
	glColor3f(1,1,0); 
	glBegin(GL_LINES); 
	for(int z = 0; z < split_z; z++)						// pre vsetky pasy 
	{ 
		for(int cast=0; cast < pasy[z].size();cast ++) 
		{ 
			int right = pasy[z][cast].right+1; 
			for(int x = pasy[z][cast].left; x <= right; x++) 
			{ 
							glVertex3fv( &vertex[ 3*(z*max_x+x) ] ); 
				glVertex3f( vertex[ 3*(z*max_x+x) + 0] + normal[ 3*(z*max_x+x) + 0],  
							vertex[ 3*(z*max_x+x) + 1] + normal[ 3*(z*max_x+x) + 1],  
							vertex[ 3*(z*max_x+x) + 2] + normal[ 3*(z*max_x+x) + 2] ); 
			} 
		} 
	} 
 
	z = split_z-1; 
	for(int cast=0; cast < pasy[z].size();cast ++) 
	{ 
		int right = pasy[z][cast].right+1; 
		for(int x = pasy[z][cast].left; x <= right; x++) 
		{ 
			glVertex3fv( &vertex[ 3*((z+1)*max_x+x) ] ); 
			glVertex3f( vertex[ 3*((z+1)*max_x+x) + 0] + normal[ 3*((z+1)*max_x+x) + 0],  
						vertex[ 3*((z+1)*max_x+x) + 1] + normal[ 3*((z+1)*max_x+x) + 1],  
						vertex[ 3*((z+1)*max_x+x) + 2] + normal[ 3*((z+1)*max_x+x) + 2] ); 
		} 
	} 
 
	glEnd(); 
	glColor3f(1,1,1); 
} 
 
 
void Terrain::Kresli_glBegin_colors() 
{ 
	int max_x,zi; 
	triangles=0; 
	float w[3] = {1,1,1}; 
	float b[3] = {0,0,0}; 
 
	max_x = (split_x+1); 
	for(unsigned int textur=0; textur<(unsigned int)pocet_textur; textur++)	// pre kazdu texturu 
	{ 
		glBindTexture(GL_TEXTURE_2D, texture[textur]); 
		if(!keys['Z']) 
		for(int j = 0; j < split_z; j++)						// pre vsetky pasy 
		{ 
			for(int cast=0; cast < pasy[j].size();cast ++) 
			{ 
				int right = pasy[j][cast].right; 
				//for(int i = pasy[j][cast].left; i <= pasy[j][cast].right; i++) 
				for(int i = pasy[j][cast].left; i <= right; i++) 
				{ 
					if(texture_map[(j*split_x+i)]==textur)		// ak textura stvorca je == ako aktualna textura 
					{ 
						float s = -11.f; 
						glBegin(GL_TRIANGLE_STRIP); 
						//for(; (i <= pasy[j][cast].right)&&(texture_map[(j*split_x+i)]==textur); i++)	// kreslime pokial neskonci pas a textura je == aktualnej 
						for(; (i <= right)&&(texture_map[(j*split_x+i)]==textur); i++)	// kreslime pokial neskonci pas a textura je == aktualnej 
						{ 
							glTexCoord2f(s,1);		// parne vrcholy 
							glColor3fv(&colors[3*(j*max_x+i)]); 
							glVertex3fv(&vertex[3*(j*max_x+i)]); 
							glTexCoord2f(s,0);		// neparne vrcholy 
							glColor3fv(&colors[3*((j+1)*max_x+i)]); 
							glVertex3fv(&vertex[3*((j+1)*max_x+i)]); 
							s += 1.f; 
 
							triangles++;triangles++; 
 
							if(s>10.f) 
							{ 
							//	triangles++;triangles++; 
								s = -11.f; 
								glEnd(); 
								glBegin(GL_TRIANGLE_STRIP); 
								glTexCoord2f(s,1); 
								glColor3fv(&colors[3*(j*max_x+i)]); 
								glVertex3fv(&vertex[3*(j*max_x+i)]); 
								glTexCoord2f(s,0); 
								glColor3fv(&colors[3*((j+1)*max_x+i)]); 
								glVertex3fv(&vertex[3*((j+1)*max_x+i)]); 
								s += 1.f; 
							} 
						} 
					//	triangles++;triangles++; 
						glTexCoord2f(s,1); 
						glColor3fv(&colors[3*(j*max_x+i)]); 
						glVertex3fv(&vertex[3*(j*max_x+i)]); 
						glTexCoord2f(s,0); 
						glColor3fv(&colors[3*((j+1)*max_x+i)]); 
						glVertex3fv(&vertex[3*((j+1)*max_x+i)]); 
						glEnd(); 
					} 
				} 
			} 
		} 
	} 
	if(keys['M'])return; 
	for( textur=0; textur<(unsigned int)pocet_textur; textur++)	// pre kazdu texturu 
	{ 
		glBindTexture(GL_TEXTURE_2D, texture[textur]); 
		for( int z=0; z=0; i--) 
			{ 
				if(!(prechod[zi][i].typ % 2)) break; 
				if(!Je_v_pohlade( prechod[zi][i].x, &(pasy[z]) ) ) continue; 
				switch(prechod[zi][i].typ) 
				{ 
				case _10: 
					glBegin(GL_TRIANGLE_STRIP); 
				//	glColor3fv( w); 
					glTexCoord2f(0,1); 
					glColor3fv(&colors[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(0,0); 
					glColor3fv(&colors[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glColor3fv( b); 
					glTexCoord2f(1,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glTexCoord2f(1,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case __10: 
					glBegin(GL_TRIANGLE_STRIP); 
				//	glColor3fv( w); 
					glTexCoord2f(0,1); 
					glColor3fv(&colors[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glColor3fv( b); 
					glTexCoord2f(0,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
				//	glColor3fv( w); 
					glTexCoord2f(1,1); 
					glColor3fv(&colors[3*(z*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glColor3fv( b); 
					glTexCoord2f(1,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1110: 
					glBegin(GL_TRIANGLE_STRIP); 
				//	glColor3fv( w); 
					glTexCoord2f(0,1); 
					glColor3fv(&colors[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(0,0); 
					glColor3fv(&colors[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(1,1); 
					glColor3fv(&colors[3*(z*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glColor3fv( b); 
					glTexCoord2f(1,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1011: 
					glBegin(GL_TRIANGLE_STRIP); 
				//	glColor3fv( w); 
					glTexCoord2f(0,1); 
					glColor3fv(&colors[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(0,0); 
					glColor3fv(&colors[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glColor3fv( b); 
					glTexCoord2f(1,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
				//	glColor3fv( w); 
					glTexCoord2f(1,0); 
					glColor3fv(&colors[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1101: 
					glBegin(GL_TRIANGLE_STRIP); 
				//	glColor3fv( w); 
					glTexCoord2f(0,1); 
					glColor3fv(&colors[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glColor3fv( b); 
					glTexCoord2f(0,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
				//	glColor3fv( w); 
					glTexCoord2f(1,1); 
					glColor3fv(&colors[3*(z*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glTexCoord2f(1,0); 
					glColor3fv(&colors[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _0111: 
					glBegin(GL_TRIANGLE_STRIP); 
					glColor3fv( b); 
					glTexCoord2f(0,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
				//	glColor3fv( w); 
					glTexCoord2f(0,0); 
					glColor3fv(&colors[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(1,1); 
					glColor3fv(&colors[3*(z*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
					glTexCoord2f(1,0); 
					glColor3fv(&colors[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				case _1001: 
					glBegin(GL_TRIANGLE_STRIP); 
				//	glColor3fv( w); 
					glTexCoord2f(0,1); 
					glColor3fv(&colors[3*(z*max_x+prechod[zi][i].x)]); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x)]); 
					glColor3fv( b); 
					glTexCoord2f(0,0); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x)]); 
					glTexCoord2f(1,1); 
					glVertex3fv(&vertex[3*(z*max_x+prechod[zi][i].x+1)]); 
				//	glColor3fv( w); 
					glTexCoord2f(1,0); 
					glColor3fv(&colors[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+prechod[zi][i].x+1)]); 
					glEnd(); 
					triangles++;triangles++; 
					break; 
				} 
			} 
		} 
	} 
	glDisable(GL_BLEND); 
	glColor3fv( w); 
} 
 
void Terrain::Kresli_Fog() 
{ 
	int max_x = (split_x+1); 
	float c[3] = {0.6f, 0.6f, 0.6f}; 
 
	glBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); 
	glEnable(GL_BLEND); 
	glDisable(GL_TEXTURE_2D); 
	for(int z=0; z0.999f && fog[z*max_x+x+1]>0.999f && fog[(z+1)*max_x+x]>0.999f && fog[(z+1)*max_x+x+1]>0.999f) 
				{ 
					glColor4f(c[0], c[1], c[2], fog[z*max_x+x]); 
					glVertex3fv(&vertex[3*(z*max_x+x)]); 
					glColor4f(c[0], c[1], c[2], fog[(z+1)*max_x+x]); 
					glVertex3fv(&vertex[3*((z+1)*max_x+x)]); 
					glEnd(); 
 
					for( x++; x<=right && fog[z*max_x+x+1]>0.999f && fog[(z+1)*max_x+x+1]>0.999f; x++); 
					 
					if(x<=right) 
					{ 
						glBegin(GL_TRIANGLE_STRIP); 
						glColor4f(c[0], c[1], c[2], fog[z*max_x+x]); 
						glVertex3fv(&vertex[3*(z*max_x+x)]); 
						glColor4f(c[0], c[1], c[2], fog[(z+1)*max_x+x]); 
						glVertex3fv(&vertex[3*((z+1)*max_x+x)]); 
						triangles++;triangles++; 
					} 
					continue; 
				} 
				glColor4f(c[0], c[1], c[2], fog[z*max_x+x]); 
				glVertex3fv(&vertex[3*(z*max_x+x)]); 
				glColor4f(c[0], c[1], c[2], fog[(z+1)*max_x+x]); 
				glVertex3fv(&vertex[3*((z+1)*max_x+x)]); 
				triangles++;triangles++; 
			} 
			if(x==(right+1)) 
			{ 
				glColor4f(c[0], c[1], c[2], fog[z*max_x+x]); 
				glVertex3fv(&vertex[3*(z*max_x+x)]); 
				glColor4f(c[0], c[1], c[2], fog[(z+1)*max_x+x]); 
				glVertex3fv(&vertex[3*((z+1)*max_x+x)]); 
				glEnd(); 
			} 
		} 
	} 
	glEnable(GL_TEXTURE_2D); 
	glDisable(GL_BLEND); 
} 
 
static inline float Distance( float *a, float *b) 
{	return (float)sqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) + (a[2]-b[2])*(a[2]-b[2]) ); } 
static inline float Distance_( float *a, float *b) 
{	return (float)    ( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) + (a[2]-b[2])*(a[2]-b[2]) ); } 
static inline float Linear_max( float d){	return d; } 
static inline float Linear_od_x( float d) 
{	if( d < 0.5f )	return d*2.0f; else return 1.f; } 
static inline float Mocnina2( float d){	return d*d;	} 
static inline float Odmocnina( float d){	return (float)sqrt(d);	} 
static inline float EXP( float d, float clip_distance){	return (float)exp( -0.03f*d*clip_distance);	} 
static inline float EXP2( float d, float clip_distance){	return (float)exp( -(0.03f*d*clip_distance)*(0.03f*d*clip_distance));	} 
 
void Terrain::Vypocitaj_Fog(float *vp, float clip_distance) 
{ 
	int max_x = (split_x+1); 
	float p; 
 
	clip_distance = 1/clip_distance; 
	 
	for(int z=0; zp[0] );		// z = vp - p 
	 
	// rovnica gule x*x + y*y + z*z - r = 0 
	a = n[0]*n[0] + n[1]*n[1] + n[2]*n[2]; 
	b = 2*(n[0]*z[0] + n[1]*z[1] + n[2]*z[2]); 
//	c = z[0]*z[0] + z[1]*z[1] + z[2]*z[2] - s->r*s->r; 
 
	if(Ries_kvadrat( a, b, c, &t[0] ) ) 
	{ 
		if( (t[0]>1 && t[1]>1) || (t[0]<0 && t[1]<0)) 
		{ 
			return 0.f; 
		} 
		if(t[1] > 1) t[1] = 1; 
		if(t[0] < 0) t[0] = 0; 
		return s->hustota*fabs(t[1]-t[0])*sqrt(a); 
	//	if(t[0] < 0)	Rovnasa( &x1[0], &vp[0] ); 
	//	else	Vypoc_bod( &x1[0], &vp[0], &n[0], t[0]); 
	//	Vypoc_bod( &x2[0], &vp[0], &n[0], t[1]); 
	//	return s->hustota*Distance( &x1[0], &x2[0] ); 
	} 
	else return 0; 
} 
 
void Terrain::Vypocitaj_Volumetric_Fog_Sphere(float *vp, CFrustum *Frustum) 
{ 
	int max_x = (split_x+1); 
	float *c_pom; 
	float *z_pom; 
	bool  *je_v_pohlade; 
 
	if(!volum_fog.size() )return; 
	c_pom = new float[volum_fog.size()]; 
	z_pom = new float[3*volum_fog.size()]; 
	je_v_pohlade = new bool[volum_fog.size()]; 
 
 
	if(keys['W'] && keys[VK_ADD])volum_fog[0].hustota += 0.001f; 
	if(keys['W'] && keys[VK_SUBTRACT])volum_fog[0].hustota -= 0.001f; 
 
	for(int i=0; iSphereInFrustum( volum_fog[i].p[0], volum_fog[i].p[1], volum_fog[i].p[2], volum_fog[i].r); 
	} 
 
	for(int z=0; zlow[0] , vp) + p->low[3]  )/ Nasob( &s[0], &p->low[0] ); 
//	t[1] = -( Nasob( &p->high[0], vp) + p->high[3] )/ Nasob( &s[0], &p->high[0]); 
	t[0] = 1.f / Nasob( &s[0], l ); 
	t[1] = 1.f / Nasob( &s[0], h ); 
 
	if( t[0] > 1 ) t[0] = 1; 
	if( t[1] > 1 ) t[1] = 1; 
 
	if( t[0] < 0 ) t[0] = 0; 
	if( t[1] < 0 ) t[1] = 0; 
	 
//	Vypoc_bod( &x1[0], vp, &s[0], t[0]); 
//	Vypoc_bod( &x2[0], vp, &s[0], t[0]); 
 
	return p->hustota*fabs(t[1]-t[0])*Velkost( &s[0]); 
} 
 
void Terrain::Vypocitaj_Volumetric_Fog_Plate(float *vp) 
{ 
	int max_x = (split_x+1); 
	float *l,*h; 
 
	if(!volum_fog_plate.size()) return; 
	l = new float[3*volum_fog_plate.size()]; 
	h = new float[3*volum_fog_plate.size()]; 
	for(int i=0; i