Example #1
0
/*
* RB_DrawElementsInstanced
*
* Draws <numInstances> instances of elements
*/
void RB_DrawElementsInstanced( int firstVert, int numVerts, int firstElem, int numElems,
                               int firstShadowVert, int numShadowVerts, int firstShadowElem, int numShadowElems,
                               int numInstances, instancePoint_t *instances )
{
    if( !numInstances ) {
        return;
    }

    // currently not supporting dynamic instances
    // they will need a separate stream so they can be used with both static and dynamic geometry
    // (dynamic geometry will need changes to rbDynamicDraw_t)
    assert( rb.currentVBOId > RB_VBO_NONE );
    if( rb.currentVBOId <= RB_VBO_NONE ) {
        return;
    }

    rb.drawElements.numVerts = numVerts;
    rb.drawElements.numElems = numElems;
    rb.drawElements.firstVert = firstVert;
    rb.drawElements.firstElem = firstElem;
    rb.drawElements.numInstances = 0;

    rb.drawShadowElements.numVerts = numShadowVerts;
    rb.drawShadowElements.numElems = numShadowElems;
    rb.drawShadowElements.firstVert = firstShadowVert;
    rb.drawShadowElements.firstElem = firstShadowElem;
    rb.drawShadowElements.numInstances = 0;

    // check for vertex-attrib-divisor style instancing
    if( glConfig.ext.instanced_arrays ) {
        if( rb.currentVBO->instancesOffset ) {
            // static VBO's must come with their own set of instance data
            rb.currentVAttribs |= VATTRIB_INSTANCES_BITS;
        }
    }

    if( !( rb.currentVAttribs & VATTRIB_INSTANCES_BITS ) ) {
        // can't use instanced arrays so we'll have to manually update
        // the uniform state in between draw calls
        if( rb.maxDrawInstances < numInstances ) {
            if( rb.drawInstances ) {
                RB_Free( rb.drawInstances );
            }
            rb.drawInstances = RB_Alloc( numInstances * sizeof( *rb.drawInstances ) );
            rb.maxDrawInstances = numInstances;
        }
        memcpy( rb.drawInstances, instances, numInstances * sizeof( *instances ) );
    }

    rb.drawElements.numInstances = numInstances;
    rb.drawShadowElements.numInstances = numInstances;
    RB_DrawElements_();
}
Example #2
0
/*
* RB_DrawElementsInstanced
*
* Draws <numInstances> instances of elements
*/
void RB_DrawElementsInstanced( int firstVert, int numVerts, int firstElem, int numElems, 
	int numInstances, instancePoint_t *instances )
{
	if( !numInstances ) {
		return;
	}

	// check for vertex-attrib-divisor style instancing
	if( glConfig.ext.instanced_arrays ) {
		// upload instances
		if( rb.currentVBOId < RB_VBO_NONE ) {
			rb.currentVAttribs |= VATTRIB_INSTANCES_BIT;

			// FIXME: this is nasty!
			while( numInstances > MAX_STREAM_VBO_INSTANCES ) {
				R_UploadVBOInstancesData( rb.currentVBO, 0, MAX_STREAM_VBO_INSTANCES, instances );

				rb.drawElements.numInstances = MAX_STREAM_VBO_INSTANCES;
				RB_DrawElements_( firstVert, numVerts, firstElem, numElems );

				instances += MAX_STREAM_VBO_INSTANCES;
				numInstances -= MAX_STREAM_VBO_INSTANCES;
			}

			if( !numInstances ) {
				return;
			}

			R_UploadVBOInstancesData( rb.currentVBO, 0, numInstances, instances );
		} else if( rb.currentVBO->instancesOffset ) {
			// static VBO's must come with their own set of instance data
			rb.currentVAttribs |= VATTRIB_INSTANCES_BIT;
		}
	}

	if( !( rb.currentVAttribs & VATTRIB_INSTANCES_BIT ) ) {
		// can't use instanced arrays so we'll have to manually update
		// the uniform state in between draw calls
		if( rb.maxDrawInstances < numInstances ) {
			if( rb.drawInstances ) {
				RB_Free( rb.drawInstances );
			}
			rb.drawInstances = RB_Alloc( numInstances * sizeof( *rb.drawInstances ) );
			rb.maxDrawInstances = numInstances;
		}
		memcpy( rb.drawInstances, instances, numInstances * sizeof( *instances ) );
	}

	rb.drawElements.numInstances = numInstances;
	RB_DrawElements_( firstVert, numVerts, firstElem, numElems );
}
Example #3
0
/*
* RB_RegisterStreamVBOs
*
* Allocate/keep alive dynamic vertex buffers object
* we'll steam the dynamic geometry into
*/
void RB_RegisterStreamVBOs( void )
{
    int i;
    rbDynamicStream_t *stream;
    vattribmask_t vattribs[RB_VBO_NUM_STREAMS] = {
        VATTRIBS_MASK & ~VATTRIB_INSTANCES_BITS,
        COMPACT_STREAM_VATTRIBS
    };

    // allocate stream VBO's
    for( i = 0; i < RB_VBO_NUM_STREAMS; i++ ) {
        stream = &rb.dynamicStreams[i];
        if( stream->vbo ) {
            R_TouchMeshVBO( stream->vbo );
            continue;
        }
        stream->vbo = R_CreateMeshVBO( &rb,
                                       MAX_STREAM_VBO_VERTS, MAX_STREAM_VBO_ELEMENTS, 0,
                                       vattribs[i], VBO_TAG_STREAM, VATTRIB_TEXCOORDS_BIT|VATTRIB_NORMAL_BIT|VATTRIB_SVECTOR_BIT );
        stream->vertexData = RB_Alloc( MAX_STREAM_VBO_VERTS * stream->vbo->vertexSize );
    }
}