/* ============ FBO_Bind ============ */ void FBO_Bind(FBO_t * fbo) { if (glState.currentFBO == fbo) return; if (r_logFile->integer) { // don't just call LogComment, or we will get a call to va() every frame! if (fbo) GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo->name)); else GLimp_LogComment("--- FBO_Bind ( NULL ) ---\n"); } if (!fbo) { qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); //qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glState.currentFBO = NULL; return; } qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->frameBuffer); /* if(fbo->colorBuffers[0]) { qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->colorBuffers[0]); } */ /* if(fbo->depthBuffer) { qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->depthBuffer); qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->depthBuffer); } */ glState.currentFBO = fbo; }
/* =================== RB_EndSurface =================== */ void RB_EndSurface(void) { shaderCommands_t *input = &tess; if (input->numIndexes == 0) { return; } if (input->indexes[input->maxShaderIndicies - 1] != 0) { ri.Error(ERR_DROP, "RB_EndSurface() - input->maxShaderIndicies(%i) hit", input->maxShaderIndicies); } if (input->xyz[input->maxShaderVerts - 1].v[0] != 0) { ri.Error(ERR_DROP, "RB_EndSurface() - input->maxShaderVerts(%i) hit", input->maxShaderVerts); } 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"); }
/* ============ R_BindNullIBO ============ */ void R_BindNullIBO() { GLimp_LogComment( "--- R_BindNullIBO ---\n" ); if ( glState.currentIBO ) { glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glState.currentIBO = nullptr; glState.vertexAttribPointersSet = 0; } }
/* ============ R_BindNullIBO ============ */ void R_BindNullIBO(void) { GLimp_LogComment("--- R_BindNullIBO ---\n"); if(glState.currentIBO) { qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); glState.currentIBO = NULL; glState.vertexAttribPointersSet = 0; } }
/* ============ R_BindNullVBO ============ */ void R_BindNullVBO() { GLimp_LogComment( "--- R_BindNullVBO ---\n" ); if ( glState.currentVBO ) { glBindBuffer( GL_ARRAY_BUFFER, 0 ); glState.currentVBO = nullptr; } GL_CheckErrors(); }
/* ============= RB_SwapBuffers ============= */ const void *RB_SwapBuffers( const void *data ) { const swapBuffersCommand_t *cmd; // finish any 2D drawing if needed if ( tess.numIndexes ) { RB_EndSurface(); } // texture swapping test if ( r_showImages->integer ) { RB_ShowImages(); } cmd = (const swapBuffersCommand_t *)data; // we measure overdraw by reading back the stencil buffer and // counting up the number of increments that have happened #ifndef USE_OPENGLES if ( r_measureOverdraw->integer ) { int i; long sum = 0; unsigned char *stencilReadback; stencilReadback = ri.Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight ); qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) { sum += stencilReadback[i]; } backEnd.pc.c_overDraw += sum; ri.Hunk_FreeTempMemory( stencilReadback ); } #endif if ( !glState.finishCalled ) { qglFinish(); } GLimp_LogComment( "***************** RB_SwapBuffers *****************\n\n\n" ); GLimp_EndFrame(); backEnd.projection2D = qfalse; #ifdef USE_BLOOM backEnd.doneBloom = qfalse; backEnd.doneSurfaces = qfalse; #endif return (const void *)( cmd + 1 ); }
/* ============ R_BindNullVBO ============ */ void R_BindNullVBO(void) { GLimp_LogComment("--- R_BindNullVBO ---\n"); if(glState.currentVBO) { qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glState.currentVBO = NULL; } GL_CheckErrors(); }
/* ** GL_SelectTexture */ void GL_SelectTexture( int unit ) { if ( glState.currenttmu == unit ) { return; } if ( unit == 0 ) { qglActiveTextureARB( GL_TEXTURE0_ARB ); GLimp_LogComment( "glActiveTextureARB( GL_TEXTURE0_ARB )\n" ); qglClientActiveTextureARB( GL_TEXTURE0_ARB ); GLimp_LogComment( "glClientActiveTextureARB( GL_TEXTURE0_ARB )\n" ); } else if ( unit == 1 ) { qglActiveTextureARB( GL_TEXTURE1_ARB ); GLimp_LogComment( "glActiveTextureARB( GL_TEXTURE1_ARB )\n" ); qglClientActiveTextureARB( GL_TEXTURE1_ARB ); GLimp_LogComment( "glClientActiveTextureARB( GL_TEXTURE1_ARB )\n" ); } else { ri.Error( ERR_DROP, "GL_SelectTexture: unit = %i", unit ); } glState.currenttmu = unit; }
/* ============== Tess_InstantQuad ============== */ void Tess_InstantQuad( vec4_t quadVerts[ 4 ] ) { GLimp_LogComment( "--- Tess_InstantQuad ---\n" ); tess.multiDrawPrimitives = 0; tess.numVertexes = 0; tess.numIndexes = 0; tess.attribsSet = 0; Tess_MapVBOs( false ); VectorCopy( quadVerts[ 0 ], tess.verts[ tess.numVertexes ].xyz ); Vector4Set( tess.verts[ tess.numVertexes ].color, 255, 255, 255, 255 ); tess.verts[ tess.numVertexes ].texCoords[ 0 ] = floatToHalf( 0.0f ); tess.verts[ tess.numVertexes ].texCoords[ 1 ] = floatToHalf( 0.0f ); tess.numVertexes++; VectorCopy( quadVerts[ 1 ], tess.verts[ tess.numVertexes ].xyz ); Vector4Set( tess.verts[ tess.numVertexes ].color, 255, 255, 255, 255 ); tess.verts[ tess.numVertexes ].texCoords[ 0 ] = floatToHalf( 1.0f ); tess.verts[ tess.numVertexes ].texCoords[ 1 ] = floatToHalf( 0.0f ); tess.numVertexes++; VectorCopy( quadVerts[ 2 ], tess.verts[ tess.numVertexes ].xyz ); Vector4Set( tess.verts[ tess.numVertexes ].color, 255, 255, 255, 255 ); tess.verts[ tess.numVertexes ].texCoords[ 0 ] = floatToHalf( 1.0f ); tess.verts[ tess.numVertexes ].texCoords[ 1 ] = floatToHalf( 1.0f ); tess.numVertexes++; VectorCopy( quadVerts[ 3 ], tess.verts[ tess.numVertexes ].xyz ); Vector4Set( tess.verts[ tess.numVertexes ].color, 255, 255, 255, 255 ); tess.verts[ tess.numVertexes ].texCoords[ 0 ] = floatToHalf( 0.0f ); tess.verts[ tess.numVertexes ].texCoords[ 1 ] = floatToHalf( 1.0f ); tess.numVertexes++; tess.indexes[ tess.numIndexes++ ] = 0; tess.indexes[ tess.numIndexes++ ] = 1; tess.indexes[ tess.numIndexes++ ] = 2; tess.indexes[ tess.numIndexes++ ] = 0; tess.indexes[ tess.numIndexes++ ] = 2; tess.indexes[ tess.numIndexes++ ] = 3; Tess_UpdateVBOs( ); GL_VertexAttribsState( ATTR_POSITION | ATTR_TEXCOORD | ATTR_COLOR ); Tess_DrawElements(); tess.multiDrawPrimitives = 0; tess.numVertexes = 0; tess.numIndexes = 0; tess.attribsSet = 0; GL_CheckErrors(); }
void GLSL_BindNullProgram(void) { if(r_logFile->integer) { GLimp_LogComment("--- GL_BindNullProgram ---\n"); } if(glState.currentProgram) { qglUseProgramObjectARB(0); glState.currentProgram = NULL; } }
/* ==================== Tess_SurfaceEntity Entities that have a single procedurally generated surface ==================== */ static void Tess_SurfaceEntity( surfaceType_t* ) { GLimp_LogComment( "--- Tess_SurfaceEntity ---\n" ); switch ( backEnd.currentEntity->e.reType ) { case RT_SPRITE: Tess_SurfaceSprite(); break; default: break; } }
void GLSL_BindProgram(shaderProgram_t * program) { GLuint programObject = program ? program->program : 0; char *name = program ? program->name : "NULL"; if(r_logFile->integer) { // don't just call LogComment, or we will get a call to va() every frame! GLimp_LogComment(va("--- GLSL_BindProgram( %s ) ---\n", name)); } if (GL_UseProgramObject(programObject)) backEnd.pc.c_glslShaderBinds++; }
/* ============ FBO_Bind ============ */ void FBO_Bind(FBO_t * fbo) { if (glState.currentFBO == fbo) return; if (r_logFile->integer) { // don't just call LogComment, or we will get a call to va() every frame! GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo ? fbo->name : "NULL")); } GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, fbo ? fbo->frameBuffer : 0); glState.currentFBO = fbo; }
/* ============ R_BindNullFBO ============ */ void R_BindNullFBO( void ) { if ( r_logFile->integer ) { GLimp_LogComment( "--- R_BindNullFBO ---\n" ); } if ( glState.currentFBO ) { glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 ); glState.currentFBO = NULL; } }
/* ============= RB_SetColor ============= */ const void *RB_SetColor( const void *data ) { const setColorCommand_t *cmd; GLimp_LogComment( "--- RB_SetColor ---\n" ); cmd = ( const setColorCommand_t * ) data; backEnd.color2D[ 0 ] = cmd->color[ 0 ]; backEnd.color2D[ 1 ] = cmd->color[ 1 ]; backEnd.color2D[ 2 ] = cmd->color[ 2 ]; backEnd.color2D[ 3 ] = cmd->color[ 3 ]; return ( const void * )( cmd + 1 ); }
void RB_FogOff( void ) { GLimp_LogComment( "--- RB_FogOff() ---\n" ); #if 0 if ( !fogIsOn ) { return; } glDisable( GL_FOG ); fogIsOn = qfalse; #endif }
static void Tess_SurfaceSprite() { vec3_t delta, left, up; float radius; vec4_t color; GLimp_LogComment( "--- Tess_SurfaceSprite ---\n" ); radius = backEnd.currentEntity->e.radius; if( tess.surfaceShader->autoSpriteMode == 1 ) { // the calculations are done in GLSL shader Tess_AddSprite( backEnd.currentEntity->e.origin, backEnd.currentEntity->e.shaderRGBA, radius, backEnd.currentEntity->e.rotation ); return; } VectorSubtract( backEnd.currentEntity->e.origin, backEnd.viewParms.pvsOrigin, delta ); if( VectorNormalize( delta ) < NORMAL_EPSILON ) return; CrossProduct( backEnd.viewParms.orientation.axis[ 2 ], delta, left ); if( VectorNormalize( left ) < NORMAL_EPSILON ) VectorSet( left, 1, 0, 0 ); if( backEnd.currentEntity->e.rotation != 0 ) RotatePointAroundVector( left, delta, left, backEnd.currentEntity->e.rotation ); CrossProduct( delta, left, up ); VectorScale( left, radius, left ); VectorScale( up, radius, up ); if ( backEnd.viewParms.isMirror ) VectorSubtract( vec3_origin, left, left ); color[ 0 ] = backEnd.currentEntity->e.shaderRGBA[ 0 ] * ( 1.0 / 255.0 ); color[ 1 ] = backEnd.currentEntity->e.shaderRGBA[ 1 ] * ( 1.0 / 255.0 ); color[ 2 ] = backEnd.currentEntity->e.shaderRGBA[ 2 ] * ( 1.0 / 255.0 ); color[ 3 ] = backEnd.currentEntity->e.shaderRGBA[ 3 ] * ( 1.0 / 255.0 ); Tess_AddQuadStamp( backEnd.currentEntity->e.origin, left, up, color ); }
void RB_FogOn() { GLimp_LogComment("--- RB_FogOn() ---\n"); #if 1 if(fogIsOn) { return; } // if(r_uiFullScreen->integer) { // don't fog in the menu // R_FogOff(); // return; // } if(!r_wolfFog->integer) { return; } // if(backEnd.viewParms.isGLFogged) { // if(!(backEnd.viewParms.glFog.registered)) // return; // } if(backEnd.refdef.rdflags & RDF_SKYBOXPORTAL) { // don't force world fog on portal sky if(!(tr.glfogsettings[FOG_PORTALVIEW].registered)) { return; } } else if(!tr.glfogNum) { return; } #if defined(USE_D3D10) // TODO #else glEnable(GL_FOG); #endif fogIsOn = qtrue; #endif }
/* ============ R_BindVao ============ */ void R_BindVao(vao_t * vao) { if(!vao) { //R_BindNullVao(); ri.Error(ERR_DROP, "R_BindVao: NULL vao"); return; } if(r_logFile->integer) { // don't just call LogComment, or we will get a call to va() every frame! GLimp_LogComment(va("--- R_BindVao( %s ) ---\n", vao->name)); } if(glState.currentVao != vao) { glState.currentVao = vao; glState.vertexAttribsInterpolation = 0; glState.vertexAnimation = qfalse; backEnd.pc.c_vaoBinds++; if (glRefConfig.vertexArrayObject) { qglBindVertexArray(vao->vao); // why you no save GL_ELEMENT_ARRAY_BUFFER binding, Intel? if (1) qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO); // tess VAO always has buffers bound if (vao == tess.vao) qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO); } else { qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO); qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO); // tess VAO doesn't have vertex pointers set until data is uploaded if (vao != tess.vao) Vao_SetVertexPointers(vao); } } }
/* ============= RB_DrawBuffer ============= */ const void *RB_DrawBuffer( const void *data ) { const drawBufferCommand_t *cmd; GLimp_LogComment( "--- RB_DrawBuffer ---\n" ); cmd = ( const drawBufferCommand_t * ) data; // clear screen for debugging if ( r_clear->integer ) { float ClearColor[ 4 ] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red,green,blue,alpha dx.d3dDevice->ClearRenderTargetView( dx.renderTargetView, ClearColor ); } return ( const void * )( cmd + 1 ); }
const void *RB_SwapBuffers( const void *data ) { const swapBuffersCommand_t *cmd; // finish any 2D drawing if needed if ( tess.numIndexes ) { RB_EndSurface(); } // texture swapping test if ( r_showImages->integer ) { RB_ShowImages(); } cmd = (const swapBuffersCommand_t *)data; // we measure overdraw by reading back the stencil buffer and // counting up the number of increments that have happened if ( r_measureOverdraw->integer ) { int i; long sum = 0; unsigned char *stencilReadback; stencilReadback = (unsigned char *) Z_Malloc( glConfig.vidWidth * glConfig.vidHeight, TAG_TEMP_WORKSPACE, qfalse ); qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, stencilReadback ); for ( i = 0; i < glConfig.vidWidth * glConfig.vidHeight; i++ ) { sum += stencilReadback[i]; } backEnd.pc.c_overDraw += sum; Z_Free( stencilReadback ); } if ( !glState.finishCalled ) { qglFinish(); } GLimp_LogComment( "***************** RB_SwapBuffers *****************\n\n\n" ); GLimp_EndFrame(); backEnd.projection2D = qfalse; return (const void *)(cmd + 1); }
/* ============ R_BindNullFBO ============ */ void R_BindNullFBO(void) { #if defined(USE_D3D10) // TODO #else if(r_logFile->integer) { GLimp_LogComment("--- R_BindNullFBO ---\n"); } if(glState.currentFBO) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glState.currentFBO = NULL; } #endif }
void RB_FogOff() { GLimp_LogComment("--- RB_FogOff() ---\n"); #if 1 if(!fogIsOn) { return; } #if defined(USE_D3D10) // TODO #else glDisable(GL_FOG); #endif fogIsOn = qfalse; #endif }
/* ============== Tess_SurfaceVBOMD5Mesh ============== */ static void Tess_SurfaceVBOMD5Mesh( srfVBOMD5Mesh_t *srf ) { int i; md5Model_t *model; GLimp_LogComment( "--- Tess_SurfaceVBOMD5Mesh ---\n" ); if ( !srf->vbo || !srf->ibo ) { return; } Tess_EndBegin(); R_BindVBO( srf->vbo ); R_BindIBO( srf->ibo ); tess.numIndexes = srf->numIndexes; tess.numVertexes = srf->numVerts; model = srf->md5Model; tess.vboVertexSkinning = true; tess.numBones = srf->numBoneRemap; for ( i = 0; i < srf->numBoneRemap; i++ ) { refBone_t *bone = &backEnd.currentEntity->e.skeleton.bones[ srf->boneRemapInverse[ i ] ]; if ( backEnd.currentEntity->e.skeleton.type == SK_ABSOLUTE ) { TransInitRotationQuat( model->bones[ srf->boneRemapInverse[ i ] ].rotation, &tess.bones[ i ] ); TransAddTranslation( model->bones[ srf->boneRemapInverse[ i ] ].origin, &tess.bones[ i ] ); TransInverse( &tess.bones[ i ], &tess.bones[ i ] ); TransCombine( &tess.bones[ i ], &bone->t, &tess.bones[ i ] ); } else { TransInit( &tess.bones[ i ] ); } TransAddScale( backEnd.currentEntity->e.skeleton.scale, &tess.bones[ i ] ); TransInsScale( model->internalScale, &tess.bones[ i ] ); } Tess_End(); }
/* ============== RB_InstantQuad based on Tess_InstantQuad from xreal ============== */ void RB_InstantQuad2(vec4_t quadVerts[4], vec2_t texCoords[4]) { GLimp_LogComment("--- RB_InstantQuad2 ---\n"); tess.numVertexes = 0; tess.numIndexes = 0; tess.firstIndex = 0; VectorCopy4(quadVerts[0], tess.xyz[tess.numVertexes]); VectorCopy2(texCoords[0], tess.texCoords[tess.numVertexes]); tess.numVertexes++; VectorCopy4(quadVerts[1], tess.xyz[tess.numVertexes]); VectorCopy2(texCoords[1], tess.texCoords[tess.numVertexes]); tess.numVertexes++; VectorCopy4(quadVerts[2], tess.xyz[tess.numVertexes]); VectorCopy2(texCoords[2], tess.texCoords[tess.numVertexes]); tess.numVertexes++; VectorCopy4(quadVerts[3], tess.xyz[tess.numVertexes]); VectorCopy2(texCoords[3], tess.texCoords[tess.numVertexes]); tess.numVertexes++; tess.indexes[tess.numIndexes++] = 0; tess.indexes[tess.numIndexes++] = 1; tess.indexes[tess.numIndexes++] = 2; tess.indexes[tess.numIndexes++] = 0; tess.indexes[tess.numIndexes++] = 2; tess.indexes[tess.numIndexes++] = 3; tess.minIndex = 0; tess.maxIndex = 3; RB_UpdateTessVao(ATTR_POSITION | ATTR_TEXCOORD); R_DrawElementsVao(tess.numIndexes, tess.firstIndex, tess.minIndex, tess.maxIndex); tess.numIndexes = 0; tess.numVertexes = 0; tess.firstIndex = 0; tess.minIndex = 0; tess.maxIndex = 0; }
void Tess_SurfacePolybuffer( srfPolyBuffer_t *surf ) { int i; int numIndexes; int numVertexes; glIndex_t *indices; float *xyzw; float *st; byte *color; GLimp_LogComment( "--- Tess_SurfacePolybuffer ---\n" ); Tess_CheckOverflow( surf->pPolyBuffer->numVerts, surf->pPolyBuffer->numIndicies ); numIndexes = std::min( surf->pPolyBuffer->numIndicies, MAX_PB_INDICIES ); indices = surf->pPolyBuffer->indicies; for ( i = 0; i < numIndexes; i++ ) { tess.indexes[ tess.numIndexes + i ] = tess.numVertexes + indices[ i ]; } tess.numIndexes += numIndexes; numVertexes = std::min( surf->pPolyBuffer->numVerts, MAX_PB_VERTS ); xyzw = &surf->pPolyBuffer->xyz[ 0 ][ 0 ]; st = &surf->pPolyBuffer->st[ 0 ][ 0 ]; color = &surf->pPolyBuffer->color[ 0 ][ 0 ]; for ( i = 0; i < numVertexes; i++, xyzw += 4, st += 2, color += 4 ) { VectorCopy( xyzw, tess.verts[ tess.numVertexes + i ].xyz ); tess.verts[ tess.numVertexes + i ].texCoords[ 0 ] = floatToHalf( st[ 0 ] ); tess.verts[ tess.numVertexes + i ].texCoords[ 1 ] = floatToHalf( st[ 1 ] ); Vector4Copy( color, tess.verts[ tess.numVertexes + i ].color ); } tess.attribsSet |= ATTR_POSITION | ATTR_COLOR | ATTR_TEXCOORD; tess.numVertexes += numVertexes; }
/* ============ R_BindFBO ============ */ void R_BindFBO( FBO_t *fbo ) { #if defined( USE_D3D10 ) // TODO #else if ( !fbo ) { R_BindNullFBO(); return; } if ( r_logFile->integer ) { // don't just call LogComment, or we will get a call to va() every frame! GLimp_LogComment( va( "--- R_BindFBO( %s ) ---\n", fbo->name ) ); } if ( glState.currentFBO != fbo ) { glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo->frameBuffer ); /* if(fbo->colorBuffers[0]) { glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->colorBuffers[0]); } */ /* if(fbo->depthBuffer) { glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->depthBuffer); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->depthBuffer); } */ glState.currentFBO = fbo; } #endif }
/* ============== Tess_CheckOverflow ============== */ void Tess_CheckOverflow( int verts, int indexes ) { // FIXME: need to check if a vbo is bound, otherwise we fail on startup if ( glState.currentVBO != nullptr && glState.currentIBO != nullptr ) { Tess_CheckVBOAndIBO( tess.vbo, tess.ibo ); } if ( tess.buildingVBO ) { return; } if ( tess.numVertexes + verts < SHADER_MAX_VERTEXES && tess.numIndexes + indexes < SHADER_MAX_INDEXES ) { return; } if ( r_logFile->integer ) { // don't just call LogComment, or we will get // a call to va() every frame! GLimp_LogComment( va ( "--- Tess_CheckOverflow(%i + %i vertices, %i + %i triangles ) ---\n", tess.numVertexes, verts, ( tess.numIndexes / 3 ), indexes ) ); } Tess_End(); if ( verts >= SHADER_MAX_VERTEXES ) { ri.Error( ERR_DROP, "Tess_CheckOverflow: verts > std::max (%d > %d)", verts, SHADER_MAX_VERTEXES ); } if ( indexes >= SHADER_MAX_INDEXES ) { ri.Error( ERR_DROP, "Tess_CheckOverflow: indexes > std::max (%d > %d)", indexes, SHADER_MAX_INDEXES ); } Tess_Begin( tess.stageIteratorFunc, tess.stageIteratorFunc2, tess.surfaceShader, tess.lightShader, tess.skipTangentSpaces, tess.skipVBO, tess.lightmapNum, tess.fogNum ); }
/* ============ FBO_Bind ============ */ void FBO_Bind(FBO_t * fbo) { if (!glRefConfig.framebufferObject) { ri.Printf(PRINT_WARNING, "FBO_Bind() called without framebuffers enabled!\n"); return; } if (glState.currentFBO == fbo) return; if (r_logFile->integer) { // don't just call LogComment, or we will get a call to va() every frame! GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo ? fbo->name : "NULL")); } GL_BindFramebuffer(GL_FRAMEBUFFER, fbo ? fbo->frameBuffer : 0); glState.currentFBO = fbo; }
/* ================ RB_SetGL2D ================ */ static void RB_SetGL2D( void ) { matrix_t proj; GLimp_LogComment( "--- RB_SetGL2D ---\n" ); #if defined( USE_D3D10 ) // TODO #else // disable offscreen rendering if ( glConfig.framebufferObjectAvailable ) { R_BindNullFBO(); } #endif backEnd.projection2D = qtrue; #if defined( USE_D3D10 ) // TODO #else // set 2D virtual screen size GL_Viewport( 0, 0, glConfig.vidWidth, glConfig.vidHeight ); GL_Scissor( 0, 0, glConfig.vidWidth, glConfig.vidHeight ); MatrixOrthogonalProjection( proj, 0, glConfig.vidWidth, glConfig.vidHeight, 0, 0, 1 ); GL_LoadProjectionMatrix( proj ); GL_LoadModelViewMatrix( matrixIdentity ); GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA ); qglDisable( GL_CULL_FACE ); qglDisable( GL_CLIP_PLANE0 ); #endif // set time for 2D shaders backEnd.refdef.time = ri.Milliseconds(); backEnd.refdef.floatTime = backEnd.refdef.time * 0.001f; }