Remove the deprecated nv20 renderer

This commit is contained in:
dhewg 2012-07-18 21:33:14 +02:00
parent 3f67a28abe
commit 6aa9b3602e
9 changed files with 4 additions and 971 deletions

View file

@ -296,7 +296,6 @@ set(src_renderer
renderer/draw_arb.cpp
renderer/draw_arb2.cpp
renderer/draw_common.cpp
renderer/draw_nv20.cpp
renderer/tr_backend.cpp
renderer/tr_deform.cpp
renderer/tr_font.cpp

View file

@ -553,10 +553,6 @@ void idRenderSystemLocal::SetBackEndRenderer() {
if ( glConfig.allowARB2Path ) {
backEndRenderer = BE_ARB2;
}
} else if ( idStr::Icmp( r_renderer.GetString(), "nv20" ) == 0 ) {
if ( glConfig.allowNV20Path ) {
backEndRenderer = BE_NV20;
}
}
// fallback
@ -564,8 +560,6 @@ void idRenderSystemLocal::SetBackEndRenderer() {
// choose the best
if ( glConfig.allowARB2Path ) {
backEndRenderer = BE_ARB2;
} else if ( glConfig.allowNV20Path ) {
backEndRenderer = BE_NV20;
} else {
// the others are considered experimental
backEndRenderer = BE_ARB;
@ -579,10 +573,6 @@ void idRenderSystemLocal::SetBackEndRenderer() {
case BE_ARB:
common->Printf( "using ARB renderSystem\n" );
break;
case BE_NV20:
common->Printf( "using NV20 renderSystem\n" );
backEndRendererHasVertexPrograms = true;
break;
case BE_ARB2:
common->Printf( "using ARB2 renderSystem\n" );
backEndRendererHasVertexPrograms = true;

View file

@ -87,7 +87,6 @@ typedef struct glconfig_s {
bool isFullscreen;
bool allowNV30Path;
bool allowNV20Path;
bool allowARB2Path;
bool isInitialized;

View file

@ -49,7 +49,7 @@ If you have questions concerning this license or the applicable additional terms
glconfig_t glConfig;
const char *r_rendererArgs[] = { "best", "arb", "arb2", "nv20", NULL };
const char *r_rendererArgs[] = { "best", "arb", "arb2", NULL };
idCVar r_inhibitFragmentProgram( "r_inhibitFragmentProgram", "0", CVAR_RENDERER | CVAR_BOOL, "ignore the fragment program extension" );
idCVar r_useLightPortalFlow( "r_useLightPortalFlow", "1", CVAR_RENDERER | CVAR_BOOL, "use a more precise area reference determination" );
@ -62,7 +62,6 @@ idCVar r_customHeight( "r_customHeight", "486", CVAR_RENDERER | CVAR_ARCHIVE | C
idCVar r_singleTriangle( "r_singleTriangle", "0", CVAR_RENDERER | CVAR_BOOL, "only draw a single triangle per primitive" );
idCVar r_checkBounds( "r_checkBounds", "0", CVAR_RENDERER | CVAR_BOOL, "compare all surface bounds with precalculated ones" );
idCVar r_useNV20MonoLights( "r_useNV20MonoLights", "1", CVAR_RENDERER | CVAR_INTEGER, "use pass optimization for mono lights" );
idCVar r_useConstantMaterials( "r_useConstantMaterials", "1", CVAR_RENDERER | CVAR_BOOL, "use pre-calculated material registers if possible" );
idCVar r_useTripleTextureARB( "r_useTripleTextureARB", "1", CVAR_RENDERER | CVAR_BOOL, "cards with 3+ texture units do a two pass instead of three pass" );
idCVar r_useSilRemap( "r_useSilRemap", "1", CVAR_RENDERER | CVAR_BOOL, "consider verts with the same XYZ, but different ST the same for shadows" );
@ -228,32 +227,6 @@ void ( APIENTRY * qglMultiTexCoord2fvARB )( GLenum texture, GLfloat *st );
void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
void ( APIENTRY *qglCombinerParameterfvNV )( GLenum pname, const GLfloat *params );
void ( APIENTRY *qglCombinerParameterivNV )( GLenum pname, const GLint *params );
void ( APIENTRY *qglCombinerParameterfNV )( GLenum pname, const GLfloat param );
void ( APIENTRY *qglCombinerParameteriNV )( GLenum pname, const GLint param );
void ( APIENTRY *qglCombinerInputNV )( GLenum stage, GLenum portion, GLenum variable, GLenum input,
GLenum mapping, GLenum componentUsage );
void ( APIENTRY *qglCombinerOutputNV )( GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput,
GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct,
GLboolean cdDotProduct, GLboolean muxSum );
void ( APIENTRY *qglFinalCombinerInputNV )( GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage );
void (APIENTRY *qglVertexArrayRangeNV)( GLsizei length, void *pointer );
// TTimo: wgl vs glX
// http://oss.sgi.com/projects/ogl-sample/registry/NV/vertex_array_range.txt
// since APIs are the same anyway, let's be wgl/glX agnostic
void *(APIENTRY *qAllocateMemoryNV)( GLsizei size, float readFrequency, float writeFrequency, float priority);
void (APIENTRY *qFreeMemoryNV)( void *pointer );
#ifdef GLX_VERSION_1_1
#define Q_ALLOCATE_MEMORY_NV "glXAllocateMemoryNV"
#define Q_FREE_MEMORY_NV "glXFreeMemoryNV"
#else
#define Q_ALLOCATE_MEMORY_NV "wglAllocateMemoryNV"
#define Q_FREE_MEMORY_NV "wglFreeMemoryNV"
#endif
void (APIENTRY *qglTexImage3D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
void (APIENTRY * qglColorTableEXT)( int, int, int, int, int, const void * );
@ -404,28 +377,6 @@ static void R_CheckPortableExtensions( void ) {
tr.stencilDecr = GL_DECR;
}
// GL_NV_register_combiners
glConfig.registerCombinersAvailable = R_CheckExtension( "GL_NV_register_combiners" );
if ( glConfig.registerCombinersAvailable ) {
qglCombinerParameterfvNV = (void (APIENTRY *)( GLenum pname, const GLfloat *params ))
GLimp_ExtensionPointer( "glCombinerParameterfvNV" );
qglCombinerParameterivNV = (void (APIENTRY *)( GLenum pname, const GLint *params ))
GLimp_ExtensionPointer( "glCombinerParameterivNV" );
qglCombinerParameterfNV = (void (APIENTRY *)( GLenum pname, const GLfloat param ))
GLimp_ExtensionPointer( "glCombinerParameterfNV" );
qglCombinerParameteriNV = (void (APIENTRY *)( GLenum pname, const GLint param ))
GLimp_ExtensionPointer( "glCombinerParameteriNV" );
qglCombinerInputNV = (void (APIENTRY *)( GLenum stage, GLenum portion, GLenum variable, GLenum input,
GLenum mapping, GLenum componentUsage ))
GLimp_ExtensionPointer( "glCombinerInputNV" );
qglCombinerOutputNV = (void (APIENTRY *)( GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput,
GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct,
GLboolean cdDotProduct, GLboolean muxSum ))
GLimp_ExtensionPointer( "glCombinerOutputNV" );
qglFinalCombinerInputNV = (void (APIENTRY *)( GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage ))
GLimp_ExtensionPointer( "glFinalCombinerInputNV" );
}
// GL_EXT_stencil_two_side
glConfig.twoSidedStencilAvailable = R_CheckExtension( "GL_EXT_stencil_two_side" );
if ( glConfig.twoSidedStencilAvailable )
@ -638,7 +589,6 @@ void R_InitOpenGL( void ) {
// parse our vertex and fragment programs, possibly disably support for
// one of the paths if there was an error
R_NV20_Init();
R_ARB2_Init();
cmdSystem->AddCommand( "reloadARBprograms", R_ReloadARBPrograms_f, CMD_FL_RENDERER, "reloads ARB programs" );
@ -1747,12 +1697,6 @@ static void GfxInfo_f( const idCmdArgs &args ) {
const char *active[2] = { "", " (ACTIVE)" };
common->Printf( "ARB path ENABLED%s\n", active[tr.backEndRenderer == BE_ARB] );
if ( glConfig.allowNV20Path ) {
common->Printf( "NV20 path ENABLED%s\n", active[tr.backEndRenderer == BE_NV20] );
} else {
common->Printf( "NV20 path disabled\n" );
}
if ( glConfig.allowARB2Path ) {
common->Printf( "ARB2 path ENABLED%s\n", active[tr.backEndRenderer == BE_ARB2] );
} else {
@ -2215,6 +2159,6 @@ idRenderSystemLocal::GetCardCaps
========================
*/
void idRenderSystemLocal::GetCardCaps( bool &oldCard, bool &nv10or20 ) {
nv10or20 = tr.backEndRenderer == BE_NV20;
oldCard = ( tr.backEndRenderer == BE_ARB || tr.backEndRenderer == BE_NV20 );
nv10or20 = false;
oldCard = tr.backEndRenderer == BE_ARB;
}

View file

@ -331,10 +331,6 @@ static progDef_t progs[MAX_GLPROGS] = {
{ GL_VERTEX_PROGRAM_ARB, VPROG_AMBIENT, "ambientLight.vfp" },
{ GL_FRAGMENT_PROGRAM_ARB, FPROG_AMBIENT, "ambientLight.vfp" },
{ GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW, "shadow.vp" },
{ GL_VERTEX_PROGRAM_ARB, VPROG_NV20_BUMP_AND_LIGHT, "nv20_bumpAndLight.vp" },
{ GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_COLOR, "nv20_diffuseColor.vp" },
{ GL_VERTEX_PROGRAM_ARB, VPROG_NV20_SPECULAR_COLOR, "nv20_specularColor.vp" },
{ GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_AND_SPECULAR_COLOR, "nv20_diffuseAndSpecularColor.vp" },
{ GL_VERTEX_PROGRAM_ARB, VPROG_ENVIRONMENT, "environment.vfp" },
{ GL_FRAGMENT_PROGRAM_ARB, FPROG_ENVIRONMENT, "environment.vfp" },
{ GL_VERTEX_PROGRAM_ARB, VPROG_GLASSWARP, "arbVP_glasswarp.txt" },

View file

@ -1678,9 +1678,6 @@ void RB_STD_DrawView( void ) {
case BE_ARB2:
RB_ARB2_DrawInteractions();
break;
case BE_NV20:
RB_NV20_DrawInteractions();
break;
}
// disable stencil shadow test

View file

@ -1,870 +0,0 @@
/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
Doom 3 Source Code 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 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "sys/platform.h"
#include "renderer/VertexCache.h"
#include "renderer/tr_local.h"
typedef enum {
FPROG_BUMP_AND_LIGHT,
FPROG_DIFFUSE_COLOR,
FPROG_SPECULAR_COLOR,
FPROG_DIFFUSE_AND_SPECULAR_COLOR,
FPROG_NUM_FRAGMENT_PROGRAMS
} fragmentProgram_t;
GLuint fragmentDisplayListBase; // FPROG_NUM_FRAGMENT_PROGRAMS lists
void RB_NV20_DependentSpecularPass( const drawInteraction_t *din );
void RB_NV20_DependentAmbientPass( void );
/*
=========================================================================================
GENERAL INTERACTION RENDERING
=========================================================================================
*/
/*
====================
GL_SelectTextureNoClient
====================
*/
void GL_SelectTextureNoClient( int unit ) {
backEnd.glState.currenttmu = unit;
qglActiveTextureARB( GL_TEXTURE0_ARB + unit );
}
/*
==================
RB_NV20_BumpAndLightFragment
==================
*/
static void RB_NV20_BumpAndLightFragment( void ) {
if ( r_useCombinerDisplayLists.GetBool() ) {
qglCallList( fragmentDisplayListBase + FPROG_BUMP_AND_LIGHT );
return;
}
// program the nvidia register combiners
qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 3 );
// stage 0 rgb performs the dot product
// SPARE0 = TEXTURE0 dot TEXTURE1
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 );
// stage 1 rgb multiplies texture 2 and 3 together
// SPARE1 = TEXTURE2 * TEXTURE3
qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV,
GL_TEXTURE2_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV,
GL_TEXTURE3_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerOutputNV( GL_COMBINER1_NV, GL_RGB,
GL_SPARE1_NV, GL_DISCARD_NV, GL_DISCARD_NV,
GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
// stage 1 alpha does nohing
// stage 2 color multiplies spare0 * spare 1 just for debugging
// SPARE0 = SPARE0 * SPARE1
qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_A_NV,
GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_B_NV,
GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerOutputNV( GL_COMBINER2_NV, GL_RGB,
GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
// stage 2 alpha multiples spare0 * spare 1
// SPARE0 = SPARE0 * SPARE1
qglCombinerInputNV( GL_COMBINER2_NV, GL_ALPHA, GL_VARIABLE_A_NV,
GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_BLUE );
qglCombinerInputNV( GL_COMBINER2_NV, GL_ALPHA, GL_VARIABLE_B_NV,
GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_BLUE );
qglCombinerOutputNV( GL_COMBINER2_NV, GL_ALPHA,
GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
// final combiner
qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_SPARE0_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_SPARE0_NV,
GL_UNSIGNED_IDENTITY_NV, GL_ALPHA );
}
/*
==================
RB_NV20_DI_BumpAndLightPass
We are going to write alpha as light falloff * ( bump dot light ) * lightProjection
If the light isn't a monoLightShader, the lightProjection will be skipped, because
it will have to be done on an itterated basis
==================
*/
static void RB_NV20_DI_BumpAndLightPass( const drawInteraction_t *din, bool monoLightShader ) {
GL_State( GLS_COLORMASK | GLS_DEPTHMASK | backEnd.depthFunc );
// texture 0 is the normalization cube map
// GL_TEXTURE0_ARB will be the normalized vector
// towards the light source
#ifdef MACOS_X
GL_SelectTexture( 0 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 0 );
#endif
if ( din->ambientLight ) {
globalImages->ambientNormalMap->Bind();
} else {
globalImages->normalCubeMapImage->Bind();
}
// texture 1 will be the per-surface bump map
#ifdef MACOS_X
GL_SelectTexture( 1 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 1 );
#endif
din->bumpImage->Bind();
// texture 2 will be the light falloff texture
#ifdef MACOS_X
GL_SelectTexture( 2 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 2 );
#endif
din->lightFalloffImage->Bind();
// texture 3 will be the light projection texture
#ifdef MACOS_X
GL_SelectTexture( 3 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 3 );
#endif
if ( monoLightShader ) {
din->lightImage->Bind();
} else {
// if the projected texture is multi-colored, we
// will need to do it in subsequent passes
globalImages->whiteImage->Bind();
}
// bind our "fragment program"
RB_NV20_BumpAndLightFragment();
// draw it
qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_NV20_BUMP_AND_LIGHT );
RB_DrawElementsWithCounters( din->surf->geo );
}
/*
==================
RB_NV20_DiffuseColorFragment
==================
*/
static void RB_NV20_DiffuseColorFragment( void ) {
if ( r_useCombinerDisplayLists.GetBool() ) {
qglCallList( fragmentDisplayListBase + FPROG_DIFFUSE_COLOR );
return;
}
// program the nvidia register combiners
qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 1 );
// stage 0 is free, so we always do the multiply of the vertex color
// when the vertex color is inverted, qglCombinerInputNV(GL_VARIABLE_B_NV) will be changed
qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV,
GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV,
GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB,
GL_TEXTURE0_ARB, GL_DISCARD_NV, GL_DISCARD_NV,
GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
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 );
// for GL_CONSTANT_COLOR0_NV * TEXTURE0 * TEXTURE1
qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_CONSTANT_COLOR0_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_E_TIMES_F_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_TEXTURE0_ARB,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_TEXTURE1_ARB,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_ALPHA );
}
/*
==================
RB_NV20_DI_DiffuseColorPass
==================
*/
static void RB_NV20_DI_DiffuseColorPass( const drawInteraction_t *din ) {
GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_ALPHAMASK
| backEnd.depthFunc );
// texture 0 will be the per-surface diffuse map
#ifdef MACOS_X
GL_SelectTexture( 0 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 0 );
#endif
din->diffuseImage->Bind();
// texture 1 will be the light projected texture
#ifdef MACOS_X
GL_SelectTexture( 1 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 1 );
#endif
din->lightImage->Bind();
// texture 2 is disabled
#ifdef MACOS_X
GL_SelectTexture( 2 );
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 2 );
#endif
globalImages->BindNull();
// texture 3 is disabled
#ifdef MACOS_X
GL_SelectTexture( 3 );
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 3 );
#endif
globalImages->BindNull();
// bind our "fragment program"
RB_NV20_DiffuseColorFragment();
// override one parameter for inverted vertex color
if ( din->vertexColor == SVC_INVERSE_MODULATE ) {
qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV,
GL_PRIMARY_COLOR_NV, GL_UNSIGNED_INVERT_NV, GL_RGB );
}
// draw it
qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_COLOR );
RB_DrawElementsWithCounters( din->surf->geo );
}
/*
==================
RB_NV20_SpecularColorFragment
==================
*/
static void RB_NV20_SpecularColorFragment( void ) {
if ( r_useCombinerDisplayLists.GetBool() ) {
qglCallList( fragmentDisplayListBase + FPROG_SPECULAR_COLOR );
return;
}
// program the nvidia register combiners
qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 4 );
// we want GL_CONSTANT_COLOR1_NV * PRIMARY_COLOR * TEXTURE2 * TEXTURE3 * specular( TEXTURE0 * TEXTURE1 )
// stage 0 rgb performs the dot product
// GL_SPARE0_NV = ( TEXTURE0 dot TEXTURE1 - 0.5 ) * 2
// TEXTURE2 = TEXTURE2 * PRIMARY_COLOR
// the scale and bias steepen the specular curve
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_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_TRUE, GL_FALSE, GL_FALSE );
// stage 0 alpha does nothing
// stage 1 color takes bump * bump
// GL_SPARE0_NV = ( GL_SPARE0_NV * GL_SPARE0_NV - 0.5 ) * 2
// the scale and bias steepen the specular curve
qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV,
GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV,
GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerOutputNV( GL_COMBINER1_NV, GL_RGB,
GL_SPARE0_NV, GL_DISCARD_NV, GL_DISCARD_NV,
GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE );
// stage 1 alpha does nothing
// stage 2 color
// GL_SPARE0_NV = GL_SPARE0_NV * TEXTURE3
// SECONDARY_COLOR = CONSTANT_COLOR * TEXTURE2
qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_A_NV,
GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_B_NV,
GL_TEXTURE3_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_C_NV,
GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_D_NV,
GL_TEXTURE2_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerOutputNV( GL_COMBINER2_NV, GL_RGB,
GL_SPARE0_NV, GL_SECONDARY_COLOR_NV, GL_DISCARD_NV,
GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
// stage 2 alpha does nothing
// stage 3 scales the texture by the vertex color
qglCombinerInputNV( GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_A_NV,
GL_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_B_NV,
GL_PRIMARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerOutputNV( GL_COMBINER3_NV, GL_RGB,
GL_SECONDARY_COLOR_NV, GL_DISCARD_NV, GL_DISCARD_NV,
GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
// stage 3 alpha does nothing
// final combiner = GL_SPARE0_NV * SECONDARY_COLOR + PRIMARY_COLOR * SECONDARY_COLOR
qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_SPARE0_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_SECONDARY_COLOR_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_E_TIMES_F_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_SPARE0_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_SECONDARY_COLOR_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_ALPHA );
}
/*
==================
RB_NV20_DI_SpecularColorPass
==================
*/
static void RB_NV20_DI_SpecularColorPass( const drawInteraction_t *din ) {
GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_ALPHAMASK
| backEnd.depthFunc );
// texture 0 is the normalization cube map for the half angle
#ifdef MACOS_X
GL_SelectTexture( 0 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 0 );
#endif
globalImages->normalCubeMapImage->Bind();
// texture 1 will be the per-surface bump map
#ifdef MACOS_X
GL_SelectTexture( 1 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 1 );
#endif
din->bumpImage->Bind();
// texture 2 will be the per-surface specular map
#ifdef MACOS_X
GL_SelectTexture( 2 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 2 );
#endif
din->specularImage->Bind();
// texture 3 will be the light projected texture
#ifdef MACOS_X
GL_SelectTexture( 3 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 3 );
#endif
din->lightImage->Bind();
// bind our "fragment program"
RB_NV20_SpecularColorFragment();
// override one parameter for inverted vertex color
if ( din->vertexColor == SVC_INVERSE_MODULATE ) {
qglCombinerInputNV( GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_B_NV,
GL_PRIMARY_COLOR_NV, GL_UNSIGNED_INVERT_NV, GL_RGB );
}
// draw it
qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_NV20_SPECULAR_COLOR );
RB_DrawElementsWithCounters( din->surf->geo );
}
/*
==================
RB_NV20_DiffuseAndSpecularColorFragment
==================
*/
static void RB_NV20_DiffuseAndSpecularColorFragment( void ) {
if ( r_useCombinerDisplayLists.GetBool() ) {
qglCallList( fragmentDisplayListBase + FPROG_DIFFUSE_AND_SPECULAR_COLOR );
return;
}
// program the nvidia register combiners
qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 3 );
// GL_CONSTANT_COLOR0_NV will be the diffuse color
// GL_CONSTANT_COLOR1_NV will be the specular color
// stage 0 rgb performs the dot product
// GL_SECONDARY_COLOR_NV = ( TEXTURE0 dot TEXTURE1 - 0.5 ) * 2
// the scale and bias steepen the specular curve
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_SECONDARY_COLOR_NV, GL_DISCARD_NV, GL_DISCARD_NV,
GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_TRUE, GL_FALSE, GL_FALSE );
// stage 0 alpha does nothing
// stage 1 color takes bump * bump
// PRIMARY_COLOR = ( GL_SECONDARY_COLOR_NV * GL_SECONDARY_COLOR_NV - 0.5 ) * 2
// the scale and bias steepen the specular curve
qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV,
GL_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV,
GL_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerOutputNV( GL_COMBINER1_NV, GL_RGB,
GL_SECONDARY_COLOR_NV, GL_DISCARD_NV, GL_DISCARD_NV,
GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE );
// stage 1 alpha does nothing
// stage 2 color
// PRIMARY_COLOR = ( PRIMARY_COLOR * TEXTURE3 ) * 2
// SPARE0 = 1.0 * 1.0 (needed for final combiner)
qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_A_NV,
GL_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_B_NV,
GL_TEXTURE3_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_C_NV,
GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB );
qglCombinerInputNV( GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_D_NV,
GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB );
qglCombinerOutputNV( GL_COMBINER2_NV, GL_RGB,
GL_SECONDARY_COLOR_NV, GL_SPARE0_NV, GL_DISCARD_NV,
GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
// stage 2 alpha does nothing
// final combiner = TEXTURE2_ARB * CONSTANT_COLOR0_NV + PRIMARY_COLOR_NV * CONSTANT_COLOR1_NV
// alpha = GL_ZERO
qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_CONSTANT_COLOR1_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_SECONDARY_COLOR_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_E_TIMES_F_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_E_NV, GL_TEXTURE2_ARB,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_F_NV, GL_CONSTANT_COLOR0_NV,
GL_UNSIGNED_IDENTITY_NV, GL_RGB );
qglFinalCombinerInputNV( GL_VARIABLE_G_NV, GL_ZERO,
GL_UNSIGNED_IDENTITY_NV, GL_ALPHA );
}
/*
==================
RB_NV20_DI_DiffuseAndSpecularColorPass
==================
*/
static void RB_NV20_DI_DiffuseAndSpecularColorPass( const drawInteraction_t *din ) {
GL_State( GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc );
// texture 0 is the normalization cube map for the half angle
// still bound from RB_NV_BumpAndLightPass
// GL_SelectTextureNoClient( 0 );
// GL_Bind( tr.normalCubeMapImage );
// texture 1 is the per-surface bump map
// still bound from RB_NV_BumpAndLightPass
// GL_SelectTextureNoClient( 1 );
// GL_Bind( din->bumpImage );
// texture 2 is the per-surface diffuse map
#ifdef MACOS_X
GL_SelectTexture( 2 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 2 );
#endif
din->diffuseImage->Bind();
// texture 3 is the per-surface specular map
#ifdef MACOS_X
GL_SelectTexture( 3 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 3 );
#endif
din->specularImage->Bind();
// bind our "fragment program"
RB_NV20_DiffuseAndSpecularColorFragment();
// draw it
qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_AND_SPECULAR_COLOR );
RB_DrawElementsWithCounters( din->surf->geo );
}
/*
==================
RB_NV20_DrawInteraction
==================
*/
static void RB_NV20_DrawInteraction( const drawInteraction_t *din ) {
// load all the vertex program parameters
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, din->localLightOrigin.ToFloatPtr() );
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_VIEW_ORIGIN, din->localViewOrigin.ToFloatPtr() );
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_S, din->lightProjection[0].ToFloatPtr() );
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_T, din->lightProjection[1].ToFloatPtr() );
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_Q, din->lightProjection[2].ToFloatPtr() );
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_FALLOFF_S, din->lightProjection[3].ToFloatPtr() );
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_S, din->bumpMatrix[0].ToFloatPtr() );
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_T, din->bumpMatrix[1].ToFloatPtr() );
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr() );
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr() );
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_S, din->specularMatrix[0].ToFloatPtr() );
qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_T, din->specularMatrix[1].ToFloatPtr() );
// set the constant colors
qglCombinerParameterfvNV( GL_CONSTANT_COLOR0_NV, din->diffuseColor.ToFloatPtr() );
qglCombinerParameterfvNV( GL_CONSTANT_COLOR1_NV, din->specularColor.ToFloatPtr() );
// vertex color passes should be pretty rare (cross-faded bump map surfaces), so always
// run them down as three-passes
if ( din->vertexColor != SVC_IGNORE ) {
qglEnableClientState( GL_COLOR_ARRAY );
RB_NV20_DI_BumpAndLightPass( din, false );
RB_NV20_DI_DiffuseColorPass( din );
RB_NV20_DI_SpecularColorPass( din );
qglDisableClientState( GL_COLOR_ARRAY );
return;
}
qglColor3f( 1, 1, 1 );
// on an ideal card, we would now just bind the textures and call a
// single pass vertex / fragment program, but
// on NV20, we need to decide which single / dual / tripple pass set of programs to use
// ambient light could be done as a single pass if we want to optimize for it
// monochrome light is two passes
if ( ( r_useNV20MonoLights.GetInteger() == 2 ) ||
( din->lightImage->isMonochrome && r_useNV20MonoLights.GetInteger() ) ) {
// do a two-pass rendering
RB_NV20_DI_BumpAndLightPass( din, true );
RB_NV20_DI_DiffuseAndSpecularColorPass( din );
} else {
// general case is three passes
// ( bump dot lightDir ) * lightFalloff
// diffuse * lightProject
// specular * ( bump dot halfAngle extended ) * lightProject
RB_NV20_DI_BumpAndLightPass( din, false );
RB_NV20_DI_DiffuseColorPass( din );
RB_NV20_DI_SpecularColorPass( din );
}
}
/*
=============
RB_NV20_CreateDrawInteractions
=============
*/
static void RB_NV20_CreateDrawInteractions( const drawSurf_t *surf ) {
if ( !surf ) {
return;
}
qglEnable( GL_VERTEX_PROGRAM_ARB );
qglEnable( GL_REGISTER_COMBINERS_NV );
#ifdef MACOS_X
GL_SelectTexture(0);
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
#else
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
qglEnableVertexAttribArrayARB( 8 );
qglEnableVertexAttribArrayARB( 9 );
qglEnableVertexAttribArrayARB( 10 );
qglEnableVertexAttribArrayARB( 11 );
#endif
for ( ; surf ; surf=surf->nextOnLight ) {
// set the vertex pointers
idDrawVert *ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache );
qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color );
#ifdef MACOS_X
GL_SelectTexture( 0 );
qglTexCoordPointer( 2, GL_FLOAT, sizeof( idDrawVert ), ac->st.ToFloatPtr() );
GL_SelectTexture( 1 );
qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() );
GL_SelectTexture( 2 );
qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() );
GL_SelectTexture( 3 );
qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
GL_SelectTexture( 0 );
#else
qglVertexAttribPointerARB( 11, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() );
qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() );
qglVertexAttribPointerARB( 8, 2, GL_FLOAT, false, sizeof( idDrawVert ), ac->st.ToFloatPtr() );
#endif
qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );
RB_CreateSingleDrawInteractions( surf, RB_NV20_DrawInteraction );
}
#ifndef MACOS_X
qglDisableVertexAttribArrayARB( 8 );
qglDisableVertexAttribArrayARB( 9 );
qglDisableVertexAttribArrayARB( 10 );
qglDisableVertexAttribArrayARB( 11 );
#endif
// disable features
#ifdef MACOS_X
GL_SelectTexture( 3 );
globalImages->BindNull();
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
GL_SelectTexture( 2 );
globalImages->BindNull();
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
GL_SelectTexture( 1 );
globalImages->BindNull();
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
#else
GL_SelectTextureNoClient( 3 );
globalImages->BindNull();
GL_SelectTextureNoClient( 2 );
globalImages->BindNull();
GL_SelectTextureNoClient( 1 );
globalImages->BindNull();
#endif
backEnd.glState.currenttmu = -1;
GL_SelectTexture( 0 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
qglDisable( GL_VERTEX_PROGRAM_ARB );
qglDisable( GL_REGISTER_COMBINERS_NV );
}
//======================================================================================
/*
==================
RB_NV20_DrawInteractions
==================
*/
void RB_NV20_DrawInteractions( void ) {
viewLight_t *vLight;
//
// for each light, perform adding and shadowing
//
for ( vLight = backEnd.viewDef->viewLights ; vLight ; vLight = vLight->next ) {
// do fogging later
if ( vLight->lightShader->IsFogLight() ) {
continue;
}
if ( vLight->lightShader->IsBlendLight() ) {
continue;
}
if ( !vLight->localInteractions && !vLight->globalInteractions
&& !vLight->translucentInteractions ) {
continue;
}
backEnd.vLight = vLight;
// clear the stencil buffer if needed
if ( vLight->globalShadows || vLight->localShadows ) {
backEnd.currentScissor = vLight->scissorRect;
if ( r_useScissor.GetBool() ) {
qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1,
backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
}
qglClear( GL_STENCIL_BUFFER_BIT );
} else {
// no shadows, so no need to read or write the stencil buffer
// we might in theory want to use GL_ALWAYS instead of disabling
// completely, to satisfy the invarience rules
qglStencilFunc( GL_ALWAYS, 128, 255 );
}
backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL;
if ( r_useShadowVertexProgram.GetBool() ) {
qglEnable( GL_VERTEX_PROGRAM_ARB );
qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW );
RB_StencilShadowPass( vLight->globalShadows );
RB_NV20_CreateDrawInteractions( vLight->localInteractions );
qglEnable( GL_VERTEX_PROGRAM_ARB );
qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW );
RB_StencilShadowPass( vLight->localShadows );
RB_NV20_CreateDrawInteractions( vLight->globalInteractions );
qglDisable( GL_VERTEX_PROGRAM_ARB ); // if there weren't any globalInteractions, it would have stayed on
} else {
RB_StencilShadowPass( vLight->globalShadows );
RB_NV20_CreateDrawInteractions( vLight->localInteractions );
RB_StencilShadowPass( vLight->localShadows );
RB_NV20_CreateDrawInteractions( vLight->globalInteractions );
}
// translucent surfaces never get stencil shadowed
if ( r_skipTranslucent.GetBool() ) {
continue;
}
qglStencilFunc( GL_ALWAYS, 128, 255 );
backEnd.depthFunc = GLS_DEPTHFUNC_LESS;
RB_NV20_CreateDrawInteractions( vLight->translucentInteractions );
backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL;
}
}
//=======================================================================
/*
==================
R_NV20_Init
==================
*/
void R_NV20_Init( void ) {
glConfig.allowNV20Path = false;
common->Printf( "---------- R_NV20_Init ----------\n" );
if ( !glConfig.registerCombinersAvailable || !glConfig.ARBVertexProgramAvailable || glConfig.maxTextureUnits < 4 ) {
common->Printf( "Not available.\n" );
return;
}
GL_CheckErrors();
// create our "fragment program" display lists
fragmentDisplayListBase = qglGenLists( FPROG_NUM_FRAGMENT_PROGRAMS );
// force them to issue commands to build the list
bool temp = r_useCombinerDisplayLists.GetBool();
r_useCombinerDisplayLists.SetBool( false );
qglNewList( fragmentDisplayListBase + FPROG_BUMP_AND_LIGHT, GL_COMPILE );
RB_NV20_BumpAndLightFragment();
qglEndList();
qglNewList( fragmentDisplayListBase + FPROG_DIFFUSE_COLOR, GL_COMPILE );
RB_NV20_DiffuseColorFragment();
qglEndList();
qglNewList( fragmentDisplayListBase + FPROG_SPECULAR_COLOR, GL_COMPILE );
RB_NV20_SpecularColorFragment();
qglEndList();
qglNewList( fragmentDisplayListBase + FPROG_DIFFUSE_AND_SPECULAR_COLOR, GL_COMPILE );
RB_NV20_DiffuseAndSpecularColorFragment();
qglEndList();
r_useCombinerDisplayLists.SetBool( temp );
common->Printf( "---------------------------------\n" );
glConfig.allowNV20Path = true;
}

