From e17acec1c9bec3a26d97ca2873bb77bdcb48665e Mon Sep 17 00:00:00 2001 From: icculus Date: Thu, 2 Jan 2003 21:06:00 +0000 Subject: Initial revision git-svn-id: svn://svn.icculus.org/blackshades/trunk@2 5198baeb-e213-0410-be47-fc2ff85ca46f --- Source/Decals.cpp | 445 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 445 insertions(+) create mode 100644 Source/Decals.cpp (limited to 'Source/Decals.cpp') diff --git a/Source/Decals.cpp b/Source/Decals.cpp new file mode 100644 index 0000000..075f69b --- /dev/null +++ b/Source/Decals.cpp @@ -0,0 +1,445 @@ +#include "Decals.h" + +extern double multiplier; +extern bool slomo; +extern Fog fog; +extern bool blood; +extern float fogcolorr; +extern float fogcolorg; +extern float fogcolorb; +//Functions +extern float sinefluct; +extern int environment; +extern Model gunmodels[10]; +extern Camera camera; +extern float precipitationhorz; +extern float precipitationvert; +extern float precipitationdensity; +extern float snowdelay; + +int Decals::MakeDecal(int atype, XYZ location, float size, XYZ normal, int poly, Model *model, XYZ move, float rotation){ + int major=0; + float normalv[3]; + XYZ right; + XYZ up; + XYZ nothing; + XYZ axis[3]; + XYZ temp; + + nothing=0; + + axis[0].x=1; + axis[1].y=1; + axis[2].z=1; + + normalv[0]=abs(normal.x); + normalv[1]=abs(normal.y); + normalv[2]=abs(normal.z); + + + if(normalv[1]>normalv[major])major=1; + if(normalv[2]>normalv[major])major=2; + + if (normalv[0] == 1 || normalv[1] == 1 || normalv[2] == 1) + { + if ((major == 0 && normal.x > 0) || major == 1){ + right=0; + right.z=-1;} + else if (major == 0){ + right=0; + right.z=1;} + else { + right=0; + right.x=normal.z;} + } + else + CrossProduct(axis[major], normal, &right); + + CrossProduct(normal, right, &up); + Normalise(&up); + Normalise(&right); + + float count; + float count2; + float countinc=1/size; + if(countinc<.01)countinc=.01; + if(countinc>.2)countinc=.2; + float normaloffset=.02; + int good; + + numpoints[howmanydecals]=0; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right - up) * (size/3) /*+ normal/100*/; + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0; + if((move.x==0&&move.z==0&&rotation==0)|| + LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp) + )numpoints[howmanydecals]++; + else { + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right - up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count - up) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + if(good==-1){ + good=-1; + count2=1-countinc; + while(good==-1&&count2>-1){ + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count2/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count2 - up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + count2-=countinc; + } + if(good!=-1)numpoints[howmanydecals]++; + } + } + + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right - up) * (size/3) /*+ normal/100*/; + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0; + if((move.x==0&&move.y==0&&move.z==0&&rotation==0)|| + LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp) + )numpoints[howmanydecals]++; + else { + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count - up) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right - up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + if(good==-1){ + good=-1; + count2=1-countinc; + while(good==-1&&count2>-1){ + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count2/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count2 - up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + count2-=countinc; + } + if(good!=-1)numpoints[howmanydecals]++; + } + } + + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right + up) * (size/3) /*+ normal/100*/; + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1; + if((move.x==0&&move.y==0&&move.z==0&&rotation==0)|| + LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp) + )numpoints[howmanydecals]++; + else { + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right + up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count + up) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + if(good==-1){ + good=-1; + count2=1-countinc; + while(good==-1&&count2>-1){ + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count2/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count2 + up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + count2-=countinc; + } + if(good!=-1)numpoints[howmanydecals]++; + } + } + + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right + up) * (size/3) /*+ normal/100*/; + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1; + if((move.x==0&&move.y==0&&move.z==0&&rotation==0)|| + LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp) + )numpoints[howmanydecals]++; + else { + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count + up) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + good=-1; + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right + up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + if(good!=-1)numpoints[howmanydecals]++; + if(good==-1){ + good=-1; + count2=1-countinc; + while(good==-1&&count2>-1){ + count=1-countinc; + while(good==-1&&count>-1){ + texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count2/2; + texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2; + points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count2 + up*count) * (size/3); + count-=countinc; + good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation); + } + count2-=countinc; + } + if(good!=-1)numpoints[howmanydecals]++; + } + } + for(int i=0;i=0){ + numpoints[which]=numpoints[howmanydecals-1]; + alivetime[which]=alivetime[howmanydecals-1]; + type[which]=type[howmanydecals-1]; + for(int i=0;i0){howmanydecals--;} + } +} + +void Decals::LoadBulletHoleTexture(char *fileName) +{ + TGAImageRec *tempTexture; + GLuint type; + + //Load Image + tempTexture = LoadTGA( fileName ); + //Is it valid? + if(tempTexture){ + //Alpha channel? + if ( tempTexture->bpp == 24 ) + type = GL_RGB; + else + type = GL_RGBA; + + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + glGenTextures( 1, &bulletholetextureptr ); + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + glBindTexture( GL_TEXTURE_2D, bulletholetextureptr); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + + gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data ); + free( tempTexture->data ); + free( tempTexture ); + } +} + +void Decals::LoadBloodTexture(char *fileName, int which) +{ + TGAImageRec *tempTexture; + GLuint type; + + //Load Image + tempTexture = LoadTGA( fileName ); + //Is it valid? + if(tempTexture){ + //Alpha channel? + if ( tempTexture->bpp == 24 ) + type = GL_RGB; + else + type = GL_RGBA; + + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + glGenTextures( 1, &bloodtextureptr[which] ); + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + glBindTexture( GL_TEXTURE_2D, bloodtextureptr[which]); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + + gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data ); + free( tempTexture->data ); + free( tempTexture ); + } +} + +void Decals::LoadCraterTexture(char *fileName) +{ + TGAImageRec *tempTexture; + GLuint type; + + //Load Image + tempTexture = LoadTGA( fileName ); + //Is it valid? + if(tempTexture){ + //Alpha channel? + if ( tempTexture->bpp == 24 ) + type = GL_RGB; + else + type = GL_RGBA; + + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + + glGenTextures( 1, &cratertextureptr ); + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + glBindTexture( GL_TEXTURE_2D, cratertextureptr); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + + gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data ); + free( tempTexture->data ); + free( tempTexture ); + } +} + +void Decals::DoStuff() +{ + for(int i=0;i10&&(type[i]==bullethole||type[i]==crater))DeleteDecal(i); + if(alivetime[i]>20&&(type[i]==bloodpool))DeleteDecal(i); + } +} + +void Decals::draw() +{ + glAlphaFunc(GL_GREATER, 0.01); + + float bloodpoolspeed=1; + + glDepthFunc(GL_LEQUAL); + glEnable(GL_BLEND); + glEnable(GL_CULL_FACE); + glEnable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glDepthMask(0); + glAlphaFunc(GL_GREATER, 0.01); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_POLYGON_OFFSET_FILL); + for(int i=0;i=bloodpoolspeed*.2&&alivetime[i]=bloodpoolspeed*.4&&alivetime[i]=bloodpoolspeed*.6&&alivetime[i]=bloodpoolspeed*.8&&alivetime[i]=bloodpoolspeed*1&&alivetime[i]=bloodpoolspeed*1.2&&alivetime[i]=bloodpoolspeed*1.4&&alivetime[i]=bloodpoolspeed*1.6&&alivetime[i]=bloodpoolspeed*1.8&&alivetime[i]=bloodpoolspeed*2.0)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[10]); + if(type[i]==bloodpool&&alivetime[i]=bloodpoolspeed*2.0)glColor4f(1,1,1,20-alivetime[i]); + + glPushMatrix(); + glBegin(GL_TRIANGLE_FAN); + for(int j=0;j=bloodpoolspeed*.2&&alivetime[i]=bloodpoolspeed*.4&&alivetime[i]=bloodpoolspeed*.6&&alivetime[i]=bloodpoolspeed*.8&&alivetime[i]=bloodpoolspeed*1&&alivetime[i]=bloodpoolspeed*1.2&&alivetime[i]=bloodpoolspeed*1.4&&alivetime[i]=bloodpoolspeed*1.6&&alivetime[i]=bloodpoolspeed*1.8&&alivetime[i]