fbef8596a9
Fixed bug with specular view origin incorrectly set up for meshes
1423 lines
No EOL
36 KiB
C
1423 lines
No EOL
36 KiB
C
/*
|
|
Copyright (C) 2001-2002 Charles Hollemeersch
|
|
|
|
This program 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,
|
|
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.
|
|
|
|
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.
|
|
|
|
PENTA: the whole file is freakin penta...
|
|
|
|
All code conserning the drawing of bump mapped polygons.
|
|
Per vertex setup, shaders and the passes.
|
|
This is the general/gf2 approach for the gf3 code see gumpgf.c
|
|
*/
|
|
|
|
#include "quakedef.h"
|
|
|
|
//view origin in object space
|
|
vec3_t object_vieworg;
|
|
|
|
/**************************************************************
|
|
|
|
PART1: Gl state management
|
|
|
|
***************************************************************/
|
|
|
|
|
|
void GL_EnableDiffuseShader () {
|
|
//ordinary combiners = compatible with everything
|
|
|
|
//texture coords for unit 0: Tangent space light vector
|
|
//texture coords for unit 1: Normal map texture coords
|
|
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_DisableDiffuseShader () {
|
|
GL_DisableMultitexture();
|
|
glEnable(GL_TEXTURE_2D);
|
|
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
|
}
|
|
|
|
void GL_EnableSpecularShader () {
|
|
|
|
vec3_t scaler = {0.75f, 0.75f, 0.75f};
|
|
|
|
if ( gl_cardtype == GEFORCE || gl_cardtype == GEFORCE3 ) {
|
|
GL_SelectTexture(GL_TEXTURE0_ARB);
|
|
glDisable(GL_TEXTURE_2D);
|
|
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
|
|
//GL_Bind(normcube_texture_object);
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, normcube_texture_object);
|
|
GL_EnableMultitexture();
|
|
|
|
//setup and enable the register combiners
|
|
qglCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, 2);
|
|
qglCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &scaler[0]);
|
|
|
|
//combiner0 RGB: calculate N'dotH -> store in Spare0 RGB
|
|
qglCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE1_ARB, GL_EXPAND_NORMAL_NV, GL_RGB);
|
|
qglCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_TEXTURE0_ARB, GL_EXPAND_NORMAL_NV, GL_RGB);
|
|
qglCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE);
|
|
|
|
//combiner0 Alpha: ignore all
|
|
qglCombinerOutputNV(GL_COMBINER0_NV, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
|
|
//combiner1 RGB: ignore all
|
|
qglCombinerOutputNV(GL_COMBINER1_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
|
|
//combiner1 Alpha: calculate 4*((N'dotH)^2 - 0.75f) -> store in Spare0 Alpha
|
|
qglCombinerInputNV(GL_COMBINER1_NV, GL_ALPHA, GL_VARIABLE_A_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_BLUE);
|
|
qglCombinerInputNV(GL_COMBINER1_NV, GL_ALPHA, GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_BLUE);
|
|
qglCombinerInputNV(GL_COMBINER1_NV, GL_ALPHA, GL_VARIABLE_C_NV, GL_CONSTANT_COLOR0_NV, GL_SIGNED_NEGATE_NV, GL_BLUE);
|
|
qglCombinerInputNV(GL_COMBINER1_NV, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
|
|
qglCombinerOutputNV(GL_COMBINER1_NV, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE);
|
|
|
|
//final combiner RGB: who cares
|
|
// Alpha: specular value of 4*((N'dotH)^2 - 0.75f)
|
|
qglFinalCombinerInputNV(GL_VARIABLE_G_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA);
|
|
|
|
glEnable(GL_REGISTER_COMBINERS_NV);
|
|
} else {
|
|
GL_EnableDiffuseShader ();
|
|
}
|
|
}
|
|
|
|
void GL_DisableSpecularShader () {
|
|
|
|
//not supported?
|
|
if ( gl_cardtype == GEFORCE || gl_cardtype == GEFORCE3 ) {
|
|
GL_DisableMultitexture();
|
|
glDisable(GL_REGISTER_COMBINERS_NV);
|
|
glEnable(GL_TEXTURE_2D);
|
|
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
|
|
} else {
|
|
GL_DisableDiffuseShader ();
|
|
}
|
|
}
|
|
|
|
void GL_EnableColorShader (qboolean specular) {
|
|
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
|
|
//primary color = light color
|
|
//tu0 = light filter cube map
|
|
//tu1 = material color map
|
|
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_DisableColorShader (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);
|
|
}
|
|
|
|
void GL_EnableAttShader() {
|
|
|
|
GL_Bind(glow_texture_object);
|
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
}
|
|
|
|
void GL_DisableAttShader() {
|
|
//empty
|
|
glDisable(GL_REGISTER_COMBINERS_NV);
|
|
}
|
|
|
|
/*
|
|
Draw incoming fragment to destination alpha.
|
|
|
|
Note: A fragment in the next comment means a pixel that will be drawn on the screen
|
|
(gl has some specific definition of it)
|
|
*/
|
|
void GL_DrawAlpha() {
|
|
glColorMask(false, false, false, true);
|
|
glDisable(GL_BLEND);
|
|
}
|
|
|
|
/*
|
|
Draw incoming fragment by modulating it with destination alpha
|
|
*/
|
|
void GL_ModulateAlphaDrawAlpha() {
|
|
glColorMask(false, false, false, true);
|
|
glBlendFunc (GL_DST_ALPHA, GL_ZERO);
|
|
glEnable (GL_BLEND);
|
|
}
|
|
|
|
/*
|
|
Draw incoming fragment by adding it to destination alpha
|
|
*/
|
|
void GL_AddAlphaDrawAlpha() {
|
|
glColorMask(false, false, false, true);
|
|
glBlendFunc (GL_ONE, GL_ONE);
|
|
glEnable (GL_BLEND);
|
|
}
|
|
|
|
/*
|
|
Draw incoming fragment by modulation it with destination alpha
|
|
*/
|
|
void GL_ModulateAlphaDrawColor() {
|
|
glColorMask(true, true, true, true);
|
|
glBlendFunc (GL_DST_ALPHA, GL_ONE);
|
|
glEnable (GL_BLEND);
|
|
}
|
|
|
|
/*
|
|
Draw incoming alpha squared to destination alpha
|
|
*/
|
|
void GL_DrawSquareAlpha() {
|
|
glColorMask(false, false, false, true);
|
|
glBlendFunc (GL_SRC_ALPHA, GL_ZERO);
|
|
glEnable (GL_BLEND);
|
|
}
|
|
|
|
/*
|
|
Square the destination alpha
|
|
*/
|
|
void GL_SquareAlpha() {
|
|
glColorMask(false, false, false, true);
|
|
glBlendFunc (GL_ZERO, GL_DST_ALPHA);
|
|
glEnable (GL_BLEND);
|
|
}
|
|
|
|
/*
|
|
Add incoming fragment to destination color
|
|
*/
|
|
void GL_AddColor() {
|
|
glColorMask(true, true, true, true);
|
|
glBlendFunc (GL_ONE, GL_ONE);
|
|
glEnable (GL_BLEND);
|
|
}
|
|
|
|
/*
|
|
Ovewrite destination color with incoming fragment
|
|
*/
|
|
void GL_DrawColor() {
|
|
glColorMask(true, true, true, true);
|
|
glDisable (GL_BLEND);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
R_WorldToObjectMatrix
|
|
|
|
Returns a world to object coordinate transformation matrix.
|
|
This is crap and I know it ;)
|
|
The problem is that quake does strange stuff with its angles
|
|
(look at R_RotateForEntity) so inverting the matrix will
|
|
certainly give the desired result.
|
|
Why I use the gl matrix? Well quake doesn't have build in matix
|
|
routines an I don't have any lying around in c (Lot's in Pascal
|
|
of course i'm a Delphi man)
|
|
|
|
=================
|
|
*/
|
|
|
|
void R_WorldToObjectMatrix(entity_t *e, matrix_4x4 result)
|
|
{
|
|
matrix_4x4 world;
|
|
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
R_RotateForEntity (e);
|
|
glGetFloatv (GL_MODELVIEW_MATRIX, &world[0][0]);
|
|
glPopMatrix();
|
|
MatrixAffineInverse(world,result);
|
|
}
|
|
|
|
/*
|
|
=============
|
|
GL_SetupCubeMapMatrix
|
|
|
|
Loads the current matrix with a tranformation used for light filters
|
|
=============
|
|
*/
|
|
|
|
void GL_SetupCubeMapMatrix(const transform_t *tr) {
|
|
|
|
glLoadIdentity();
|
|
|
|
glRotatef (-currentshadowlight->angles[0], 1, 0, 0);
|
|
glRotatef (-currentshadowlight->angles[1], 0, 1, 0);
|
|
glRotatef (-currentshadowlight->angles[2], 0, 0, 1);
|
|
|
|
glRotatef (currentshadowlight->rspeed*cl.time,0,0,1);
|
|
|
|
glTranslatef(-currentshadowlight->origin[0],
|
|
-currentshadowlight->origin[1],
|
|
-currentshadowlight->origin[2]);
|
|
|
|
//if (!world)
|
|
// R_RotateForEntity(currententity);
|
|
glTranslatef (tr->origin[0], tr->origin[1], tr->origin[2]);
|
|
|
|
glRotatef (tr->angles[1], 0, 0, 1);
|
|
glRotatef (-tr->angles[0], 0, 1, 0);
|
|
glRotatef (tr->angles[2], 1, 0, 0);
|
|
}
|
|
/**************************************************************
|
|
|
|
PART2: Geommety sending code
|
|
|
|
This parts containts code for sending different geommety
|
|
types (brushes, alias, ...) with different per vertex
|
|
options (light, H, att)
|
|
Every method is the core of 1 pass during bump map rendering.
|
|
This is all direct mode stuff, it should be put in vertex
|
|
arrays.
|
|
|
|
***************************************************************/
|
|
|
|
/*
|
|
=============
|
|
R_DrawWorldLLV
|
|
|
|
-Draws the world sending the tangent space light vector as unit 0's texture coordinates.
|
|
-Sends as uni1t's texture coordinates the original texture coordinates.
|
|
-Rebinds unit1's texture if the surface material changes (binds the current surface's bump map)
|
|
=============
|
|
*/
|
|
void R_DrawWorldLLV(lightcmd_t *lightCmds) {
|
|
|
|
int command, num, i;
|
|
int lightPos = 0;
|
|
vec3_t lightOr;
|
|
msurface_t *surf;
|
|
float *v;
|
|
shader_t *s;//XYZ
|
|
|
|
//support flickering lights
|
|
VectorCopy(currentshadowlight->origin,lightOr);
|
|
|
|
while (1) {
|
|
|
|
command = lightCmds[lightPos++].asInt;
|
|
if (command == 0) break; //end of list
|
|
|
|
surf = lightCmds[lightPos++].asVoid;
|
|
|
|
if (surf->visframe != r_framecount) {
|
|
lightPos+=(4+surf->polys->numverts*(2+3));
|
|
continue;
|
|
}
|
|
|
|
num = surf->polys->numverts;
|
|
lightPos+=4;//skip color
|
|
|
|
|
|
//XYZ
|
|
s = surf->shader->shader;
|
|
if (s->numbumpstages > 0)
|
|
GL_Bind(s->bumpstages[0].texture[0]->texnum);
|
|
|
|
glBegin(command);
|
|
//v = surf->polys->verts[0];
|
|
v = (float *)(&globalVertexTable[surf->polys->firstvertex]);
|
|
for (i=0; i<num; i++, v+= VERTEXSIZE) {
|
|
//skip attent texture coord.
|
|
lightPos+=2;
|
|
|
|
//calculate local light vector and put it into tangent space
|
|
/*
|
|
VectorSubtract(lightOr,cl.worldmodel->vertexes[ind].position,lightDir);
|
|
|
|
if (surf->flags & SURF_PLANEBACK) {
|
|
tsLightDir[2] = -DotProduct(lightDir,surf->plane->normal);
|
|
} else {
|
|
tsLightDir[2] = DotProduct(lightDir,surf->plane->normal);
|
|
}
|
|
|
|
tsLightDir[1] = -DotProduct(lightDir,surf->texinfo->vecs[1]);
|
|
tsLightDir[0] = DotProduct(lightDir,surf->texinfo->vecs[0]);
|
|
|
|
glTexCoord3fv(&tsLightDir[0]);
|
|
*/
|
|
glTexCoord3fv(&lightCmds[lightPos].asFloat);
|
|
lightPos+=3;
|
|
|
|
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, v[3], v[4]);
|
|
glVertex3fv(&v[0]);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
=============
|
|
R_DrawWorldHAV
|
|
|
|
-Draws the world sending the tangent space half angle vector as unit 0's texture coordinates.
|
|
-Sends as uni1t's texture coordinates the original texture coordinates.
|
|
-Rebinds unit1's texture if the surface material changes (binds the current surface's bump map)
|
|
=============
|
|
*/
|
|
void R_DrawWorldHAV(lightcmd_t *lightCmds) {
|
|
|
|
int command, num, i;
|
|
int lightPos = 0;
|
|
vec3_t lightOr,tsH,H;
|
|
msurface_t *surf;
|
|
float *v,*lightP;
|
|
vec3_t lightDir;
|
|
shader_t *s;//XYZ
|
|
|
|
//support flickering lights
|
|
VectorCopy(currentshadowlight->origin,lightOr);
|
|
|
|
while (1) {
|
|
|
|
command = lightCmds[lightPos++].asInt;
|
|
if (command == 0) break; //end of list
|
|
|
|
surf = lightCmds[lightPos++].asVoid;
|
|
|
|
if (surf->visframe != r_framecount) {
|
|
lightPos+=(4+surf->polys->numverts*(2+3));
|
|
continue;
|
|
}
|
|
|
|
num = surf->polys->numverts;
|
|
lightPos+=4;//skip color
|
|
|
|
//XYZ
|
|
s = surf->shader->shader;
|
|
if (s->numbumpstages > 0)
|
|
GL_Bind(s->bumpstages[0].texture[0]->texnum);
|
|
|
|
glBegin(command);
|
|
//v = surf->polys->verts[0];
|
|
v = (float *)(&globalVertexTable[surf->polys->firstvertex]);
|
|
for (i=0; i<num; i++, v+= VERTEXSIZE) {
|
|
lightPos+=2;//skip texcoords
|
|
lightP = &lightCmds[lightPos].asFloat;
|
|
VectorCopy(lightP,lightDir);
|
|
VectorNormalize(lightDir);
|
|
lightPos+=3;//skip local light vector
|
|
|
|
//r_origin = camera position
|
|
VectorSubtract(r_refdef.vieworg,v,H);
|
|
VectorNormalize(H);
|
|
|
|
//put H in tangent space firste since lightDir (precalc) is already in tang space
|
|
if (surf->flags & SURF_PLANEBACK) {
|
|
tsH[2] = -DotProduct(H,surf->plane->normal);
|
|
} else {
|
|
tsH[2] = DotProduct(H,surf->plane->normal);
|
|
}
|
|
|
|
tsH[1] = -DotProduct(H,surf->binormal);
|
|
tsH[0] = DotProduct(H,surf->tangent);
|
|
|
|
VectorAdd(lightDir,tsH,tsH);
|
|
|
|
glTexCoord3fv(&tsH[0]);
|
|
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, v[3], v[4]);
|
|
glVertex3fv(&v[0]);
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
/*
|
|
=============
|
|
R_DrawWorldATT
|
|
|
|
Draw the world sending as texture unit 0's texture coordinates the precalcuated attenuation
|
|
coordinates.
|
|
As primary color the light color modulated by the current brightness (for flickering lights
|
|
this depends on t)
|
|
=============
|
|
*/
|
|
void R_DrawWorldATT(lightcmd_t *lightCmds) {
|
|
int command, num, i;
|
|
int lightPos = 0;
|
|
|
|
//edit: modulation of light maps
|
|
msurface_t *surf;
|
|
float *v;
|
|
|
|
//support flickering lights
|
|
float b = d_lightstylevalue[currentshadowlight->style]/255.0;
|
|
|
|
while (1) {
|
|
|
|
command = lightCmds[lightPos++].asInt;
|
|
if (command == 0) break; //end of list
|
|
|
|
//edit: modulation of light maps
|
|
surf = lightCmds[lightPos++].asVoid;
|
|
|
|
if (surf->visframe != r_framecount) {
|
|
lightPos+=(4+surf->polys->numverts*(2+3));
|
|
continue;
|
|
}
|
|
|
|
num = surf->polys->numverts;
|
|
//v = surf->polys->verts[0];
|
|
v = (float *)(&globalVertexTable[surf->polys->firstvertex]);
|
|
|
|
glColor4f( (&lightCmds[lightPos].asFloat)[0] *b,
|
|
(&lightCmds[lightPos].asFloat)[1] *b,
|
|
(&lightCmds[lightPos].asFloat)[2] *b,
|
|
(&lightCmds[lightPos].asFloat)[3] *b );
|
|
|
|
lightPos+=4;
|
|
|
|
glBegin(command);
|
|
for (i=0; i<num; i++, v+= VERTEXSIZE) {
|
|
|
|
glTexCoord2fv(&lightCmds[lightPos].asFloat);
|
|
lightPos+=2;
|
|
lightPos+=3;
|
|
glVertex3fv(&v[0]);
|
|
}
|
|
glEnd();
|
|
}
|
|
}
|
|
|
|
/*
|
|
=============
|
|
R_DrawWorldWV
|
|
|
|
-Draw the world sending as texture unit 0's coordinates the world space coordinates of the current vertex
|
|
-Sends as uni1t's texture coordinates the original texture coordinates.
|
|
-Rebinds unit1's texture if the surface material changes (binds the current surface's color map)
|
|
=============
|
|
*/
|
|
void R_DrawWorldWV(lightcmd_t *lightCmds, qboolean specular) {
|
|
|
|
int command, num, i;
|
|
int lightPos = 0;
|
|
|
|
//edit: modulation of light maps
|
|
msurface_t *surf;
|
|
float *v;
|
|
shader_t *s;//XYZ
|
|
|
|
while (1) {
|
|
|
|
command = lightCmds[lightPos++].asInt;
|
|
if (command == 0) break; //end of list
|
|
|
|
surf = lightCmds[lightPos++].asVoid;
|
|
|
|
if (surf->visframe != r_framecount) {
|
|
lightPos+=(4+surf->polys->numverts*(2+3));
|
|
continue;
|
|
}
|
|
|
|
num = surf->polys->numverts;
|
|
//v = surf->polys->verts[0];
|
|
v = (float *)(&globalVertexTable[surf->polys->firstvertex]);
|
|
|
|
//XYZ
|
|
s = surf->shader->shader;
|
|
if ( specular )
|
|
if (s->numbumpstages > 0)
|
|
GL_Bind(s->bumpstages[0].texture[0]->texnum);
|
|
else
|
|
if (s->numcolorstages > 0)
|
|
GL_Bind(s->colorstages[0].texture[0]->texnum);
|
|
|
|
lightPos+=4;//no attent color
|
|
|
|
glBegin(command);
|
|
for (i=0; i<num; i++, v+= VERTEXSIZE) {
|
|
lightPos+=2;//no attent coords
|
|
lightPos+=3;
|
|
glTexCoord3fv(&v[0]);
|
|
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, v[3], v[4]);
|
|
glVertex3fv(&v[0]);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
=============
|
|
R_DrawBrushLLV
|
|
|
|
-Draws the brush sending the tangent space light vector as unit 0's texture coordinates.
|
|
-Sends as uni1t's texture coordinates the original texture coordinates.
|
|
-Rebinds unit1's texture if the surface material changes (binds the current surface's bump map)
|
|
=============
|
|
*/
|
|
void R_DrawBrushLLV(entity_t *e) {
|
|
|
|
model_t *model = e->model;
|
|
msurface_t *surf;
|
|
glpoly_t *poly;
|
|
int i, j, count;
|
|
brushlightinstant_t *ins = e->brushlightinstant;
|
|
float *v;
|
|
shader_t *s;
|
|
|
|
count = 0;
|
|
|
|
surf = &model->surfaces[model->firstmodelsurface];
|
|
for (i=0; i<model->nummodelsurfaces; i++, surf++)
|
|
{
|
|
if (!ins->polygonVis[i]) continue;
|
|
|
|
poly = surf->polys;
|
|
|
|
//XYZ
|
|
s = surf->shader->shader;
|
|
if (s->numbumpstages > 0)
|
|
GL_Bind(s->bumpstages[0].texture[0]->texnum);
|
|
|
|
glBegin(GL_TRIANGLE_FAN);
|
|
//v = poly->verts[0];
|
|
v = (float *)(&globalVertexTable[poly->firstvertex]);
|
|
for (j=0 ; j<poly->numverts ; j++, v+= VERTEXSIZE)
|
|
{
|
|
glTexCoord3fv(&ins->tslights[count+j][0]);
|
|
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, v[3], v[4]);
|
|
glVertex3fv(v);
|
|
}
|
|
glEnd();
|
|
count+=surf->numedges;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=============
|
|
R_DrawBrushHAV
|
|
|
|
-Draws the brush sending the tangent space half angle vector as unit 0's texture coordinates.
|
|
-Sends as uni1t's texture coordinates the original texture coordinates.
|
|
-Rebinds unit1's texture if the surface material changes (binds the current surface's bump map)
|
|
=============
|
|
*/
|
|
void R_DrawBrushHAV(entity_t *e) {
|
|
|
|
model_t *model = e->model;
|
|
msurface_t *surf;
|
|
glpoly_t *poly;
|
|
int i, j, count;
|
|
brushlightinstant_t *ins = e->brushlightinstant;
|
|
float *v;
|
|
shader_t *s;//XYZ
|
|
|
|
count = 0;
|
|
|
|
surf = &model->surfaces[model->firstmodelsurface];
|
|
for (i=0; i<model->nummodelsurfaces; i++, surf++)
|
|
{
|
|
if (!ins->polygonVis[i]) continue;
|
|
|
|
poly = surf->polys;
|
|
|
|
//XYZ
|
|
s = surf->shader->shader;
|
|
if (s->numbumpstages > 0)
|
|
GL_Bind(s->bumpstages[0].texture[0]->texnum);
|
|
|
|
glBegin(GL_TRIANGLE_FAN);
|
|
//v = poly->verts[0];
|
|
v = (float *)(&globalVertexTable[poly->firstvertex]);
|
|
for (j=0 ; j<poly->numverts ; j++, v+= VERTEXSIZE)
|
|
{
|
|
glTexCoord3fv(&ins->tshalfangles[count+j][0]);
|
|
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, v[3], v[4]);
|
|
glVertex3fv(v);
|
|
}
|
|
glEnd();
|
|
count+=surf->numedges;
|
|
}
|
|
}
|
|
/*
|
|
=============
|
|
R_DrawBrushATT
|
|
|
|
Draw the brush sending as texture unit 0's texture coordinates the calcuated attentuation
|
|
coordinates.
|
|
As primary color the light color modulated by the current brightness (for flickering lights
|
|
this depends on t)
|
|
=============
|
|
*/
|
|
void R_DrawBrushATT(entity_t *e) {
|
|
|
|
model_t *model = e->model;
|
|
msurface_t *surf;
|
|
glpoly_t *poly;
|
|
int i, j, count, countc;
|
|
brushlightinstant_t *ins = e->brushlightinstant;
|
|
float *v, bright;
|
|
|
|
count = 0;
|
|
countc = 0;
|
|
surf = &model->surfaces[model->firstmodelsurface];
|
|
for (i=0; i<model->nummodelsurfaces; i++, surf++)
|
|
{
|
|
if (!ins->polygonVis[i]) continue;
|
|
|
|
poly = surf->polys;
|
|
|
|
//GL_Bind(surf->texinfo->texture->gl_texturenum);
|
|
|
|
bright = ins->colorscales[countc];
|
|
countc++;
|
|
|
|
glColor4f(bright,bright,bright,bright);
|
|
|
|
glBegin(GL_TRIANGLE_FAN);
|
|
//v = poly->verts[0];
|
|
v = (float *)(&globalVertexTable[poly->firstvertex]);
|
|
for (j=0 ; j<poly->numverts ; j++, v+= VERTEXSIZE)
|
|
{
|
|
glTexCoord2fv(&ins->atencoords[count+j][0]);
|
|
//qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, v[3], v[4]);
|
|
glVertex3fv(v);
|
|
}
|
|
glEnd();
|
|
count+=surf->numedges;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=============
|
|
R_DrawBrushWV
|
|
|
|
=============
|
|
*/
|
|
|
|
void R_DrawBrushWV(entity_t *e, qboolean specular) {
|
|
|
|
model_t *model = e->model;
|
|
msurface_t *surf;
|
|
glpoly_t *poly;
|
|
int i, j, count;
|
|
brushlightinstant_t *ins = e->brushlightinstant;
|
|
float *v;
|
|
shader_t *s;
|
|
|
|
count = 0;
|
|
|
|
surf = &model->surfaces[model->firstmodelsurface];
|
|
for (i=0; i<model->nummodelsurfaces; i++, surf++)
|
|
{
|
|
if (!ins->polygonVis[i]) continue;
|
|
|
|
poly = surf->polys;
|
|
|
|
//XYZ
|
|
s = surf->shader->shader;
|
|
if ( specular )
|
|
if (s->numbumpstages > 0)
|
|
GL_Bind(s->bumpstages[0].texture[0]->texnum);
|
|
else
|
|
if (s->numcolorstages > 0)
|
|
GL_Bind(s->colorstages[0].texture[0]->texnum);
|
|
|
|
glBegin(GL_TRIANGLE_FAN);
|
|
//v = poly->verts[0];
|
|
v = (float *)(&globalVertexTable[poly->firstvertex]);
|
|
for (j=0 ; j<poly->numverts ; j++, v+= VERTEXSIZE)
|
|
{
|
|
glTexCoord3fv(v);
|
|
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, v[3], v[4]);
|
|
glVertex3fv(v);
|
|
}
|
|
glEnd();
|
|
count+=surf->numedges;
|
|
}
|
|
}
|
|
/*
|
|
=============
|
|
R_DrawBrushObjectLight
|
|
|
|
Idea: Creepy object oriented programming by using function pointers.
|
|
Function: Puts the light into object space, adapts the world->eye matrix
|
|
and calls BrushGeoSender if all that has been done.
|
|
Cleans up afterwards so nothing has changed.
|
|
=============
|
|
*/
|
|
void R_DrawBrushObjectLight(entity_t *e,void (*BrushGeoSender) (entity_t *e)) {
|
|
|
|
model_t *clmodel;
|
|
|
|
vec3_t oldlightorigin;
|
|
//backup light origin since we will have to translate
|
|
//light into model space
|
|
VectorCopy (currentshadowlight->origin, oldlightorigin);
|
|
|
|
currententity = e;
|
|
currenttexture = -1;
|
|
|
|
clmodel = e->model;
|
|
|
|
glPushMatrix ();
|
|
e->angles[0] = -e->angles[0]; // stupid quake bug
|
|
R_RotateForEntity (e);
|
|
e->angles[0] = -e->angles[0]; // stupid quake bug
|
|
|
|
VectorCopy(((brushlightinstant_t *)e->brushlightinstant)->lightpos,currentshadowlight->origin);
|
|
BrushGeoSender(e);
|
|
|
|
VectorCopy(oldlightorigin,currentshadowlight->origin);
|
|
glPopMatrix ();
|
|
}
|
|
|
|
void R_DrawAliasFrameLLV (aliashdr_t *paliashdr, aliasframeinstant_t *instant)
|
|
{
|
|
fstvert_t *texcoords;
|
|
int *indecies, anim;
|
|
aliaslightinstant_t *linstant = instant->lightinstant;
|
|
shader_t *s;
|
|
|
|
texcoords = (fstvert_t *)((byte *)paliashdr + paliashdr->texcoords);
|
|
indecies = (int *)((byte *)paliashdr + paliashdr->indecies);
|
|
|
|
//bind normal map
|
|
anim = (int)(cl.time*10) & 3;
|
|
|
|
s = pheader->shader;
|
|
if (s->numbumpstages > 0)
|
|
GL_Bind(s->bumpstages[0].texture[0]->texnum);
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, instant->vertices);
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
|
|
glTexCoordPointer(3, GL_FLOAT, 0, linstant->tslights);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
qglClientActiveTextureARB(GL_TEXTURE1_ARB);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glDrawElements(GL_TRIANGLES,linstant->numtris*3,GL_UNSIGNED_INT,&linstant->indecies[0]);
|
|
|
|
if (sh_noshadowpopping.value) {
|
|
glStencilFunc(GL_LEQUAL, 1, 0xffffffff);
|
|
glDrawElements(GL_TRIANGLES,(paliashdr->numtris*3)-(linstant->numtris*3),GL_UNSIGNED_INT,&linstant->indecies[linstant->numtris*3]);
|
|
glStencilFunc(GL_EQUAL, 0, 0xffffffff);
|
|
}
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
|
|
void R_DrawAliasFrameHAV (aliashdr_t *paliashdr, aliasframeinstant_t *instant)
|
|
{
|
|
fstvert_t *texcoords;
|
|
int *indecies, anim;
|
|
aliaslightinstant_t *linstant = instant->lightinstant;
|
|
shader_t *s;
|
|
|
|
texcoords = (fstvert_t *)((byte *)paliashdr + paliashdr->texcoords);
|
|
indecies = (int *)((byte *)paliashdr + paliashdr->indecies);
|
|
|
|
//bind normal map
|
|
anim = (int)(cl.time*10) & 3;
|
|
s = pheader->shader;
|
|
if (s->numbumpstages > 0)
|
|
GL_Bind(s->bumpstages[0].texture[0]->texnum);
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, instant->vertices);
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
|
|
glTexCoordPointer(3, GL_FLOAT, 0, linstant->tshalfangles);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
qglClientActiveTextureARB(GL_TEXTURE1_ARB);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glDrawElements(GL_TRIANGLES,linstant->numtris*3,GL_UNSIGNED_INT,&linstant->indecies[0]);
|
|
|
|
if (sh_noshadowpopping.value) {
|
|
glStencilFunc(GL_LEQUAL, 1, 0xffffffff);
|
|
glDrawElements(GL_TRIANGLES,(paliashdr->numtris*3)-(linstant->numtris*3),GL_UNSIGNED_INT,&linstant->indecies[linstant->numtris*3]);
|
|
glStencilFunc(GL_EQUAL, 0, 0xffffffff);
|
|
}
|
|
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
=============
|
|
R_DrawAliasFrameWV
|
|
|
|
Draw an alias model with the ojbect space vertex coordinates as texture coords
|
|
=============
|
|
*/
|
|
void R_DrawAliasFrameWV (aliashdr_t *paliashdr, aliasframeinstant_t *instant, qboolean specular) {
|
|
|
|
int *indecies, anim;
|
|
fstvert_t *texcoords;
|
|
aliaslightinstant_t *linstant = instant->lightinstant;
|
|
shader_t *s;
|
|
|
|
texcoords = (fstvert_t *)((byte *)paliashdr + paliashdr->texcoords);
|
|
indecies = (int *)((byte *)paliashdr + paliashdr->indecies);
|
|
|
|
anim = (int)(cl.time*10) & 3;
|
|
s = pheader->shader;
|
|
if ( specular )
|
|
if (s->numbumpstages > 0)
|
|
GL_Bind(s->bumpstages[0].texture[0]->texnum);
|
|
else
|
|
if (s->numcolorstages > 0)
|
|
GL_Bind(s->colorstages[0].texture[0]->texnum);
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, instant->vertices);
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
|
|
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
|
|
glTexCoordPointer(3, GL_FLOAT, 0, instant->vertices);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
if ( gl_cardtype == GENERIC || gl_cardtype == GEFORCE ) {//PA:
|
|
|
|
qglClientActiveTextureARB(GL_TEXTURE1_ARB);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glNormalPointer(GL_FLOAT, 0, instant->normals);
|
|
glEnableClientState(GL_NORMAL_ARRAY);
|
|
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
glColorPointer(3, GL_FLOAT, 0, linstant->colors);
|
|
}
|
|
|
|
glDrawElements(GL_TRIANGLES,linstant->numtris*3,GL_UNSIGNED_INT,&linstant->indecies[0]);
|
|
|
|
if (sh_noshadowpopping.value) {
|
|
glStencilFunc(GL_LEQUAL, 1, 0xffffffff);
|
|
glDrawElements(GL_TRIANGLES,(paliashdr->numtris*3)-(linstant->numtris*3),GL_UNSIGNED_INT,&linstant->indecies[linstant->numtris*3]);
|
|
glStencilFunc(GL_EQUAL, 0, 0xffffffff);
|
|
}
|
|
|
|
if ( gl_cardtype == GENERIC || gl_cardtype == GEFORCE ) {//PA:
|
|
glDisableClientState(GL_NORMAL_ARRAY);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
}
|
|
|
|
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
}
|
|
|
|
void PrintScreenPos(vec3_t v) {
|
|
|
|
double Dproject_matrix[16];
|
|
double Dworld_matrix[16];
|
|
GLint Iviewport[4]; // <AWE> changed from int to GLint.
|
|
double px, py, pz;
|
|
|
|
glGetDoublev (GL_MODELVIEW_MATRIX, Dworld_matrix);
|
|
glGetDoublev (GL_PROJECTION_MATRIX, Dproject_matrix);
|
|
glGetIntegerv (GL_VIEWPORT, Iviewport);
|
|
gluProject(v[0], v[1], v[2],
|
|
Dworld_matrix, Dproject_matrix, Iviewport, &px, &py, &pz);
|
|
Con_Printf("Pos: %f %f %f\n", px, py, pz);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
R_DrawAliasObjectLight
|
|
|
|
Same as R_DrawBrushObjectLight but with alias models
|
|
|
|
=================
|
|
*/
|
|
void R_DrawAliasObjectLight(entity_t *e,void (*AliasGeoSender) (aliashdr_t *paliashdr, aliasframeinstant_t* instant))
|
|
{
|
|
int pose, numposes;
|
|
//matrix_4x4 transf;
|
|
//float org[4],res[4];
|
|
aliashdr_t *paliashdr;
|
|
alias3data_t *data;
|
|
vec3_t oldlightpos, oldvieworg;
|
|
aliasframeinstant_t *aliasframeinstant;
|
|
int i,maxnumsurf;
|
|
|
|
currententity = e;
|
|
|
|
// VectorCopy (currententity->origin, r_entorigin);
|
|
// VectorSubtract (r_origin, r_entorigin, modelorg);
|
|
|
|
glPushMatrix ();
|
|
R_RotateForEntity (e);
|
|
|
|
//
|
|
// locate the proper data
|
|
//
|
|
data = (alias3data_t *)Mod_Extradata (e->model);
|
|
maxnumsurf = data->numSurfaces;
|
|
aliasframeinstant = e->aliasframeinstant;
|
|
|
|
for (i=0;i<maxnumsurf;++i){
|
|
|
|
paliashdr = (aliashdr_t *)((char*)data + data->ofsSurfaces[i]);
|
|
|
|
if (!aliasframeinstant) {
|
|
glPopMatrix();
|
|
Con_Printf("R_DrawAliasObjectLight: missing instant for ent %s\n", e->model->name);
|
|
return;
|
|
}
|
|
|
|
if (aliasframeinstant->shadowonly) continue;
|
|
|
|
if ((e->frame >= paliashdr->numframes) || (e->frame < 0))
|
|
{
|
|
glPopMatrix();
|
|
return;
|
|
}
|
|
|
|
VectorCopy(currentshadowlight->origin,oldlightpos);
|
|
VectorCopy(currentshadowlight->origin,currentshadowlight->oldlightorigin);
|
|
VectorCopy( r_refdef.vieworg,oldvieworg);
|
|
VectorCopy( aliasframeinstant->lightinstant->vieworg, r_refdef.vieworg);
|
|
VectorCopy(aliasframeinstant->lightinstant->lightpos ,currentshadowlight->origin);
|
|
pose = paliashdr->frames[e->frame].firstpose;
|
|
numposes = paliashdr->frames[e->frame].numposes;
|
|
|
|
//Draw it!
|
|
AliasGeoSender(paliashdr,aliasframeinstant);
|
|
|
|
aliasframeinstant = aliasframeinstant->_next;
|
|
|
|
VectorCopy(oldvieworg, r_refdef.vieworg);
|
|
VectorCopy(oldlightpos,currentshadowlight->origin);
|
|
} /* for paliashdr */
|
|
|
|
glPopMatrix();
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
R_DrawSpriteModelWV
|
|
|
|
Draw a sprite texture with as tex0 coordinates the world space position of it's vertexes.
|
|
tex1 is the sprites texture coordinates.
|
|
|
|
=================
|
|
*/
|
|
void R_DrawSpriteModelWV (entity_t *e)
|
|
{
|
|
vec3_t point;
|
|
mspriteframe_t *frame;
|
|
float *up, *right;
|
|
vec3_t v_forward, v_right, v_up;
|
|
msprite_t *psprite;
|
|
|
|
frame = R_GetSpriteFrame (e);
|
|
psprite = currententity->model->cache.data;
|
|
|
|
if (psprite->type == SPR_ORIENTED)
|
|
{ // bullet marks on walls PENTA: bulltet marks in quake 1? never seen one ;)
|
|
AngleVectors (currententity->angles, v_forward, v_right, v_up);
|
|
up = v_up;
|
|
right = v_right;
|
|
}
|
|
else
|
|
{ // normal sprite
|
|
up = vup;
|
|
right = vright;
|
|
}
|
|
|
|
GL_Bind(frame->gl_texturenum);
|
|
|
|
glBegin (GL_QUADS);
|
|
|
|
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0, 1);
|
|
VectorMA (e->origin, frame->down, up, point);
|
|
VectorMA (point, frame->left, right, point);
|
|
glTexCoord3fv(point);
|
|
glVertex3fv (point);
|
|
|
|
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0, 0);
|
|
VectorMA (e->origin, frame->up, up, point);
|
|
VectorMA (point, frame->left, right, point);
|
|
glTexCoord3fv(point);
|
|
glVertex3fv (point);
|
|
|
|
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1, 0);
|
|
VectorMA (e->origin, frame->up, up, point);
|
|
VectorMA (point, frame->right, right, point);
|
|
glTexCoord3fv(point);
|
|
glVertex3fv (point);
|
|
|
|
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1, 1);
|
|
VectorMA (e->origin, frame->down, up, point);
|
|
VectorMA (point, frame->right, right, point);
|
|
glTexCoord3fv(point);
|
|
glVertex3fv (point);
|
|
|
|
glEnd ();
|
|
|
|
}
|
|
|
|
/**************************************************************
|
|
|
|
PART3: Abstraction
|
|
|
|
***************************************************************/
|
|
|
|
/*
|
|
=============
|
|
GL_DrawWorldBumped
|
|
|
|
Draws the world bumped how this is done you don't have to know!
|
|
=============
|
|
*/
|
|
void R_DrawWorldBumpedGF() {
|
|
|
|
if (!currentshadowlight->visible)
|
|
return;
|
|
|
|
glDepthMask (0);
|
|
glShadeModel (GL_SMOOTH);
|
|
|
|
/*
|
|
if (gl_geforce3) {
|
|
|
|
if (currentshadowlight->filtercube) {
|
|
//draw attent into dest alpha
|
|
GL_DrawAlpha();
|
|
GL_EnableAttentShaderGF3(NULL);
|
|
R_DrawWorldWV(currentshadowlight->lightCmds);
|
|
GL_DisableAttentShaderGF3();
|
|
GL_ModulateAlphaDrawColor();
|
|
} else {
|
|
GL_AddColor();
|
|
}
|
|
glColor3fv(¤tshadowlight->color[0]);
|
|
|
|
GL_EnableDiffuseShaderGF3(true,currentshadowlight->origin);
|
|
R_DrawWorldGF3Diffuse(currentshadowlight->lightCmds);
|
|
GL_DisableDiffuseShaderGF3();
|
|
|
|
GL_EnableSpecularShaderGF3(true,currentshadowlight->origin);
|
|
R_DrawWorldGF3Specular(currentshadowlight->lightCmds);
|
|
GL_DisableDiffuseShaderGF3();
|
|
|
|
glColor3f (1,1,1);
|
|
glDisable (GL_BLEND);
|
|
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glDepthMask (1);
|
|
return;
|
|
}
|
|
*/
|
|
// Diffuse bump mapping
|
|
|
|
GL_DrawAlpha();
|
|
GL_EnableDiffuseShader ();
|
|
if (!currentshadowlight->isStatic) {
|
|
R_DrawWorldLLV(&lightCmdsBuff[0]);
|
|
} else {
|
|
R_DrawWorldLLV(currentshadowlight->lightCmds);
|
|
}
|
|
GL_DisableDiffuseShader ();
|
|
|
|
// Attenuation
|
|
|
|
GL_ModulateAlphaDrawAlpha();
|
|
GL_EnableAttShader();
|
|
R_DrawWorldATT(currentshadowlight->lightCmds);
|
|
GL_DisableAttShader();
|
|
|
|
// Color map/light filter
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
glPushMatrix();
|
|
|
|
GL_SetupCubeMapMatrix(true);
|
|
|
|
GL_ModulateAlphaDrawColor();
|
|
glColor3fv(¤tshadowlight->baseColor[0]);
|
|
GL_EnableColorShader (false);
|
|
R_DrawWorldWV(currentshadowlight->lightCmds, false);
|
|
GL_DisableColorShader (false);
|
|
|
|
glPopMatrix();
|
|
|
|
// Specular
|
|
|
|
if ( gl_cardtype == GEFORCE || gl_cardtype == GEFORCE3 )
|
|
GL_DrawAlpha();
|
|
else
|
|
GL_DrawSquareAlpha();
|
|
|
|
GL_EnableSpecularShader ();
|
|
|
|
R_DrawWorldHAV(currentshadowlight->lightCmds);
|
|
|
|
GL_DisableSpecularShader ();
|
|
|
|
if ( gl_cardtype == GENERIC ) {
|
|
int i;
|
|
//raise specular to a high exponent my multiplying it a few times
|
|
//this is evidently slow and we should use a better system for it
|
|
GL_SquareAlpha();
|
|
for (i=0; i<3; i++) {
|
|
//why draw world att?: 1) I dont want to write new code for this
|
|
// 2) It uses the least bandwith/ setup
|
|
R_DrawWorldATT (currentshadowlight->lightCmds);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Attenttuation
|
|
|
|
GL_ModulateAlphaDrawAlpha();
|
|
GL_EnableAttShader();
|
|
R_DrawWorldATT(currentshadowlight->lightCmds);
|
|
GL_DisableAttShader();
|
|
|
|
// Color map/light filter
|
|
glPushMatrix();
|
|
|
|
GL_SetupCubeMapMatrix(true);
|
|
|
|
GL_ModulateAlphaDrawColor();
|
|
glColor3fv(¤tshadowlight->baseColor[0]);
|
|
GL_EnableColorShader (true);
|
|
R_DrawWorldWV(currentshadowlight->lightCmds, true);
|
|
|
|
GL_DisableColorShader (true);
|
|
|
|
|
|
// End separate specular
|
|
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
glColor3f (1,1,1);
|
|
glDisable (GL_BLEND);
|
|
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glDepthMask (1);
|
|
}
|
|
|
|
void R_DrawWorldBumpedGEN() {
|
|
R_DrawWorldBumpedGF();
|
|
}
|
|
/*
|
|
=============
|
|
GL_DrawBrushBumped
|
|
|
|
Draw a brush entity with bump maps
|
|
=============
|
|
*//*
|
|
void R_DrawBrushBumped(entity_t *e) {
|
|
|
|
// Diffuse bump mapping
|
|
|
|
GL_DrawAlpha();
|
|
GL_EnableDiffuseShader ();
|
|
R_DrawBrushLLV(e);
|
|
GL_DisableDiffuseShader ();
|
|
|
|
// Attenttuation
|
|
|
|
GL_ModulateAlphaDrawAlpha();
|
|
GL_EnableAttShader();
|
|
R_DrawBrushATT(e);
|
|
GL_DisableAttShader();
|
|
|
|
// Color map/light filter
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
glPushMatrix();
|
|
|
|
GL_SetupCubeMapMatrix(false);
|
|
|
|
GL_ModulateAlphaDrawColor();
|
|
glColor3fv(¤tshadowlight->baseColor[0]);
|
|
GL_EnableColorShader (false);
|
|
R_DrawBrushWV(e, false);
|
|
GL_DisableColorShader (false);
|
|
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
|
|
// Specular bump mapping
|
|
|
|
if ( gl_cardtype == GEFORCE || gl_cardtype == GEFORCE3 )
|
|
GL_DrawAlpha();
|
|
else
|
|
GL_DrawSquareAlpha();
|
|
|
|
GL_EnableSpecularShader ();
|
|
R_DrawBrushHAV(e);
|
|
GL_DisableSpecularShader ();
|
|
|
|
if ( gl_cardtype == GENERIC ) {
|
|
int i;
|
|
GL_SquareAlpha();
|
|
//Why R_DrawBrushWV?: Same as for world but not WV is better
|
|
for (i=0; i<3; i++) R_DrawBrushWV(e, false);
|
|
}
|
|
|
|
|
|
|
|
// Attenttuation
|
|
|
|
GL_ModulateAlphaDrawAlpha();
|
|
GL_EnableAttShader();
|
|
R_DrawBrushATT(e);
|
|
GL_DisableAttShader();
|
|
|
|
// Color map/light filter
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
glPushMatrix();
|
|
GL_SetupCubeMapMatrix(false);
|
|
|
|
GL_ModulateAlphaDrawColor();
|
|
glColor3fv(¤tshadowlight->baseColor[0]);
|
|
GL_EnableColorShader (true);
|
|
R_DrawBrushWV(e, true);
|
|
GL_DisableColorShader (true);
|
|
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
}
|
|
*/
|
|
/*
|
|
=============
|
|
R_DrawAliasBumped
|
|
|
|
Draw a alias entity with bump maps
|
|
=============
|
|
*//*
|
|
void R_DrawAliasBumped(aliashdr_t *paliashdr, aliasframeinstant_t *instant) {
|
|
|
|
|
|
//Diffuse bump mapping
|
|
GL_DrawAlpha();
|
|
GL_EnableDiffuseShader ();
|
|
R_DrawAliasFrameLLV(paliashdr,instant);
|
|
GL_DisableDiffuseShader ();
|
|
|
|
// Color map/light filter
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
glPushMatrix();
|
|
GL_SetupCubeMapMatrix(false);
|
|
|
|
GL_ModulateAlphaDrawColor();
|
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
GL_EnableColorShader (false);
|
|
R_DrawAliasFrameWV(paliashdr,instant, false);
|
|
GL_DisableColorShader (false);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
//Specular bump mapping
|
|
if ( gl_cardtype == GEFORCE )
|
|
GL_DrawAlpha();
|
|
else
|
|
GL_DrawSquareAlpha();
|
|
|
|
GL_EnableSpecularShader ();
|
|
R_DrawAliasFrameHAV(paliashdr,instant);
|
|
GL_DisableSpecularShader ();
|
|
|
|
if ( gl_cardtype == GENERIC ) {
|
|
int i;
|
|
GL_SquareAlpha();
|
|
for (i=0; i<3; i++) R_DrawAliasFrameWV(paliashdr,instant, false);
|
|
}
|
|
|
|
|
|
// Color map/light filter
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
glPushMatrix();
|
|
GL_SetupCubeMapMatrix(false);
|
|
|
|
GL_ModulateAlphaDrawColor();
|
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
GL_EnableColorShader (true);
|
|
R_DrawAliasFrameWV(paliashdr,instant, true);
|
|
GL_DisableColorShader (true);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glPopMatrix();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
}
|
|
*/ |