View file

@ -65,19 +65,6 @@ extern PFNGLUNMAPBUFFERARBPROC qglUnmapBufferARB;
extern PFNGLGETBUFFERPARAMETERIVARBPROC qglGetBufferParameterivARB;
extern PFNGLGETBUFFERPOINTERVARBPROC qglGetBufferPointervARB;
// NV_register_combiners
extern void ( APIENTRY *qglCombinerParameterfvNV )( GLenum pname, const GLfloat *params );
extern void ( APIENTRY *qglCombinerParameterivNV )( GLenum pname, const GLint *params );
extern void ( APIENTRY *qglCombinerParameterfNV )( GLenum pname, const GLfloat param );
extern void ( APIENTRY *qglCombinerParameteriNV )( GLenum pname, const GLint param );
extern void ( APIENTRY *qglCombinerInputNV )( GLenum stage, GLenum portion, GLenum variable, GLenum input,
GLenum mapping, GLenum componentUsage );
extern void ( APIENTRY *qglCombinerOutputNV )( GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput,
GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct,
GLboolean cdDotProduct, GLboolean muxSum );
extern void ( APIENTRY *qglFinalCombinerInputNV )( GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage );
// 3D textures
extern void ( APIENTRY *qglTexImage3D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);

View file

@ -673,7 +673,6 @@ const int MAX_GUI_SURFACES = 1024; // default size of the drawSurfs list for gu
typedef enum {
BE_ARB,
BE_NV20,
BE_ARB2,
BE_BAD
} backEndName_t;
@ -833,11 +832,10 @@ extern idCVar r_flareSize; // scale the flare deforms from the material def
extern idCVar r_gamma; // changes gamma tables
extern idCVar r_brightness; // changes gamma tables
extern idCVar r_renderer; // arb, nv20, gl2, etc
extern idCVar r_renderer; // arb, gl2, etc
extern idCVar r_checkBounds; // compare all surface bounds with precalculated ones
extern idCVar r_useNV20MonoLights; // 1 = allow an interaction pass optimization
extern idCVar r_useLightPortalFlow; // 1 = do a more precise area reference determination
extern idCVar r_useTripleTextureARB; // 1 = cards with 3+ texture units do a two pass instead of three pass
extern idCVar r_useShadowSurfaceScissor;// 1 = scissor shadows by the scissor rect of the interaction surfaces
@ -1277,9 +1275,6 @@ DRAW_*
void RB_ARB_DrawInteractions( void );
void R_NV20_Init( void );
void RB_NV20_DrawInteractions( void );
void R_ARB2_Init( void );
void RB_ARB2_DrawInteractions( void );
void R_ReloadARBPrograms_f( const idCmdArgs &args );
@ -1291,10 +1286,6 @@ typedef enum {
VPROG_ENVIRONMENT,
VPROG_BUMPY_ENVIRONMENT,
VPROG_STENCIL_SHADOW,
VPROG_NV20_BUMP_AND_LIGHT,
VPROG_NV20_DIFFUSE_COLOR,
VPROG_NV20_SPECULAR_COLOR,
VPROG_NV20_DIFFUSE_AND_SPECULAR_COLOR,
VPROG_TEST,
FPROG_INTERACTION,
FPROG_ENVIRONMENT,