📄 tr_shade.c
字号:
case TMOD_SCROLL:
RB_CalcScrollTexCoords( pStage->bundle[b].texMods[tm].scroll,
( float * ) tess.svars.texcoords[b] );
break;
case TMOD_SCALE:
RB_CalcScaleTexCoords( pStage->bundle[b].texMods[tm].scale,
( float * ) tess.svars.texcoords[b] );
break;
case TMOD_STRETCH:
RB_CalcStretchTexCoords( &pStage->bundle[b].texMods[tm].wave,
( float * ) tess.svars.texcoords[b] );
break;
case TMOD_TRANSFORM:
RB_CalcTransformTexCoords( &pStage->bundle[b].texMods[tm],
( float * ) tess.svars.texcoords[b] );
break;
case TMOD_ROTATE:
RB_CalcRotateTexCoords( pStage->bundle[b].texMods[tm].rotateSpeed,
( float * ) tess.svars.texcoords[b] );
break;
default:
ri.Error( ERR_DROP, "ERROR: unknown texmod '%d' in shader '%s'\n", pStage->bundle[b].texMods[tm].type, tess.shader->name );
break;
}
}
}
}
/*
** RB_IterateStagesGeneric
*/
static void RB_IterateStagesGeneric( shaderCommands_t *input )
{
int stage;
for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ )
{
shaderStage_t *pStage = tess.xstages[stage];
if ( !pStage )
{
break;
}
ComputeColors( pStage );
ComputeTexCoords( pStage );
if ( !setArraysOnce )
{
qglEnableClientState( GL_COLOR_ARRAY );
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, input->svars.colors );
}
//
// do multitexture
//
if ( pStage->bundle[1].image[0] != 0 )
{
DrawMultitextured( input, stage );
}
else
{
if ( !setArraysOnce )
{
qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[0] );
}
//
// set state
//
if ( pStage->bundle[0].vertexLightmap && ( (r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2 ) && r_lightmap->integer )
{
GL_Bind( tr.whiteImage );
}
else
R_BindAnimatedImage( &pStage->bundle[0] );
GL_State( pStage->stateBits );
//
// draw
//
R_DrawElements( input->numIndexes, input->indexes );
}
// allow skipping out to show just lightmaps during development
if ( r_lightmap->integer && ( pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap ) )
{
break;
}
}
}
/*
** RB_StageIteratorGeneric
*/
void RB_StageIteratorGeneric( void )
{
shaderCommands_t *input;
input = &tess;
RB_DeformTessGeometry();
//
// log this call
//
if ( r_logFile->integer )
{
// don't just call LogComment, or we will get
// a call to va() every frame!
GLimp_LogComment( va("--- RB_StageIteratorGeneric( %s ) ---\n", tess.shader->name) );
}
//
// set face culling appropriately
//
GL_Cull( input->shader->cullType );
// set polygon offset if necessary
if ( input->shader->polygonOffset )
{
qglEnable( GL_POLYGON_OFFSET_FILL );
qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );
}
//
// if there is only a single pass then we can enable color
// and texture arrays before we compile, otherwise we need
// to avoid compiling those arrays since they will change
// during multipass rendering
//
if ( tess.numPasses > 1 || input->shader->multitextureEnv )
{
setArraysOnce = qfalse;
qglDisableClientState (GL_COLOR_ARRAY);
qglDisableClientState (GL_TEXTURE_COORD_ARRAY);
}
else
{
setArraysOnce = qtrue;
qglEnableClientState( GL_COLOR_ARRAY);
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] );
}
//
// lock XYZ
//
qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD
if (qglLockArraysEXT)
{
qglLockArraysEXT(0, input->numVertexes);
GLimp_LogComment( "glLockArraysEXT\n" );
}
//
// enable color and texcoord arrays after the lock if necessary
//
if ( !setArraysOnce )
{
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
qglEnableClientState( GL_COLOR_ARRAY );
}
//
// call shader function
//
RB_IterateStagesGeneric( input );
//
// now do any dynamic lighting needed
//
if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE
&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) {
ProjectDlightTexture();
}
//
// now do fog
//
if ( tess.fogNum && tess.shader->fogPass ) {
RB_FogPass();
}
//
// unlock arrays
//
if (qglUnlockArraysEXT)
{
qglUnlockArraysEXT();
GLimp_LogComment( "glUnlockArraysEXT\n" );
}
//
// reset polygon offset
//
if ( input->shader->polygonOffset )
{
qglDisable( GL_POLYGON_OFFSET_FILL );
}
}
/*
** RB_StageIteratorVertexLitTexture
*/
void RB_StageIteratorVertexLitTexture( void )
{
shaderCommands_t *input;
shader_t *shader;
input = &tess;
shader = input->shader;
//
// compute colors
//
RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors );
//
// log this call
//
if ( r_logFile->integer )
{
// don't just call LogComment, or we will get
// a call to va() every frame!
GLimp_LogComment( va("--- RB_StageIteratorVertexLitTexturedUnfogged( %s ) ---\n", tess.shader->name) );
}
//
// set face culling appropriately
//
GL_Cull( input->shader->cullType );
//
// set arrays and lock
//
qglEnableClientState( GL_COLOR_ARRAY);
qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );
qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][0] );
qglVertexPointer (3, GL_FLOAT, 16, input->xyz);
if ( qglLockArraysEXT )
{
qglLockArraysEXT(0, input->numVertexes);
GLimp_LogComment( "glLockArraysEXT\n" );
}
//
// call special shade routine
//
R_BindAnimatedImage( &tess.xstages[0]->bundle[0] );
GL_State( tess.xstages[0]->stateBits );
R_DrawElements( input->numIndexes, input->indexes );
//
// now do any dynamic lighting needed
//
if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) {
ProjectDlightTexture();
}
//
// now do fog
//
if ( tess.fogNum && tess.shader->fogPass ) {
RB_FogPass();
}
//
// unlock arrays
//
if (qglUnlockArraysEXT)
{
qglUnlockArraysEXT();
GLimp_LogComment( "glUnlockArraysEXT\n" );
}
}
//define REPLACE_MODE
void RB_StageIteratorLightmappedMultitexture( void ) {
shaderCommands_t *input;
input = &tess;
//
// log this call
//
if ( r_logFile->integer ) {
// don't just call LogComment, or we will get
// a call to va() every frame!
GLimp_LogComment( va("--- RB_StageIteratorLightmappedMultitexture( %s ) ---\n", tess.shader->name) );
}
//
// set face culling appropriately
//
GL_Cull( input->shader->cullType );
//
// set color, pointers, and lock
//
GL_State( GLS_DEFAULT );
qglVertexPointer( 3, GL_FLOAT, 16, input->xyz );
#ifdef REPLACE_MODE
qglDisableClientState( GL_COLOR_ARRAY );
qglColor3f( 1, 1, 1 );
qglShadeModel( GL_FLAT );
#else
qglEnableClientState( GL_COLOR_ARRAY );
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.constantColor255 );
#endif
//
// select base stage
//
GL_SelectTexture( 0 );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
R_BindAnimatedImage( &tess.xstages[0]->bundle[0] );
qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][0] );
//
// configure second stage
//
GL_SelectTexture( 1 );
qglEnable( GL_TEXTURE_2D );
if ( r_lightmap->integer ) {
GL_TexEnv( GL_REPLACE );
} else {
GL_TexEnv( GL_MODULATE );
}
R_BindAnimatedImage( &tess.xstages[0]->bundle[1] );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][1] );
//
// lock arrays
//
if ( qglLockArraysEXT ) {
qglLockArraysEXT(0, input->numVertexes);
GLimp_LogComment( "glLockArraysEXT\n" );
}
R_DrawElements( input->numIndexes, input->indexes );
//
// disable texturing on TEXTURE1, then select TEXTURE0
//
qglDisable( GL_TEXTURE_2D );
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
GL_SelectTexture( 0 );
#ifdef REPLACE_MODE
GL_TexEnv( GL_MODULATE );
qglShadeModel( GL_SMOOTH );
#endif
//
// now do any dynamic lighting needed
//
if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) {
ProjectDlightTexture();
}
//
// now do fog
//
if ( tess.fogNum && tess.shader->fogPass ) {
RB_FogPass();
}
//
// unlock arrays
//
if ( qglUnlockArraysEXT ) {
qglUnlockArraysEXT();
GLimp_LogComment( "glUnlockArraysEXT\n" );
}
}
/*
** RB_EndSurface
*/
void RB_EndSurface( void ) {
shaderCommands_t *input;
input = &tess;
if (input->numIndexes == 0) {
return;
}
if (input->indexes[SHADER_MAX_INDEXES-1] != 0) {
ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_INDEXES hit");
}
if (input->xyz[SHADER_MAX_VERTEXES-1][0] != 0) {
ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_VERTEXES hit");
}
if ( tess.shader == tr.shadowShader ) {
RB_ShadowTessEnd();
return;
}
// for debugging of sort order issues, stop rendering after a given sort value
if ( r_debugSort->integer && r_debugSort->integer < tess.shader->sort ) {
return;
}
//
// update performance counters
//
backEnd.pc.c_shaders++;
backEnd.pc.c_vertexes += tess.numVertexes;
backEnd.pc.c_indexes += tess.numIndexes;
backEnd.pc.c_totalIndexes += tess.numIndexes * tess.numPasses;
//
// call off to shader specific tess end function
//
tess.currentStageIteratorFunc();
//
// draw debugging stuff
//
if ( r_showtris->integer ) {
DrawTris (input);
}
if ( r_shownormals->integer ) {
DrawNormals (input);
}
// clear shader so we can tell we don't have any unclosed surfaces
tess.numIndexes = 0;
GLimp_LogComment( "----------\n" );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -