/* * RFB_BlitObject * * The target FBO must be equal or greater in both dimentions than * the currently bound FBO! */ void RFB_BlitObject( int dest, int bitMask, int mode ) { int bits; int dx, dy, dw, dh; r_fbo_t *fbo = r_bound_framebuffer_object, *destfbo = r_framebuffer_objects + dest - 1; if( !r_bound_framebuffer_object ) { return; } if( !glConfig.ext.framebuffer_blit ) { return; } assert( dest > 0 && dest <= r_num_framebuffer_objects ); if( dest <= 0 || dest > r_num_framebuffer_objects ) { return; } bits = bitMask; if( !bits ) { return; } RB_ApplyScissor(); switch( mode ) { case FBO_COPY_CENTREPOS: dx = (destfbo->width - fbo->width) / 2; dy = (destfbo->height - fbo->height) / 2; dw = fbo->width; dh = fbo->height; break; case FBO_COPY_INVERT_Y: dx = 0; dy = destfbo->height - fbo->height; dw = fbo->width; dh = fbo->height; break; default: dx = 0; dy = 0; dw = fbo->width; dh = fbo->height; break; } qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); qglBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, fbo->objectID ); qglBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, destfbo->objectID ); qglBlitFramebufferEXT( 0, 0, fbo->width, fbo->height, dx, dy, dx + dw, dy + dh, bits, GL_NEAREST ); qglBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, 0 ); qglBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, 0 ); qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo->objectID ); assert( qglGetError() == GL_NO_ERROR ); }
/* * RB_Clear */ void RB_Clear( int bits, float r, float g, float b, float a ) { int state = rb.gl.state; if( bits & GL_DEPTH_BUFFER_BIT ) state |= GLSTATE_DEPTHWRITE; if( bits & GL_STENCIL_BUFFER_BIT ) qglClearStencil( 128 ); if( bits & GL_COLOR_BUFFER_BIT ) { state = ( state & ~GLSTATE_NO_COLORWRITE ) | GLSTATE_ALPHAWRITE; qglClearColor( r, g, b, a ); } RB_SetState( state ); RB_ApplyScissor(); qglClear( bits ); RB_DepthRange( 0.0f, 1.0f ); }
/* * RB_DrawElementsReal */ void RB_DrawElementsReal( rbDrawElements_t *de ) { int firstVert, numVerts, firstElem, numElems; int numInstances; if( ! ( r_drawelements->integer || rb.currentEntity == &rb.nullEnt ) || !de ) return; RB_ApplyScissor(); numVerts = de->numVerts; numElems = de->numElems; firstVert = de->firstVert; firstElem = de->firstElem; numInstances = de->numInstances; if( numInstances ) { if( glConfig.ext.instanced_arrays ) { // the instance data is contained in vertex attributes qglDrawElementsInstancedARB( rb.primitive, numElems, GL_UNSIGNED_SHORT, (GLvoid *)(firstElem * sizeof( elem_t )), numInstances ); rb.stats.c_totalDraws++; } else if( glConfig.ext.draw_instanced ) { int i, numUInstances = 0; // manually update uniform values for instances for currently bound program, // respecting the MAX_GLSL_UNIFORM_INSTANCES limit for( i = 0; i < numInstances; i += numUInstances ) { numUInstances = min( numInstances - i, MAX_GLSL_UNIFORM_INSTANCES ); RB_SetInstanceData( numUInstances, rb.drawInstances + i ); qglDrawElementsInstancedARB( rb.primitive, numElems, GL_UNSIGNED_SHORT, (GLvoid *)(firstElem * sizeof( elem_t )), numUInstances ); rb.stats.c_totalDraws++; } } else { int i; // manually update uniform values for instances for currently bound program, // one by one for( i = 0; i < numInstances; i++ ) { RB_SetInstanceData( 1, rb.drawInstances + i ); if( glConfig.ext.draw_range_elements ) { qglDrawRangeElementsEXT( rb.primitive, firstVert, firstVert + numVerts - 1, numElems, GL_UNSIGNED_SHORT, (GLvoid *)(firstElem * sizeof( elem_t )) ); } else { qglDrawElements( rb.primitive, numElems, GL_UNSIGNED_SHORT, (GLvoid *)(firstElem * sizeof( elem_t )) ); } rb.stats.c_totalDraws++; } } } else { numInstances = 1; if( glConfig.ext.draw_range_elements ) { qglDrawRangeElementsEXT( rb.primitive, firstVert, firstVert + numVerts - 1, numElems, GL_UNSIGNED_SHORT, (GLvoid *)(firstElem * sizeof( elem_t )) ); } else { qglDrawElements( rb.primitive, numElems, GL_UNSIGNED_SHORT, (GLvoid *)(firstElem * sizeof( elem_t )) ); } rb.stats.c_totalDraws++; } rb.stats.c_totalVerts += numVerts * numInstances; if( rb.primitive == GL_TRIANGLES ) { rb.stats.c_totalTris += numElems * numInstances / 3; } }
/* * RFB_BlitObject * * The target FBO must be equal or greater in both dimentions than * the currently bound FBO! */ void RFB_BlitObject( int src, int dest, int bitMask, int mode, int filter, int readAtt, int drawAtt ) { int bits; int destObj; int dx, dy, dw, dh; r_fbo_t scrfbo; r_fbo_t *fbo; r_fbo_t *destfbo; if( !glConfig.ext.framebuffer_blit ) { return; } assert( src >= 0 && src <= r_num_framebuffer_objects ); if( src < 0 || src > r_num_framebuffer_objects ) { return; } if( src == 0 ) { fbo = &scrfbo; } else { fbo = r_framebuffer_objects + src - 1; } assert( dest >= 0 && dest <= r_num_framebuffer_objects ); if( dest < 0 || dest > r_num_framebuffer_objects ) { return; } if( dest ) { destfbo = r_framebuffer_objects + dest - 1; } else { destfbo = NULL; } bits = bitMask; if( !bits ) { return; } RB_ApplyScissor(); if( src == 0 ) { memset( fbo, 0, sizeof( *fbo ) ); fbo->width = glConfig.width; fbo->height = glConfig.height; } if( destfbo ) { dw = destfbo->width; dh = destfbo->height; destObj = destfbo->objectID; } else { dw = glConfig.width; dh = glConfig.height; destObj = 0; } switch( mode ) { case FBO_COPY_CENTREPOS: dx = ( dw - fbo->width ) / 2; dy = ( dh - fbo->height ) / 2; dw = fbo->width; dh = fbo->height; break; case FBO_COPY_INVERT_Y: dx = 0; dy = dh - fbo->height; dw = fbo->width; dh = fbo->height; break; case FBO_COPY_NORMAL_DST_SIZE: dx = 0; dy = 0; //dw = dw; //dh = dh; break; default: dx = 0; dy = 0; dw = fbo->width; dh = fbo->height; break; } qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); qglBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, fbo->objectID ); qglBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, destObj ); #ifndef GL_ES_VERSION_2_0 if( src == 0 ) { qglReadBuffer( GL_BACK ); qglDrawBuffer( GL_COLOR_ATTACHMENT0_EXT + drawAtt ); } else { qglReadBuffer( GL_COLOR_ATTACHMENT0_EXT + readAtt ); qglDrawBuffer( GL_COLOR_ATTACHMENT0_EXT + drawAtt ); } #endif qglBlitFramebufferEXT( 0, 0, fbo->width, fbo->height, dx, dy, dx + dw, dy + dh, bits, filter ); qglBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, 0 ); qglBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, 0 ); qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo->objectID ); #ifndef GL_ES_VERSION_2_0 if( src == 0 ) { qglReadBuffer( GL_BACK ); qglDrawBuffer( GL_BACK ); } else { qglReadBuffer( GL_COLOR_ATTACHMENT0_EXT ); qglDrawBuffer( GL_COLOR_ATTACHMENT0_EXT ); } #endif assert( qglGetError() == GL_NO_ERROR ); }