Esempio n. 1
0
/*
* 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 );
}
Esempio n. 2
0
/*
* 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 );
}
Esempio n. 3
0
/*
* 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;
    }
}
Esempio n. 4
0
/*
* 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 );
}