/* * 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_(); }
/* * 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 ); }