Fixed some issues with the generic path (but nothing official yet probably major bugs still)

This commit is contained in:
cholleme 2003-11-02 19:51:39 +00:00
parent 42c8a2cafa
commit c19bdf4c41

View file

@ -24,6 +24,7 @@ Generic bumpmapping with some Geforce optimizations
#include "quakedef.h"
static cvar_t sh_fakespecular = {"sh_fakespecular","1", true};
//#define GENDEBUG
@ -42,7 +43,111 @@ static void generic_checkerror()
#endif
/************************
Generic "fragment programs"
************************/
/**
Light attenuation shader
*/
void GL_EnableGenericAttShader() {
GL_Bind(glow_texture_object);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
GL_EnableMultitexture();
GL_Bind(glow_texture_object);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
void GL_DisableGenericAttShader() {
GL_DisableMultitexture();
}
/**
Color map modulation shader
primary color = light color
tu0 = light filter cube map
tu1 = material color map
*/
void GL_EnableGenericColorShader (qboolean specular) {
GL_SelectTexture(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
GL_SelectTexture(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, currentshadowlight->filtercube);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
if (!specular) {
GL_EnableMultitexture();
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
} else {
GL_EnableMultitexture();
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_ALPHA);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
}
}
void GL_DisableGenericColorShader (qboolean specular) {
if (!specular) {
GL_DisableMultitexture();
} else {
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
GL_DisableMultitexture();
}
glEnable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
}
/**
Diffuse dot product shader
texture coords for unit 0: Tangent space light vector
texture coords for unit 1: Normal map texture coords
*/
void GL_EnableGenericDiffuseShader () {
GL_SelectTexture(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, normcube_texture_object);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
GL_EnableMultitexture();
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGBA_ARB);
}
void GL_DisableGenericDiffuseShader () {
GL_DisableMultitexture();
glEnable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
}
/************************
@ -56,11 +161,11 @@ void Generic_SetupTcMod(tcmod_t *tc)
{
case TCMOD_ROTATE:
glTranslatef(0.5,0.5,0.0);
glRotatef(cl.time * tc->params[0],0,0,1);
glRotatef(realtime * tc->params[0],0,0,1);
glTranslatef(-0.5, -0.5, 0.0);
break;
case TCMOD_SCROLL:
glTranslatef(cl.time * tc->params[0], cl.time * tc->params[1], 0.0);
glTranslatef(realtime * tc->params[0], realtime * tc->params[1], 0.0);
break;
case TCMOD_SCALE:
glScalef(tc->params[0],tc->params[1],1.0);
@ -110,15 +215,16 @@ void Generic_SetupSimpleStage(stage_t *s)
/************************
Generic triangle list routines
Generic triangle list routines
*************************/
void FormatError(); // In gl_bumpgf.c
/*
void Generic_drawTriangleListBump (const vertexdef_t *verts, int *indecies,
int numIndecies, shader_t *shader,
const transform_t *tr)
const transform_t *tr, const lightobject_t *lo)
{
return;
glEnableClientState(GL_VERTEX_ARRAY);
@ -178,6 +284,186 @@ void Generic_drawTriangleListBump (const vertexdef_t *verts, int *indecies,
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
Generic_DisableBumpShader(shader);
}
*/
static const lightobject_t *currentLo;
void VertWV(float *pos, float *tex, float *lm, float *tg, float *bn, float*nr) {
glTexCoord3fv(pos);
qglMultiTexCoord2fvARB(GL_TEXTURE1_ARB, tex);
glVertex3fv(pos);
}
void VertTex(float *pos, float *tex, float *lm, float *tg, float *bn, float*nr) {
glTexCoord2fv(tex);
glVertex3fv(pos);
}
void VertFakeSpecular(float *pos, float *tex, float *lm, float *tg, float *bn, float*nr) {
glNormal3fv(nr);
glTexCoord3fv(pos);
qglMultiTexCoord2fvARB(GL_TEXTURE1_ARB, tex);
glVertex3fv(pos);
}
void VertAtt(float *pos, float *tex, float *lm, float *tg, float *bn, float*nr) {
vec3_t nearToVert;
float tu, tv, tw;
VectorSubtract (pos, currentLo->objectorigin, nearToVert);
tu = (nearToVert[0]/currentshadowlight->radiusv[0])*0.5+0.5;
tv = (nearToVert[1]/currentshadowlight->radiusv[1])*0.5+0.5;
tw = (nearToVert[2]/currentshadowlight->radiusv[2])*0.5+0.5;
glTexCoord2f(tu, tv);
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, tw, 0.5);
glVertex3fv(pos);
}
void VertDiffuse(float *pos, float *tex, float *lm, float *tg, float *bn, float*nr) {
vec3_t lightDir, tsLightDir;
VectorSubtract(currentLo->objectorigin, pos, lightDir);
tsLightDir[0] = DotProduct(lightDir,tg);
tsLightDir[1] = -DotProduct(lightDir,bn);
tsLightDir[2] = DotProduct(lightDir,nr);
qglMultiTexCoord3fvARB(GL_TEXTURE0_ARB, &tsLightDir[0]);
qglMultiTexCoord2fvARB(GL_TEXTURE1_ARB, tex);
glVertex3fv(pos);
}
void Generic_DrawTriWithFunc(const vertexdef_t *verts, int *indecies,
int numIndecies, void (*VertFunc) (float *, float *, float *, float *, float *, float*))
{
int i;
vertexdef_t v = *verts;
if (!v.vertexstride) v.vertexstride = 12;
if (!v.texcoordstride) v.texcoordstride = 8;
if (!v.lightmapstride) v.lightmapstride = 8;
if (!v.tangentstride) v.lightmapstride = 12;
if (!v.binormalstride) v.binormalstride = 12;
if (!v.normalstride) v.normalstride = 12;
glBegin(GL_TRIANGLES);
for (i=0; i<numIndecies; i++) {
int ind = indecies[i];
VertFunc( (float *)((byte *)v.vertices + ind*v.vertexstride),
(float *)((byte *)v.texcoords + ind*v.texcoordstride),
(float *)((byte *)v.lightmapcoords + ind*v.lightmapstride),
(float *)((byte *)v.tangents + ind*v.tangentstride),
(float *)((byte *)v.binormals + ind*v.binormalstride),
(float *)((byte *)v.normals + ind*v.normalstride)
);
}
glEnd();
}
void Generic_drawTriangleListBump (const vertexdef_t *verts, int *indecies,
int numIndecies, shader_t *shader,
const transform_t *tr, const lightobject_t *lo)
{
glDepthMask (0);
currentLo = lo;
//attenuate with projected 2D attenuation map
GL_DrawAlpha();
GL_EnableGenericAttShader();
Generic_DrawTriWithFunc(verts, indecies, numIndecies, VertAtt);
GL_DisableGenericAttShader();
// modulate diffuse bump (n dot l) to alpha
GL_ModulateAlphaDrawAlpha();
GL_EnableGenericDiffuseShader();
if (shader->numbumpstages > 0) {
GL_BindAdvanced(shader->bumpstages[0].texture[0]);
}
Generic_DrawTriWithFunc(verts, indecies, numIndecies, VertDiffuse);
GL_DisableGenericDiffuseShader ();
//Do fake specular
if (sh_fakespecular.value) {
float black[4] = {0.0, 0.0, 0.0, 1.0};
float white[4] = {1.0, 1.0, 1.0, 1.0};
float pos[4];
GL_ModulateAlphaDrawColor();
glColorMask(true, true, true, false);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
VectorCopy(lo->objectorigin, pos);
pos[3] = 1.0;
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, black);
glLightfv(GL_LIGHT0, GL_AMBIENT, black);
glLightfv(GL_LIGHT0, GL_SPECULAR, &currentshadowlight->color[0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 16);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
glEnable(GL_COLOR_MATERIAL);
glColor4fv(white);
GL_EnableGenericColorShader (true);
if (shader->numbumpstages > 0) {
GL_BindAdvanced(shader->bumpstages[0].texture[0]);
}
Generic_DrawTriWithFunc(verts, indecies, numIndecies, VertFakeSpecular);
GL_DisableGenericColorShader (true);
glDisable(GL_LIGHTING);
}
// Then modulate Color map and light filter with alpha and add to color
GL_ModulateAlphaDrawColor();
glColor3fv(&currentshadowlight->color[0]);
if ( currentshadowlight->filtercube )
{
glMatrixMode(GL_TEXTURE);
glPushMatrix();
GL_SetupCubeMapMatrix(tr);
GL_EnableGenericColorShader (false);
if (shader->numcolorstages > 0) {
GL_BindAdvanced(shader->colorstages[0].texture[0]);
}
Generic_DrawTriWithFunc(verts, indecies, numIndecies, VertWV);
GL_DisableGenericColorShader (false);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
else
{
// Just alpha * light color
GL_DisableMultitexture();
if (shader->numcolorstages > 0) {
GL_BindAdvanced(shader->colorstages[0].texture[0]);
}
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Generic_DrawTriWithFunc(verts, indecies, numIndecies, VertTex);
}
GL_DrawColor();
glColor3f (1,1,1);
glDisable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask (1);
}
void Generic_drawTriangleListBase (vertexdef_t *verts, int *indecies,
int numIndecies, shader_t *shader,
@ -357,15 +643,15 @@ void Generic_sendSurfacesBase(msurface_t **surfs, int numSurfaces,
GL_Bind(lightmap_textures+surf->lightmaptexturenum);
}
glBegin(GL_TRIANGLE_FAN);
v = (float *)(&globalVertexTable[surf->polys->firstvertex]);
for (j = 0; j < p->numverts; j++, v+= VERTEXSIZE)
{
glBegin(GL_TRIANGLES);
for (j=0; j<surf->polys->numindecies; j++) {
v = (float *)(&globalVertexTable[surf->polys->indecies[j]]);
qglMultiTexCoord2fvARB(GL_TEXTURE0_ARB, &v[3]);
qglMultiTexCoord3fvARB(GL_TEXTURE1_ARB, &v[5]);
glVertex3fv(&v[0]);
}
glEnd();
}
}
@ -500,10 +786,10 @@ void Generic_sendSurfacesDiffuse(msurface_t **surfs, int numSurfaces)
lastshader = shader;
}
glBegin(GL_TRIANGLE_FAN);
v = (float *)(&globalVertexTable[surf->polys->firstvertex]);
for (j = 0; j < p->numverts; j++, v+= VERTEXSIZE)
{
glBegin(GL_TRIANGLES);
for (j=0; j<surf->polys->numindecies; j++) {
v = (float *)(&globalVertexTable[surf->polys->indecies[j]]);
VectorSubtract(currentshadowlight->origin, (&v[0]), lightDir);
if (surf->flags & SURF_PLANEBACK) {
tsLightDir[2] = -DotProduct(lightDir,surf->plane->normal);
@ -533,10 +819,8 @@ void Generic_sendSurfacesATT(msurface_t **surfs, int numSurfaces)
msurface_t *surf;
shader_t *shader, *lastshader;
qboolean cull;
float tu, tv;
vec3_t *s, *t, nearPt, nearToVert;
float dist, scale;
mplane_t *splitplane;
float tu, tv, tw;
vec3_t nearToVert;
float *v;
cull = true;
@ -573,30 +857,19 @@ void Generic_sendSurfacesATT(msurface_t **surfs, int numSurfaces)
}
glColor4f(1, 1, 1, 1);
v = (float *)(&globalVertexTable[surf->polys->firstvertex]);
// Calculate attenuation
splitplane = surf->plane;
s = (vec3_t *)&surf->tangent;
t = (vec3_t *)&surf->binormal;
dist = DotProduct (currentshadowlight->origin, splitplane->normal) - splitplane->dist;
dist = abs(dist);
ProjectPlane (currentshadowlight->origin, (*s), (*t), nearPt);
glBegin(GL_TRIANGLES);
for (j=0; j<surf->polys->numindecies; j++) {
v = (float *)(&globalVertexTable[surf->polys->indecies[j]]);
// FIXME! BBLIGHTS
// scale = 1 /((2 * currentshadowlight->radius) - dist);
scale = 1 /((2 * 400) - dist);
VectorSubtract (v, currentshadowlight->origin, nearToVert);
glBegin(GL_TRIANGLE_FAN);
for (j = 0; j < p->numverts; j++, v+= VERTEXSIZE)
{
VectorSubtract (v, nearPt, nearToVert);
// Get our texture coordinates, transform into tangent plane
tu = DotProduct (nearToVert, (*s)) * scale + 0.5;
tv = DotProduct (nearToVert, (*t)) * scale + 0.5;
tu = (nearToVert[0]/currentshadowlight->radiusv[0])*0.5+0.5;
tv = (nearToVert[1]/currentshadowlight->radiusv[1])*0.5+0.5;
tw = (nearToVert[2]/currentshadowlight->radiusv[2])*0.5+0.5;
glTexCoord2f(tu, tv);
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, tw, 0.5);
glVertex3fv(&v[0]);
}
glEnd();
@ -605,7 +878,7 @@ void Generic_sendSurfacesATT(msurface_t **surfs, int numSurfaces)
glEnable(GL_CULL_FACE);
}
void Generic_sendSurfacesWV(msurface_t **surfs, int numSurfaces)
void Generic_sendSurfacesWV(msurface_t **surfs, int numSurfaces, qboolean specular)
{
int i, j;
glpoly_t *p;
@ -644,15 +917,21 @@ void Generic_sendSurfacesWV(msurface_t **surfs, int numSurfaces)
cull = true;
}
lastshader = shader;
GL_SelectTexture(GL_TEXTURE0_ARB);
GL_SelectTexture(GL_TEXTURE1_ARB);
if (!specular) {
if (shader->numcolorstages > 0)
GL_BindAdvanced(shader->colorstages[0].texture[0]);
} else {
if (shader->numbumpstages > 0)
GL_BindAdvanced(shader->bumpstages[0].texture[0]);
}
}
glBegin(GL_TRIANGLE_FAN);
v = (float *)(&globalVertexTable[surf->polys->firstvertex]);
for (j = 0; j < p->numverts; j++, v+= VERTEXSIZE)
{
glNormal3fv(surf->plane->normal);
glBegin(GL_TRIANGLES);
for (j=0; j<surf->polys->numindecies; j++) {
v = (float *)(&globalVertexTable[surf->polys->indecies[j]]);
glTexCoord3fv(&v[0]);
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, v[3], v[4]);
glVertex3fv(&v[0]);
@ -709,6 +988,7 @@ void Generic_sendSurfacesTex(msurface_t **surfs, int numSurfaces)
GL_BindAdvanced(shader->colorstages[0].texture[0]);
}
/*
glBegin(GL_TRIANGLE_FAN);
v = (float *)(&globalVertexTable[surf->polys->firstvertex]);
for (j = 0; j < p->numverts; j++, v+= VERTEXSIZE)
@ -717,27 +997,77 @@ void Generic_sendSurfacesTex(msurface_t **surfs, int numSurfaces)
glVertex3fv(&v[0]);
}
glEnd();
*/
glBegin(GL_TRIANGLES);
for (j=0; j<surf->polys->numindecies; j++) {
v = (float *)(&globalVertexTable[surf->polys->indecies[j]]);
glTexCoord2fv(&v[3]);
glVertex3fv(&v[0]);
}
glEnd();
}
if (!cull)
glEnable(GL_CULL_FACE);
}
void Generic_drawSurfaceListBump (vertexdef_t *verts, msurface_t **surfs,
int numSurfaces,const transform_t *tr)
int numSurfaces,const transform_t *tr, const lightobject_t *lo)
{
glDepthMask (0);
// First draw diffuse bump (n dot l) to alpha
//attenuate with projected 2D attenuation map
GL_DrawAlpha();
GL_EnableDiffuseShader();
Generic_sendSurfacesDiffuse(surfs, numSurfaces);
GL_DisableDiffuseShader ();
// Then attenuate with projected 2D attenuation map
GL_ModulateAlphaDrawAlpha();
GL_EnableAttShader();
GL_EnableGenericAttShader();
Generic_sendSurfacesATT(surfs, numSurfaces);
GL_DisableAttShader();
GL_DisableGenericAttShader();
// modulate diffuse bump (n dot l) to alpha
GL_ModulateAlphaDrawAlpha();
GL_EnableGenericDiffuseShader();
Generic_sendSurfacesDiffuse(surfs, numSurfaces);
GL_DisableGenericDiffuseShader ();
//Do fake specular
if (sh_fakespecular.value) {
//This is so fake...
//-it gets attenuated with the diffuse dot product and the light attenuation
//-The specular gets caclulated per vertex
//-But it remotely looks like specular at the cost of one extra pass
float black[4] = {0.0, 0.0, 0.0, 1.0};
float white[4] = {1.0, 1.0, 1.0, 1.0};
float pos[4];
GL_ModulateAlphaDrawColor();
glColorMask(true, true, true, false);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
VectorCopy(lo->objectorigin, pos);
pos[3] = 1.0;
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, black);
glLightfv(GL_LIGHT0, GL_AMBIENT, black);
glLightfv(GL_LIGHT0, GL_SPECULAR, &currentshadowlight->color[0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 16);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
glEnable(GL_COLOR_MATERIAL);
glColor4fv(white);
GL_EnableGenericColorShader (true);
Generic_sendSurfacesWV(surfs, numSurfaces, true);
GL_DisableGenericColorShader (true);
glDisable(GL_LIGHTING);
}
// Then modulate Color map and light filter with alpha and add to color
GL_ModulateAlphaDrawColor();
@ -748,9 +1078,10 @@ void Generic_drawSurfaceListBump (vertexdef_t *verts, msurface_t **surfs,
glPushMatrix();
GL_SetupCubeMapMatrix(tr);
GL_EnableColorShader (false);
Generic_sendSurfacesWV(surfs, numSurfaces);
GL_DisableColorShader (false);
GL_EnableGenericColorShader (false);
Generic_sendSurfacesWV(surfs, numSurfaces, false);
GL_DisableGenericColorShader (false);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
@ -758,16 +1089,26 @@ void Generic_drawSurfaceListBump (vertexdef_t *verts, msurface_t **surfs,
{
// Just alpha * light color
GL_SelectTexture(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
GL_SelectTexture(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
//glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Generic_sendSurfacesTex(surfs, numSurfaces);
}
GL_DrawColor();
glColor3f (1,1,1);
glDisable (GL_BLEND);
@ -817,6 +1158,7 @@ void BUMP_InitGeneric(void)
if ( gl_cardtype != GENERIC && gl_cardtype != GEFORCE )
return;
Cvar_RegisterVariable(&sh_fakespecular);
//bind the correct stuff to the bump mapping driver
gl_bumpdriver.drawSurfaceListBase = Generic_drawSurfaceListBase;
gl_bumpdriver.drawSurfaceListBump = Generic_drawSurfaceListBump;