/* * R_DrawBSPSurf */ qboolean R_DrawBSPSurf( const entity_t *e, const shader_t *shader, const mfog_t *fog, drawSurfaceBSP_t *drawSurf ) { vboSlice_t *slice; slice = R_GetVBOSlice( drawSurf - rsh.worldBrushModel->drawSurfaces ); assert( slice != NULL ); RB_BindVBO( drawSurf->vbo->index, GL_TRIANGLES ); if( drawSurf->dlightFrame == rsc.frameCount ) { RB_SetDlightBits( drawSurf->dlightBits & rn.dlightBits ); } else { RB_SetDlightBits( 0 ); } if( drawSurf->shadowFrame == rsc.frameCount ) { RB_SetShadowBits( drawSurf->shadowBits & rn.shadowBits ); } else { RB_SetShadowBits( 0 ); } RB_SetLightstyle( drawSurf->superLightStyle ); if( drawSurf->numInstances ) { RB_DrawElementsInstanced( slice->firstVert, slice->numVerts, slice->firstElem, slice->numElems, drawSurf->numInstances, drawSurf->instances ); } else { RB_DrawElements( slice->firstVert, slice->numVerts, slice->firstElem, slice->numElems ); } return qfalse; }
/* * R_DrawBSPSurf */ bool R_DrawBSPSurf( const entity_t *e, const shader_t *shader, const mfog_t *fog, const portalSurface_t *portalSurface, drawSurfaceBSP_t *drawSurf ) { const vboSlice_t *slice; const vboSlice_t *shadowSlice; static const vboSlice_t nullSlice = { 0 }; int firstVert, firstElem; int firstShadowVert, firstShadowElem; slice = R_GetVBOSlice( drawSurf - rsh.worldBrushModel->drawSurfaces ); shadowSlice = R_GetVBOSlice( rsh.worldBrushModel->numDrawSurfaces + ( drawSurf - rsh.worldBrushModel->drawSurfaces ) ); if( !shadowSlice ) { shadowSlice = &nullSlice; } assert( slice != NULL ); RB_BindVBO( drawSurf->vbo->index, GL_TRIANGLES ); if( drawSurf->dlightFrame == rsc.frameCount ) { RB_SetDlightBits( drawSurf->dlightBits & rn.dlightBits ); } else { RB_SetDlightBits( 0 ); } if( drawSurf->shadowFrame == rsc.frameCount ) { RB_SetShadowBits( (drawSurf->shadowBits & rn.shadowBits) & rsc.renderedShadowBits ); } else { RB_SetShadowBits( 0 ); } RB_SetLightstyle( drawSurf->superLightStyle ); firstVert = drawSurf->firstVboVert + slice->firstVert; firstElem = drawSurf->firstVboElem + slice->firstElem; firstShadowVert = drawSurf->firstVboVert + shadowSlice->firstVert; firstShadowElem = drawSurf->firstVboElem + shadowSlice->firstElem; if( drawSurf->numInstances ) { RB_DrawElementsInstanced( firstVert, slice->numVerts, firstElem, slice->numElems, firstShadowVert, shadowSlice->numVerts, firstShadowElem, shadowSlice->numElems, drawSurf->numInstances, drawSurf->instances ); } else { RB_DrawElements( firstVert, slice->numVerts,firstElem, slice->numElems, firstShadowVert, shadowSlice->numVerts, firstShadowElem, shadowSlice->numElems ); } return false; }
/* * RB_FlushDynamicMeshes */ void RB_FlushDynamicMeshes( void ) { int i, numDraws = rb.numDynamicDraws; rbDynamicStream_t *stream; rbDynamicDraw_t *draw; int sx, sy, sw, sh; float offsetx = 0.0f, offsety = 0.0f, transx, transy; mat4_t m; if( !numDraws ) { return; } for( i = 0; i < RB_VBO_NUM_STREAMS; i++ ) { stream = &rb.dynamicStreams[i]; // R_UploadVBO* are going to rebind buffer arrays for upload // so update our local VBO state cache by calling RB_BindVBO RB_BindVBO( -i - 1, GL_TRIANGLES ); // dummy value for primitive here // because of firstVert, upload elems first if( stream->drawElements.numElems ) { mesh_t elemMesh; memset( &elemMesh, 0, sizeof( elemMesh ) ); elemMesh.elems = dynamicStreamElems[i] + stream->drawElements.firstElem; elemMesh.numElems = stream->drawElements.numElems; R_UploadVBOElemData( stream->vbo, 0, stream->drawElements.firstElem, &elemMesh ); stream->drawElements.firstElem += stream->drawElements.numElems; stream->drawElements.numElems = 0; } if( stream->drawElements.numVerts ) { R_UploadVBOVertexRawData( stream->vbo, stream->drawElements.firstVert, stream->drawElements.numVerts, stream->vertexData + stream->drawElements.firstVert * stream->vbo->vertexSize ); stream->drawElements.firstVert += stream->drawElements.numVerts; stream->drawElements.numVerts = 0; } } RB_GetScissor( &sx, &sy, &sw, &sh ); Matrix4_Copy( rb.objectMatrix, m ); transx = m[12]; transy = m[13]; for( i = 0, draw = rb.dynamicDraws; i < numDraws; i++, draw++ ) { RB_BindShader( draw->entity, draw->shader, draw->fog ); RB_BindVBO( draw->streamId, draw->primitive ); RB_SetPortalSurface( draw->portalSurface ); RB_SetShadowBits( draw->shadowBits ); RB_Scissor( draw->scissor[0], draw->scissor[1], draw->scissor[2], draw->scissor[3] ); // translate the mesh in 2D if( ( offsetx != draw->offset[0] ) || ( offsety != draw->offset[1] ) ) { offsetx = draw->offset[0]; offsety = draw->offset[1]; m[12] = transx + offsetx; m[13] = transy + offsety; RB_LoadObjectMatrix( m ); } RB_DrawElements( draw->drawElements.firstVert, draw->drawElements.numVerts, draw->drawElements.firstElem, draw->drawElements.numElems, draw->drawElements.firstVert, draw->drawElements.numVerts, draw->drawElements.firstElem, draw->drawElements.numElems ); } rb.numDynamicDraws = 0; RB_Scissor( sx, sy, sw, sh ); // restore the original translation in the object matrix if it has been changed if( offsetx || offsety ) { m[12] = transx; m[13] = transy; RB_LoadObjectMatrix( m ); } }
/* * R_DrawBSPSurf */ void R_DrawBSPSurf( const entity_t *e, const shader_t *shader, const mfog_t *fog, const portalSurface_t *portalSurface, unsigned int entShadowBits, drawSurfaceBSP_t *drawSurf ) { const vboSlice_t *slice; const vboSlice_t *shadowSlice; static const vboSlice_t nullSlice = { 0 }; int firstVert, firstElem; int numVerts, numElems; int firstShadowVert, firstShadowElem; int numShadowVerts, numShadowElems; unsigned shadowBits, dlightBits; slice = R_GetVBOSlice( drawSurf - rsh.worldBrushModel->drawSurfaces ); shadowSlice = R_GetVBOSlice( rsh.worldBrushModel->numDrawSurfaces + ( drawSurf - rsh.worldBrushModel->drawSurfaces ) ); if( !shadowSlice ) { shadowSlice = &nullSlice; } assert( slice != NULL ); if( drawSurf->dlightFrame == rsc.frameCount ) { dlightBits = drawSurf->dlightBits & rn.dlightBits; } else { dlightBits = 0; } if( drawSurf->shadowFrame == rsc.frameCount ) { shadowBits = (drawSurf->shadowBits & rn.shadowBits) & rsc.renderedShadowBits; } else { shadowBits = 0; } // shadowBits are shared for all rendering instances (normal view, portals, etc) // if either shadow slice is empty or shadowBits is 0, then we must pass the surface unshadowed numVerts = slice->numVerts; numElems = slice->numElems; firstVert = drawSurf->firstVboVert + slice->firstVert; firstElem = drawSurf->firstVboElem + slice->firstElem; if( shadowBits && shadowSlice->numElems ) { numShadowVerts = shadowSlice->numVerts; numShadowElems = shadowSlice->numElems; firstShadowVert = drawSurf->firstVboVert + shadowSlice->firstVert; firstShadowElem = drawSurf->firstVboElem + shadowSlice->firstElem; } else { shadowBits = 0; numShadowVerts = 0; numShadowElems = 0; firstShadowVert = 0; firstShadowElem = 0; } RB_BindVBO( drawSurf->vbo->index, GL_TRIANGLES ); RB_SetDlightBits( dlightBits ); RB_SetShadowBits( shadowBits ); RB_SetLightstyle( drawSurf->superLightStyle ); if( drawSurf->numInstances ) { RB_DrawElementsInstanced( firstVert, numVerts, firstElem, numElems, firstShadowVert, numShadowVerts, firstShadowElem, numShadowElems, drawSurf->numInstances, drawSurf->instances ); } else { RB_DrawElements( firstVert, numVerts, firstElem, numElems, firstShadowVert, numShadowVerts, firstShadowElem, numShadowElems ); } }