Redline/source/transparency.cpp
maride 02061d74c2 Original 1.0.5 code
(as received from Jonas Echterhoff)
2016-04-02 14:43:55 +02:00

612 lines
20 KiB
C++

//transparency.cpp
//sort and draw all transparent polygons
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#include <stdlib.h>
#include "fileio.h"
#include "vectors.h"
#include "environment.h"
#include "transparency.h"
#include "entities.h"
#include "textures.h"
#include "renderframe.h"
#include "config.h"
#include "gameframe.h"
#include "gameinitexit.h"
#include "text.h"
#include "sky.h"
//an index used to sort transparent polygons
typedef struct{
float distance;
int poly;
}tTransparentPolyDistSort;
float gTunnelFactor=0;
float gBlurMapFactor=0;
float gGlowFactor=0;
float gShineFactor=1;
int gGhostShine=false;
#define kMaxTransparentPolys 16384 //maximum number of transparent polygons in scene
#define kMaxMaterialStorage 1024
tPolyMaterial *gMaterialStorage;
tTransparentPoly *gTranparentPolys; //transparent poly buffer
tTransparentPolyDistSort *gPolyDistance; //transparent poly index
int gTransparentPolyCount=0; //transparent polygons currently used
int gMaterialStorageCount=0;
void InitTransparency()
{
gMaterialStorage=(tPolyMaterial*)malloc(sizeof(tPolyMaterial)*kMaxMaterialStorage);
gTranparentPolys=(tTransparentPoly*)malloc(sizeof(tTransparentPoly)*kMaxTransparentPolys);
gPolyDistance=(tTransparentPolyDistSort*)malloc(sizeof(tTransparentPolyDistSort)*kMaxTransparentPolys);
}
//returns a pointer to an unused tTransparentPoly which needs to be filled with data
//and increments the transparent polygon count
tTransparentPoly* GetNextTransparentPoly(int allocateMaterial)
{
if(gTransparentPolyCount<kMaxTransparentPolys)
{
if(allocateMaterial)
if(gMaterialStorageCount<kMaxMaterialStorage)
gTranparentPolys[gTransparentPolyCount].mat=gMaterialStorage+gMaterialStorageCount++;
else
return NULL;
gTranparentPolys[gTransparentPolyCount].textureSet=0;
gTranparentPolys[gTransparentPolyCount].ghost=0;
gTranparentPolys[gTransparentPolyCount].glow=gGlowFactor;
gTranparentPolys[gTransparentPolyCount].blur=gBlurMapFactor;
gTransparentPolyCount++;
return gTranparentPolys+gTransparentPolyCount-1;
}
else
return NULL;
}
//setup OpenGL to use the properties of the material passed in mat
int UseMaterial(tPolyMaterial *mat,int allowTransparency,int textureSet)
{
GLfloat specularReflectance[4];
GLfloat ambientReflectance[4];
GLfloat diffuseReflectance[4];
GLfloat emission[4]={0,0,0,1};
*(tVector3*)specularReflectance=mat->specular;
*(tVector3*)ambientReflectance=mat->ambient;
*(tVector3*)diffuseReflectance=mat->diffuse;
specularReflectance[3]=1;
ambientReflectance[3]=1;
diffuseReflectance[3]=1;
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,diffuseReflectance);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambientReflectance);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specularReflectance);
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,mat->shininess);
if(mat->flags&kMaterialEnableGlow)
{
emission[0]=gGlowFactor;
emission[1]=gGlowFactor*0.3;
}
if(mat->flags&kMaterialEnableShine)
{
emission[0]=gShineFactor*gEnvironment->spotLightColor.x;
emission[1]=gShineFactor*gEnvironment->spotLightColor.y;
emission[2]=gShineFactor*gEnvironment->spotLightColor.z;
}
if(gGhostShine)
{
emission[0]=1.5;
emission[1]=1.5;
emission[2]=1.5;
}
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,emission);
if(mat->flags&kMaterialDisableLighting)
glDisable(GL_LIGHTING);
else
glEnable(GL_LIGHTING);
TexturesSelectTex(FileGetIndexedReference(mat->texRef,textureSet));
/* glMatrixMode(GL_TEXTURE);
glLoadIdentity();
if(mat->flags&kMaterialMoveUVs)
glTranslatef(kFrameTime*gFrameCount,kFrameTime*gFrameCount,0);
glMatrixMode(GL_MODELVIEW);*/
if(mat->flags&kMaterialDisableWrap)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
}
else if(mat->flags&kMaterialDisableWrapS)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
}
else if(mat->flags&kMaterialDisableWrapT)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
}
if(mat->flags&kMaterialBothSides)
glDisable(GL_CULL_FACE);
else
glEnable(GL_CULL_FACE);
if(gEnvironment->environmentMapping)
if(mat->flags&kMaterialSphereMap){
if(TexturesSelectTextureUnit(1))
{
#ifndef __TARGET_TOOLAPP
if(gMapEnv)
if(gMapEnv->spheremap)
TexturesSelectTex(gMapEnv->spheremap);
else
TexturesSelectTex(gEnvironment->spheremap);
else
#endif
TexturesSelectTex(gEnvironment->spheremap);
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
tMatrix4 m;
MatrixCopy(gTransformDir,m);
glLoadMatrixf((float*)m);
glMatrixMode(GL_MODELVIEW);
if(gEnvironment->environmentMapping==kEnvironmentMappingSphereInterpolate)
{
#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
#define GL_MODULATE_ADD_ATI 0x8744
/* GLfloat color[4]={1,1,1,gEnvironment->environmentMapIntensity*gEnvironmentMapFactor};
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB,GL_CONSTANT_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_ALPHA);
glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,color); */
GLfloat color[4]={1,1,1,0.5};
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_MODULATE_ADD_ATI);
//glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB,GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_ARB,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB,GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_ARB,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB,GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_ALPHA);
//glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,color);
}
else
{
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_ADD_SIGNED_ARB);
}
TexturesSelectTextureUnit(0);
}
}
else {
if(TexturesSelectTextureUnit(1)){
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
TexturesSelectTextureUnit(0);
}
}
#ifndef __TARGET_TOOLAPP
int enableLightMap=false;
if(gMapEnv)
if(gMapEnv->lightMap)
if((!gMapEnv->lightMap2)||((mat->flags&kMaterialSphereMap)&&!gTunnelFactor))
if(TexturesSelectTextureUnit(2))
{
TexturesSelectTex(gMapEnv->lightMap);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_MODULATE);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
if(gMapEnv->lightMapBotRight.x!=gMapEnv->lightMapTopLeft.x)
{
GLfloat xPlane[]={1.0f/(gMapEnv->lightMapBotRight.x-gMapEnv->lightMapTopLeft.x),0.0f,0.0f,(gTransformPos.x-gMapEnv->lightMapTopLeft.x+gFrameCount*kFrameTime*gMapEnv->lightMapSpeed.x)/(gMapEnv->lightMapBotRight.x-gMapEnv->lightMapTopLeft.x)};
glTexGenfv(GL_S,GL_OBJECT_PLANE,xPlane);
}
if(gMapEnv->lightMapBotRight.y!=gMapEnv->lightMapTopLeft.y)
{
GLfloat yPlane[]={0.0f,0.0f,1.0f/(gMapEnv->lightMapBotRight.y-gMapEnv->lightMapTopLeft.y),(gTransformPos.z-gMapEnv->lightMapTopLeft.y+gFrameCount*kFrameTime*gMapEnv->lightMapSpeed.y)/(gMapEnv->lightMapBotRight.y-gMapEnv->lightMapTopLeft.y)};
glTexGenfv(GL_T,GL_OBJECT_PLANE,yPlane);
}
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
enableLightMap=true;
TexturesSelectTextureUnit(0);
}
if(!enableLightMap)
if(TexturesSelectTextureUnit(2))
{
glDisable(GL_TEXTURE_2D);
TexturesSelectTextureUnit(0);
}
#endif
if(allowTransparency)
{
if(mat->flags&kMaterialUseAlphaChannel)
{
//glColor4f(1,1,1,0.5);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
// glEnable(GL_ALPHA_TEST);
// glAlphaFunc(GL_GREATER,0.0);
}
else{
// glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
}
if(mat->flags&kMaterialAlphaTest)
{
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER,0.5);
}
else
glDisable(GL_ALPHA_TEST);
}
if(TexturesSelectTextureUnit(3))
{
glDisable(GL_TEXTURE_2D);
TexturesSelectTextureUnit(0);
}
return mat->flags&kMaterialUseAlphaChannel;
}
//setup OpenGL to use the properties of the material passed in mat
void UseMaterial2(tPolyMaterial *mat,tPolyMaterial *mat2,int textureSet)
{
GLfloat specularReflectance[4];
GLfloat ambientReflectance[4];
GLfloat diffuseReflectance[4];
GLfloat emission[4]={0,0,0,1};
*(tVector3*)specularReflectance=mat->specular;
*(tVector3*)ambientReflectance=mat->ambient;
*(tVector3*)diffuseReflectance=mat->diffuse;
specularReflectance[3]=1;
ambientReflectance[3]=1;
diffuseReflectance[3]=1;
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,diffuseReflectance);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambientReflectance);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specularReflectance);
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,mat->shininess);
if(mat->flags&kMaterialEnableGlow)
{
emission[0]=gGlowFactor;
emission[1]=gGlowFactor*0.3;
}
if(mat->flags&kMaterialEnableShine)
{
emission[0]=gShineFactor*gEnvironment->spotLightColor.x;
emission[1]=gShineFactor*gEnvironment->spotLightColor.y;
emission[2]=gShineFactor*gEnvironment->spotLightColor.z;
}
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,emission);
if(mat->flags&kMaterialDisableLighting)
glDisable(GL_LIGHTING);
else
glEnable(GL_LIGHTING);
TexturesSelectTex(FileGetIndexedReference(mat->texRef,textureSet));
if(mat->flags&kMaterialDisableWrap)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
}
else if(mat->flags&kMaterialDisableWrapS)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
}
else if(mat->flags&kMaterialDisableWrapT)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
}
if(mat->flags&kMaterialBothSides)
glDisable(GL_CULL_FACE);
else
glEnable(GL_CULL_FACE);
if(gConfig->stencil){
if(TexturesSelectTextureUnit(1))
{
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_MODULATE);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glMatrixMode(GL_TEXTURE);
glEnable(GL_TEXTURE_2D);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
if(!gLightning)
{
TexturesSelectTex(FileGetIndexedReference(mat2->texRef,gEnvironment->envFlags));
if(mat2->flags&kMaterialDisableWrap)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
}
}
else
TexturesSelectTex(FileGetReference("null.raw"));
TexturesSelectTextureUnit(0);
}
}
else
{
glEnable(GL_LIGHTING);
if(TexturesSelectTextureUnit(1))
{
glDisable(GL_TEXTURE_2D);
TexturesSelectTextureUnit(0);
}
}
#ifndef __TARGET_TOOLAPP
if(gMapEnv)
if(gMapEnv->lightMap2)
{
if(TexturesSelectTextureUnit(2))
{
if(!gLightning)
TexturesSelectTex(gMapEnv->lightMap2);
else
TexturesSelectTex(FileGetReference("null.raw"));
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_MODULATE);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
GLfloat xPlane[]={1/(gMapEnv->lightMap2BotRight.x-gMapEnv->lightMap2TopLeft.x),0,0,(gTransformPos.x-gMapEnv->lightMap2TopLeft.x+gFrameCount*kFrameTime*gMapEnv->lightMap2Speed.x)/(gMapEnv->lightMap2BotRight.x-gMapEnv->lightMap2TopLeft.x)};
glTexGenfv(GL_S,GL_OBJECT_PLANE,xPlane);
GLfloat yPlane[]={0,0,1/(gMapEnv->lightMap2BotRight.y-gMapEnv->lightMap2TopLeft.y),(gTransformPos.z-gMapEnv->lightMap2TopLeft.y+gFrameCount*kFrameTime*gMapEnv->lightMap2Speed.y)/(gMapEnv->lightMap2BotRight.y-gMapEnv->lightMap2TopLeft.y)};
glTexGenfv(GL_T,GL_OBJECT_PLANE,yPlane);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
TexturesSelectTextureUnit(0);
}
}
else if(gMapEnv->lightMap)
if(TexturesSelectTextureUnit(2))
{
if(!gLightning)
TexturesSelectTex(gMapEnv->lightMap);
else
TexturesSelectTex(FileGetReference("null.raw"));
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_MODULATE);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
GLfloat xPlane[]={1/(gMapEnv->lightMapBotRight.x-gMapEnv->lightMapTopLeft.x),0,0,(gTransformPos.x-gMapEnv->lightMapTopLeft.x+gFrameCount*kFrameTime*gMapEnv->lightMapSpeed.x)/(gMapEnv->lightMapBotRight.x-gMapEnv->lightMapTopLeft.x)};
glTexGenfv(GL_S,GL_OBJECT_PLANE,xPlane);
GLfloat yPlane[]={0,0,1/(gMapEnv->lightMapBotRight.y-gMapEnv->lightMapTopLeft.y),(gTransformPos.z-gMapEnv->lightMapTopLeft.y+gFrameCount*kFrameTime*gMapEnv->lightMapSpeed.y)/(gMapEnv->lightMapBotRight.y-gMapEnv->lightMapTopLeft.y)};
glTexGenfv(GL_T,GL_OBJECT_PLANE,yPlane);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
TexturesSelectTextureUnit(0);
}
#endif
if(mat->flags&kMaterialSphereMap&&gEnvironment->particlesAmount){
if(TexturesSelectTextureUnit(3))
{
TexturesSelectTex(FileGetReference("rainreflection.pct"));
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB,GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_ALPHA);
TexturesSelectTextureUnit(0);
}
} else if(TexturesSelectTextureUnit(3))
{
glDisable(GL_TEXTURE_2D);
TexturesSelectTextureUnit(0);
}
}
int UseGhostMaterial(tPolyMaterial *mat,int textureSet)
{
GLfloat specularReflectance[4];
GLfloat ambientReflectance[4];
GLfloat diffuseReflectance[4];
*(tVector3*)specularReflectance=mat->specular;
*(tVector3*)ambientReflectance=mat->ambient;
*(tVector3*)diffuseReflectance=mat->diffuse;
specularReflectance[3]=1;
ambientReflectance[3]=1;
diffuseReflectance[3]=1;
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,diffuseReflectance);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambientReflectance);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specularReflectance);
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,mat->shininess);
TexturesSelectTex(FileGetIndexedReference(mat->texRef,textureSet));
if(mat->flags&kMaterialDisableWrap)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
}
else if(mat->flags&kMaterialDisableWrapS)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
}
else if(mat->flags&kMaterialDisableWrapT)
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
}
else
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
}
glDisable(GL_CULL_FACE);
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_ONE);
return true;
}
//compare function used to sort the polygon index by the Z-Distance from the camera
int PolyTableCompare(tTransparentPolyDistSort *a,tTransparentPolyDistSort *b)
{
float diff=(a->distance)-(b->distance);
if(diff==0) return 0;
else return sign(diff);
}
//calculates the z-distance from the camera for each polygon index value
void PolyTableDepthSetup(tVector3 *clipPlanes)
{
tVector3 camZ=-*MatrixGetZVector(gCameraEntity->dir);
for(int i=0;i<gTransparentPolyCount;i++)
{
tTransparentPoly* p=gTranparentPolys+i;
//we simply use the sum of the three vertices for comparison
tVector3 center=(p->v[0].vertex+p->v[1].vertex+p->v[2].vertex)*(1.0f/3.0f);
if(clipPlanes)
if(ClipPointDistanced(clipPlanes,&center,20.0f))
gPolyDistance[i].distance=-10000.0f;
else
gPolyDistance[i].distance=(center-gCameraEntity->pos)*camZ;
else
gPolyDistance[i].distance=(center-gCameraEntity->pos)*camZ;
gPolyDistance[i].poly=i;
}
}
void DrawTransparentPolys(tVector3 *clipPlanes)
{
glPushAttrib(GL_LIGHTING_BIT+GL_TEXTURE_BIT+GL_POLYGON_BIT+GL_COLOR_BUFFER_BIT+GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
PolyTableDepthSetup(clipPlanes);
SetupWorldTranslation();
//depth-sort the polygons
qsort(gPolyDistance,gTransparentPolyCount,sizeof(tTransparentPolyDistSort),(int (*)(const void *, const void *))&PolyTableCompare);
//draw all the polygons
int texture=-1;
int textureSet=-1;
int ghost=0;
int i=0;
for(;i<gTransparentPolyCount&&gPolyDistance[i].distance==-10000.0f;i++);
for(;i<gTransparentPolyCount;i++)
{
int polyIndex=gPolyDistance[i].poly;
//if the texture isn't currently selected, then select it
if(texture!=gTranparentPolys[polyIndex].mat->texRef||textureSet!=gTranparentPolys[polyIndex].textureSet||ghost!=gTranparentPolys[polyIndex].ghost||gGlowFactor!=gTranparentPolys[polyIndex].glow)
{
gGlowFactor=gTranparentPolys[polyIndex].glow;
if(gTranparentPolys[polyIndex].ghost)
UseGhostMaterial(gTranparentPolys[polyIndex].mat,gTranparentPolys[polyIndex].textureSet);
else
UseMaterial(gTranparentPolys[polyIndex].mat,true,gTranparentPolys[polyIndex].textureSet);
glDepthMask(!(gTranparentPolys[polyIndex].mat->flags&kMaterialDisableShadow));
texture=gTranparentPolys[polyIndex].mat->texRef;
textureSet=gTranparentPolys[polyIndex].textureSet;
ghost=gTranparentPolys[polyIndex].ghost;
}
glBegin(GL_TRIANGLES);
for(int v=0;v<3;v++)
{
glNormal3fv(&gTranparentPolys[polyIndex].v[v].normal.x);
glTexCoord3f(gTranparentPolys[polyIndex].v[v].texel.x,gTranparentPolys[polyIndex].v[v].texel.y,0.25+0.5*gTranparentPolys[polyIndex].blur);
// glTexCoord3f(gTranparentPolys[polyIndex].v[v].texel.x,gTranparentPolys[polyIndex].v[v].texel.y,0.75);
glVertex3fv(&gTranparentPolys[polyIndex].v[v].vertex.x);
}
glEnd();
}
//reset transparent polygon count
gTransparentPolyCount=0;
gMaterialStorageCount=0;
glDisable(GL_BLEND);
if(TexturesSelectTextureUnit(1)){
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
TexturesSelectTextureUnit(0);
}
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPopAttrib();
}