02061d74c2
(as received from Jonas Echterhoff)
612 lines
20 KiB
C++
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,¢er,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();
|
|
} |