5 extern float viewdistance;
6 extern float lightambient[3],lightbrightness[3];
7 extern float fadestart;
8 extern int environment;
11 extern float multiplier;
12 extern FRUSTUM frustum;
13 extern float texdetail,terraindetail;
16 extern float blurness;
17 extern float targetblurness;
18 extern Objects objects;
19 extern TGAImageRec texture;
21 extern bool visibleloading;
22 extern bool skyboxtexture;
23 extern int tutoriallevel;
27 int Terrain::lineTerrain(XYZ p1,XYZ p2, XYZ *p)
30 static float distance;
31 static float olddistance;
32 static int intersecting;
33 static int firstintersecting;
35 static int startx,starty;
38 static int numtris=(size-1)*(size-1)*2;
39 static float highest,lowest;
55 if(startx>endx){i=endx;endx=startx;startx=i;}
56 if(starty>endy){i=endy;endy=starty;starty=i;}
60 if(endx>size-1)endx=size-1;
61 if(endy>size-1)endy=size-1;
63 for(i=startx;i<=endx;i++){
64 for(j=starty;j<=endy;j++){
68 if(heightmap[i+k][j]>highest)highest=heightmap[i+k][j];
69 if(heightmap[i+k][j]<lowest)lowest=heightmap[i+k][j];
70 if(heightmap[i+k][j+1]>highest)highest=heightmap[i+k][j+1];
71 if(heightmap[i+k][j+1]<lowest)lowest=heightmap[i+k][j+1];
73 if((p1.y<=highest||p2.y<=highest)&&(p1.y>=lowest||p2.y>=lowest)){
75 triangles[0].y=heightmap[i][j];
79 triangles[1].y=heightmap[i][j+1];
83 triangles[2].y=heightmap[i+1][j];
86 intersecting=LineFacet(p1,p2,triangles[0],triangles[1],triangles[2],&point);
87 distance=findDistancefast(&p1,&point);
88 if((distance<olddistance||firstintersecting==-1)&&intersecting==1){olddistance=distance; firstintersecting=1; *p=point;}
91 triangles[0].y=heightmap[i+1][j];
95 triangles[1].y=heightmap[i][j+1];
99 triangles[2].y=heightmap[i+1][j+1];
102 intersecting=LineFacet(p1,p2,triangles[0],triangles[1],triangles[2],&point);
103 distance=findDistancefast(&p1,&point);
104 if((distance<olddistance||firstintersecting==-1)&&intersecting==1){olddistance=distance; firstintersecting=1; *p=point;}
108 return firstintersecting;
111 void Terrain::UpdateTransparency(int whichx, int whichy){
113 static int i,j,a,b,c,d,patch_size,stepsize;
114 static float distance;
116 static float viewdistsquared;
118 viewdistsquared=viewdistance*viewdistance;
119 patch_size=size/subdivision;
122 c=whichx*patch_elements+whichy*patch_elements*subdivision;
124 for(i=patch_size*whichx;i<patch_size*(whichx+1)+1;i+=stepsize){
125 for(j=patch_size*whichy;j<patch_size*(whichy+1)+1;j+=stepsize){
129 vertex.y=heightmap[i][j]*scale;
130 distance=findDistancefast(&viewer,&vertex);
131 if(distance>viewdistsquared)distance=viewdistsquared;
132 colors[i][j][3]=(viewdistsquared-(distance-(viewdistsquared*fadestart))*(1/(1-fadestart)))/viewdistsquared;
137 for(i=patch_size*whichx;i<patch_size*(whichx+1);i+=stepsize){
138 for(j=patch_size*whichy;j<patch_size*(whichy+1);j+=stepsize){
139 a=(i-(patch_size*whichx))/stepsize;
140 b=(j-(patch_size*whichy))/stepsize;
141 d=(a*54)+(b*54*patch_size/stepsize);
142 vArray[d+c+6]=colors[i][j][3];
144 vArray[d+c+15]=colors[i][j+stepsize][3];
146 vArray[d+c+24]=colors[i+stepsize][j][3];
148 vArray[d+c+33]=colors[i+stepsize][j][3];
150 vArray[d+c+42]=colors[i][j+stepsize][3];
152 vArray[d+c+51]=colors[i+stepsize][j+stepsize][3];
157 void Terrain::UpdateTransparencyother(int whichx, int whichy){
159 static int i,j,a,b,c,d,patch_size,stepsize;
160 static float distance;
162 patch_size=size/subdivision;
165 c=whichx*patch_elements+whichy*patch_elements*subdivision;
167 for(i=patch_size*whichx;i<patch_size*(whichx+1);i+=stepsize){
168 for(j=patch_size*whichy;j<patch_size*(whichy+1);j+=stepsize){
169 a=(i-(patch_size*whichx))/stepsize;
170 b=(j-(patch_size*whichy))/stepsize;
171 d=(a*54)+(b*54*patch_size/stepsize);
172 vArray[d+c+6]=colors[i][j][3]*opacityother[i][j];
174 vArray[d+c+15]=colors[i][j+stepsize][3]*opacityother[i][j+stepsize];
176 vArray[d+c+24]=colors[i+stepsize][j][3]*opacityother[i+stepsize][j];
178 vArray[d+c+33]=colors[i+stepsize][j][3]*opacityother[i+stepsize][j];
180 vArray[d+c+42]=colors[i][j+stepsize][3]*opacityother[i][j+stepsize];
182 vArray[d+c+51]=colors[i+stepsize][j+stepsize][3]*opacityother[i+stepsize][j+stepsize];
187 void Terrain::UpdateTransparencyotherother(int whichx, int whichy){
189 static int i,j,a,b,c,d,patch_size,stepsize;
190 static float distance;
192 static float viewdistsquared;
194 viewdistsquared=viewdistance*viewdistance;
195 patch_size=size/subdivision;
198 c=whichx*patch_elements+whichy*patch_elements*subdivision;
200 for(i=patch_size*whichx;i<patch_size*(whichx+1)+1;i+=stepsize){
201 for(j=patch_size*whichy;j<patch_size*(whichy+1)+1;j+=stepsize){
205 vertex.y=heightmap[i][j]*scale;
206 distance=findDistancefast(&viewer,&vertex);
207 if(distance>viewdistsquared)distance=viewdistsquared;
208 colors[i][j][3]=(viewdistsquared-(distance-(viewdistsquared*fadestart))*(1/(1-fadestart)))/viewdistsquared;
213 for(i=patch_size*whichx;i<patch_size*(whichx+1);i+=stepsize){
214 for(j=patch_size*whichy;j<patch_size*(whichy+1);j+=stepsize){
215 a=(i-(patch_size*whichx))/stepsize;
216 b=(j-(patch_size*whichy))/stepsize;
217 d=(a*54)+(b*54*patch_size/stepsize);
218 vArray[d+c+6]=colors[i][j][3];
220 vArray[d+c+15]=colors[i][j+stepsize][3];
222 vArray[d+c+24]=colors[i+stepsize][j][3];
224 vArray[d+c+33]=colors[i+stepsize][j][3];
226 vArray[d+c+42]=colors[i][j+stepsize][3];
228 vArray[d+c+51]=colors[i+stepsize][j+stepsize][3];
233 void Terrain::UpdateVertexArray(int whichx, int whichy){
234 static int i,j,a,b,c,patch_size,stepsize;
237 numtris[whichx][whichy]=0;
239 patch_size=size/subdivision;
242 c=whichx*patch_elements+whichy*patch_elements*subdivision;
243 for(i=patch_size*whichx;i<patch_size*(whichx+1);i+=stepsize){
244 for(j=patch_size*whichy;j<patch_size*(whichy+1);j+=stepsize){
245 a=(i-((float)size/subdivision*(float)whichx))/stepsize;
246 b=(j-((float)size/subdivision*(float)whichy))/stepsize;
247 vArray[(a*54)+(b*54*patch_size/stepsize)+c+0]=i*scale;
248 vArray[(a*54)+(b*54*patch_size/stepsize)+c+1]=heightmap[i][j]*scale;
249 vArray[(a*54)+(b*54*patch_size/stepsize)+c+2]=j*scale;
250 vArray[(a*54)+(b*54*patch_size/stepsize)+c+3]=colors[i][j][0];
251 vArray[(a*54)+(b*54*patch_size/stepsize)+c+4]=colors[i][j][1];
252 vArray[(a*54)+(b*54*patch_size/stepsize)+c+5]=colors[i][j][2];
253 vArray[(a*54)+(b*54*patch_size/stepsize)+c+6]=colors[i][j][3];
254 vArray[(a*54)+(b*54*patch_size/stepsize)+c+7]=i*scale*texscale+texoffsetx[i][j];
255 vArray[(a*54)+(b*54*patch_size/stepsize)+c+8]=j*scale*texscale+texoffsety[i][j];
257 vArray[(a*54)+(b*54*patch_size/stepsize)+c+9]=i*scale;
258 vArray[(a*54)+(b*54*patch_size/stepsize)+c+10]=heightmap[i][j+stepsize]*scale;
259 vArray[(a*54)+(b*54*patch_size/stepsize)+c+11]=j*scale+stepsize*scale;
260 vArray[(a*54)+(b*54*patch_size/stepsize)+c+12]=colors[i][j+stepsize][0];
261 vArray[(a*54)+(b*54*patch_size/stepsize)+c+13]=colors[i][j+stepsize][1];
262 vArray[(a*54)+(b*54*patch_size/stepsize)+c+14]=colors[i][j+stepsize][2];
263 vArray[(a*54)+(b*54*patch_size/stepsize)+c+15]=colors[i][j+stepsize][3];
264 vArray[(a*54)+(b*54*patch_size/stepsize)+c+16]=i*scale*texscale+texoffsetx[i][j+stepsize];
265 vArray[(a*54)+(b*54*patch_size/stepsize)+c+17]=j*scale*texscale+stepsize*scale*texscale+texoffsety[i][j+stepsize];
267 vArray[(a*54)+(b*54*patch_size/stepsize)+c+18]=i*scale+stepsize*scale;
268 vArray[(a*54)+(b*54*patch_size/stepsize)+c+19]=heightmap[i+stepsize][j]*scale;
269 vArray[(a*54)+(b*54*patch_size/stepsize)+c+20]=j*scale;
270 vArray[(a*54)+(b*54*patch_size/stepsize)+c+21]=colors[i+stepsize][j][0];
271 vArray[(a*54)+(b*54*patch_size/stepsize)+c+22]=colors[i+stepsize][j][1];
272 vArray[(a*54)+(b*54*patch_size/stepsize)+c+23]=colors[i+stepsize][j][2];
273 vArray[(a*54)+(b*54*patch_size/stepsize)+c+24]=colors[i+stepsize][j][3];
274 vArray[(a*54)+(b*54*patch_size/stepsize)+c+25]=i*scale*texscale+stepsize*scale*texscale+texoffsetx[i+stepsize][j];
275 vArray[(a*54)+(b*54*patch_size/stepsize)+c+26]=j*scale*texscale+texoffsety[i+stepsize][j];
277 vArray[(a*54)+(b*54*patch_size/stepsize)+c+27]=i*scale+stepsize*scale;
278 vArray[(a*54)+(b*54*patch_size/stepsize)+c+28]=heightmap[i+stepsize][j]*scale;
279 vArray[(a*54)+(b*54*patch_size/stepsize)+c+29]=j*scale;
280 vArray[(a*54)+(b*54*patch_size/stepsize)+c+30]=colors[i+stepsize][j][0];
281 vArray[(a*54)+(b*54*patch_size/stepsize)+c+31]=colors[i+stepsize][j][1];
282 vArray[(a*54)+(b*54*patch_size/stepsize)+c+32]=colors[i+stepsize][j][2];
283 vArray[(a*54)+(b*54*patch_size/stepsize)+c+33]=colors[i+stepsize][j][3];
284 vArray[(a*54)+(b*54*patch_size/stepsize)+c+34]=i*scale*texscale+stepsize*scale*texscale+texoffsetx[i+stepsize][j];
285 vArray[(a*54)+(b*54*patch_size/stepsize)+c+35]=j*scale*texscale+texoffsety[i+stepsize][j];
287 vArray[(a*54)+(b*54*patch_size/stepsize)+c+36]=i*scale;
288 vArray[(a*54)+(b*54*patch_size/stepsize)+c+37]=heightmap[i][j+stepsize]*scale;
289 vArray[(a*54)+(b*54*patch_size/stepsize)+c+38]=j*scale+stepsize*scale;
290 vArray[(a*54)+(b*54*patch_size/stepsize)+c+39]=colors[i][j+stepsize][0];
291 vArray[(a*54)+(b*54*patch_size/stepsize)+c+40]=colors[i][j+stepsize][1];
292 vArray[(a*54)+(b*54*patch_size/stepsize)+c+41]=colors[i][j+stepsize][2];
293 vArray[(a*54)+(b*54*patch_size/stepsize)+c+42]=colors[i][j+stepsize][3];
294 vArray[(a*54)+(b*54*patch_size/stepsize)+c+43]=i*scale*texscale+texoffsetx[i][j+stepsize];
295 vArray[(a*54)+(b*54*patch_size/stepsize)+c+44]=j*scale*texscale+stepsize*scale*texscale+texoffsety[i][j+stepsize];
297 vArray[(a*54)+(b*54*patch_size/stepsize)+c+45]=i*scale+stepsize*scale;
298 vArray[(a*54)+(b*54*patch_size/stepsize)+c+46]=heightmap[i+stepsize][j+stepsize]*scale;
299 vArray[(a*54)+(b*54*patch_size/stepsize)+c+47]=j*scale+stepsize*scale;
300 vArray[(a*54)+(b*54*patch_size/stepsize)+c+48]=colors[i+stepsize][j+stepsize][0];
301 vArray[(a*54)+(b*54*patch_size/stepsize)+c+49]=colors[i+stepsize][j+stepsize][1];
302 vArray[(a*54)+(b*54*patch_size/stepsize)+c+50]=colors[i+stepsize][j+stepsize][2];
303 vArray[(a*54)+(b*54*patch_size/stepsize)+c+51]=colors[i+stepsize][j+stepsize][3];
304 vArray[(a*54)+(b*54*patch_size/stepsize)+c+52]=i*scale*texscale+stepsize*scale*texscale+texoffsetx[i+stepsize][j+stepsize];
305 vArray[(a*54)+(b*54*patch_size/stepsize)+c+53]=j*scale*texscale+stepsize*scale*texscale+texoffsety[i+stepsize][j+stepsize];
306 numtris[whichx][whichy]+=2;
310 maxypatch[whichx][whichy]=-10000;
311 minypatch[whichx][whichy]=10000;
312 for(a=0;a<size/subdivision;a++){
313 for(b=0;b<size/subdivision;b++){
314 if(heightmap[(size/subdivision)*whichx+a][(size/subdivision)*whichy+b]*scale>maxypatch[whichx][whichy]) maxypatch[whichx][whichy]=heightmap[(size/subdivision)*whichx+a][(size/subdivision)*whichy+b]*scale;
315 if(heightmap[(size/subdivision)*whichx+a][(size/subdivision)*whichy+b]*scale<minypatch[whichx][whichy]) minypatch[whichx][whichy]=heightmap[(size/subdivision)*whichx+a][(size/subdivision)*whichy+b]*scale;
318 heightypatch[whichx][whichy]=(maxypatch[whichx][whichy]-minypatch[whichx][whichy]);
319 if(heightypatch[whichx][whichy]<size/subdivision*scale)heightypatch[whichx][whichy]=size/subdivision*scale;
320 avgypatch[whichx][whichy]=(minypatch[whichx][whichy]+maxypatch[whichx][whichy])/2;
322 for(i=whichx*size/subdivision;i<(whichx+1)*size/subdivision-1;i++){
323 for(j=whichy*size/subdivision;j<(whichy+1)*size/subdivision-1;j++){
324 triangles[(i*(size-1)*2)+(j*2)][0].x=i*scale;
325 triangles[(i*(size-1)*2)+(j*2)][0].y=heightmap[i][j]*scale;
326 triangles[(i*(size-1)*2)+(j*2)][0].z=j*scale;
328 triangles[(i*(size-1)*2)+(j*2)][1].x=i*scale;
329 triangles[(i*(size-1)*2)+(j*2)][1].y=heightmap[i][j+1]*scale;
330 triangles[(i*(size-1)*2)+(j*2)][1].z=j*scale+scale;
332 triangles[(i*(size-1)*2)+(j*2)][2].x=i*scale+1*scale;
333 triangles[(i*(size-1)*2)+(j*2)][2].y=heightmap[i+1][j]*scale;
334 triangles[(i*(size-1)*2)+(j*2)][2].z=j*scale;
336 triangles[(i*(size-1)*2)+(j*2)+1][0].x=i*scale+1*scale;
337 triangles[(i*(size-1)*2)+(j*2)+1][0].y=heightmap[i+1][j]*scale;
338 triangles[(i*(size-1)*2)+(j*2)+1][0].z=j*scale;
340 triangles[(i*(size-1)*2)+(j*2)+1][1].x=i*scale;
341 triangles[(i*(size-1)*2)+(j*2)+1][1].y=heightmap[i][j+1]*scale;
342 triangles[(i*(size-1)*2)+(j*2)+1][1].z=j*scale+1*scale;
344 triangles[(i*(size-1)*2)+(j*2)+1][2].x=i*scale+1*scale;
345 triangles[(i*(size-1)*2)+(j*2)+1][2].y=heightmap[i+1][j+1]*scale;
346 triangles[(i*(size-1)*2)+(j*2)+1][2].z=j*scale+1*scale;
353 bool Terrain::load(char *fileName)
357 static float patch_size;
359 float temptexdetail=texdetail;
360 texdetail=terraindetail;
361 //LoadTGA( fileName );
362 unsigned char fileNamep[256];
363 CopyCStringToPascal(fileName,fileNamep);
365 upload_image( fileNamep ,0);
369 int bytesPerPixel=texture.bpp/8;
372 for(i=0;i<(long)(texture.sizeY*texture.sizeX*bytesPerPixel);i++){
374 texture.data[tempnum]=texture.data[i];
380 if(visibleloading)pgame->LoadingScreen();
382 texdetail=temptexdetail;
386 /*if ( texture.bpp == 24 )
391 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
393 if(!terraintexture)glGenTextures( 1, &terraintexture );
394 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
396 glBindTexture( GL_TEXTURE_2D, terraintexture);
397 //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
398 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
400 gluBuild2DMipmaps( GL_TEXTURE_2D, type, texture.sizeX, texture.sizeY, type, GL_UNSIGNED_BYTE, texture.data );
407 heightmap[size-1-i][j]=(float)((texture.data[(i+(j*size))*texture.bpp/8]))/5/terraindetail;
412 if(visibleloading)pgame->LoadingScreen();
416 for(i=0;i<subdivision;i++){
417 for(j=0;j<subdivision;j++){
418 textureness[i][j]=-1;
421 if(visibleloading)pgame->LoadingScreen();
428 texoffsetx[i][j]=(float)abs(Random()%100)/1200/scale*3;
429 texoffsety[i][j]=(float)abs(Random()%100)/1200/scale*3;
432 if(environment==snowyenvironment){
433 if(j!=0&&heightmap[i][j]-heightmap[i][j-1]>slopeness){ slopeness=heightmap[i][j]-heightmap[i][j-1];}
434 opacityother[i][j]=slopeness*slopeness*2;
435 if(opacityother[i][j]>1)opacityother[i][j]=1;
436 opacityother[i][j]-=(float)abs(Random()%100)/300;
438 if(environment==desertenvironment){
439 if(j!=0&&heightmap[i][j]-heightmap[i][j-1]>slopeness){ slopeness=heightmap[i][j]-heightmap[i][j-1];}
440 opacityother[i][j]=slopeness*slopeness*2;
441 if(opacityother[i][j]>1)opacityother[i][j]=1;
442 opacityother[i][j]-=(float)abs(Random()%100)/300;
444 if(environment==grassyenvironment){
445 if(i!=0&&heightmap[i][j]-heightmap[i-1][j]>slopeness){ slopeness=heightmap[i][j]-heightmap[i-1][j];}
446 if(j!=0&&heightmap[i][j]-heightmap[i][j-1]>slopeness){ slopeness=heightmap[i][j]-heightmap[i][j-1];}
447 if(i<size-1&&heightmap[i][j]-heightmap[i+1][j]>slopeness){ slopeness=heightmap[i][j]-heightmap[i+1][j];}
448 if(j<size-1&&heightmap[i][j]-heightmap[i][j+1]>slopeness){ slopeness=heightmap[i][j]-heightmap[i][j+1];}
449 opacityother[i][j]=slopeness*slopeness*10;
450 if(opacityother[i][j]>1)opacityother[i][j]=1;
451 opacityother[i][j]-=(float)abs(Random()%100)/100;
455 if(visibleloading)pgame->LoadingScreen();
459 if(environment==snowyenvironment){
460 heightmap[i][j]-=opacityother[i][j];
462 if(environment==desertenvironment){
463 heightmap[i][j]-=opacityother[i][j];
467 if(visibleloading)pgame->LoadingScreen();
471 //Smooth opacityother
476 if(i!=0){ total+=opacityother[j][i-1]; todivide++;}
477 if(i!=size-1){ total+=opacityother[j][i+1]; todivide++;}
478 if(j!=0){ total+=opacityother[j-1][i]; todivide++;}
479 if(j!=size-1){ total+=opacityother[j+1][i]; todivide++;}
480 if(i!=0&&j!=0){ total+=opacityother[j-1][i-1]; todivide++;}
481 if(i!=size-1&&j!=0){ total+=opacityother[j-1][i+1]; todivide++;}
482 if(j!=size-1&&i!=size-1){ total+=opacityother[j+1][i+1]; todivide++;}
483 if(j!=size-1&&i!=0){ total+=opacityother[j+1][i-1]; todivide++;}
484 total+=opacityother[j][i]; todivide++;
486 opacityother[j][i]=total/(float)todivide;
493 if(opacityother[i][j]<.1)opacityother[i][j]=0;
494 if(textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==-1){
495 if(!opacityother[i][j])textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=allfirst;
496 if(opacityother[i][j]==1)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=allsecond;
498 if(opacityother[i][j]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
499 if(opacityother[i][j]!=1&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allsecond)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
505 if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
506 if(opacityother[x][y]!=1&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allsecond)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
507 if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
508 if(opacityother[i][j]!=1&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allsecond)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
512 if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
513 if(opacityother[x][y]!=1&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allsecond)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
514 if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
515 if(opacityother[i][j]!=1&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allsecond)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
521 if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
522 if(opacityother[x][y]!=1&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allsecond)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
523 if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
524 if(opacityother[i][j]!=1&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allsecond)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
532 if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
533 if(opacityother[x][y]!=1&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allsecond)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
534 if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
535 if(opacityother[i][j]!=1&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allsecond)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
539 if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
540 if(opacityother[x][y]!=1&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allsecond)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
541 if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
542 if(opacityother[i][j]!=1&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allsecond)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
548 if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
549 if(opacityother[x][y]!=1&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allsecond)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
550 if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
551 if(opacityother[i][j]!=1&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allsecond)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
559 if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
560 if(opacityother[x][y]!=1&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allsecond)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
561 if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
562 if(opacityother[i][j]!=1&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allsecond)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
568 if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
569 if(opacityother[x][y]!=1&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allsecond)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed;
570 if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
571 if(opacityother[i][j]!=1&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allsecond)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed;
577 if(visibleloading)pgame->LoadingScreen();
579 patch_size=size/subdivision;
580 patch_elements=(patch_size)*(patch_size)*54;
584 for(i=0;i<subdivision;i++){
585 for(j=0;j<subdivision;j++){
586 UpdateVertexArray(i,j);
593 void Terrain::CalculateNormals()
596 static XYZ facenormal;
597 static XYZ p,q,a,b,c;
599 for(i=0; i<size; i++){
600 for(j=0; j<size; j++){
607 for(i=0;i<size-1;i++){
608 for(j=0;j<size-1;j++){
613 b.y=heightmap[i][j+1];
616 c.y=heightmap[i+1][j];
626 CrossProduct(&p,&q,&facenormal);
628 facenormals[i][j]=facenormal;
630 normals[i][j]=normals[i][j]+facenormal;
631 normals[i][j+1]=normals[i][j+1]+facenormal;
632 normals[i+1][j]=normals[i+1][j]+facenormal;
636 a.y=heightmap[i+1][j];
639 b.y=heightmap[i][j+1];
642 c.y=heightmap[i+1][j+1];
652 CrossProduct(&p,&q,&facenormal);
654 normals[i+1][j+1]=normals[i+1][j+1]+facenormal;
655 normals[i][j+1]=normals[i][j+1]+facenormal;
656 normals[i+1][j]=normals[i+1][j]+facenormal;
658 Normalise(&facenormals[i][j]);
662 for(i=0; i<size; i++){
663 for(j=0; j<size; j++){
664 Normalise(&normals[i][j]);
665 normals[i][j]=normals[i][j];
670 void Terrain::drawpatch(int whichx, int whichy, float opacity){
671 if(opacity>=1)glDisable(GL_BLEND);
674 UpdateTransparency(whichx,whichy);
677 //Set up vertex array
678 glEnableClientState(GL_VERTEX_ARRAY);
679 glEnableClientState(GL_COLOR_ARRAY);
680 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
681 glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0+whichx*patch_elements+whichy*patch_elements*subdivision]);
682 glColorPointer(4,GL_FLOAT, 9*sizeof(GLfloat),&vArray[3+whichx*patch_elements+whichy*patch_elements*subdivision]);
683 glTexCoordPointer(2, GL_FLOAT, 9*sizeof(GLfloat),&vArray[7+whichx*patch_elements+whichy*patch_elements*subdivision]);
686 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy]*3);
688 glDisableClientState(GL_VERTEX_ARRAY);
689 glDisableClientState(GL_COLOR_ARRAY);
690 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
693 void Terrain::drawpatchother(int whichx, int whichy, float opacity){
696 UpdateTransparency(whichx,whichy);
698 UpdateTransparencyother(whichx,whichy);
700 //Set up vertex array
701 glEnableClientState(GL_VERTEX_ARRAY);
702 glEnableClientState(GL_COLOR_ARRAY);
703 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
704 glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0+whichx*patch_elements+whichy*patch_elements*subdivision]);
705 glColorPointer(4,GL_FLOAT, 9*sizeof(GLfloat),&vArray[3+whichx*patch_elements+whichy*patch_elements*subdivision]);
706 glTexCoordPointer(2, GL_FLOAT, 9*sizeof(GLfloat),&vArray[7+whichx*patch_elements+whichy*patch_elements*subdivision]);
709 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy]*3);
711 glDisableClientState(GL_VERTEX_ARRAY);
712 glDisableClientState(GL_COLOR_ARRAY);
713 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
716 void Terrain::drawpatchotherother(int whichx, int whichy, float opacity){
718 UpdateTransparencyotherother(whichx,whichy);
720 glMatrixMode(GL_TEXTURE);
726 //Set up vertex array
727 glEnableClientState(GL_VERTEX_ARRAY);
728 glEnableClientState(GL_COLOR_ARRAY);
729 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
730 glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0+whichx*patch_elements+whichy*patch_elements*subdivision]);
731 glColorPointer(4,GL_FLOAT, 9*sizeof(GLfloat),&vArray[3+whichx*patch_elements+whichy*patch_elements*subdivision]);
732 glTexCoordPointer(2, GL_FLOAT, 9*sizeof(GLfloat),&vArray[7+whichx*patch_elements+whichy*patch_elements*subdivision]);
735 glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy]*3);
737 glDisableClientState(GL_VERTEX_ARRAY);
738 glDisableClientState(GL_COLOR_ARRAY);
739 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
742 glMatrixMode(GL_MODELVIEW);
746 float Terrain::getHeight(float pointx, float pointz)
748 static float height1,height2;
749 static int tilex,tiley;
750 static XYZ startpoint,endpoint,intersect,triangle[3],average;
755 if(pointx>=size-1||pointz>=size-1||pointx<=0||pointz<=0)return 0;
769 triangle[0].y=heightmap[tilex][tiley];
771 triangle[1].x=tilex+1;
773 triangle[1].y=heightmap[tilex+1][tiley];
776 triangle[2].z=tiley+1;
777 triangle[2].y=heightmap[tilex][tiley+1];
779 if(!LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect)){
780 triangle[0].x=tilex+1;
782 triangle[0].y=heightmap[tilex+1][tiley];
784 triangle[1].x=tilex+1;
785 triangle[1].z=tiley+1;
786 triangle[1].y=heightmap[tilex+1][tiley+1];
789 triangle[2].z=tiley+1;
790 triangle[2].y=heightmap[tilex][tiley+1];
791 LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect);
793 return intersect.y*scale+getOpacity(pointx*scale,pointz*scale)/8;
795 //height1=heightmap[tilex][tiley]*(1-(pointx-tilex))+heightmap[tilex+1][tiley]*(pointx-tilex);
796 //height2=heightmap[tilex][tiley+1]*(1-(pointx-tilex))+heightmap[tilex+1][tiley+1]*(pointx-tilex);
798 //return height1*(1-(pointz-tiley))*scale+height2*(pointz-tiley)*scale;
801 float Terrain::getHeightExtrude(float pointx, float pointz,float point2x, float point2z)
803 static float height1,height2;
804 static int tilex,tiley;
805 static XYZ startpoint,endpoint,intersect,triangle[3],average;
812 if(pointx>=size-1||pointz>=size-1||pointx<=0||pointz<=0)return 0;
813 if(point2x>=size-1||point2z>=size-1||point2x<=0||point2z<=0)return 0;
815 startpoint.x=point2x;
817 startpoint.z=point2z;
827 triangle[0].y=heightmap[tilex][tiley];
829 triangle[1].x=tilex+1;
831 triangle[1].y=heightmap[tilex+1][tiley];
834 triangle[2].z=tiley+1;
835 triangle[2].y=heightmap[tilex][tiley+1];
839 mid=(triangle[0]+triangle[1]+triangle[2])/2;
841 triangle[0]=mid+(triangle[0]-mid)*10;
842 triangle[1]=mid+(triangle[0]-mid)*10;
843 triangle[2]=mid+(triangle[0]-mid)*10;
846 if(!LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect)){
847 triangle[0].x=tilex+1;
849 triangle[0].y=heightmap[tilex+1][tiley];
851 triangle[1].x=tilex+1;
852 triangle[1].z=tiley+1;
853 triangle[1].y=heightmap[tilex+1][tiley+1];
856 triangle[2].z=tiley+1;
857 triangle[2].y=heightmap[tilex][tiley+1];
858 LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect);
860 return intersect.y*scale+getOpacity(pointx*scale,pointz*scale)/8;
862 //height1=heightmap[tilex][tiley]*(1-(pointx-tilex))+heightmap[tilex+1][tiley]*(pointx-tilex);
863 //height2=heightmap[tilex][tiley+1]*(1-(pointx-tilex))+heightmap[tilex+1][tiley+1]*(pointx-tilex);
865 //return height1*(1-(pointz-tiley))*scale+height2*(pointz-tiley)*scale;
869 float Terrain::getOpacity(float pointx, float pointz)
871 static float height1,height2;
872 static int tilex,tiley;
877 if(pointx>=size-1||pointz>=size-1||pointx<=0||pointz<=0)return 0;
882 height1=opacityother[tilex][tiley]*(1-(pointx-tilex))+opacityother[tilex+1][tiley]*(pointx-tilex);
883 height2=opacityother[tilex][tiley+1]*(1-(pointx-tilex))+opacityother[tilex+1][tiley+1]*(pointx-tilex);
885 return height1*(1-(pointz-tiley))+height2*(pointz-tiley);
888 XYZ Terrain::getNormal(float pointx, float pointz)
890 static XYZ height1,height2,total;
891 static int tilex,tiley;
897 if(pointx>=size-1||pointz>=size-1||pointx<=0||pointz<=0)return height1;
901 height1=normals[tilex][tiley]*(1-(pointx-tilex))+normals[tilex+1][tiley]*(pointx-tilex);
902 height2=normals[tilex][tiley+1]*(1-(pointx-tilex))+normals[tilex+1][tiley+1]*(pointx-tilex);
903 total=height1*(1-(pointz-tiley))+height2*(pointz-tiley);
908 XYZ Terrain::getLighting(float pointx, float pointz)
910 static XYZ height1,height2;
911 static int tilex,tiley;
917 if(pointx>=size-1||pointz>=size-1||pointx<=0||pointz<=0)return height1;
921 height1.x=colors[tilex][tiley][0]*(1-(pointx-tilex))+colors[tilex+1][tiley][0]*(pointx-tilex);
922 height1.y=colors[tilex][tiley][1]*(1-(pointx-tilex))+colors[tilex+1][tiley][1]*(pointx-tilex);
923 height1.z=colors[tilex][tiley][2]*(1-(pointx-tilex))+colors[tilex+1][tiley][2]*(pointx-tilex);
924 height2.x=colors[tilex][tiley+1][0]*(1-(pointx-tilex))+colors[tilex+1][tiley+1][0]*(pointx-tilex);
925 height2.y=colors[tilex][tiley+1][1]*(1-(pointx-tilex))+colors[tilex+1][tiley+1][1]*(pointx-tilex);
926 height2.z=colors[tilex][tiley+1][2]*(1-(pointx-tilex))+colors[tilex+1][tiley+1][2]*(pointx-tilex);
928 return height1*(1-(pointz-tiley))+height2*(pointz-tiley);
931 void Terrain::draw(int layer)
934 static float opacity;
935 static XYZ terrainpoint;
936 static float distance[subdivision][subdivision];
938 static int beginx,endx;
939 static int beginz,endz;
941 static float patch_size=size/subdivision*scale;
942 static float viewdistsquared;
944 viewdistsquared=viewdistance*viewdistance;
947 beginx=(viewer.x-viewdistance)/(patch_size)-1;
948 if(beginx<0)beginx=0;
949 beginz=(viewer.z-viewdistance)/(patch_size)-1;
950 if(beginz<0)beginz=0;
952 endx=(viewer.x+viewdistance)/(patch_size)+1;
953 if(endx>subdivision)endx=subdivision;
954 endz=(viewer.z+viewdistance)/(patch_size)+1;
955 if(endz>subdivision)endz=subdivision;
958 for(i=beginx;i<endx;i++){
959 for(j=beginz;j<endz;j++){
960 terrainpoint.x=i*patch_size+(patch_size)/2;
961 terrainpoint.y=viewer.y;//heightmap[i][j]*scale;
962 terrainpoint.z=j*patch_size+(patch_size)/2;
963 distance[i][j]=findDistancefast(&viewer,&terrainpoint);
967 for(i=beginx;i<endx;i++){
968 for(j=beginz;j<endz;j++){
969 if(distance[i][j]<(viewdistance+patch_size)*(viewdistance+patch_size)){
971 if(distance[i][j]>viewdistsquared*fadestart-viewdistsquared)opacity=0;
972 if(opacity==1&&i!=subdivision)if(distance[i+1][j]>viewdistsquared*fadestart-viewdistsquared)opacity=0;
973 if(opacity==1&&j!=subdivision)if(distance[i][j+1]>viewdistsquared*fadestart-viewdistsquared)opacity=0;
974 if(opacity==1&&j!=subdivision&&i!=subdivision)if(distance[i+1][j+1]>viewdistsquared*fadestart-viewdistsquared)opacity=0;
975 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
977 if(frustum.CubeInFrustum(i*patch_size+patch_size*.5,avgypatch[i][j],j*patch_size+patch_size*.5,heightypatch[i][j]/2))
979 if(environment==desertenvironment&&distance[i][j]>viewdistsquared/4)glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness);
980 else if(environment==desertenvironment)glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
981 if(!layer&&textureness[i][j]!=allsecond)drawpatch(i,j,opacity);
982 if(layer==1&&textureness[i][j]!=allfirst)drawpatchother(i,j,opacity);
983 if(layer==2&&textureness[i][j]!=allfirst)drawpatchotherother(i,j,opacity);
989 if(environment==desertenvironment)glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
992 void Terrain::drawdecals()
996 static float distancemult;
999 static float patch_size=size/subdivision*scale;
1000 static float viewdistsquared;
1003 viewdistsquared=viewdistance*viewdistance;
1008 glDisable(GL_LIGHTING);
1009 glDisable(GL_CULL_FACE);
1010 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1012 for(i=0;i<numdecals;i++){
1013 if(decaltype[i]==blooddecalfast&&decalalivetime[i]<2)decalalivetime[i]=2;
1014 if((decaltype[i]==shadowdecal||decaltype[i]==shadowdecalpermanent)&&decaltype[i]!=lasttype){
1015 glBindTexture( GL_TEXTURE_2D, shadowtexture);
1018 glAlphaFunc(GL_GREATER, 0.0001);
1019 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1022 if(decaltype[i]==footprintdecal&&decaltype[i]!=lasttype){
1023 glBindTexture( GL_TEXTURE_2D, footprinttexture);
1026 glAlphaFunc(GL_GREATER, 0.0001);
1027 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1030 if(decaltype[i]==bodyprintdecal&&decaltype[i]!=lasttype){
1031 glBindTexture( GL_TEXTURE_2D, bodyprinttexture);
1034 glAlphaFunc(GL_GREATER, 0.0001);
1035 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1038 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalslow)&&decaltype[i]!=lasttype){
1039 glBindTexture( GL_TEXTURE_2D, bloodtexture);
1042 glAlphaFunc(GL_GREATER, 0.15);
1043 glBlendFunc(GL_ONE,GL_ZERO);
1046 if((decaltype[i]==blooddecalfast)&&decaltype[i]!=lasttype){
1047 glBindTexture( GL_TEXTURE_2D, bloodtexture2);
1050 glAlphaFunc(GL_GREATER, 0.15);
1051 glBlendFunc(GL_ONE,GL_ZERO);
1054 if(decaltype[i]==shadowdecal||decaltype[i]==shadowdecalpermanent){
1055 distancemult=(viewdistsquared-(findDistancefast(&viewer,&decalposition[i])-(viewdistsquared*fadestart))*(1/(1-fadestart)))/viewdistsquared;
1056 if(distancemult>=1)glColor4f(1,1,1,decalopacity[i]);
1057 if(distancemult<1)glColor4f(1,1,1,decalopacity[i]*distancemult);
1059 if(decaltype[i]==footprintdecal||decaltype[i]==bodyprintdecal){
1060 distancemult=(viewdistsquared-(findDistancefast(&viewer,&decalposition[i])-(viewdistsquared*fadestart))*(1/(1-fadestart)))/viewdistsquared;
1061 if(distancemult>=1){
1062 glColor4f(1,1,1,decalopacity[i]);
1063 if(decalalivetime[i]>3)glColor4f(1,1,1,decalopacity[i]*(5-decalalivetime[i])/2);
1066 glColor4f(1,1,1,decalopacity[i]*distancemult);
1067 if(decalalivetime[i]>3)glColor4f(1,1,1,decalopacity[i]*(5-decalalivetime[i])/2*distancemult);
1070 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)){
1071 distancemult=(viewdistsquared-(findDistancefast(&viewer,&decalposition[i])-(viewdistsquared*fadestart))*(1/(1-fadestart)))/viewdistsquared;
1072 if(distancemult>=1){
1073 glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]);
1074 if(decalalivetime[i]<4)glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]*decalalivetime[i]*.25);
1075 if(decalalivetime[i]>58)glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]*(60-decalalivetime[i])/2);
1078 glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]*distancemult);
1079 if(decalalivetime[i]<4)glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]*decalalivetime[i]*distancemult*.25);
1080 if(decalalivetime[i]>58)glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]*(60-decalalivetime[i])/2*distancemult);
1083 lasttype=decaltype[i];
1084 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1085 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1087 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1089 glBegin(GL_TRIANGLES);
1090 for(int j=0;j<3;j++)
1092 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); glVertex3f(decalvertex[i][j].x,decalvertex[i][j].y,decalvertex[i][j].z);
1097 for(i=numdecals-1;i>=0;i--){
1098 decalalivetime[i]+=multiplier;
1099 if(decaltype[i]==blooddecalslow)decalalivetime[i]-=multiplier*2/3;
1100 if(decaltype[i]==blooddecalfast)decalalivetime[i]+=multiplier*4;
1101 if(decaltype[i]==shadowdecal)DeleteDecal(i);
1102 if(decaltype[i]==footprintdecal&&decalalivetime[i]>=5)DeleteDecal(i);
1103 if(decaltype[i]==bodyprintdecal&&decalalivetime[i]>=5)DeleteDecal(i);
1104 if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)&&decalalivetime[i]>=60)DeleteDecal(i);
1106 glAlphaFunc(GL_GREATER, 0.0001);
1110 void Terrain::AddObject(XYZ where, float radius, int id)
1116 for(i=0;i<subdivision;i++){
1117 for(j=0;j<subdivision;j++){
1118 if(patchobjectnum[i][j]<300-1){
1120 points[0].x=(size/subdivision)*i;
1121 points[0].z=(size/subdivision)*j;
1122 points[0].y=heightmap[(int)points[0].x][(int)points[0].z];
1123 points[1].x=(size/subdivision)*(i+1);
1124 points[1].z=(size/subdivision)*j;
1125 points[1].y=heightmap[(int)points[1].x][(int)points[1].z];
1126 points[2].x=(size/subdivision)*(i+1);
1127 points[2].z=(size/subdivision)*(j+1);
1128 points[2].y=heightmap[(int)points[2].x][(int)points[2].z];
1129 points[3].x=(size/subdivision)*i;
1130 points[3].z=(size/subdivision)*(j+1);
1131 points[3].y=heightmap[(int)points[3].x][(int)points[3].z];
1132 points[0]*=scale*terraindetail;
1133 points[1]*=scale*terraindetail;
1134 points[2]*=scale*terraindetail;
1135 points[3]*=scale*terraindetail;
1136 if(!done&&where.x+radius>points[0].x&&where.x-radius<points[2].x&&where.z+radius>points[0].z&&where.z-radius<points[2].z){
1137 patchobjects[i][j][patchobjectnum[i][j]]=id;
1138 patchobjectnum[i][j]++;
1146 void Terrain::DeleteDecal(int which)
1149 decaltype[which]=decaltype[numdecals-1];
1150 decalposition[which]=decalposition[numdecals-1];
1151 for(int i=0;i<3;i++){
1152 decalvertex[which][i]=decalvertex[numdecals-1][i];
1153 decaltexcoords[which][i][0]=decaltexcoords[numdecals-1][i][0];
1154 decaltexcoords[which][i][1]=decaltexcoords[numdecals-1][i][1];
1156 decalrotation[which]=decalrotation[numdecals-1];
1157 decalalivetime[which]=decalalivetime[numdecals-1];
1158 decalopacity[which]=decalopacity[numdecals-1];
1159 decalbrightness[which]=decalbrightness[numdecals-1];
1164 void Terrain::MakeDecal(int type, XYZ where, float size, float opacity, float rotation){
1166 if(opacity>0&&size>0){
1167 static int patchx[4];
1168 static int patchy[4];
1170 decaltexcoords[numdecals][0][0]=1;
1171 decaltexcoords[numdecals][0][1]=0;
1173 patchx[0]=(where.x+size)/scale;
1174 patchx[1]=(where.x-size)/scale;
1175 patchx[2]=(where.x-size)/scale;
1176 patchx[3]=(where.x+size)/scale;
1178 patchy[0]=(where.z-size)/scale;
1179 patchy[1]=(where.z-size)/scale;
1180 patchy[2]=(where.z+size)/scale;
1181 patchy[3]=(where.z+size)/scale;
1183 /*if(patchx[1]<subdivision-1&&patchy[1]<subdivision-1&&patchx[1]>0&&patchy[1]>0)
1184 if(patchx[2]<subdivision-1&&patchy[2]<subdivision-1&&patchx[2]>0&&patchy[2]>0)
1185 if(patchx[3]<subdivision-1&&patchy[3]<subdivision-1&&patchx[3]>0&&patchy[3]>0)
1186 if(patchx[0]<subdivision-1&&patchy[0]<subdivision-1&&patchx[0]>0&&patchy[0]>0){
1188 if((patchx[0]!=patchx[1]||patchy[0]!=patchy[1])&&(patchx[0]!=patchx[2]||patchy[0]!=patchy[2])&&(patchx[0]!=patchx[3]||patchy[0]!=patchy[3])){
1189 MakeDecalLock(type,where,patchx[0],patchy[0],size,opacity,rotation);
1192 if((patchx[1]!=patchx[2]||patchy[1]!=patchy[2])&&(patchx[1]!=patchx[3]||patchy[1]!=patchy[3])){
1193 MakeDecalLock(type,where,patchx[1],patchy[1],size,opacity,rotation);
1196 if((patchx[2]!=patchx[3]||patchy[2]!=patchy[3])){
1197 MakeDecalLock(type,where,patchx[2],patchy[2],size,opacity,rotation);
1199 MakeDecalLock(type,where,patchx[3],patchy[3],size,opacity,rotation);
1205 void Terrain::MakeDecalLock(int type, XYZ where,int whichx, int whichy, float size, float opacity, float rotation){
1207 static float placex,placez;
1212 rot=getLighting(where.x,where.z);
1213 decalbrightness[numdecals]=(rot.x+rot.y+rot.z)/3;
1214 if(decalbrightness[numdecals]<.4)decalbrightness[numdecals]=.4;
1216 //if(type==blooddecal||type==blooddecalfast||type==blooddecalslow){
1217 if(environment==grassyenvironment){
1218 decalbrightness[numdecals]*=.6;
1222 if(decalbrightness[numdecals]>1)decalbrightness[numdecals]=1;
1223 decalbright=decalbrightness[numdecals];
1225 decalposition[numdecals]=where;
1226 decaltype[numdecals]=type;
1227 decalopacity[numdecals]=opacity;
1228 decalrotation[numdecals]=rotation;
1229 decalalivetime[numdecals]=0;
1231 placex=(float)whichx*scale+scale;
1232 placez=(float)whichy*scale;
1234 decaltexcoords[numdecals][0][0]=(placex-where.x)/size/2+.5;
1235 decaltexcoords[numdecals][0][1]=(placez-where.z)/size/2+.5;
1237 decalvertex[numdecals][0].x=placex;
1238 decalvertex[numdecals][0].z=placez;
1239 decalvertex[numdecals][0].y=heightmap[whichx+1][whichy]*scale+.01;
1242 placex=(float)whichx*scale+scale;
1243 placez=(float)whichy*scale+scale;
1245 decaltexcoords[numdecals][1][0]=(placex-where.x)/size/2+.5;
1246 decaltexcoords[numdecals][1][1]=(placez-where.z)/size/2+.5;
1248 decalvertex[numdecals][1].x=placex;
1249 decalvertex[numdecals][1].z=placez;
1250 decalvertex[numdecals][1].y=heightmap[whichx+1][whichy+1]*scale+.01;
1253 placex=(float)whichx*scale;
1254 placez=(float)whichy*scale+scale;
1256 decaltexcoords[numdecals][2][0]=(placex-where.x)/size/2+.5;
1257 decaltexcoords[numdecals][2][1]=(placez-where.z)/size/2+.5;
1259 decalvertex[numdecals][2].x=placex;
1260 decalvertex[numdecals][2].z=placez;
1261 decalvertex[numdecals][2].y=heightmap[whichx][whichy+1]*scale+.01;
1263 if(decalrotation[numdecals]){
1264 for(int i=0;i<3;i++){
1266 rot.x=decaltexcoords[numdecals][i][0]-.5;
1267 rot.z=decaltexcoords[numdecals][i][1]-.5;
1268 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1269 decaltexcoords[numdecals][i][0]=rot.x+.5;
1270 decaltexcoords[numdecals][i][1]=rot.z+.5;
1274 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1275 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1276 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1277 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1278 if(numdecals<max_decals-1)numdecals++;
1280 decalbrightness[numdecals]=decalbright;
1282 decalposition[numdecals]=where;
1283 decaltype[numdecals]=type;
1284 decalopacity[numdecals]=opacity;
1285 decalrotation[numdecals]=rotation;
1286 decalalivetime[numdecals]=0;
1288 placex=(float)whichx*scale+scale;
1289 placez=(float)whichy*scale;
1291 decaltexcoords[numdecals][0][0]=(placex-where.x)/size/2+.5;
1292 decaltexcoords[numdecals][0][1]=(placez-where.z)/size/2+.5;
1294 decalvertex[numdecals][0].x=placex;
1295 decalvertex[numdecals][0].z=placez;
1296 decalvertex[numdecals][0].y=heightmap[whichx+1][whichy]*scale+.01;
1299 placex=(float)whichx*scale;
1300 placez=(float)whichy*scale;
1302 decaltexcoords[numdecals][1][0]=(placex-where.x)/size/2+.5;
1303 decaltexcoords[numdecals][1][1]=(placez-where.z)/size/2+.5;
1305 decalvertex[numdecals][1].x=placex;
1306 decalvertex[numdecals][1].z=placez;
1307 decalvertex[numdecals][1].y=heightmap[whichx][whichy]*scale+.01;
1310 placex=(float)whichx*scale;
1311 placez=(float)whichy*scale+scale;
1313 decaltexcoords[numdecals][2][0]=(placex-where.x)/size/2+.5;
1314 decaltexcoords[numdecals][2][1]=(placez-where.z)/size/2+.5;
1316 decalvertex[numdecals][2].x=placex;
1317 decalvertex[numdecals][2].z=placez;
1318 decalvertex[numdecals][2].y=heightmap[whichx][whichy+1]*scale+.01;
1320 if(decalrotation[numdecals]){
1321 for(int i=0;i<3;i++){
1323 rot.x=decaltexcoords[numdecals][i][0]-.5;
1324 rot.z=decaltexcoords[numdecals][i][1]-.5;
1325 rot=DoRotation(rot,0,-decalrotation[numdecals],0);
1326 decaltexcoords[numdecals][i][0]=rot.x+.5;
1327 decaltexcoords[numdecals][i][1]=rot.z+.5;
1331 if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0))
1332 if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0))
1333 if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1))
1334 if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1))
1335 if(numdecals<max_decals-1)numdecals++;
1339 void Terrain::DoLighting()
1341 static int i,j,k,todivide;
1342 static float brightness, total;
1343 static XYZ blank, terrainpoint,lightloc;
1344 lightloc=light.location;
1345 Normalise(&lightloc);
1347 for(i=0;i<size;i++){
1348 for(j=0;j<size;j++){
1349 terrainpoint.x=(float)i*scale;
1350 terrainpoint.z=(float)j*scale;
1351 terrainpoint.y=heightmap[i][j]*scale+.1;
1353 if(lineTerrain(lightlocation*10+terrainpoint,terrainpoint,&blank)==-1)
1355 brightness=dotproduct(&lightloc,&normals[i][j]);
1357 if(brightness>1)brightness=1;
1358 if(brightness<0)brightness=0;
1360 colors[i][j][0]=light.color[0]*brightness+light.ambient[0];
1361 colors[i][j][1]=light.color[1]*brightness+light.ambient[1];
1362 colors[i][j][2]=light.color[2]*brightness+light.ambient[2];
1364 if(colors[i][j][0]>1)colors[i][j][0]=1;
1365 if(colors[i][j][1]>1)colors[i][j][1]=1;
1366 if(colors[i][j][2]>1)colors[i][j][2]=1;
1367 if(colors[i][j][0]<0)colors[i][j][0]=0;
1368 if(colors[i][j][1]<0)colors[i][j][1]=0;
1369 if(colors[i][j][2]<0)colors[i][j][2]=0;
1374 for(i=0;i<size;i++){
1375 for(j=0;j<size;j++){
1379 if(i!=0){ total+=colors[j][i-1][k]; todivide++;}
1380 if(i!=size-1){ total+=colors[j][i+1][k]; todivide++;}
1381 if(j!=0){ total+=colors[j-1][i][k]; todivide++;}
1382 if(j!=size-1){ total+=colors[j+1][i][k]; todivide++;}
1383 if(i!=0&&j!=0){ total+=colors[j-1][i-1][k]; todivide++;}
1384 if(i!=size-1&&j!=0){ total+=colors[j-1][i+1][k]; todivide++;}
1385 if(j!=size-1&&i!=size-1){ total+=colors[j+1][i+1][k]; todivide++;}
1386 if(j!=size-1&&i!=0){ total+=colors[j+1][i-1][k]; todivide++;}
1387 total+=colors[j][i][k]; todivide++;
1389 colors[j][i][k]=total/todivide;
1395 void Terrain::DoShadows()
1397 static int i,j,k,l,todivide;
1398 static float brightness, total;
1399 static XYZ testpoint,testpoint2, terrainpoint,lightloc,col;
1400 lightloc=light.location;
1405 if(skyboxtexture&&tutoriallevel){
1411 Normalise(&lightloc);
1413 for(i=0;i<size;i++){
1414 for(j=0;j<size;j++){
1415 terrainpoint.x=(float)(i)*scale;
1416 terrainpoint.z=(float)(j)*scale;
1417 terrainpoint.y=heightmap[i][j]*scale;
1420 patchx=(float)(i)*subdivision/size;
1421 patchz=(float)(j)*subdivision/size;
1422 if(patchobjectnum[patchx][patchz]){
1423 for(k=0;k<patchobjectnum[patchx][patchz];k++){
1424 l=patchobjects[patchx][patchz][k];
1425 if(objects.type[l]!=treetrunktype){
1426 testpoint=terrainpoint;
1427 testpoint2=terrainpoint+lightloc*50*(1-shadowed);
1428 if(objects.model[l].LineCheck(&testpoint,&testpoint2,&col,&objects.position[l],&objects.rotation[l])!=-1){
1429 shadowed=1-(findDistance(&terrainpoint,&col)/50);
1433 if(visibleloading)pgame->LoadingScreen();
1435 brightness=dotproduct(&lightloc,&normals[i][j]);
1436 if(shadowed)brightness*=1-shadowed;
1438 if(brightness>1)brightness=1;
1439 if(brightness<0)brightness=0;
1441 colors[i][j][0]=light.color[0]*brightness+light.ambient[0];
1442 colors[i][j][1]=light.color[1]*brightness+light.ambient[1];
1443 colors[i][j][2]=light.color[2]*brightness+light.ambient[2];
1445 if(colors[i][j][0]>1)colors[i][j][0]=1;
1446 if(colors[i][j][1]>1)colors[i][j][1]=1;
1447 if(colors[i][j][2]>1)colors[i][j][2]=1;
1448 if(colors[i][j][0]<0)colors[i][j][0]=0;
1449 if(colors[i][j][1]<0)colors[i][j][1]=0;
1450 if(colors[i][j][2]<0)colors[i][j][2]=0;
1454 if(visibleloading)pgame->LoadingScreen();
1457 for(i=0;i<size;i++){
1458 for(j=0;j<size;j++){
1462 if(i!=0){ total+=colors[j][i-1][k]; todivide++;}
1463 if(i!=size-1){ total+=colors[j][i+1][k]; todivide++;}
1464 if(j!=0){ total+=colors[j-1][i][k]; todivide++;}
1465 if(j!=size-1){ total+=colors[j+1][i][k]; todivide++;}
1466 if(i!=0&&j!=0){ total+=colors[j-1][i-1][k]; todivide++;}
1467 if(i!=size-1&&j!=0){ total+=colors[j-1][i+1][k]; todivide++;}
1468 if(j!=size-1&&i!=size-1){ total+=colors[j+1][i+1][k]; todivide++;}
1469 if(j!=size-1&&i!=0){ total+=colors[j+1][i-1][k]; todivide++;}
1470 total+=colors[j][i][k]; todivide++;
1472 colors[j][i][k]=total/todivide;
1477 for(i=0;i<subdivision;i++){
1478 for(j=0;j<subdivision;j++){
1479 UpdateVertexArray(i,j);
1489 footprinttexture = 0;
1490 bodyprinttexture = 0;
1495 memset(patchobjectnum, 0, sizeof(patchobjectnum));
1496 memset(patchobjects, 0, sizeof(patchobjects));
1500 memset(heightmap, 0, sizeof(heightmap));
1501 memset(normals, 0, sizeof(normals));
1502 memset(facenormals, 0, sizeof(facenormals));
1503 memset(triangles, 0, sizeof(triangles));
1504 memset(colors, 0, sizeof(colors));
1505 memset(opacityother, 0, sizeof(opacityother));
1506 memset(texoffsetx, 0, sizeof(texoffsetx));
1507 memset(texoffsety, 0, sizeof(texoffsety));
1508 memset(numtris, 0, sizeof(numtris));
1509 memset(textureness, 0, sizeof(textureness));
1511 memset(vArray, 0, sizeof(vArray));
1513 memset(visible, 0, sizeof(visible));
1514 memset(avgypatch, 0, sizeof(avgypatch));
1515 memset(maxypatch, 0, sizeof(maxypatch));
1516 memset(minypatch, 0, sizeof(minypatch));
1517 memset(heightypatch, 0, sizeof(heightypatch));
1521 memset(decaltexcoords, 0, sizeof(decaltexcoords));
1522 memset(decalvertex, 0, sizeof(decalvertex));
1523 memset(decaltype, 0, sizeof(decaltype));
1524 memset(decalopacity, 0, sizeof(decalopacity));
1525 memset(decalrotation, 0, sizeof(decalrotation));
1526 memset(decalalivetime, 0, sizeof(decalalivetime));
1527 memset(decalbrightness, 0, sizeof(decalbrightness));
1528 memset(decalposition, 0, sizeof(decalposition));
1533 if(terraintexture)glDeleteTextures( 1, &terraintexture );
1534 if(shadowtexture) glDeleteTextures( 1, &shadowtexture );
1535 if(bodyprinttexture) glDeleteTextures( 1, &bodyprinttexture );
1536 if(footprinttexture) glDeleteTextures( 1, &footprinttexture );
1537 if(bloodtexture) glDeleteTextures( 1, &bloodtexture );
1538 if(bloodtexture2) glDeleteTextures( 1, &bloodtexture2 );
1539 if(breaktexture) glDeleteTextures( 1, &breaktexture );