//DRAWCEL static void DrawCel (shaderCommands_t *input) { GL_Bind( tr.whiteImage ); qglColor3f (1,1,1); GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); qglDisableClientState (GL_COLOR_ARRAY); qglDisableClientState (GL_TEXTURE_COORD_ARRAY); qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD if (qglLockArraysEXT) { qglLockArraysEXT(0, input->numVertexes); GLimp_LogComment( "glLockArraysEXT\n" ); } R_DrawCel( input->numIndexes, input->indexes ); if (qglUnlockArraysEXT) { qglUnlockArraysEXT(); GLimp_LogComment( "glUnlockArraysEXT\n" ); } }
/* ================ DrawTris Draws triangle outlines for debugging ================ */ static void DrawTris (shaderCommands_t *input) { GL_Bind( tr.whiteImage ); qglColor3f (1,1,1); GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); qglDepthRange( 0, 0 ); qglDisableClientState (GL_COLOR_ARRAY); qglDisableClientState (GL_TEXTURE_COORD_ARRAY); qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD if (qglLockArraysEXT) { qglLockArraysEXT(0, input->numVertexes); GLimp_LogComment( "glLockArraysEXT\n" ); } #ifdef HAVE_GLES qglDrawElements( GL_LINE_STRIP, input->numIndexes, GL_INDEX_TYPE, input->indexes ); #else R_DrawElements( input->numIndexes, input->indexes ); #endif if (qglUnlockArraysEXT) { qglUnlockArraysEXT(); GLimp_LogComment( "glUnlockArraysEXT\n" ); } qglDepthRange( 0, 1 ); }
void CMistyFog2::Render(CWorldEffectsSystem *system) { if (mFadeAlpha <= 0.0) { return; } qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglLoadIdentity (); MYgluPerspective (80.0, 1.0, 4, 2048.0); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglLoadIdentity (); qglRotatef (-90, 1, 0, 0); // put Z going up qglRotatef (90, 0, 0, 1); // put Z going up qglRotatef (0, 1, 0, 0); qglRotatef (-90, 0, 1, 0); qglRotatef (-90, 0, 0, 1); qglDisable(GL_TEXTURE_2D); GL_State(GLS_SRCBLEND_SRC_ALPHA|GLS_DSTBLEND_ONE); qglShadeModel (GL_SMOOTH); qglColorPointer(4, GL_FLOAT, 0, mColors); qglEnableClientState(GL_COLOR_ARRAY); qglVertexPointer( 3, GL_FLOAT, 0, mVerts ); qglEnableClientState(GL_VERTEX_ARRAY); if (qglLockArraysEXT) { qglLockArraysEXT(0, MISTYFOG_HEIGHT*MISTYFOG_WIDTH); } qglDrawElements(GL_QUADS, (MISTYFOG_HEIGHT-1)*(MISTYFOG_WIDTH-1)*4, GL_UNSIGNED_INT, mIndexes); if ( qglUnlockArraysEXT ) { qglUnlockArraysEXT(); } qglDisableClientState(GL_COLOR_ARRAY); // qglDisableClientState(GL_VERTEX_ARRAY); backend doesn't ever re=enable this properly qglPopMatrix(); qglMatrixMode(GL_PROJECTION); qglPopMatrix(); qglMatrixMode(GL_MODELVIEW); // bug somewhere in the backend which requires this }
/* =================== RB_OutlinesPass Draws outlines on surfaces with shader.hasOutlines set =================== */ static void RB_OutlinesPass( void ) { int outlines; float outlinesAlpha; outlines = r_outlines->value; outlinesAlpha = r_outlinesAlpha->value; if ( !tess.shader->hasOutlines ) return; if ( !r_outlines->integer ) return; GL_Bind( tr.whiteImage ); qglColor4f( 0, 0, 0, outlinesAlpha ); GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); qglPolygonMode( GL_BACK, GL_LINE ); qglLineWidth( outlines + 1 ); qglCullFace( GL_BACK ); qglDisableClientState( GL_COLOR_ARRAY ); qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); qglVertexPointer (3, GL_FLOAT, 16, tess.xyz); // padded for SIMD if (qglLockArraysEXT) { qglLockArraysEXT(0, tess.numVertexes); GLimp_LogComment( "glLockArraysEXT\n" ); } R_DrawElements( tess.numIndexes, tess.indexes ); if (qglUnlockArraysEXT) { qglUnlockArraysEXT(); GLimp_LogComment( "glUnlockArraysEXT\n" ); } // FIX: Must reset these manually or renderer will b0rk! qglCullFace( GL_FRONT ); qglLineWidth( 1 ); }
void CQuickSpriteSystem::Flush(void) { if (mNextVert==0) { return; } /* if (mUseFog && r_drawfog->integer == 2 && mFogIndex == tr.world->globalFog) { //enable hardware fog when we draw this thing if applicable -rww fog_t *fog = tr.world->fogs + mFogIndex; qglFogf(GL_FOG_MODE, GL_EXP2); qglFogf(GL_FOG_DENSITY, logtestExp2 / fog->parms.depthForOpaque); qglFogfv(GL_FOG_COLOR, fog->parms.color); qglEnable(GL_FOG); } */ //this should not be needed, since I just wait to disable fog for the surface til after surface sprites are done // // render the main pass // R_BindAnimatedImage( mTexBundle ); GL_State(mGLStateBits); // // set arrays and lock // qglTexCoordPointer( 2, GL_FLOAT, 0, mTextureCoords ); qglEnableClientState( GL_TEXTURE_COORD_ARRAY); qglEnableClientState( GL_COLOR_ARRAY); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, mColors ); qglVertexPointer (3, GL_FLOAT, 16, mVerts); if ( qglLockArraysEXT ) { qglLockArraysEXT(0, mNextVert); GLimp_LogComment( "glLockArraysEXT\n" ); } qglDrawArrays(GL_QUADS, 0, mNextVert); backEnd.pc.c_vertexes += mNextVert; backEnd.pc.c_indexes += mNextVert; backEnd.pc.c_totalIndexes += mNextVert; //only for software fog pass (global soft/volumetric) -rww if (mUseFog && (r_drawfog->integer != 2 || mFogIndex != tr.world->globalFog)) { fog_t *fog = tr.world->fogs + mFogIndex; // // render the fog pass // GL_Bind( tr.fogImage ); GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL ); // // set arrays and lock // qglTexCoordPointer( 2, GL_FLOAT, 0, mFogTextureCoords); // qglEnableClientState( GL_TEXTURE_COORD_ARRAY); // Done above qglDisableClientState( GL_COLOR_ARRAY ); qglColor4ubv((GLubyte *)&fog->colorInt); // qglVertexPointer (3, GL_FLOAT, 16, mVerts); // Done above qglDrawArrays(GL_QUADS, 0, mNextVert); // Second pass from fog backEnd.pc.c_totalIndexes += mNextVert; } // // unlock arrays // if (qglUnlockArraysEXT) { qglUnlockArraysEXT(); GLimp_LogComment( "glUnlockArraysEXT\n" ); } mNextVert=0; }
void RB_StageIteratorLightmappedMultitexture( void ) { shaderCommands_t *input; shader_t *shader; input = &tess; shader = input->shader; // // 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( 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_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( 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" ); } }
/* ** RB_StageIteratorGeneric */ void RB_StageIteratorGeneric( void ) { shaderCommands_t *input; shader_t *shader; input = &tess; shader = input->shader; 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( shader->cullType ); // set polygon offset if necessary if ( 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 || 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 ( shader->polygonOffset ) { qglDisable( GL_POLYGON_OFFSET_FILL ); } }
/* ================ DrawTris Draws triangle outlines for debugging ================ */ static void DrawTris( shaderCommands_t *input ) { char *s = r_trisColor->string; vec4_t trisColor = { 1, 1, 1, 1 }; unsigned int stateBits = 0; GL_Bind( tr.whiteImage ); if ( *s == '0' && ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) { s += 2; if ( Q_IsHexColorString( s ) ) { trisColor[0] = ( (float)( gethex( *( s ) ) * 16 + gethex( *( s + 1 ) ) ) ) / 255.00; trisColor[1] = ( (float)( gethex( *( s + 2 ) ) * 16 + gethex( *( s + 3 ) ) ) ) / 255.00; trisColor[2] = ( (float)( gethex( *( s + 4 ) ) * 16 + gethex( *( s + 5 ) ) ) ) / 255.00; if ( Q_HexColorStringHasAlpha( s ) ) { trisColor[3] = ( (float)( gethex( *( s + 6 ) ) * 16 + gethex( *( s + 7 ) ) ) ) / 255.00; } } } else { int i; char *token; for ( i = 0 ; i < 4 ; i++ ) { token = COM_Parse( &s ); if ( token ) { trisColor[i] = atof( token ); } else { trisColor[i] = 1.f; } } if ( !trisColor[3] ) { trisColor[3] = 1.f; } } if ( trisColor[3] < 1.f ) { stateBits |= ( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); } qglColor4fv( trisColor ); // ydnar r_showtris 2 if ( r_showtris->integer == 2 ) { stateBits |= ( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); GL_State( stateBits ); qglDepthRange( 0, 0 ); } #ifdef CELSHADING_HACK else if ( r_showtris->integer == 3 ) { stateBits |= ( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); GL_State( stateBits ); qglEnable( GL_POLYGON_OFFSET_LINE ); qglPolygonOffset( 4.0, 0.5 ); qglLineWidth( 5.0 ); } #endif else { stateBits |= ( GLS_POLYMODE_LINE ); GL_State( stateBits ); qglEnable( GL_POLYGON_OFFSET_LINE ); qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); } qglDisableClientState( GL_COLOR_ARRAY ); qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); qglVertexPointer( 3, GL_FLOAT, 16, input->xyz ); // padded for SIMD if ( qglLockArraysEXT ) { qglLockArraysEXT( 0, input->numVertexes ); GLimp_LogComment( "glLockArraysEXT\n" ); } R_DrawElements( input->numIndexes, input->indexes ); if ( qglUnlockArraysEXT ) { qglUnlockArraysEXT(); GLimp_LogComment( "glUnlockArraysEXT\n" ); } qglDepthRange( 0, 1 ); qglDisable( GL_POLYGON_OFFSET_LINE ); }
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 GL fog SetIteratorFog(); // // 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, 8, tess.texCoords0 ); // // configure second stage // GL_SelectTexture( 1 ); qglEnable( GL_TEXTURE_2D ); if ( r_lightmap->integer ) { GL_TexEnv( GL_REPLACE ); } else { GL_TexEnv( GL_MODULATE ); } //----(SA) modified for snooper if ( tess.xstages[0]->bundle[1].isLightmap && ( backEnd.refdef.rdflags & RDF_SNOOPERVIEW ) ) { GL_Bind( tr.whiteImage ); } else { R_BindAnimatedImage( &tess.xstages[0]->bundle[1] ); } qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); qglTexCoordPointer( 2, GL_FLOAT, 8, tess.texCoords1 ); // // 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 ) if ( tess.dlightBits && tess.shader->fogPass && !( tess.shader->surfaceFlags & ( SURF_NODLIGHT | SURF_SKY ) ) ) { if ( r_dynamiclight->integer == 2 ) { DynamicLightPass(); } else { DynamicLightSinglePass(); } } // // now do fog // if ( tess.fogNum && tess.shader->fogPass ) { RB_FogPass(); } // // unlock arrays // if ( qglUnlockArraysEXT ) { qglUnlockArraysEXT(); GLimp_LogComment( "glUnlockArraysEXT\n" ); } }
void CQuickSpriteSystem::Flush(void) { if (mNextVert==0) { return; } // // render the main pass // R_BindAnimatedImage( mTexBundle ); GL_State(mGLStateBits); // // set arrays and lock // qglTexCoordPointer( 2, GL_FLOAT, 0, mTextureCoords ); qglEnableClientState( GL_TEXTURE_COORD_ARRAY); qglEnableClientState( GL_COLOR_ARRAY); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, mColors ); qglVertexPointer (3, GL_FLOAT, 16, mVerts); if ( qglLockArraysEXT ) { qglLockArraysEXT(0, mNextVert); GLimp_LogComment( "glLockArraysEXT\n" ); } qglDrawArrays(GL_QUADS, 0, mNextVert); backEnd.pc.c_vertexes += mNextVert; backEnd.pc.c_indexes += mNextVert; backEnd.pc.c_totalIndexes += mNextVert; if (mUseFog) { // // render the fog pass // GL_Bind( tr.fogImage ); GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL ); // // set arrays and lock // qglTexCoordPointer( 2, GL_FLOAT, 0, mFogTextureCoords); // qglEnableClientState( GL_TEXTURE_COORD_ARRAY); // Done above qglDisableClientState( GL_COLOR_ARRAY ); qglColor4ubv((GLubyte *)&mFogColor); // qglVertexPointer (3, GL_FLOAT, 16, mVerts); // Done above qglDrawArrays(GL_QUADS, 0, mNextVert); // Second pass from fog backEnd.pc.c_totalIndexes += mNextVert; } // // unlock arrays // if (qglUnlockArraysEXT) { qglUnlockArraysEXT(); GLimp_LogComment( "glUnlockArraysEXT\n" ); } mNextVert=0; }
/* ============= GL_DrawAliasFrameLerp interpolates between two frames and origins FIXME: batch lerp all vertexes ============= */ void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp) { float l; daliasframe_t *frame, *oldframe; dtrivertx_t *v, *ov, *verts; int *order; int count; float frontlerp; float alpha; vec3_t move, delta, vectors[3]; vec3_t frontv, backv; int i; int index_xyz; float *lerp; frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames + currententity->frame * paliashdr->framesize); verts = v = frame->verts; oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames + currententity->oldframe * paliashdr->framesize); ov = oldframe->verts; order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds); // glTranslatef (frame->translate[0], frame->translate[1], frame->translate[2]); // glScalef (frame->scale[0], frame->scale[1], frame->scale[2]); if (currententity->flags & RF_TRANSLUCENT) alpha = currententity->alpha; else alpha = 1.0; // PMM - added double shell if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) qglDisable( GL_TEXTURE_2D ); frontlerp = 1.0 - backlerp; // move should be the delta back to the previous frame * backlerp VectorSubtract (currententity->oldorigin, currententity->origin, delta); AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]); move[0] = DotProduct (delta, vectors[0]); // forward move[1] = -DotProduct (delta, vectors[1]); // left move[2] = DotProduct (delta, vectors[2]); // up VectorAdd (move, oldframe->translate, move); for (i=0 ; i<3 ; i++) { move[i] = backlerp*move[i] + frontlerp*frame->translate[i]; } for (i=0 ; i<3 ; i++) { frontv[i] = frontlerp*frame->scale[i]; backv[i] = backlerp*oldframe->scale[i]; } lerp = s_lerped[0]; GL_LerpVerts( paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv ); if ( gl_vertex_arrays->value ) { float colorArray[MAX_VERTS*4]; qglEnableClientState( GL_VERTEX_ARRAY ); qglVertexPointer( 3, GL_FLOAT, 16, s_lerped ); // padded for SIMD // if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) ) // PMM - added double damage shell if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) { qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha ); } else { qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 3, GL_FLOAT, 0, colorArray ); // // pre light everything // for ( i = 0; i < paliashdr->num_xyz; i++ ) { float l = shadedots[verts[i].lightnormalindex]; colorArray[i*3+0] = l * shadelight[0]; colorArray[i*3+1] = l * shadelight[1]; colorArray[i*3+2] = l * shadelight[2]; } } if ( qglLockArraysEXT != 0 ) qglLockArraysEXT( 0, paliashdr->num_xyz ); while (1) { // get the vertex count and primitive type count = *order++; if (!count) break; // done if (count < 0) { count = -count; qglBegin (GL_TRIANGLE_FAN); } else { qglBegin (GL_TRIANGLE_STRIP); } // PMM - added double damage shell if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) { do { index_xyz = order[2]; order += 3; qglVertex3fv( s_lerped[index_xyz] ); } while (--count); } else { do { // texture coordinates come from the draw list qglTexCoord2f (((float *)order)[0], ((float *)order)[1]); index_xyz = order[2]; order += 3; // normals and vertexes come from the frame list // l = shadedots[verts[index_xyz].lightnormalindex]; // qglColor4f (l* shadelight[0], l*shadelight[1], l*shadelight[2], alpha); qglArrayElement( index_xyz ); } while (--count); } qglEnd (); } if ( qglUnlockArraysEXT != 0 ) qglUnlockArraysEXT(); } else { while (1) { // get the vertex count and primitive type count = *order++; if (!count) break; // done if (count < 0) { count = -count; qglBegin (GL_TRIANGLE_FAN); } else { qglBegin (GL_TRIANGLE_STRIP); } if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) ) { do { index_xyz = order[2]; order += 3; qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha); qglVertex3fv (s_lerped[index_xyz]); } while (--count); } else { do { // texture coordinates come from the draw list qglTexCoord2f (((float *)order)[0], ((float *)order)[1]); index_xyz = order[2]; order += 3; // normals and vertexes come from the frame list l = shadedots[verts[index_xyz].lightnormalindex]; qglColor4f (l* shadelight[0], l*shadelight[1], l*shadelight[2], alpha); qglVertex3fv (s_lerped[index_xyz]); } while (--count); } qglEnd (); } } // if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) ) // PMM - added double damage shell if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) qglEnable( GL_TEXTURE_2D ); }
/* * RB_GLSL_StageIteratorGeneric * Stage iterator for GLSL programs */ void RB_GLSL_StageIteratorGeneric(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("--- R_GLSL_StageIteratorGeneric( %s ) ---\n", input->shader->name)); } /* set face culling appropiately */ 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); } /* set vertex color array */ qglEnableClientState(GL_COLOR_ARRAY); qglColorPointer(4, GL_UNSIGNED_BYTE, 0, input->vertexColors); /* set texture coordinate array 0 */ GL_SelectTexture(0); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer(2, GL_FLOAT, 16, input->texCoords[0][0]); /* set texture coordinate array 1 */ GL_SelectTexture(1); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer(2, GL_FLOAT, 16, input->texCoords[0][1]); /* set vertex normal array */ qglEnableClientState(GL_NORMAL_ARRAY); qglNormalPointer(GL_FLOAT, 16, input->normal); /* lock XYZ */ qglVertexPointer(3, GL_FLOAT, 16, input->xyz); /* padded SIMD */ if (qglLockArraysEXT) { qglLockArraysEXT(0, input->numVertexes); GLimp_LogComment("glLockArraysEXT\n"); } RB_GLSL_IterateStagesGeneric(input); /* now do any dynamic lighting needed */ if (input->dlightBits && input->shader->sort <= SS_OPAQUE && !(input->shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY))) ProjectDlightTexture(); // <-- RiO_Outlines: now do outlines RB_OutlinesPass(); // --> /* now do fog */ if (input->fogNum && input->shader->fogPass) RB_FogPass(); // TODO: uses svars which aren't set, so move to program /* unlock arrays */ if (qglUnlockArraysEXT) { qglUnlockArraysEXT(); GLimp_LogComment("glUnlockArraysExt\n"); } /* reset polygon offset */ if (input->shader->polygonOffset) qglDisable(GL_POLYGON_OFFSET_FILL); }
/* * Interpolates between two frames and origins */ void R_DrawAliasFrameLerp ( dmdl_t *paliashdr, float backlerp ) { #if defined(VERTEX_ARRAYS) uint16_t total; GLenum type; #endif float l; daliasframe_t *frame, *oldframe; dtrivertx_t *v, *ov, *verts; int *order; int count; float frontlerp; float alpha; vec3_t move, delta, vectors [ 3 ]; vec3_t frontv, backv; int i; int index_xyz; float *lerp; frame = (daliasframe_t *) ( (byte *) paliashdr + paliashdr->ofs_frames + currententity->frame * paliashdr->framesize ); verts = v = frame->verts; oldframe = (daliasframe_t *) ( (byte *) paliashdr + paliashdr->ofs_frames + currententity->oldframe * paliashdr->framesize ); ov = oldframe->verts; order = (int *) ( (byte *) paliashdr + paliashdr->ofs_glcmds ); if ( currententity->flags & RF_TRANSLUCENT ) { alpha = currententity->alpha; } else { alpha = 1.0; } if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM ) ) { qglDisable( GL_TEXTURE_2D ); } frontlerp = 1.0 - backlerp; /* move should be the delta back to the previous frame * backlerp */ VectorSubtract( currententity->oldorigin, currententity->origin, delta ); AngleVectors( currententity->angles, vectors [ 0 ], vectors [ 1 ], vectors [ 2 ] ); move [ 0 ] = DotProduct( delta, vectors [ 0 ] ); /* forward */ move [ 1 ] = -DotProduct( delta, vectors [ 1 ] ); /* left */ move [ 2 ] = DotProduct( delta, vectors [ 2 ] ); /* up */ VectorAdd( move, oldframe->translate, move ); for ( i = 0; i < 3; i++ ) { move [ i ] = backlerp * move [ i ] + frontlerp * frame->translate [ i ]; } for ( i = 0; i < 3; i++ ) { frontv [ i ] = frontlerp * frame->scale [ i ]; backv [ i ] = backlerp * oldframe->scale [ i ]; } lerp = s_lerped [ 0 ]; R_LerpVerts( paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv ); if ( gl_vertex_arrays->value ) { float colorArray [ MAX_VERTS * 4 ]; qglEnableClientState( GL_VERTEX_ARRAY ); qglVertexPointer( 3, GL_FLOAT, 16, s_lerped ); if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM ) ) { qglColor4f( shadelight [ 0 ], shadelight [ 1 ], shadelight [ 2 ], alpha ); } else { qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 3, GL_FLOAT, 0, colorArray ); /* pre light everything */ for ( i = 0; i < paliashdr->num_xyz; i++ ) { float l = shadedots [ verts [ i ].lightnormalindex ]; colorArray [ i * 3 + 0 ] = l * shadelight [ 0 ]; colorArray [ i * 3 + 1 ] = l * shadelight [ 1 ]; colorArray [ i * 3 + 2 ] = l * shadelight [ 2 ]; } } #if !defined(VERTEX_ARRAYS) if ( qglLockArraysEXT != 0 ) { qglLockArraysEXT( 0, paliashdr->num_xyz ); } #endif while ( 1 ) { /* get the vertex count and primitive type */ count = *order++; if ( !count ) { break; /* done */ } if ( count < 0 ) { count = -count; #if defined(VERTEX_ARRAYS) type = GL_TRIANGLE_FAN; #else qglBegin( GL_TRIANGLE_FAN ); #endif } else { #if defined(VERTEX_ARRAYS) type = GL_TRIANGLE_STRIP; #else qglBegin( GL_TRIANGLE_STRIP ); #endif } #if defined(VERTEX_ARRAYS) total = count; GLfloat vtx[3*total]; GLfloat tex[2*total]; uint32_t index_vtx = 0; uint32_t index_tex = 0; #endif if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM ) ) { do { index_xyz = order [ 2 ]; order += 3; #if defined(VERTEX_ARRAYS) vtx[index_vtx++] = s_lerped [ index_xyz ][0]; vtx[index_vtx++] = s_lerped [ index_xyz ][1]; vtx[index_vtx++] = s_lerped [ index_xyz ][2]; #else qglVertex3fv( s_lerped [ index_xyz ] ); #endif } while ( --count ); } else { do { #if defined(VERTEX_ARRAYS) tex[index_tex++] = ( (float *) order ) [ 0 ]; tex[index_tex++] = ( (float *) order ) [ 1 ]; index_xyz = order [ 2 ]; order += 3; #else /* texture coordinates come from the draw list */ qglTexCoord2f( ( (float *) order ) [ 0 ], ( (float *) order ) [ 1 ] ); index_xyz = order [ 2 ]; order += 3; qglArrayElement( index_xyz ); #endif } while ( --count ); } #if defined(VERTEX_ARRAYS) qglEnableClientState( GL_VERTEX_ARRAY ); qglVertexPointer( 3, GL_FLOAT, 0, vtx ); qglDrawArrays( type, 0, total ); qglDisableClientState( GL_VERTEX_ARRAY ); #else qglEnd(); #endif } #if !defined(VERTEX_ARRAYS) if ( qglUnlockArraysEXT != 0 ) { qglUnlockArraysEXT(); } #endif } else { while ( 1 ) { /* get the vertex count and primitive type */ count = *order++; if ( !count ) { break; /* done */ } if ( count < 0 ) { count = -count; #if defined(VERTEX_ARRAYS) type = GL_TRIANGLE_FAN; #else qglBegin( GL_TRIANGLE_FAN ); #endif } else { #if defined(VERTEX_ARRAYS) type = GL_TRIANGLE_STRIP; #else qglBegin( GL_TRIANGLE_STRIP ); #endif } #if defined(VERTEX_ARRAYS) total = count; GLfloat vtx[3*total]; GLfloat tex[2*total]; GLfloat clr[4*total]; uint32_t index_vtx = 0; uint32_t index_tex = 0; uint32_t index_clr = 0; #endif if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) ) { do { index_xyz = order [ 2 ]; order += 3; #if defined(VERTEX_ARRAYS) clr[index_clr++] = shadelight [ 0 ]; clr[index_clr++] = shadelight [ 1 ]; clr[index_clr++] = shadelight [ 2 ]; clr[index_clr++] = alpha; vtx[index_vtx++] = s_lerped [ index_xyz ][ 0 ]; vtx[index_vtx++] = s_lerped [ index_xyz ][ 1 ]; vtx[index_vtx++] = s_lerped [ index_xyz ][ 2 ]; #else qglColor4f( shadelight [ 0 ], shadelight [ 1 ], shadelight [ 2 ], alpha ); qglVertex3fv( s_lerped [ index_xyz ] ); #endif } while ( --count ); } else { do { /* texture coordinates come from the draw list */ #if defined(VERTEX_ARRAYS) tex[index_tex++] = ( (float *) order ) [ 0 ]; tex[index_tex++] = ( (float *) order ) [ 1 ]; #else qglTexCoord2f( ( (float *) order ) [ 0 ], ( (float *) order ) [ 1 ] ); #endif index_xyz = order [ 2 ]; order += 3; /* normals and vertexes come from the frame list */ l = shadedots [ verts [ index_xyz ].lightnormalindex ]; #if defined(VERTEX_ARRAYS) clr[index_clr++] = l * shadelight [ 0 ]; clr[index_clr++] = l * shadelight [ 1 ]; clr[index_clr++] = l * shadelight [ 2 ]; clr[index_clr++] = alpha; vtx[index_vtx++] = s_lerped [ index_xyz ][ 0 ]; vtx[index_vtx++] = s_lerped [ index_xyz ][ 1 ]; vtx[index_vtx++] = s_lerped [ index_xyz ][ 2 ]; #else qglColor4f( l * shadelight [ 0 ], l * shadelight [ 1 ], l * shadelight [ 2 ], alpha ); qglVertex3fv( s_lerped [ index_xyz ] ); #endif } while ( --count ); } #if defined(VERTEX_ARRAYS) qglEnableClientState( GL_VERTEX_ARRAY ); qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); qglEnableClientState( GL_COLOR_ARRAY ); qglVertexPointer( 3, GL_FLOAT, 0, vtx ); qglTexCoordPointer( 2, GL_FLOAT, 0, tex ); qglColorPointer( 4, GL_FLOAT, 0, clr ); qglDrawArrays( type, 0, total ); qglDisableClientState( GL_VERTEX_ARRAY ); qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); qglDisableClientState( GL_COLOR_ARRAY ); #else qglEnd(); #endif } } if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM ) ) { qglEnable( GL_TEXTURE_2D ); } }
/* =================== ProjectDlightTexture Perform dynamic lighting with another rendering pass =================== */ static void ProjectDlightTexture2( void ) { int i, l; vec3_t origin; byte clipBits[SHADER_MAX_VERTEXES]; float texCoordsArray[SHADER_MAX_VERTEXES][2]; float oldTexCoordsArray[SHADER_MAX_VERTEXES][2]; float vertCoordsArray[SHADER_MAX_VERTEXES][4]; unsigned int colorArray[SHADER_MAX_VERTEXES]; glIndex_t hitIndexes[SHADER_MAX_INDEXES]; int numIndexes; float radius; int fogging; shaderStage_t *dStage; vec3_t posa; vec3_t posb; vec3_t posc; vec3_t dist; vec3_t e1; vec3_t e2; vec3_t normal; float fac,modulate; vec3_t floatColor; byte colorTemp[4]; int needResetVerts=0; if ( !backEnd.refdef.num_dlights ) { return; } for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) { dlight_t *dl; if ( !( tess.dlightBits & ( 1 << l ) ) ) { continue; // this surface definately doesn't have any of this light } dl = &backEnd.refdef.dlights[l]; VectorCopy( dl->transformed, origin ); radius = dl->radius; int clipall = 63; for ( i = 0 ; i < tess.numVertexes ; i++) { int clip; VectorSubtract( origin, tess.xyz[i], dist ); clip = 0; if ( dist[0] < -radius ) { clip |= 1; } else if ( dist[0] > radius ) { clip |= 2; } if ( dist[1] < -radius ) { clip |= 4; } else if ( dist[1] > radius ) { clip |= 8; } if ( dist[2] < -radius ) { clip |= 16; } else if ( dist[2] > radius ) { clip |= 32; } clipBits[i] = clip; clipall &= clip; } if ( clipall ) { continue; // this surface doesn't have any of this light } floatColor[0] = dl->color[0] * 255.0f; floatColor[1] = dl->color[1] * 255.0f; floatColor[2] = dl->color[2] * 255.0f; // build a list of triangles that need light numIndexes = 0; for ( i = 0 ; i < tess.numIndexes ; i += 3 ) { int a, b, c; a = tess.indexes[i]; b = tess.indexes[i+1]; c = tess.indexes[i+2]; if ( clipBits[a] & clipBits[b] & clipBits[c] ) { continue; // not lighted } // copy the vertex positions VectorCopy(tess.xyz[a],posa); VectorCopy(tess.xyz[b],posb); VectorCopy(tess.xyz[c],posc); VectorSubtract( posa, posb,e1); VectorSubtract( posc, posb,e2); CrossProduct(e1,e2,normal); // rjr - removed for hacking if ( (!r_dlightBacks->integer && DotProduct(normal,origin)-DotProduct(normal,posa) <= 0.0f) || // backface if ( DotProduct(normal,origin)-DotProduct(normal,posa) <= 0.0f || // backface DotProduct(normal,normal) < 1E-8f) // junk triangle { continue; } VectorNormalize(normal); fac=DotProduct(normal,origin)-DotProduct(normal,posa); if (fac >= radius) // out of range { continue; } modulate = 1.0f-((fac*fac) / (radius*radius)); fac = 0.5f/sqrtf(radius*radius - fac*fac); // save the verts VectorCopy(posa,vertCoordsArray[numIndexes]); VectorCopy(posb,vertCoordsArray[numIndexes+1]); VectorCopy(posc,vertCoordsArray[numIndexes+2]); // now we need e1 and e2 to be an orthonormal basis if (DotProduct(e1,e1) > DotProduct(e2,e2)) { VectorNormalize(e1); CrossProduct(e1,normal,e2); } else { VectorNormalize(e2); CrossProduct(normal,e2,e1); } VectorScale(e1,fac,e1); VectorScale(e2,fac,e2); VectorSubtract( posa, origin,dist); texCoordsArray[numIndexes][0]=DotProduct(dist,e1)+0.5f; texCoordsArray[numIndexes][1]=DotProduct(dist,e2)+0.5f; VectorSubtract( posb, origin,dist); texCoordsArray[numIndexes+1][0]=DotProduct(dist,e1)+0.5f; texCoordsArray[numIndexes+1][1]=DotProduct(dist,e2)+0.5f; VectorSubtract( posc, origin,dist); texCoordsArray[numIndexes+2][0]=DotProduct(dist,e1)+0.5f; texCoordsArray[numIndexes+2][1]=DotProduct(dist,e2)+0.5f; if ((texCoordsArray[numIndexes][0] < 0.0f && texCoordsArray[numIndexes+1][0] < 0.0f && texCoordsArray[numIndexes+2][0] < 0.0f) || (texCoordsArray[numIndexes][0] > 1.0f && texCoordsArray[numIndexes+1][0] > 1.0f && texCoordsArray[numIndexes+2][0] > 1.0f) || (texCoordsArray[numIndexes][1] < 0.0f && texCoordsArray[numIndexes+1][1] < 0.0f && texCoordsArray[numIndexes+2][1] < 0.0f) || (texCoordsArray[numIndexes][1] > 1.0f && texCoordsArray[numIndexes+1][1] > 1.0f && texCoordsArray[numIndexes+2][1] > 1.0f) ) { continue; // didn't end up hitting this tri } /* old code, get from the svars = wrong oldTexCoordsArray[numIndexes][0]=tess.svars.texcoords[0][a][0]; oldTexCoordsArray[numIndexes][1]=tess.svars.texcoords[0][a][1]; oldTexCoordsArray[numIndexes+1][0]=tess.svars.texcoords[0][b][0]; oldTexCoordsArray[numIndexes+1][1]=tess.svars.texcoords[0][b][1]; oldTexCoordsArray[numIndexes+2][0]=tess.svars.texcoords[0][c][0]; oldTexCoordsArray[numIndexes+2][1]=tess.svars.texcoords[0][c][1]; */ oldTexCoordsArray[numIndexes][0]=tess.texCoords[a][0][0]; oldTexCoordsArray[numIndexes][1]=tess.texCoords[a][0][1]; oldTexCoordsArray[numIndexes+1][0]=tess.texCoords[b][0][0]; oldTexCoordsArray[numIndexes+1][1]=tess.texCoords[b][0][1]; oldTexCoordsArray[numIndexes+2][0]=tess.texCoords[c][0][0]; oldTexCoordsArray[numIndexes+2][1]=tess.texCoords[c][0][1]; colorTemp[0] = Q_ftol(floatColor[0] * modulate); colorTemp[1] = Q_ftol(floatColor[1] * modulate); colorTemp[2] = Q_ftol(floatColor[2] * modulate); colorTemp[3] = 255; byteAlias_t *ba = (byteAlias_t *)&colorTemp; colorArray[numIndexes + 0] = ba->ui; colorArray[numIndexes + 1] = ba->ui; colorArray[numIndexes + 2] = ba->ui; hitIndexes[numIndexes] = numIndexes; hitIndexes[numIndexes+1] = numIndexes+1; hitIndexes[numIndexes+2] = numIndexes+2; numIndexes += 3; if (numIndexes>=SHADER_MAX_VERTEXES-3) { break; // we are out of space, so we are done :) } } if ( !numIndexes ) { continue; } //don't have fog enabled when we redraw with alpha test, or it will double over //and screw the tri up -rww if (r_drawfog->value == 2 && tr.world && (tess.fogNum == tr.world->globalFog || tess.fogNum == tr.world->numfogs)) { fogging = qglIsEnabled(GL_FOG); if (fogging) { qglDisable(GL_FOG); } } else { fogging = 0; } dStage = NULL; if (tess.shader && qglActiveTextureARB) { int i = 0; while (i < tess.shader->numUnfoggedPasses) { const int blendBits = (GLS_SRCBLEND_BITS+GLS_DSTBLEND_BITS); if (((tess.shader->stages[i].bundle[0].image && !tess.shader->stages[i].bundle[0].isLightmap && !tess.shader->stages[i].bundle[0].numTexMods && tess.shader->stages[i].bundle[0].tcGen != TCGEN_ENVIRONMENT_MAPPED && tess.shader->stages[i].bundle[0].tcGen != TCGEN_FOG) || (tess.shader->stages[i].bundle[1].image && !tess.shader->stages[i].bundle[1].isLightmap && !tess.shader->stages[i].bundle[1].numTexMods && tess.shader->stages[i].bundle[1].tcGen != TCGEN_ENVIRONMENT_MAPPED && tess.shader->stages[i].bundle[1].tcGen != TCGEN_FOG)) && (tess.shader->stages[i].stateBits & blendBits) == 0 ) { //only use non-lightmap opaque stages dStage = &tess.shader->stages[i]; break; } i++; } } if (!needResetVerts) { needResetVerts=1; if (qglUnlockArraysEXT) { qglUnlockArraysEXT(); GLimp_LogComment( "glUnlockArraysEXT\n" ); } } qglVertexPointer (3, GL_FLOAT, 16, vertCoordsArray); // padded for SIMD if (dStage) { GL_SelectTexture( 0 ); GL_State(0); qglTexCoordPointer( 2, GL_FLOAT, 0, oldTexCoordsArray[0] ); if (dStage->bundle[0].image && !dStage->bundle[0].isLightmap && !dStage->bundle[0].numTexMods && dStage->bundle[0].tcGen != TCGEN_ENVIRONMENT_MAPPED && dStage->bundle[0].tcGen != TCGEN_FOG) { R_BindAnimatedImage( &dStage->bundle[0] ); } else { R_BindAnimatedImage( &dStage->bundle[1] ); } GL_SelectTexture( 1 ); qglEnable( GL_TEXTURE_2D ); qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] ); qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray ); GL_Bind( tr.dlightImage ); GL_TexEnv( GL_MODULATE ); GL_State(GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL);// | GLS_ATEST_GT_0); R_DrawElements( numIndexes, hitIndexes ); qglDisable( GL_TEXTURE_2D ); GL_SelectTexture(0); } else { qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] ); qglEnableClientState( GL_COLOR_ARRAY ); qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray ); GL_Bind( tr.dlightImage ); // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light // where they aren't rendered if ( dl->additive ) { GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); } else { GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); } R_DrawElements( numIndexes, hitIndexes ); } if (fogging) { qglEnable(GL_FOG); } backEnd.pc.c_totalIndexes += numIndexes; backEnd.pc.c_dlightIndexes += numIndexes; } if (needResetVerts) { qglVertexPointer (3, GL_FLOAT, 16, tess.xyz); // padded for SIMD if (qglLockArraysEXT) { qglLockArraysEXT(0, tess.numVertexes); GLimp_LogComment( "glLockArraysEXT\n" ); } } }
void R_DrawSkyBox (void) { int i; float skyM[16]; vec_t *v, *st; if (skyrotate) { // check for no sky at all for (i = 0; i < 6; i++) { if (skymins[0][i] < skymaxs[0][i] && skymins[1][i] < skymaxs[1][i]) break; } if (i == 6) return; // nothing visible R_RotateMatrix(skyM, r_WorldViewMatrix, r_newrefdef.time * skyrotate, skyaxis[0], skyaxis[1], skyaxis[2]); } else { skyM[0] = r_WorldViewMatrix[0]; skyM[1] = r_WorldViewMatrix[1]; skyM[2] = r_WorldViewMatrix[2]; skyM[4] = r_WorldViewMatrix[4]; skyM[5] = r_WorldViewMatrix[5]; skyM[6] = r_WorldViewMatrix[6]; skyM[8] = r_WorldViewMatrix[8]; skyM[9] = r_WorldViewMatrix[9]; skyM[10] = r_WorldViewMatrix[10]; skyM[3] = skyM[7] = skyM[11] = skyM[12] = skyM[13] = skyM[14] = 0.0f; skyM[15] = 1.0f; } qglLoadMatrixf( skyM ); qglTexCoordPointer( 2, GL_FLOAT, 0, r_arrays.tcoords ); for (i = 0; i < 6; i++) { if (skyrotate) { // hack, forces full sky to draw when rotating skymins[0][i] = skymins[1][i] = -1; skymaxs[0][i] = skymaxs[1][i] = 1; } else if (skymins[0][i] >= skymaxs[0][i] || skymins[1][i] >= skymaxs[1][i]) continue; GL_Bind (sky_images[skytexorder[i]]->texnum); st = r_arrays.tcoords[0]; v = r_arrays.vertices; MakeSkyVec (skymins[0][i], skymins[1][i], i, v, st); MakeSkyVec (skymins[0][i], skymaxs[1][i], i, v+=3, st+=2); MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i, v+=3, st+=2); MakeSkyVec (skymaxs[0][i], skymins[1][i], i, v+=3, st+=2); if(gl_state.compiledVertexArray) { qglLockArraysEXT( 0, 4 ); qglDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, r_arrays.indices ); qglUnlockArraysEXT (); } else { qglDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, r_arrays.indices ); } } qglLoadMatrixf(r_WorldViewMatrix); }
/* ** 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 GL fog SetIteratorFog(); if ( qglPNTrianglesiATI && tess.ATI_tess ) { // RF< so we can send the normals as an array qglEnableClientState( GL_NORMAL_ARRAY ); #ifdef __MACOS__ //DAJ ATI qglPNTrianglesiATI( GL_PN_TRIANGLES_ATI, 1 ); #else qglEnable( GL_PN_TRIANGLES_ATI ); // ATI PN-Triangles extension #endif } // // 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] ); } // RF, send normals only if required // This must be done first, since we can't change the arrays once they have been // locked if ( qglPNTrianglesiATI && tess.ATI_tess ) { qglNormalPointer( GL_FLOAT, 16, input->normal ); } // // 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 ); } // turn truform back off if ( qglPNTrianglesiATI && tess.ATI_tess ) { #ifdef __MACOS__ //DAJ ATI qglPNTrianglesiATI( GL_PN_TRIANGLES_ATI, 0 ); #else qglDisable( GL_PN_TRIANGLES_ATI ); // ATI PN-Triangles extension #endif qglDisableClientState( GL_NORMAL_ARRAY ); } }