X-Git-Url: https://git.jsancho.org/?a=blobdiff_plain;f=Source%2FTerrain.cpp;h=a50dd52b9ba02ad389a9aa6267f6584622d978ee;hb=cd043e3f9e26c2b3406b40a354c2840941e9db7f;hp=d9c73b056b320ff90bfcc49f8cadd158cbbc74f3;hpb=2f6f7fe7b9562156a966b6cfd62afb2dc69734f7;p=lugaru.git diff --git a/Source/Terrain.cpp b/Source/Terrain.cpp index d9c73b0..a50dd52 100644 --- a/Source/Terrain.cpp +++ b/Source/Terrain.cpp @@ -3,20 +3,18 @@ Copyright (C) 2003, 2010 - Wolfire Games This file is part of Lugaru. -Lugaru is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. +Lugaru is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. -This program is distributed in the hope that it will be useful, +Lugaru is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +along with Lugaru. If not, see . */ #include "Game.h" @@ -24,7 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "Objects.h" extern XYZ viewer; extern float viewdistance; -extern float lightambient[3],lightbrightness[3]; extern float fadestart; extern int environment; extern float texscale; @@ -38,1539 +35,1707 @@ extern float blurness; extern float targetblurness; extern Objects objects; extern TGAImageRec texture; -extern Game * pgame; extern bool visibleloading; extern bool skyboxtexture; extern int tutoriallevel; //Functions -int Terrain::lineTerrain(XYZ p1,XYZ p2, XYZ *p) +int Terrain::lineTerrain(XYZ p1, XYZ p2, XYZ *p) { - static int i,j,k; - static float distance; - static float olddistance; - static int intersecting; - static int firstintersecting; - static XYZ point; - static int startx,starty; - static float slope; - static int endx,endy; - static int numtris=(size-1)*(size-1)*2; - static float highest,lowest; - - firstintersecting=-1; - olddistance=10000; - distance=1; - - XYZ triangles[3]; - - p1/=scale; - p2/=scale; - - startx=p1.x; - starty=p1.z; - endx=p2.x; - endy=p2.z; - - if(startx>endx){i=endx;endx=startx;startx=i;} - if(starty>endy){i=endy;endy=starty;starty=i;} - - if(startx<0)startx=0; - if(starty<0)starty=0; - if(endx>size-1)endx=size-1; - if(endy>size-1)endy=size-1; - - for(i=startx;i<=endx;i++){ - for(j=starty;j<=endy;j++){ - highest=-1000; - lowest=1000; - for(k=0;k<2;k++){ - if(heightmap[i+k][j]>highest)highest=heightmap[i+k][j]; - if(heightmap[i+k][j]highest)highest=heightmap[i+k][j+1]; - if(heightmap[i+k][j+1]=lowest||p2.y>=lowest)){ - triangles[0].x=i; - triangles[0].y=heightmap[i][j]; - triangles[0].z=j; - - triangles[1].x=i; - triangles[1].y=heightmap[i][j+1]; - triangles[1].z=j+1; - - triangles[2].x=i+1; - triangles[2].y=heightmap[i+1][j]; - triangles[2].z=j; - - intersecting=LineFacet(p1,p2,triangles[0],triangles[1],triangles[2],&point); - distance=findDistancefast(&p1,&point); - if((distance endx) { + i = endx; + endx = startx; + startx = i; + } + if (starty > endy) { + i = endy; + endy = starty; + starty = i; + } + + if (startx < 0) + startx = 0; + if (starty < 0) + starty = 0; + if (endx > size - 1) + endx = size - 1; + if (endy > size - 1) + endy = size - 1; + + for (i = startx; i <= endx; i++) { + for (j = starty; j <= endy; j++) { + highest = -1000; + lowest = 1000; + for (k = 0; k < 2; k++) { + if (heightmap[i + k][j] > highest) + highest = heightmap[i + k][j]; + if (heightmap[i + k][j] < lowest) + lowest = heightmap[i + k][j]; + if (heightmap[i + k][j + 1] > highest) + highest = heightmap[i + k][j + 1]; + if (heightmap[i + k][j + 1] < lowest) + lowest = heightmap[i + k][j + 1]; + } + if ((p1.y <= highest || p2.y <= highest) && (p1.y >= lowest || p2.y >= lowest)) { + triangles[0].x = i; + triangles[0].y = heightmap[i][j]; + triangles[0].z = j; + + triangles[1].x = i; + triangles[1].y = heightmap[i][j + 1]; + triangles[1].z = j + 1; + + triangles[2].x = i + 1; + triangles[2].y = heightmap[i + 1][j]; + triangles[2].z = j; + + intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point); + distance = distsq(&p1, &point); + if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) { + olddistance = distance; + firstintersecting = 1; + *p = point; + } + + triangles[0].x = i + 1; + triangles[0].y = heightmap[i + 1][j]; + triangles[0].z = j; + + triangles[1].x = i; + triangles[1].y = heightmap[i][j + 1]; + triangles[1].z = j + 1; + + triangles[2].x = i + 1; + triangles[2].y = heightmap[i + 1][j + 1]; + triangles[2].z = j + 1; + + intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point); + distance = distsq(&p1, &point); + if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) { + olddistance = distance; + firstintersecting = 1; + *p = point; + } + } + } + } + return firstintersecting; } -void Terrain::UpdateTransparency(int whichx, int whichy){ - static XYZ vertex; - static int i,j,a,b,c,d,patch_size,stepsize; - static float distance; - - static float viewdistsquared; - - viewdistsquared=viewdistance*viewdistance; - patch_size=size/subdivision; - - stepsize=1; - c=whichx*patch_elements+whichy*patch_elements*subdivision; - - for(i=patch_size*whichx;iviewdistsquared)distance=viewdistsquared; - colors[i][j][3]=(viewdistsquared-(distance-(viewdistsquared*fadestart))*(1/(1-fadestart)))/viewdistsquared; - } - } - } - - for(i=patch_size*whichx;i viewdistsquared) + distance = viewdistsquared; + colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared; + } + } + } + + for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) { + for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) { + a = (i - (patch_size * whichx)) / stepsize; + b = (j - (patch_size * whichy)) / stepsize; + d = (a * 54) + (b * 54 * patch_size / stepsize); + vArray[d + c + 6] = colors[i][j][3]; + + vArray[d + c + 15] = colors[i][j + stepsize][3]; + + vArray[d + c + 24] = colors[i + stepsize][j][3]; + + vArray[d + c + 33] = colors[i + stepsize][j][3]; + + vArray[d + c + 42] = colors[i][j + stepsize][3]; + + vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3]; + } + } } -void Terrain::UpdateTransparencyother(int whichx, int whichy){ - static XYZ vertex; - static int i,j,a,b,c,d,patch_size,stepsize; - static float distance; +void Terrain::UpdateTransparencyother(int whichx, int whichy) +{ + static XYZ vertex; + static int i, j, a, b, c, d, patch_size, stepsize; - patch_size=size/subdivision; + patch_size = size / subdivision; - stepsize=1; - c=whichx*patch_elements+whichy*patch_elements*subdivision; + stepsize = 1; + c = whichx * patch_elements + whichy * patch_elements * subdivision; - for(i=patch_size*whichx;iviewdistsquared)distance=viewdistsquared; - colors[i][j][3]=(viewdistsquared-(distance-(viewdistsquared*fadestart))*(1/(1-fadestart)))/viewdistsquared; - } - } - } - - for(i=patch_size*whichx;i viewdistsquared) + distance = viewdistsquared; + colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared; + } + } + } + + for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) { + for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) { + a = (i - (patch_size * whichx)) / stepsize; + b = (j - (patch_size * whichy)) / stepsize; + d = (a * 54) + (b * 54 * patch_size / stepsize); + vArray[d + c + 6] = colors[i][j][3]; + + vArray[d + c + 15] = colors[i][j + stepsize][3]; + + vArray[d + c + 24] = colors[i + stepsize][j][3]; + + vArray[d + c + 33] = colors[i + stepsize][j][3]; + + vArray[d + c + 42] = colors[i][j + stepsize][3]; + + vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3]; + } + } } -void Terrain::UpdateVertexArray(int whichx, int whichy){ - static int i,j,a,b,c,patch_size,stepsize; - - - numtris[whichx][whichy]=0; - - patch_size=size/subdivision; - - stepsize=1; - c=whichx*patch_elements+whichy*patch_elements*subdivision; - for(i=patch_size*whichx;imaxypatch[whichx][whichy]) maxypatch[whichx][whichy]=heightmap[(size/subdivision)*whichx+a][(size/subdivision)*whichy+b]*scale; - 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; + 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; + } + } + heightypatch[whichx][whichy] = (maxypatch[whichx][whichy] - minypatch[whichx][whichy]); + if (heightypatch[whichx][whichy] < size / subdivision * scale) + heightypatch[whichx][whichy] = size / subdivision * scale; + avgypatch[whichx][whichy] = (minypatch[whichx][whichy] + maxypatch[whichx][whichy]) / 2; + + for (i = whichx * size / subdivision; i < (whichx + 1)*size / subdivision - 1; i++) { + for (j = whichy * size / subdivision; j < (whichy + 1)*size / subdivision - 1; j++) { + triangles[(i * (size - 1) * 2) + (j * 2)][0].x = i * scale; + triangles[(i * (size - 1) * 2) + (j * 2)][0].y = heightmap[i][j] * scale; + triangles[(i * (size - 1) * 2) + (j * 2)][0].z = j * scale; + + triangles[(i * (size - 1) * 2) + (j * 2)][1].x = i * scale; + triangles[(i * (size - 1) * 2) + (j * 2)][1].y = heightmap[i][j + 1] * scale; + triangles[(i * (size - 1) * 2) + (j * 2)][1].z = j * scale + scale; + + triangles[(i * (size - 1) * 2) + (j * 2)][2].x = i * scale + 1 * scale; + triangles[(i * (size - 1) * 2) + (j * 2)][2].y = heightmap[i + 1][j] * scale; + triangles[(i * (size - 1) * 2) + (j * 2)][2].z = j * scale; + + triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].x = i * scale + 1 * scale; + triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].y = heightmap[i + 1][j] * scale; + triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].z = j * scale; + + triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].x = i * scale; + triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].y = heightmap[i][j + 1] * scale; + triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].z = j * scale + 1 * scale; + + triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].x = i * scale + 1 * scale; + triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].y = heightmap[i + 1][j + 1] * scale; + triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].z = j * scale + 1 * scale; + } + } } bool Terrain::load(const char *fileName) { - static long i,j; - static long x,y; - static float patch_size; - - float temptexdetail=texdetail; - //LoadTGA( fileName ); - - // Fixing filename so that it works with its own os - char * FixedFN = ConvertFileName(fileName); - - unsigned char fileNamep[256]; - CopyCStringToPascal(FixedFN, fileNamep); - //Load Image - upload_image( fileNamep ,0); - - //Is it valid? - if(texture.bpp>24){ - int bytesPerPixel=texture.bpp/8; - - int tempnum=0; - for(i=0;i<(long)(texture.sizeY*texture.sizeX*bytesPerPixel);i++){ - if((i+1)%4){ - texture.data[tempnum]=texture.data[i]; - tempnum++; - } - } - } - texture.bpp=24; - if(visibleloading)pgame->LoadingScreen(); - - texdetail=temptexdetail; - - size=128; - if(1==1){ - /*if ( texture.bpp == 24 ) - type = GL_RGB; - else - type = GL_RGBA; - - glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - - if(!terraintexture)glGenTextures( 1, &terraintexture ); - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - - glBindTexture( GL_TEXTURE_2D, terraintexture); - //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - - gluBuild2DMipmaps( GL_TEXTURE_2D, type, texture.sizeX, texture.sizeY, type, GL_UNSIGNED_BYTE, texture.data ); - */ - - size=texture.sizeX; - - for(i=0;iLoadingScreen(); - - float slopeness; - - for(i=0;iLoadingScreen(); - - - for(i=0;islopeness){ slopeness=heightmap[i][j]-heightmap[i][j-1];} - opacityother[i][j]=slopeness*slopeness*2; - if(opacityother[i][j]>1)opacityother[i][j]=1; - opacityother[i][j]-=(float)abs(Random()%100)/300; - } - if(environment==desertenvironment){ - if(j!=0&&heightmap[i][j]-heightmap[i][j-1]>slopeness){ slopeness=heightmap[i][j]-heightmap[i][j-1];} - opacityother[i][j]=slopeness*slopeness*2; - if(opacityother[i][j]>1)opacityother[i][j]=1; - opacityother[i][j]-=(float)abs(Random()%100)/300; - } - if(environment==grassyenvironment){ - if(i!=0&&heightmap[i][j]-heightmap[i-1][j]>slopeness){ slopeness=heightmap[i][j]-heightmap[i-1][j];} - if(j!=0&&heightmap[i][j]-heightmap[i][j-1]>slopeness){ slopeness=heightmap[i][j]-heightmap[i][j-1];} - if(islopeness){ slopeness=heightmap[i][j]-heightmap[i+1][j];} - if(jslopeness){ slopeness=heightmap[i][j]-heightmap[i][j+1];} - opacityother[i][j]=slopeness*slopeness*10; - if(opacityother[i][j]>1)opacityother[i][j]=1; - opacityother[i][j]-=(float)abs(Random()%100)/100; - } - } - } - if(visibleloading)pgame->LoadingScreen(); - - for(i=0;iLoadingScreen(); - - /*float total; - int todivide; - //Smooth opacityother - for(i=0;i0){ - i--; - if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed; - 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; - if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed; - 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; - - if(j>0){ - j--; - if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed; - 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; - if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed; - 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; - j++; - } - - if(j0){ - j--; - if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed; - 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; - if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed; - 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; - j++; - } - - if(j0){ - j--; - if(opacityother[x][y]&&textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]==allfirst)textureness[(int)(i*subdivision/size)][(int)(j*subdivision/size)]=mixed; - 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; - if(opacityother[i][j]&&textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]==allfirst)textureness[(int)(x*subdivision/size)][(int)(y*subdivision/size)]=mixed; - 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; - j++; - } - - if(jLoadingScreen(); - - patch_size=size/subdivision; - patch_elements=(patch_size)*(patch_size)*54; - CalculateNormals(); - /*DoShadows(); - - for(i=0;i 24) { + int bytesPerPixel = texture.bpp / 8; + + int tempnum = 0; + for (i = 0; i < (long)(texture.sizeY * texture.sizeX * bytesPerPixel); i++) { + if ((i + 1) % 4) { + texture.data[tempnum] = texture.data[i]; + tempnum++; + } + } + } + texture.bpp = 24; + if (visibleloading) + Game::LoadingScreen(); + + texdetail = temptexdetail; + + size = 128; + if (1 == 1) { + /*if ( texture.bpp == 24 ) + type = GL_RGB; + else + type = GL_RGBA; + + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + if(!terraintexture)glGenTextures( 1, &terraintexture ); + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + glBindTexture( GL_TEXTURE_2D, terraintexture); + //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + + gluBuild2DMipmaps( GL_TEXTURE_2D, type, texture.sizeX, texture.sizeY, type, GL_UNSIGNED_BYTE, texture.data ); + */ + + size = texture.sizeX; + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + heightmap[size - 1 - i][j] = (float)((texture.data[(i + (j * size)) * texture.bpp / 8])) / 5; + } + } + + } + if (visibleloading) + Game::LoadingScreen(); + + float slopeness; + + for (i = 0; i < subdivision; i++) { + for (j = 0; j < subdivision; j++) { + textureness[i][j] = -1; + } + } + if (visibleloading) + Game::LoadingScreen(); + + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + heightmap[i][j] *= .5; + + texoffsetx[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3; + texoffsety[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3; + + slopeness = 0; + if (environment == snowyenvironment) { + if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) { + slopeness = heightmap[i][j] - heightmap[i][j - 1]; + } + opacityother[i][j] = slopeness * slopeness * 2; + if (opacityother[i][j] > 1) + opacityother[i][j] = 1; + opacityother[i][j] -= (float)abs(Random() % 100) / 300; + } + if (environment == desertenvironment) { + if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) { + slopeness = heightmap[i][j] - heightmap[i][j - 1]; + } + opacityother[i][j] = slopeness * slopeness * 2; + if (opacityother[i][j] > 1) + opacityother[i][j] = 1; + opacityother[i][j] -= (float)abs(Random() % 100) / 300; + } + if (environment == grassyenvironment) { + if (i != 0 && heightmap[i][j] - heightmap[i - 1][j] > slopeness) { + slopeness = heightmap[i][j] - heightmap[i - 1][j]; + } + if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) { + slopeness = heightmap[i][j] - heightmap[i][j - 1]; + } + if (i < size - 1 && heightmap[i][j] - heightmap[i + 1][j] > slopeness) { + slopeness = heightmap[i][j] - heightmap[i + 1][j]; + } + if (j < size - 1 && heightmap[i][j] - heightmap[i][j + 1] > slopeness) { + slopeness = heightmap[i][j] - heightmap[i][j + 1]; + } + opacityother[i][j] = slopeness * slopeness * 10; + if (opacityother[i][j] > 1) + opacityother[i][j] = 1; + opacityother[i][j] -= (float)abs(Random() % 100) / 100; + } + } + } + if (visibleloading) + Game::LoadingScreen(); + + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + if (environment == snowyenvironment) { + heightmap[i][j] -= opacityother[i][j]; + } + if (environment == desertenvironment) { + heightmap[i][j] -= opacityother[i][j]; + } + } + } + if (visibleloading) + Game::LoadingScreen(); + + /*float total; + int todivide; + //Smooth opacityother + for(i=0;i 0) { + i--; + if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst) + textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed; + 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; + if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst) + textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed; + 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; + + if (j > 0) { + j--; + if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst) + textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed; + 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; + if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst) + textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed; + 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; + j++; + } + + if (j < size - 1) { + j++; + if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst) + textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed; + 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; + if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst) + textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed; + 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; + j--; + } + i++; + } + + if (i < size - 1) { + i++; + if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst) + textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed; + 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; + if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst) + textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed; + 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; + + if (j > 0) { + j--; + if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst) + textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed; + 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; + if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst) + textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed; + 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; + j++; + } + + if (j < size - 1) { + j++; + if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst) + textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed; + 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; + if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst) + textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed; + 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; + j--; + } + i--; + } + + if (j > 0) { + j--; + if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst) + textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed; + 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; + if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst) + textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed; + 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; + j++; + } + + if (j < size - 1) { + j++; + if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst) + textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed; + 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; + if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst) + textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed; + 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; + j--; + + } + } + } + if (visibleloading) + Game::LoadingScreen(); + + patch_size = size / subdivision; + patch_elements = (patch_size) * (patch_size) * 54; + CalculateNormals(); + /*DoShadows(); + + for(i=0;i=1)glDisable(GL_BLEND); - if(opacity<1){ - glEnable(GL_BLEND); - UpdateTransparency(whichx,whichy); - } - glColor4f(1,1,1,1); - //Set up vertex array - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0+whichx*patch_elements+whichy*patch_elements*subdivision]); - glColorPointer(4,GL_FLOAT, 9*sizeof(GLfloat),&vArray[3+whichx*patch_elements+whichy*patch_elements*subdivision]); - glTexCoordPointer(2, GL_FLOAT, 9*sizeof(GLfloat),&vArray[7+whichx*patch_elements+whichy*patch_elements*subdivision]); - - //Draw - glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy]*3); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); +void Terrain::drawpatch(int whichx, int whichy, float opacity) +{ + if (opacity >= 1) + glDisable(GL_BLEND); + if (opacity < 1) { + glEnable(GL_BLEND); + UpdateTransparency(whichx, whichy); + } + glColor4f(1, 1, 1, 1); + //Set up vertex array + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]); + glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]); + glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]); + + //Draw + glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); } -void Terrain::drawpatchother(int whichx, int whichy, float opacity){ - glEnable(GL_BLEND); - if(opacity<1){ - UpdateTransparency(whichx,whichy); - } - UpdateTransparencyother(whichx,whichy); - glColor4f(1,1,1,1); - //Set up vertex array - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0+whichx*patch_elements+whichy*patch_elements*subdivision]); - glColorPointer(4,GL_FLOAT, 9*sizeof(GLfloat),&vArray[3+whichx*patch_elements+whichy*patch_elements*subdivision]); - glTexCoordPointer(2, GL_FLOAT, 9*sizeof(GLfloat),&vArray[7+whichx*patch_elements+whichy*patch_elements*subdivision]); - - //Draw - glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy]*3); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); +void Terrain::drawpatchother(int whichx, int whichy, float opacity) +{ + glEnable(GL_BLEND); + if (opacity < 1) { + UpdateTransparency(whichx, whichy); + } + UpdateTransparencyother(whichx, whichy); + glColor4f(1, 1, 1, 1); + //Set up vertex array + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]); + glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]); + glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]); + + //Draw + glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); } -void Terrain::drawpatchotherother(int whichx, int whichy, float opacity){ - glEnable(GL_BLEND); - UpdateTransparencyotherother(whichx,whichy); +void Terrain::drawpatchotherother(int whichx, int whichy, float opacity) +{ + glEnable(GL_BLEND); + UpdateTransparencyotherother(whichx, whichy); - glMatrixMode(GL_TEXTURE); - glPushMatrix(); - glScalef(6, 6, 6); + glMatrixMode(GL_TEXTURE); + glPushMatrix(); + glScalef(6, 6, 6); - glColor4f(1,1,1,1); + glColor4f(1, 1, 1, 1); - //Set up vertex array - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0+whichx*patch_elements+whichy*patch_elements*subdivision]); - glColorPointer(4,GL_FLOAT, 9*sizeof(GLfloat),&vArray[3+whichx*patch_elements+whichy*patch_elements*subdivision]); - glTexCoordPointer(2, GL_FLOAT, 9*sizeof(GLfloat),&vArray[7+whichx*patch_elements+whichy*patch_elements*subdivision]); + //Set up vertex array + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]); + glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]); + glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]); - //Draw - glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy]*3); + //Draw + glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); } float Terrain::getHeight(float pointx, float pointz) { - static float height1,height2; - static int tilex,tiley; - static XYZ startpoint,endpoint,intersect,triangle[3],average; + static int tilex, tiley; + static XYZ startpoint, endpoint, intersect, triangle[3], average; - pointx/=scale; - pointz/=scale; + pointx /= scale; + pointz /= scale; - if(pointx>=size-1||pointz>=size-1||pointx<=0||pointz<=0)return 0; + if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0) + return 0; - startpoint.x=pointx; - startpoint.y=-1000; - startpoint.z=pointz; + startpoint.x = pointx; + startpoint.y = -1000; + startpoint.z = pointz; - endpoint=startpoint; - endpoint.y=1000; + endpoint = startpoint; + endpoint.y = 1000; - tilex=pointx; - tiley=pointz; + tilex = pointx; + tiley = pointz; - triangle[0].x=tilex; - triangle[0].z=tiley; - triangle[0].y=heightmap[tilex][tiley]; + triangle[0].x = tilex; + triangle[0].z = tiley; + triangle[0].y = heightmap[tilex][tiley]; - triangle[1].x=tilex+1; - triangle[1].z=tiley; - triangle[1].y=heightmap[tilex+1][tiley]; + triangle[1].x = tilex + 1; + triangle[1].z = tiley; + triangle[1].y = heightmap[tilex + 1][tiley]; - triangle[2].x=tilex; - triangle[2].z=tiley+1; - triangle[2].y=heightmap[tilex][tiley+1]; + triangle[2].x = tilex; + triangle[2].z = tiley + 1; + triangle[2].y = heightmap[tilex][tiley + 1]; - if(!LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect)){ - triangle[0].x=tilex+1; - triangle[0].z=tiley; - triangle[0].y=heightmap[tilex+1][tiley]; + if (!LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect)) { + triangle[0].x = tilex + 1; + triangle[0].z = tiley; + triangle[0].y = heightmap[tilex + 1][tiley]; - triangle[1].x=tilex+1; - triangle[1].z=tiley+1; - triangle[1].y=heightmap[tilex+1][tiley+1]; + triangle[1].x = tilex + 1; + triangle[1].z = tiley + 1; + triangle[1].y = heightmap[tilex + 1][tiley + 1]; - triangle[2].x=tilex; - triangle[2].z=tiley+1; - triangle[2].y=heightmap[tilex][tiley+1]; - LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect); - } - return intersect.y*scale+getOpacity(pointx*scale,pointz*scale)/8; + triangle[2].x = tilex; + triangle[2].z = tiley + 1; + triangle[2].y = heightmap[tilex][tiley + 1]; + LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect); + } + return intersect.y * scale + getOpacity(pointx * scale, pointz * scale) / 8; - //height1=heightmap[tilex][tiley]*(1-(pointx-tilex))+heightmap[tilex+1][tiley]*(pointx-tilex); - //height2=heightmap[tilex][tiley+1]*(1-(pointx-tilex))+heightmap[tilex+1][tiley+1]*(pointx-tilex); + //height1=heightmap[tilex][tiley]*(1-(pointx-tilex))+heightmap[tilex+1][tiley]*(pointx-tilex); + //height2=heightmap[tilex][tiley+1]*(1-(pointx-tilex))+heightmap[tilex+1][tiley+1]*(pointx-tilex); - //return height1*(1-(pointz-tiley))*scale+height2*(pointz-tiley)*scale; + //return height1*(1-(pointz-tiley))*scale+height2*(pointz-tiley)*scale; } -float Terrain::getHeightExtrude(float pointx, float pointz,float point2x, float point2z) +float Terrain::getHeightExtrude(float pointx, float pointz, float point2x, float point2z) { - static float height1,height2; - static int tilex,tiley; - static XYZ startpoint,endpoint,intersect,triangle[3],average; + static int tilex, tiley; + static XYZ startpoint, endpoint, intersect, triangle[3], average; - pointx/=scale; - pointz/=scale; - point2x/=scale; - point2z/=scale; + pointx /= scale; + pointz /= scale; + point2x /= scale; + point2z /= scale; - if(pointx>=size-1||pointz>=size-1||pointx<=0||pointz<=0)return 0; - if(point2x>=size-1||point2z>=size-1||point2x<=0||point2z<=0)return 0; + if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0) + return 0; + if (point2x >= size - 1 || point2z >= size - 1 || point2x <= 0 || point2z <= 0) + return 0; - startpoint.x=point2x; - startpoint.y=-1000; - startpoint.z=point2z; + startpoint.x = point2x; + startpoint.y = -1000; + startpoint.z = point2z; - endpoint=startpoint; - endpoint.y=1000; + endpoint = startpoint; + endpoint.y = 1000; - tilex=pointx; - tiley=pointz; + tilex = pointx; + tiley = pointz; - triangle[0].x=tilex; - triangle[0].z=tiley; - triangle[0].y=heightmap[tilex][tiley]; + triangle[0].x = tilex; + triangle[0].z = tiley; + triangle[0].y = heightmap[tilex][tiley]; - triangle[1].x=tilex+1; - triangle[1].z=tiley; - triangle[1].y=heightmap[tilex+1][tiley]; + triangle[1].x = tilex + 1; + triangle[1].z = tiley; + triangle[1].y = heightmap[tilex + 1][tiley]; - triangle[2].x=tilex; - triangle[2].z=tiley+1; - triangle[2].y=heightmap[tilex][tiley+1]; + triangle[2].x = tilex; + triangle[2].z = tiley + 1; + triangle[2].y = heightmap[tilex][tiley + 1]; - XYZ mid; + XYZ mid; - mid=(triangle[0]+triangle[1]+triangle[2])/2; + mid = (triangle[0] + triangle[1] + triangle[2]) / 2; - triangle[0]=mid+(triangle[0]-mid)*10; - triangle[1]=mid+(triangle[0]-mid)*10; - triangle[2]=mid+(triangle[0]-mid)*10; + triangle[0] = mid + (triangle[0] - mid) * 10; + triangle[1] = mid + (triangle[0] - mid) * 10; + triangle[2] = mid + (triangle[0] - mid) * 10; - /* - if(!LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect)){ - triangle[0].x=tilex+1; - triangle[0].z=tiley; - triangle[0].y=heightmap[tilex+1][tiley]; + /* + if(!LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect)){ + triangle[0].x=tilex+1; + triangle[0].z=tiley; + triangle[0].y=heightmap[tilex+1][tiley]; - triangle[1].x=tilex+1; - triangle[1].z=tiley+1; - triangle[1].y=heightmap[tilex+1][tiley+1]; + triangle[1].x=tilex+1; + triangle[1].z=tiley+1; + triangle[1].y=heightmap[tilex+1][tiley+1]; - triangle[2].x=tilex; - triangle[2].z=tiley+1; - triangle[2].y=heightmap[tilex][tiley+1]; - LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect); - }*/ - return intersect.y*scale+getOpacity(pointx*scale,pointz*scale)/8; + triangle[2].x=tilex; + triangle[2].z=tiley+1; + triangle[2].y=heightmap[tilex][tiley+1]; + LineFacetd(&startpoint,&endpoint,&triangle[0],&triangle[1],&triangle[2],&intersect); + }*/ + return intersect.y * scale + getOpacity(pointx * scale, pointz * scale) / 8; - //height1=heightmap[tilex][tiley]*(1-(pointx-tilex))+heightmap[tilex+1][tiley]*(pointx-tilex); - //height2=heightmap[tilex][tiley+1]*(1-(pointx-tilex))+heightmap[tilex+1][tiley+1]*(pointx-tilex); + //height1=heightmap[tilex][tiley]*(1-(pointx-tilex))+heightmap[tilex+1][tiley]*(pointx-tilex); + //height2=heightmap[tilex][tiley+1]*(1-(pointx-tilex))+heightmap[tilex+1][tiley+1]*(pointx-tilex); - //return height1*(1-(pointz-tiley))*scale+height2*(pointz-tiley)*scale; + //return height1*(1-(pointz-tiley))*scale+height2*(pointz-tiley)*scale; } float Terrain::getOpacity(float pointx, float pointz) { - static float height1,height2; - static int tilex,tiley; + static float height1, height2; + static int tilex, tiley; - pointx/=scale; - pointz/=scale; + pointx /= scale; + pointz /= scale; - if(pointx>=size-1||pointz>=size-1||pointx<=0||pointz<=0)return 0; + if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0) + return 0; - tilex=pointx; - tiley=pointz; + tilex = pointx; + tiley = pointz; - height1=opacityother[tilex][tiley]*(1-(pointx-tilex))+opacityother[tilex+1][tiley]*(pointx-tilex); - height2=opacityother[tilex][tiley+1]*(1-(pointx-tilex))+opacityother[tilex+1][tiley+1]*(pointx-tilex); + height1 = opacityother[tilex][tiley] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley] * (pointx - tilex); + height2 = opacityother[tilex][tiley + 1] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley + 1] * (pointx - tilex); - return height1*(1-(pointz-tiley))+height2*(pointz-tiley); + return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley); } XYZ Terrain::getNormal(float pointx, float pointz) { - static XYZ height1,height2,total; - static int tilex,tiley; - - pointx/=scale; - pointz/=scale; - - height1=0; - if(pointx>=size-1||pointz>=size-1||pointx<=0||pointz<=0)return height1; - tilex=pointx; - tiley=pointz; - - height1=normals[tilex][tiley]*(1-(pointx-tilex))+normals[tilex+1][tiley]*(pointx-tilex); - height2=normals[tilex][tiley+1]*(1-(pointx-tilex))+normals[tilex+1][tiley+1]*(pointx-tilex); - total=height1*(1-(pointz-tiley))+height2*(pointz-tiley); - Normalise(&total); - return total; + static XYZ height1, height2, total; + static int tilex, tiley; + + pointx /= scale; + pointz /= scale; + + height1 = 0; + if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0) + return height1; + tilex = pointx; + tiley = pointz; + + height1 = normals[tilex][tiley] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley] * (pointx - tilex); + height2 = normals[tilex][tiley + 1] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley + 1] * (pointx - tilex); + total = height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley); + Normalise(&total); + return total; } XYZ Terrain::getLighting(float pointx, float pointz) { - static XYZ height1,height2; - static int tilex,tiley; - - pointx/=scale; - pointz/=scale; - - height1=0; - if(pointx>=size-1||pointz>=size-1||pointx<=0||pointz<=0)return height1; - tilex=pointx; - tiley=pointz; - - height1.x=colors[tilex][tiley][0]*(1-(pointx-tilex))+colors[tilex+1][tiley][0]*(pointx-tilex); - height1.y=colors[tilex][tiley][1]*(1-(pointx-tilex))+colors[tilex+1][tiley][1]*(pointx-tilex); - height1.z=colors[tilex][tiley][2]*(1-(pointx-tilex))+colors[tilex+1][tiley][2]*(pointx-tilex); - height2.x=colors[tilex][tiley+1][0]*(1-(pointx-tilex))+colors[tilex+1][tiley+1][0]*(pointx-tilex); - height2.y=colors[tilex][tiley+1][1]*(1-(pointx-tilex))+colors[tilex+1][tiley+1][1]*(pointx-tilex); - height2.z=colors[tilex][tiley+1][2]*(1-(pointx-tilex))+colors[tilex+1][tiley+1][2]*(pointx-tilex); - - return height1*(1-(pointz-tiley))+height2*(pointz-tiley); + static XYZ height1, height2; + static int tilex, tiley; + + pointx /= scale; + pointz /= scale; + + height1 = 0; + if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0) + return height1; + tilex = pointx; + tiley = pointz; + + height1.x = colors[tilex][tiley][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][0] * (pointx - tilex); + height1.y = colors[tilex][tiley][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][1] * (pointx - tilex); + height1.z = colors[tilex][tiley][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][2] * (pointx - tilex); + height2.x = colors[tilex][tiley + 1][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][0] * (pointx - tilex); + height2.y = colors[tilex][tiley + 1][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][1] * (pointx - tilex); + height2.z = colors[tilex][tiley + 1][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][2] * (pointx - tilex); + + return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley); } void Terrain::draw(int layer) { - static int i,j; - static float opacity; - static XYZ terrainpoint; - static float distance[subdivision][subdivision]; - - static int beginx,endx; - static int beginz,endz; - - static float patch_size=size/subdivision*scale; - static float viewdistsquared; - - viewdistsquared=viewdistance*viewdistance; - - //Only nearby blocks - beginx=(viewer.x-viewdistance)/(patch_size)-1; - if(beginx<0)beginx=0; - beginz=(viewer.z-viewdistance)/(patch_size)-1; - if(beginz<0)beginz=0; - - endx=(viewer.x+viewdistance)/(patch_size)+1; - if(endx>subdivision)endx=subdivision; - endz=(viewer.z+viewdistance)/(patch_size)+1; - if(endz>subdivision)endz=subdivision; - - if(!layer) { - for(i=beginx;iviewdistsquared*fadestart-viewdistsquared) - opacity=0; - if(opacity==1&&i!=subdivision) - if(distance[i+1][j]>viewdistsquared*fadestart-viewdistsquared) - opacity=0; - if(opacity==1&&j!=subdivision) - if(distance[i][j+1]>viewdistsquared*fadestart-viewdistsquared) - opacity=0; - if(opacity==1&&j!=subdivision&&i!=subdivision) - if(distance[i+1][j+1]>viewdistsquared*fadestart-viewdistsquared) - opacity=0; - glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix - glPushMatrix(); - if(frustum.CubeInFrustum(i*patch_size+patch_size*.5,avgypatch[i][j],j*patch_size+patch_size*.5,heightypatch[i][j]/2)) - { - if(environment==desertenvironment&&distance[i][j]>viewdistsquared/4) - glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness); - else if(environment==desertenvironment) - glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 ); - if(!layer&&textureness[i][j]!=allsecond) - drawpatch(i,j,opacity); - if(layer==1&&textureness[i][j]!=allfirst) - drawpatchother(i,j,opacity); - if(layer==2&&textureness[i][j]!=allfirst) - drawpatchotherother(i,j,opacity); - } - glPopMatrix(); - } - } - } - if(environment==desertenvironment) - glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 ); + static int i, j; + static float opacity; + static XYZ terrainpoint; + static float distance[subdivision][subdivision]; + + static int beginx, endx; + static int beginz, endz; + + static float patch_size = size / subdivision * scale; + static float viewdistsquared; + + viewdistsquared = viewdistance * viewdistance; + + //Only nearby blocks + beginx = (viewer.x - viewdistance) / (patch_size) - 1; + if (beginx < 0) + beginx = 0; + beginz = (viewer.z - viewdistance) / (patch_size) - 1; + if (beginz < 0) + beginz = 0; + + endx = (viewer.x + viewdistance) / (patch_size) + 1; + if (endx > subdivision) + endx = subdivision; + endz = (viewer.z + viewdistance) / (patch_size) + 1; + if (endz > subdivision) + endz = subdivision; + + if (!layer) { + for (i = beginx; i < endx; i++) { + for (j = beginz; j < endz; j++) { + terrainpoint.x = i * patch_size + (patch_size) / 2; + terrainpoint.y = viewer.y; //heightmap[i][j]*scale; + terrainpoint.z = j * patch_size + (patch_size) / 2; + distance[i][j] = distsq(&viewer, &terrainpoint); + } + } + } + for (i = beginx; i < endx; i++) { + for (j = beginz; j < endz; j++) { + if (distance[i][j] < (viewdistance + patch_size) * (viewdistance + patch_size)) { + opacity = 1; + if (distance[i][j] > viewdistsquared * fadestart - viewdistsquared) + opacity = 0; + if (opacity == 1 && i != subdivision) + if (distance[i + 1][j] > viewdistsquared * fadestart - viewdistsquared) + opacity = 0; + if (opacity == 1 && j != subdivision) + if (distance[i][j + 1] > viewdistsquared * fadestart - viewdistsquared) + opacity = 0; + if (opacity == 1 && j != subdivision && i != subdivision) + if (distance[i + 1][j + 1] > viewdistsquared * fadestart - viewdistsquared) + opacity = 0; + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + if (frustum.CubeInFrustum(i * patch_size + patch_size * .5, avgypatch[i][j], j * patch_size + patch_size * .5, heightypatch[i][j] / 2)) { + if (environment == desertenvironment && distance[i][j] > viewdistsquared / 4) + glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness); + else if (environment == desertenvironment) + glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 ); + if (!layer && textureness[i][j] != allsecond) + drawpatch(i, j, opacity); + if (layer == 1 && textureness[i][j] != allfirst) + drawpatchother(i, j, opacity); + if (layer == 2 && textureness[i][j] != allfirst) + drawpatchotherother(i, j, opacity); + } + glPopMatrix(); + } + } + } + if (environment == desertenvironment) + glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 ); } void Terrain::drawdecals() { - if(decals) { - static int i,j; - static float distancemult; - static int lasttype; - - static float patch_size=size/subdivision*scale; - static float viewdistsquared; - static bool blend; - - viewdistsquared=viewdistance*viewdistance; - blend=1; - - lasttype=-1; - glEnable(GL_BLEND); - glDisable(GL_LIGHTING); - glDisable(GL_CULL_FACE); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - glDepthMask(0); - for(i=0;i=1)glColor4f(1,1,1,decalopacity[i]); - if(distancemult<1)glColor4f(1,1,1,decalopacity[i]*distancemult); - } - if(decaltype[i]==footprintdecal||decaltype[i]==bodyprintdecal){ - distancemult=(viewdistsquared-(findDistancefast(&viewer,&decalposition[i])-(viewdistsquared*fadestart))*(1/(1-fadestart)))/viewdistsquared; - if(distancemult>=1){ - glColor4f(1,1,1,decalopacity[i]); - if(decalalivetime[i]>3)glColor4f(1,1,1,decalopacity[i]*(5-decalalivetime[i])/2); - } - if(distancemult<1){ - glColor4f(1,1,1,decalopacity[i]*distancemult); - if(decalalivetime[i]>3)glColor4f(1,1,1,decalopacity[i]*(5-decalalivetime[i])/2*distancemult); - } - } - if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)){ - distancemult=(viewdistsquared-(findDistancefast(&viewer,&decalposition[i])-(viewdistsquared*fadestart))*(1/(1-fadestart)))/viewdistsquared; - if(distancemult>=1){ - glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]); - if(decalalivetime[i]<4)glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]*decalalivetime[i]*.25); - if(decalalivetime[i]>58)glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]*(60-decalalivetime[i])/2); - } - if(distancemult<1){ - glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]*distancemult); - if(decalalivetime[i]<4)glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]*decalalivetime[i]*distancemult*.25); - if(decalalivetime[i]>58)glColor4f(decalbrightness[i],decalbrightness[i],decalbrightness[i],decalopacity[i]*(60-decalalivetime[i])/2*distancemult); - } - } - lasttype=decaltype[i]; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix - glPushMatrix(); - glBegin(GL_TRIANGLES); - for(int j=0;j<3;j++) - { - glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); glVertex3f(decalvertex[i][j].x,decalvertex[i][j].y,decalvertex[i][j].z); - } - glEnd(); - glPopMatrix(); - } - for(i=numdecals-1;i>=0;i--){ - decalalivetime[i]+=multiplier; - if(decaltype[i]==blooddecalslow)decalalivetime[i]-=multiplier*2/3; - if(decaltype[i]==blooddecalfast)decalalivetime[i]+=multiplier*4; - if(decaltype[i]==shadowdecal)DeleteDecal(i); - if(decaltype[i]==footprintdecal&&decalalivetime[i]>=5)DeleteDecal(i); - if(decaltype[i]==bodyprintdecal&&decalalivetime[i]>=5)DeleteDecal(i); - if((decaltype[i]==blooddecal||decaltype[i]==blooddecalfast||decaltype[i]==blooddecalslow)&&decalalivetime[i]>=60)DeleteDecal(i); - } - glAlphaFunc(GL_GREATER, 0.0001); - } + if (decals) { + static int i; + static float distancemult; + static int lasttype; + + static float viewdistsquared; + static bool blend; + + viewdistsquared = viewdistance * viewdistance; + blend = 1; + + lasttype = -1; + glEnable(GL_BLEND); + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(0); + for (i = 0; i < numdecals; i++) { + if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2) + decalalivetime[i] = 2; + if ((decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) && decaltype[i] != lasttype) { + shadowtexture.bind(); + if (!blend) { + blend = 1; + glAlphaFunc(GL_GREATER, 0.0001); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + } + if (decaltype[i] == footprintdecal && decaltype[i] != lasttype) { + footprinttexture.bind(); + if (!blend) { + blend = 1; + glAlphaFunc(GL_GREATER, 0.0001); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + } + if (decaltype[i] == bodyprintdecal && decaltype[i] != lasttype) { + bodyprinttexture.bind(); + if (!blend) { + blend = 1; + glAlphaFunc(GL_GREATER, 0.0001); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + } + if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) { + bloodtexture.bind(); + if (blend) { + blend = 0; + glAlphaFunc(GL_GREATER, 0.15); + glBlendFunc(GL_ONE, GL_ZERO); + } + } + if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) { + bloodtexture2.bind(); + if (blend) { + blend = 0; + glAlphaFunc(GL_GREATER, 0.15); + glBlendFunc(GL_ONE, GL_ZERO); + } + } + if (decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) { + distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared; + if (distancemult >= 1) + glColor4f(1, 1, 1, decalopacity[i]); + if (distancemult < 1) + glColor4f(1, 1, 1, decalopacity[i]*distancemult); + } + if (decaltype[i] == footprintdecal || decaltype[i] == bodyprintdecal) { + distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared; + if (distancemult >= 1) { + glColor4f(1, 1, 1, decalopacity[i]); + if (decalalivetime[i] > 3) + glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2); + } + if (distancemult < 1) { + glColor4f(1, 1, 1, decalopacity[i]*distancemult); + if (decalalivetime[i] > 3) + glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2 * distancemult); + } + } + if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) { + distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared; + if (distancemult >= 1) { + glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]); + if (decalalivetime[i] < 4) + glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*.25); + if (decalalivetime[i] > 58) + glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2); + } + if (distancemult < 1) { + glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*distancemult); + if (decalalivetime[i] < 4) + glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*distancemult * .25); + if (decalalivetime[i] > 58) + glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2 * distancemult); + } + } + lasttype = decaltype[i]; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glBegin(GL_TRIANGLES); + for (int j = 0; j < 3; j++) { + glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]); + glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z); + } + glEnd(); + glPopMatrix(); + } + for (i = numdecals - 1; i >= 0; i--) { + decalalivetime[i] += multiplier; + if (decaltype[i] == blooddecalslow) + decalalivetime[i] -= multiplier * 2 / 3; + if (decaltype[i] == blooddecalfast) + decalalivetime[i] += multiplier * 4; + if (decaltype[i] == shadowdecal) + DeleteDecal(i); + if (decaltype[i] == footprintdecal && decalalivetime[i] >= 5) + DeleteDecal(i); + if (decaltype[i] == bodyprintdecal && decalalivetime[i] >= 5) + DeleteDecal(i); + if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60) + DeleteDecal(i); + } + glAlphaFunc(GL_GREATER, 0.0001); + } } void Terrain::AddObject(XYZ where, float radius, int id) { - bool done; - int i,j; - XYZ points[4]; - if(id>=0&&id<10000) - for(i=0;ipoints[0].x&&where.x-radiuspoints[0].z&&where.z-radius= 0 && id < 10000) + for (i = 0; i < subdivision; i++) { + for (j = 0; j < subdivision; j++) { + if (patchobjectnum[i][j] < 300 - 1) { + done = 0; + points[0].x = (size / subdivision) * i; + points[0].z = (size / subdivision) * j; + points[0].y = heightmap[(int)points[0].x][(int)points[0].z]; + points[1].x = (size / subdivision) * (i + 1); + points[1].z = (size / subdivision) * j; + points[1].y = heightmap[(int)points[1].x][(int)points[1].z]; + points[2].x = (size / subdivision) * (i + 1); + points[2].z = (size / subdivision) * (j + 1); + points[2].y = heightmap[(int)points[2].x][(int)points[2].z]; + points[3].x = (size / subdivision) * i; + points[3].z = (size / subdivision) * (j + 1); + points[3].y = heightmap[(int)points[3].x][(int)points[3].z]; + points[0] *= scale; + points[1] *= scale; + points[2] *= scale; + points[3] *= scale; + 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) { + patchobjects[i][j][patchobjectnum[i][j]] = id; + patchobjectnum[i][j]++; + done = 1; + } + } + } + } } void Terrain::DeleteDecal(int which) { - if(decals){ - decaltype[which]=decaltype[numdecals-1]; - decalposition[which]=decalposition[numdecals-1]; - for(int i=0;i<3;i++){ - decalvertex[which][i]=decalvertex[numdecals-1][i]; - decaltexcoords[which][i][0]=decaltexcoords[numdecals-1][i][0]; - decaltexcoords[which][i][1]=decaltexcoords[numdecals-1][i][1]; - } - decalrotation[which]=decalrotation[numdecals-1]; - decalalivetime[which]=decalalivetime[numdecals-1]; - decalopacity[which]=decalopacity[numdecals-1]; - decalbrightness[which]=decalbrightness[numdecals-1]; - numdecals--; - } + if (decals) { + decaltype[which] = decaltype[numdecals - 1]; + decalposition[which] = decalposition[numdecals - 1]; + for (int i = 0; i < 3; i++) { + decalvertex[which][i] = decalvertex[numdecals - 1][i]; + decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0]; + decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1]; + } + decalrotation[which] = decalrotation[numdecals - 1]; + decalalivetime[which] = decalalivetime[numdecals - 1]; + decalopacity[which] = decalopacity[numdecals - 1]; + decalbrightness[which] = decalbrightness[numdecals - 1]; + numdecals--; + } } -void Terrain::MakeDecal(int type, XYZ where, float size, float opacity, float rotation){ - if(decals) { - if(opacity>0&&size>0) { - static int patchx[4]; - static int patchy[4]; - - decaltexcoords[numdecals][0][0]=1; - decaltexcoords[numdecals][0][1]=0; - - patchx[0]=(where.x+size)/scale; - patchx[1]=(where.x-size)/scale; - patchx[2]=(where.x-size)/scale; - patchx[3]=(where.x+size)/scale; - - patchy[0]=(where.z-size)/scale; - patchy[1]=(where.z-size)/scale; - patchy[2]=(where.z+size)/scale; - patchy[3]=(where.z+size)/scale; - - /*if(patchx[1]0&&patchy[1]>0) - if(patchx[2]0&&patchy[2]>0) - if(patchx[3]0&&patchy[3]>0) - if(patchx[0]0&&patchy[0]>0){ - */ - 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])){ - MakeDecalLock(type,where,patchx[0],patchy[0],size,opacity,rotation); - } - - if((patchx[1]!=patchx[2]||patchy[1]!=patchy[2])&&(patchx[1]!=patchx[3]||patchy[1]!=patchy[3])){ - MakeDecalLock(type,where,patchx[1],patchy[1],size,opacity,rotation); - } - - if((patchx[2]!=patchx[3]||patchy[2]!=patchy[3])){ - MakeDecalLock(type,where,patchx[2],patchy[2],size,opacity,rotation); - } - MakeDecalLock(type,where,patchx[3],patchy[3],size,opacity,rotation); - } - } - //} +void Terrain::MakeDecal(int type, XYZ where, float size, float opacity, float rotation) +{ + if (decals) { + if (opacity > 0 && size > 0) { + static int patchx[4]; + static int patchy[4]; + + decaltexcoords[numdecals][0][0] = 1; + decaltexcoords[numdecals][0][1] = 0; + + patchx[0] = (where.x + size) / scale; + patchx[1] = (where.x - size) / scale; + patchx[2] = (where.x - size) / scale; + patchx[3] = (where.x + size) / scale; + + patchy[0] = (where.z - size) / scale; + patchy[1] = (where.z - size) / scale; + patchy[2] = (where.z + size) / scale; + patchy[3] = (where.z + size) / scale; + + /*if(patchx[1]0&&patchy[1]>0) + if(patchx[2]0&&patchy[2]>0) + if(patchx[3]0&&patchy[3]>0) + if(patchx[0]0&&patchy[0]>0){ + */ + 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])) { + MakeDecalLock(type, where, patchx[0], patchy[0], size, opacity, rotation); + } + + if ((patchx[1] != patchx[2] || patchy[1] != patchy[2]) && (patchx[1] != patchx[3] || patchy[1] != patchy[3])) { + MakeDecalLock(type, where, patchx[1], patchy[1], size, opacity, rotation); + } + + if ((patchx[2] != patchx[3] || patchy[2] != patchy[3])) { + MakeDecalLock(type, where, patchx[2], patchy[2], size, opacity, rotation); + } + MakeDecalLock(type, where, patchx[3], patchy[3], size, opacity, rotation); + } + } + //} } -void Terrain::MakeDecalLock(int type, XYZ where,int whichx, int whichy, float size, float opacity, float rotation){ - if(decals){ - static float placex,placez; - static XYZ rot; +void Terrain::MakeDecalLock(int type, XYZ where, int whichx, int whichy, float size, float opacity, float rotation) +{ + if (decals) { + static float placex, placez; + static XYZ rot; - float decalbright; + float decalbright; - rot=getLighting(where.x,where.z); - decalbrightness[numdecals]=(rot.x+rot.y+rot.z)/3; - if(decalbrightness[numdecals]<.4)decalbrightness[numdecals]=.4; + rot = getLighting(where.x, where.z); + decalbrightness[numdecals] = (rot.x + rot.y + rot.z) / 3; + if (decalbrightness[numdecals] < .4) + decalbrightness[numdecals] = .4; - if(environment==grassyenvironment){ - decalbrightness[numdecals]*=.6; - } + if (environment == grassyenvironment) { + decalbrightness[numdecals] *= .6; + } - if(decalbrightness[numdecals]>1)decalbrightness[numdecals]=1; - decalbright=decalbrightness[numdecals]; + if (decalbrightness[numdecals] > 1) + decalbrightness[numdecals] = 1; + decalbright = decalbrightness[numdecals]; - decalposition[numdecals]=where; - decaltype[numdecals]=type; - decalopacity[numdecals]=opacity; - decalrotation[numdecals]=rotation; - decalalivetime[numdecals]=0; + decalposition[numdecals] = where; + decaltype[numdecals] = type; + decalopacity[numdecals] = opacity; + decalrotation[numdecals] = rotation; + decalalivetime[numdecals] = 0; - placex=(float)whichx*scale+scale; - placez=(float)whichy*scale; + placex = (float)whichx * scale + scale; + placez = (float)whichy * scale; - decaltexcoords[numdecals][0][0]=(placex-where.x)/size/2+.5; - decaltexcoords[numdecals][0][1]=(placez-where.z)/size/2+.5; + decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5; + decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5; - decalvertex[numdecals][0].x=placex; - decalvertex[numdecals][0].z=placez; - decalvertex[numdecals][0].y=heightmap[whichx+1][whichy]*scale+.01; + decalvertex[numdecals][0].x = placex; + decalvertex[numdecals][0].z = placez; + decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01; - placex=(float)whichx*scale+scale; - placez=(float)whichy*scale+scale; + placex = (float)whichx * scale + scale; + placez = (float)whichy * scale + scale; - decaltexcoords[numdecals][1][0]=(placex-where.x)/size/2+.5; - decaltexcoords[numdecals][1][1]=(placez-where.z)/size/2+.5; + decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5; + decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5; - decalvertex[numdecals][1].x=placex; - decalvertex[numdecals][1].z=placez; - decalvertex[numdecals][1].y=heightmap[whichx+1][whichy+1]*scale+.01; + decalvertex[numdecals][1].x = placex; + decalvertex[numdecals][1].z = placez; + decalvertex[numdecals][1].y = heightmap[whichx + 1][whichy + 1] * scale + .01; - placex=(float)whichx*scale; - placez=(float)whichy*scale+scale; + placex = (float)whichx * scale; + placez = (float)whichy * scale + scale; - decaltexcoords[numdecals][2][0]=(placex-where.x)/size/2+.5; - decaltexcoords[numdecals][2][1]=(placez-where.z)/size/2+.5; + decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5; + decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5; - decalvertex[numdecals][2].x=placex; - decalvertex[numdecals][2].z=placez; - decalvertex[numdecals][2].y=heightmap[whichx][whichy+1]*scale+.01; + decalvertex[numdecals][2].x = placex; + decalvertex[numdecals][2].z = placez; + decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01; - if(decalrotation[numdecals]){ - for(int i=0;i<3;i++){ - rot.y=0; - rot.x=decaltexcoords[numdecals][i][0]-.5; - rot.z=decaltexcoords[numdecals][i][1]-.5; - rot=DoRotation(rot,0,-decalrotation[numdecals],0); - decaltexcoords[numdecals][i][0]=rot.x+.5; - decaltexcoords[numdecals][i][1]=rot.z+.5; - } - } + if (decalrotation[numdecals]) { + for (int i = 0; i < 3; i++) { + rot.y = 0; + rot.x = decaltexcoords[numdecals][i][0] - .5; + rot.z = decaltexcoords[numdecals][i][1] - .5; + rot = DoRotation(rot, 0, -decalrotation[numdecals], 0); + decaltexcoords[numdecals][i][0] = rot.x + .5; + decaltexcoords[numdecals][i][1] = rot.z + .5; + } + } - if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0)) - if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0)) - if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1)) - if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1)) - if(numdecals 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1)) + if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) + if (numdecals < max_decals - 1) + numdecals++; - decalbrightness[numdecals]=decalbright; + decalbrightness[numdecals] = decalbright; - decalposition[numdecals]=where; - decaltype[numdecals]=type; - decalopacity[numdecals]=opacity; - decalrotation[numdecals]=rotation; - decalalivetime[numdecals]=0; + decalposition[numdecals] = where; + decaltype[numdecals] = type; + decalopacity[numdecals] = opacity; + decalrotation[numdecals] = rotation; + decalalivetime[numdecals] = 0; - placex=(float)whichx*scale+scale; - placez=(float)whichy*scale; + placex = (float)whichx * scale + scale; + placez = (float)whichy * scale; - decaltexcoords[numdecals][0][0]=(placex-where.x)/size/2+.5; - decaltexcoords[numdecals][0][1]=(placez-where.z)/size/2+.5; + decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5; + decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5; - decalvertex[numdecals][0].x=placex; - decalvertex[numdecals][0].z=placez; - decalvertex[numdecals][0].y=heightmap[whichx+1][whichy]*scale+.01; + decalvertex[numdecals][0].x = placex; + decalvertex[numdecals][0].z = placez; + decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01; - placex=(float)whichx*scale; - placez=(float)whichy*scale; + placex = (float)whichx * scale; + placez = (float)whichy * scale; - decaltexcoords[numdecals][1][0]=(placex-where.x)/size/2+.5; - decaltexcoords[numdecals][1][1]=(placez-where.z)/size/2+.5; + decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5; + decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5; - decalvertex[numdecals][1].x=placex; - decalvertex[numdecals][1].z=placez; - decalvertex[numdecals][1].y=heightmap[whichx][whichy]*scale+.01; + decalvertex[numdecals][1].x = placex; + decalvertex[numdecals][1].z = placez; + decalvertex[numdecals][1].y = heightmap[whichx][whichy] * scale + .01; - placex=(float)whichx*scale; - placez=(float)whichy*scale+scale; + placex = (float)whichx * scale; + placez = (float)whichy * scale + scale; - decaltexcoords[numdecals][2][0]=(placex-where.x)/size/2+.5; - decaltexcoords[numdecals][2][1]=(placez-where.z)/size/2+.5; + decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5; + decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5; - decalvertex[numdecals][2].x=placex; - decalvertex[numdecals][2].z=placez; - decalvertex[numdecals][2].y=heightmap[whichx][whichy+1]*scale+.01; + decalvertex[numdecals][2].x = placex; + decalvertex[numdecals][2].z = placez; + decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01; - if(decalrotation[numdecals]){ - for(int i=0;i<3;i++){ - rot.y=0; - rot.x=decaltexcoords[numdecals][i][0]-.5; - rot.z=decaltexcoords[numdecals][i][1]-.5; - rot=DoRotation(rot,0,-decalrotation[numdecals],0); - decaltexcoords[numdecals][i][0]=rot.x+.5; - decaltexcoords[numdecals][i][1]=rot.z+.5; - } - } + if (decalrotation[numdecals]) { + for (int i = 0; i < 3; i++) { + rot.y = 0; + rot.x = decaltexcoords[numdecals][i][0] - .5; + rot.z = decaltexcoords[numdecals][i][1] - .5; + rot = DoRotation(rot, 0, -decalrotation[numdecals], 0); + decaltexcoords[numdecals][i][0] = rot.x + .5; + decaltexcoords[numdecals][i][1] = rot.z + .5; + } + } - if(!(decaltexcoords[numdecals][0][0]<0&&decaltexcoords[numdecals][1][0]<0&&decaltexcoords[numdecals][2][0]<0)) - if(!(decaltexcoords[numdecals][0][1]<0&&decaltexcoords[numdecals][1][1]<0&&decaltexcoords[numdecals][2][1]<0)) - if(!(decaltexcoords[numdecals][0][0]>1&&decaltexcoords[numdecals][1][0]>1&&decaltexcoords[numdecals][2][0]>1)) - if(!(decaltexcoords[numdecals][0][1]>1&&decaltexcoords[numdecals][1][1]>1&&decaltexcoords[numdecals][2][1]>1)) - if(numdecals 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1)) + if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1)) + if (numdecals < max_decals - 1) + numdecals++; + } } void Terrain::DoLighting() { - static int i,j,k,todivide; - static float brightness, total; - static XYZ blank, terrainpoint,lightloc; - lightloc=light.location; - Normalise(&lightloc); - //Calculate shadows - for(i=0;i1)brightness=1; - if(brightness<0)brightness=0; - - colors[i][j][0]=light.color[0]*brightness+light.ambient[0]; - colors[i][j][1]=light.color[1]*brightness+light.ambient[1]; - colors[i][j][2]=light.color[2]*brightness+light.ambient[2]; - - if(colors[i][j][0]>1)colors[i][j][0]=1; - if(colors[i][j][1]>1)colors[i][j][1]=1; - if(colors[i][j][2]>1)colors[i][j][2]=1; - if(colors[i][j][0]<0)colors[i][j][0]=0; - if(colors[i][j][1]<0)colors[i][j][1]=0; - if(colors[i][j][2]<0)colors[i][j][2]=0; - } - } - - //Smooth shadows - for(i=0;i 1) + brightness = 1; + if (brightness < 0) + brightness = 0; + + colors[i][j][0] = light.color[0] * brightness + light.ambient[0]; + colors[i][j][1] = light.color[1] * brightness + light.ambient[1]; + colors[i][j][2] = light.color[2] * brightness + light.ambient[2]; + + if (colors[i][j][0] > 1) colors[i][j][0] = 1; + if (colors[i][j][1] > 1) colors[i][j][1] = 1; + if (colors[i][j][2] > 1) colors[i][j][2] = 1; + if (colors[i][j][0] < 0) colors[i][j][0] = 0; + if (colors[i][j][1] < 0) colors[i][j][1] = 0; + if (colors[i][j][2] < 0) colors[i][j][2] = 0; + } + } + + //Smooth shadows + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + for (k = 0; k < 3; k++) { + total = 0; + todivide = 0; + if (i != 0) { + total += colors[j][i - 1][k]; + todivide++; + } + if (i != size - 1) { + total += colors[j][i + 1][k]; + todivide++; + } + if (j != 0) { + total += colors[j - 1][i][k]; + todivide++; + } + if (j != size - 1) { + total += colors[j + 1][i][k]; + todivide++; + } + if (i != 0 && j != 0) { + total += colors[j - 1][i - 1][k]; + todivide++; + } + if (i != size - 1 && j != 0) { + total += colors[j - 1][i + 1][k]; + todivide++; + } + if (j != size - 1 && i != size - 1) { + total += colors[j + 1][i + 1][k]; + todivide++; + } + if (j != size - 1 && i != 0) { + total += colors[j + 1][i - 1][k]; + todivide++; + } + total += colors[j][i][k]; + todivide++; + + colors[j][i][k] = total / todivide; + } + } + } } void Terrain::DoShadows() { - static int i,j,k,l,todivide; - static float brightness, total; - static XYZ testpoint,testpoint2, terrainpoint,lightloc,col; - lightloc=light.location; - if(!skyboxtexture){ - lightloc.x=0; - lightloc.z=0; - } - if(skyboxtexture&&tutoriallevel){ - lightloc.x*=.4; - lightloc.z*=.4; - } - int patchx,patchz; - float shadowed; - Normalise(&lightloc); - //Calculate shadows - for(i=0;iLoadingScreen(); - } - brightness=dotproduct(&lightloc,&normals[i][j]); - if(shadowed)brightness*=1-shadowed; - - if(brightness>1)brightness=1; - if(brightness<0)brightness=0; - - colors[i][j][0]=light.color[0]*brightness+light.ambient[0]; - colors[i][j][1]=light.color[1]*brightness+light.ambient[1]; - colors[i][j][2]=light.color[2]*brightness+light.ambient[2]; - - if(colors[i][j][0]>1)colors[i][j][0]=1; - if(colors[i][j][1]>1)colors[i][j][1]=1; - if(colors[i][j][2]>1)colors[i][j][2]=1; - if(colors[i][j][0]<0)colors[i][j][0]=0; - if(colors[i][j][1]<0)colors[i][j][1]=0; - if(colors[i][j][2]<0)colors[i][j][2]=0; - } - } - - if(visibleloading)pgame->LoadingScreen(); - - //Smooth shadows - for(i=0;i 1) + brightness = 1; + if (brightness < 0) + brightness = 0; + + colors[i][j][0] = light.color[0] * brightness + light.ambient[0]; + colors[i][j][1] = light.color[1] * brightness + light.ambient[1]; + colors[i][j][2] = light.color[2] * brightness + light.ambient[2]; + + if (colors[i][j][0] > 1) colors[i][j][0] = 1; + if (colors[i][j][1] > 1) colors[i][j][1] = 1; + if (colors[i][j][2] > 1) colors[i][j][2] = 1; + if (colors[i][j][0] < 0) colors[i][j][0] = 0; + if (colors[i][j][1] < 0) colors[i][j][1] = 0; + if (colors[i][j][2] < 0) colors[i][j][2] = 0; + } + } + + if (visibleloading) + Game::LoadingScreen(); + + //Smooth shadows + for (i = 0; i < size; i++) { + for (j = 0; j < size; j++) { + for (k = 0; k < 3; k++) { + total = 0; + todivide = 0; + if (i != 0) { + total += colors[j][i - 1][k]; + todivide++; + } + if (i != size - 1) { + total += colors[j][i + 1][k]; + todivide++; + } + if (j != 0) { + total += colors[j - 1][i][k]; + todivide++; + } + if (j != size - 1) { + total += colors[j + 1][i][k]; + todivide++; + } + if (i != 0 && j != 0) { + total += colors[j - 1][i - 1][k]; + todivide++; + } + if (i != size - 1 && j != 0) { + total += colors[j - 1][i + 1][k]; + todivide++; + } + if (j != size - 1 && i != size - 1) { + total += colors[j + 1][i + 1][k]; + todivide++; + } + if (j != size - 1 && i != 0) { + total += colors[j + 1][i - 1][k]; + todivide++; + } + total += colors[j][i][k]; + todivide++; + + colors[j][i][k] = total / todivide; + } + } + } + + for (i = 0; i < subdivision; i++) { + for (j = 0; j < subdivision; j++) { + UpdateVertexArray(i, j); + } + } } Terrain::Terrain() { - bloodtexture = 0; - bloodtexture2 = 0; - shadowtexture = 0; - footprinttexture = 0; - bodyprinttexture = 0; - breaktexture = 0; - terraintexture = 0; - size = 0; - - memset(patchobjectnum, 0, sizeof(patchobjectnum)); - memset(patchobjects, 0, sizeof(patchobjects)); - - scale = 1.0f; - type = 0; - memset(heightmap, 0, sizeof(heightmap)); - memset(normals, 0, sizeof(normals)); - memset(facenormals, 0, sizeof(facenormals)); - memset(triangles, 0, sizeof(triangles)); - memset(colors, 0, sizeof(colors)); - memset(opacityother, 0, sizeof(opacityother)); - memset(texoffsetx, 0, sizeof(texoffsetx)); - memset(texoffsety, 0, sizeof(texoffsety)); - memset(numtris, 0, sizeof(numtris)); - memset(textureness, 0, sizeof(textureness)); - - memset(vArray, 0, sizeof(vArray)); - - memset(visible, 0, sizeof(visible)); - memset(avgypatch, 0, sizeof(avgypatch)); - memset(maxypatch, 0, sizeof(maxypatch)); - memset(minypatch, 0, sizeof(minypatch)); - memset(heightypatch, 0, sizeof(heightypatch)); - - patch_elements = 0; - - memset(decaltexcoords, 0, sizeof(decaltexcoords)); - memset(decalvertex, 0, sizeof(decalvertex)); - memset(decaltype, 0, sizeof(decaltype)); - memset(decalopacity, 0, sizeof(decalopacity)); - memset(decalrotation, 0, sizeof(decalrotation)); - memset(decalalivetime, 0, sizeof(decalalivetime)); - memset(decalbrightness, 0, sizeof(decalbrightness)); - memset(decalposition, 0, sizeof(decalposition)); - numdecals = 0; + size = 0; + + memset(patchobjectnum, 0, sizeof(patchobjectnum)); + memset(patchobjects, 0, sizeof(patchobjects)); + + scale = 1.0f; + type = 0; + memset(heightmap, 0, sizeof(heightmap)); + memset(normals, 0, sizeof(normals)); + memset(facenormals, 0, sizeof(facenormals)); + memset(triangles, 0, sizeof(triangles)); + memset(colors, 0, sizeof(colors)); + memset(opacityother, 0, sizeof(opacityother)); + memset(texoffsetx, 0, sizeof(texoffsetx)); + memset(texoffsety, 0, sizeof(texoffsety)); + memset(numtris, 0, sizeof(numtris)); + memset(textureness, 0, sizeof(textureness)); + + memset(vArray, 0, sizeof(vArray)); + + memset(visible, 0, sizeof(visible)); + memset(avgypatch, 0, sizeof(avgypatch)); + memset(maxypatch, 0, sizeof(maxypatch)); + memset(minypatch, 0, sizeof(minypatch)); + memset(heightypatch, 0, sizeof(heightypatch)); + + patch_elements = 0; + + memset(decaltexcoords, 0, sizeof(decaltexcoords)); + memset(decalvertex, 0, sizeof(decalvertex)); + memset(decaltype, 0, sizeof(decaltype)); + memset(decalopacity, 0, sizeof(decalopacity)); + memset(decalrotation, 0, sizeof(decalrotation)); + memset(decalalivetime, 0, sizeof(decalalivetime)); + memset(decalbrightness, 0, sizeof(decalbrightness)); + memset(decalposition, 0, sizeof(decalposition)); + numdecals = 0; } Terrain::~Terrain() { - if(terraintexture)glDeleteTextures( 1, &terraintexture ); - if(shadowtexture) glDeleteTextures( 1, &shadowtexture ); - if(bodyprinttexture) glDeleteTextures( 1, &bodyprinttexture ); - if(footprinttexture) glDeleteTextures( 1, &footprinttexture ); - if(bloodtexture) glDeleteTextures( 1, &bloodtexture ); - if(bloodtexture2) glDeleteTextures( 1, &bloodtexture2 ); - if(breaktexture) glDeleteTextures( 1, &breaktexture ); + terraintexture.destroy(); + shadowtexture.destroy(); + bodyprinttexture.destroy(); + footprinttexture.destroy(); + bloodtexture.destroy(); + bloodtexture2.destroy(); + breaktexture.destroy(); }