void MultiDrawIndirect::SetupMultiDrawParameters() { unsigned int j; NvModel* pData; unsigned int VertexOffset; unsigned int IndexOffset; glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_IndirectDrawBuffer); CHECK_GL_ERROR(); VertexOffset = 0; IndexOffset = 0; CHECK_GL_ERROR(); pData = m_Model->getModel(); for (j = 0; j < m_GridSize * m_GridSize; j++) { VertexOffset = (j % MAX_MODEL_INSTANCES) * pData->getCompiledVertexCount(); m_MultidrawCommands[j].count = pData->getCompiledIndexCount(NvModelPrimType::TRIANGLES); m_MultidrawCommands[j].instanceCount = 1; m_MultidrawCommands[j].firstIndex = IndexOffset; m_MultidrawCommands[j].baseVertex = VertexOffset; m_MultidrawCommands[j].baseInstance = j; } IndexOffset += pData->getCompiledIndexCount(); glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); CHECK_GL_ERROR(); }
void MultiDrawIndirect::DrawAsSingleCalls() { unsigned int j; NvModel* pData; unsigned int VertexOffset; unsigned int IndexOffset; VertexOffset = 0; IndexOffset = 0; glBindVertexArray(m_VertexArrayObject); pData = m_Model->getModel(); for (j = 0; j < m_GridSize * m_GridSize; j++) { VertexOffset = (j % MAX_MODEL_INSTANCES) * pData->getCompiledVertexCount(); glUniform2f(m_SceneShader->m_PositionUHandle, m_Offsets[2 * j], m_Offsets[(2 * j) + 1]); glDrawElementsBaseVertex( GL_TRIANGLES, pData->getCompiledIndexCount(NvModelPrimType::TRIANGLES), GL_UNSIGNED_INT, (GLvoid *) (IndexOffset * sizeof(IndexOffset)), VertexOffset); } IndexOffset += pData->getCompiledIndexCount(); glBindVertexArray(0); CHECK_GL_ERROR(); }
void MultiDrawIndirect::SetConstants() { std::vector<NvGLModel*>::iterator ii; NvModel* pData; int32_t SizeOfCompiledVertex; unsigned int NumberOfCompiledVertices; unsigned int NumberOfIndices; pData = m_Model->getModel(); NumberOfCompiledVertices = 0; NumberOfIndices = 0; SizeOfCompiledVertex = pData->getCompiledVertexSize(); NumberOfCompiledVertices += pData->getCompiledVertexCount(); NumberOfIndices += pData->getCompiledIndexCount(NvModelPrimType::TRIANGLES); m_IndexSize = sizeof(uint32_t); m_VertexSize = sizeof(float) * SizeOfCompiledVertex; m_SizeofIndexBuffer = NumberOfIndices * m_IndexSize; // Vertices m_SizeofVertexBuffer = NumberOfCompiledVertices * m_VertexSize * m_MaxModelInstances; m_OffsetofInstanceBuffer = m_SizeofVertexBuffer; m_SizeofVertexBuffer += 2 * sizeof(GLfloat) * m_MaxGridSize * m_MaxGridSize; }
void InstancingApp::initGLObjects( int32_t sceneIndex, float* pV, int32_t* pI, NvModelGL* pMdl ) { NvModelPrimType::Enum prim; NvModel *pBaseMdl = pMdl->getModel(); int32_t floatCount = pBaseMdl->getCompiledVertexCount() * pBaseMdl->getCompiledVertexSize() * MAX_INSTANCES; int32_t intCount = pBaseMdl->getCompiledIndexCount(prim) * MAX_INSTANCES; // create vbo from the data glGenBuffers(1, &m_vboID[sceneIndex]); glBindBuffer(GL_ARRAY_BUFFER, m_vboID[sceneIndex]); glBufferData(GL_ARRAY_BUFFER, floatCount * sizeof(float) + 6 * MAX_OBJECTS * sizeof(float), pV, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); // create ibo from the data glGenBuffers(1, &m_iboID[sceneIndex]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_iboID[sceneIndex]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, intCount * sizeof(uint32_t), pI, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
bool InstancingApp::initSceneInstancingData( int32_t sceneIndex ) { NvModelPrimType::Enum prim; NvModelGL* pMdl = m_pModel[sceneIndex]; NvModel *pBaseMdl = pMdl->getModel(); int32_t floatCount = pBaseMdl->getCompiledVertexCount() * pBaseMdl->getCompiledVertexSize() * MAX_INSTANCES; int32_t intCount = pBaseMdl->getCompiledIndexCount(prim) * MAX_INSTANCES; // array big enough to hold n instances and data for hw instancing // after n copies of the vertex data of the object there is room // for all position and rotation data for all instances float* pV = new float[ floatCount + 6 * MAX_OBJECTS ]; GLint* pI = new GLint[ intCount ]; // early out if no data if( pV == 0 || pI == 0 ) { if( pV ) delete[] pV; if( pI ) delete[] pI; return false; } // ptr to the per object instancing data in the vbo float* phwInstanceData = pV + floatCount; // init data for this scene initSceneColorPalette( sceneIndex ); initPerInstanceRotations( sceneIndex, phwInstanceData ); initPerInstancePositions( sceneIndex, phwInstanceData ); initModelCopies( sceneIndex, pV, pI, pMdl ); initGLObjects( sceneIndex, pV, pI, pMdl ); // free temp data delete[] pV; delete[] pI; return true; }
void InstancingApp::initModelCopies( int32_t sceneIndex, float* pV, int32_t* pI, NvModelGL* pMdl ) { NvModel *pBaseMdl = pMdl->getModel(); NvModelPrimType::Enum prim; int32_t vtxSize = pBaseMdl->getCompiledVertexSize(); int32_t vtxCount = pBaseMdl->getCompiledVertexCount(); int32_t idxCount = pBaseMdl->getCompiledIndexCount(prim); int32_t tcOff = pBaseMdl->getCompiledTexCoordOffset(); const float* pModel = pBaseMdl->getCompiledVertices(); // write MAX_INSTANCES copies of the scene object to be instanced to // a big vertex buffer and index buffer - this data is used in the // shader instancing rendering path for( int32_t i = 0; i < MAX_INSTANCES; ++i ) { int32_t voff = vtxCount * vtxSize * i; int32_t ioff = idxCount * i; for( int32_t v = 0; v < vtxCount; ++v ) { // copy original vertex memcpy( (void*) &pV[ voff + v * vtxSize ], (void*) &pModel[ v * vtxSize ], vtxSize * sizeof( float) ); // patch instance id into .z component of the 3d texture coordinates pV[ voff + v * vtxSize + tcOff + 2 ] = float( i ); } // copy indices and modify them accordingly for( int32_t idx = 0; idx < idxCount; ++idx ) { pI[ioff + idx] = *(pBaseMdl->getCompiledIndices(prim) + idx); pI[ ioff + idx ] += vtxCount * i; } } }
void MultiDrawIndirect::SetupMultipleModelData() { NvModel* pData; float* pVertexData; uint32_t* pIndexData; unsigned int j; pIndexData = (uint32_t *) glMapBufferRange( GL_ELEMENT_ARRAY_BUFFER, 0, m_SizeofIndexBuffer, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); pVertexData = (float *) glMapBufferRange( GL_ARRAY_BUFFER, 0, m_SizeofVertexBuffer, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); pData = m_Model->getModel(); for (unsigned int k = 0; k < m_MaxModelInstances; k++) { float *pPositionData, Scale; memcpy( pVertexData, pData->getCompiledVertices(), pData->getCompiledVertexCount() * m_VertexSize); pPositionData = pVertexData; Scale = 1.0f + (rand() / (float) RAND_MAX) * 3.0f;; for (int z = 0; z < pData->getCompiledVertexCount(); z++) { pPositionData[0] = pPositionData[0]; pPositionData[1] = pPositionData[1] * Scale; pPositionData[2] = pPositionData[2]; pPositionData += pData->getCompiledVertexSize(); } pVertexData += pData->getCompiledVertexCount() * pData->getCompiledVertexSize(); } memcpy( pIndexData, pData->getCompiledIndices(NvModelPrimType::TRIANGLES), pData->getCompiledIndexCount() * m_IndexSize); pIndexData += pData->getCompiledIndexCount(); float* pInstData = (float*)pVertexData; for (j = 0; j < m_MaxGridSize; j++) { GetGridPoints(j, m_Offsets); } for (j = 0; j < m_MaxGridSize * m_MaxGridSize; j++) { *(pInstData++) = m_Offsets[2 * j]; *(pInstData++) = m_Offsets[(2 * j) + 1]; } glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); glUnmapBuffer(GL_ARRAY_BUFFER); }