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::SetupMultiDrawIndirectData( GLint PositionHandle, GLint NormalHandle, GLint TexcoordHandle, GLint InstanceHandle) { GLuint BufferID; NvModel* pData; int32_t PositionSize; int32_t NormalSize; int32_t TexCoordSize; pData = m_Model->getModel(); PositionSize = pData->getPositionSize(); NormalSize = pData->getNormalSize(); TexCoordSize = pData->getTexCoordSize(); SetConstants(); glBindVertexArray(m_VertexArrayObject); glGenBuffers(1, &BufferID); glBindBuffer(GL_ARRAY_BUFFER, BufferID); glBufferData( GL_ARRAY_BUFFER, m_SizeofVertexBuffer, NULL, GL_STATIC_DRAW); glGenBuffers(1, &BufferID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferID); glBufferData( GL_ELEMENT_ARRAY_BUFFER, m_SizeofIndexBuffer, NULL, GL_STATIC_DRAW); SetupMultipleModelData(); glVertexAttribPointer( PositionHandle, PositionSize, GL_FLOAT, GL_FALSE, m_VertexSize, 0); glEnableVertexAttribArray(PositionHandle); glVertexAttribPointer( NormalHandle, NormalSize, GL_FLOAT, GL_FALSE, m_VertexSize, OFFSET(pData->getCompiledNormalOffset() * sizeof(float))); glEnableVertexAttribArray(NormalHandle); glVertexAttribPointer( TexcoordHandle, TexCoordSize, GL_FLOAT, GL_FALSE, m_VertexSize, OFFSET(pData->getCompiledTexCoordOffset() * sizeof(float))); glEnableVertexAttribArray(TexcoordHandle); if (InstanceHandle >= 0) { glVertexAttribPointer( InstanceHandle, 2, GL_FLOAT, GL_FALSE, 0, OFFSET(m_OffsetofInstanceBuffer)); glEnableVertexAttribArray(InstanceHandle); glVertexAttribDivisor(InstanceHandle,1); } glBindVertexArray(0); CHECK_GL_ERROR(); }
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); }
bool InstancedTessellation::initPerModelTessellationInstancingData( NvGLModel* mdl, int32_t modelIndex ) { NvModel* pModel = mdl->getModel(); int numFaces = pModel->getCompiledIndexCount( NvModelPrimType::TRIANGLES ) / 3; const GLuint* pIndices = pModel->getCompiledIndices( NvModelPrimType::TRIANGLES ); const float* pVertices = pModel->getCompiledVertices(); int floatsPerV = pModel->getCompiledVertexSize(); int vtxOffset = pModel->getCompiledPositionOffset(); int normalOffset = pModel->getCompiledNormalOffset(); int textureOffset = pModel->getCompiledTexCoordOffset(); PerInstanceData* pId = new PerInstanceData[ numFaces ]; m_pTriangleData[ modelIndex ] = pId; // build per instance/triangle data in memory for( int i = 0; i < numFaces; ++i ) { GLuint idx[ 3 ]; const float* pVertex[ 3 ]; nv::vec3f v[ 3 ]; nv::vec3f n[ 3 ]; nv::vec2f txt[ 3 ]; // get indices idx[0] = pIndices[ i * 3 + 0 ]; idx[1] = pIndices[ i * 3 + 1 ]; idx[2] = pIndices[ i * 3 + 2 ]; // get vertices and normals pVertex[0] = pVertices + floatsPerV * idx[ 0 ]; pVertex[1] = pVertices + floatsPerV * idx[ 1 ]; pVertex[2] = pVertices + floatsPerV * idx[ 2 ]; // copy vertex data v[0] = *((nv::vec3f*)(pVertex[0]+vtxOffset)); v[1] = *((nv::vec3f*)(pVertex[1]+vtxOffset)); v[2] = *((nv::vec3f*)(pVertex[2]+vtxOffset)); n[0] = nv::normalize( *((nv::vec3f*)(pVertex[0]+normalOffset)) ); n[1] = nv::normalize( *((nv::vec3f*)(pVertex[1]+normalOffset)) ); n[2] = nv::normalize( *((nv::vec3f*)(pVertex[2]+normalOffset)) ); txt[0] = *( (nv::vec2f*) (pVertex[0]+textureOffset) ); txt[1] = *( (nv::vec2f*) (pVertex[1]+textureOffset) ); txt[2] = *( (nv::vec2f*) (pVertex[2]+textureOffset) ); // initialize interpolated vertices pId[ i ].m_p0 = v[0]; pId[ i ].m_p1 = v[1]; pId[ i ].m_p2 = v[2]; pId[ i ].m_n0 = n[0]; pId[ i ].m_n1 = n[1]; pId[ i ].m_n2 = n[2]; //pId[ i ].m_t0t1 = nv::vec4f(txt[0].x, txt[0].y, txt[1].x, txt[1].y ); //pId[ i ].m_t2 = nv::vec2f(txt[2].x, txt[2].y ); } glGenBuffers(1, &m_perTriangleDataVboID[modelIndex]); glBindBuffer(GL_ARRAY_BUFFER, m_perTriangleDataVboID[modelIndex]); glBufferData(GL_ARRAY_BUFFER, numFaces * sizeof(PerInstanceData), pId, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); return true; }
void InstancedTessellation::drawModelLitInstancingOFF() { BaseShader* shader = m_tessMode == eNPatch ? m_npatchShader : m_deformationShader; if( m_tessMode == eNPatch ) m_npatchShader->enable(); else m_deformationShader->enable(); if( m_tessMode == eDeformation ) { float time = m_time; glUniform1f( m_deformationShader->m_timeHandle, time ); } //send matrices glUniformMatrix4fv(shader->m_modelViewMatrixHandle, 1, GL_FALSE, m_viewMatrix._array); glUniformMatrix4fv(shader->m_projectionMatrixHandle, 1, GL_FALSE, m_projectionMatrixHandle._array); glUniform4fv(shader->m_lightPositionHandle1, 1, m_lightPositionEye._array); glUniform4f(shader->m_colorHandle, m_modelColor.x, m_modelColor.y, m_modelColor.z, 1.0f); //m_normalMatrixHandle now contains a 3x3 inverse component of the m_modelViewMatrixHandle //hence, we need to transpose this before sending it to the shader glUniformMatrix4fv(shader->m_normalMatrixHandle, 1, GL_FALSE, m_normalMatrixHandle._array); glBindBuffer(GL_ARRAY_BUFFER, m_tessVboID[m_tessFactor-1] ); if( m_wireframe == false ) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_tessIboID[m_tessFactor-1] ); else glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_wireframeTessIboID[m_tessFactor-1] ); glVertexAttribPointer(shader->m_b01Handle, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0 ) ; glEnableVertexAttribArray(shader->m_b01Handle); NvModel* pModel = m_pModel[m_modelIndex]->getModel(); int numFaces = pModel->getCompiledIndexCount( NvModelPrimType::TRIANGLES ) / 3; for( int i = 0; i < numFaces; ++i ) { if( m_tessMode == eNPatch ) { glUniform3fv( m_npatchShader->m_posHandle, 3, (GLfloat*)&((m_pTriangleData[m_modelIndex])[i].m_p0) ); glUniform3fv( m_npatchShader->m_normHandle, 3, (GLfloat*)&((m_pTriangleData[m_modelIndex])[i].m_n0) ); } else { glUniform3fv( m_deformationShader->m_posHandle, 3, (GLfloat*)&((m_pTriangleData[m_modelIndex])[i].m_p0) ); glUniform3fv( m_deformationShader->m_normHandle, 3, (GLfloat*)&((m_pTriangleData[m_modelIndex])[i].m_n0) ); } if( m_wireframe == false ) glDrawElements(GL_TRIANGLES, ( m_tessFactor * m_tessFactor ) * 3, GL_UNSIGNED_INT, 0); else glDrawElements(GL_LINES, ( ( ( m_tessFactor + 1 ) * m_tessFactor ) / 2 ) * 3 * 2, GL_UNSIGNED_INT, 0); } glBindBuffer(GL_ARRAY_BUFFER, m_tessVboID[m_tessFactor-1] ); glDisableVertexAttribArray(shader->m_b01Handle); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
void InstancedTessellation::drawModelLitInstancingON() { InstancedTessShader* shader = m_tessMode == eNPatch ? m_instancedNPatchShader : m_instancedDeformationShader; shader->enable(); if( m_tessMode == eDeformation ) { float time = m_time; m_deformationShader->setUniform1f( m_deformationShader->m_timeHandle, time ); } shader->setUniformMatrix4fv(shader->m_modelViewMatrixHandle, m_viewMatrix._array, 1, GL_FALSE); shader->setUniformMatrix4fv(shader->m_projectionMatrixHandle, m_projectionMatrixHandle._array, 1, GL_FALSE); shader->setUniform4f(shader->m_lightPositionHandle1, m_lightPositionEye.x, m_lightPositionEye.y, m_lightPositionEye.z, m_lightPositionEye.w); shader->setUniform4f(shader->m_colorHandle, m_modelColor.x, m_modelColor.y, m_modelColor.z, 1.0f); //m_normalMatrixHandle now contains a 3x3 inverse component of the m_modelViewMatrixHandle //hence, we need to transpose this before sending it to the shader shader->setUniformMatrix4fv(shader->m_normalMatrixHandle, m_normalMatrixHandle._array, 1, GL_FALSE); glBindBuffer(GL_ARRAY_BUFFER, m_tessVboID[m_tessFactor-1] ); if( m_wireframe == false ) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_tessIboID[m_tessFactor-1] ); else glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_wireframeTessIboID[m_tessFactor-1] ); glVertexAttribPointer(shader->m_b01Handle, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0 ) ; glEnableVertexAttribArray(shader->m_b01Handle); NvModel* pModel = m_pModel[m_modelIndex]->getModel(); int numFaces = pModel->getCompiledIndexCount( NvModelPrimType::TRIANGLES ) / 3; glBindBuffer(GL_ARRAY_BUFFER, m_perTriangleDataVboID[m_modelIndex] ); glVertexAttribPointer(shader->m_posHandle0, 3, GL_FLOAT, GL_FALSE, 18 * sizeof(float), 0 ) ; glEnableVertexAttribArray(shader->m_posHandle0); glVertexAttribPointer(shader->m_posHandle1, 3, GL_FLOAT, GL_FALSE, 18 * sizeof(float), (GLvoid*)(3 * sizeof(float) ) ) ; glEnableVertexAttribArray(shader->m_posHandle1); glVertexAttribPointer(shader->m_posHandle2, 3, GL_FLOAT, GL_FALSE, 18 * sizeof(float), (GLvoid*)(6 * sizeof(float) ) ) ; glEnableVertexAttribArray(shader->m_posHandle2); glVertexAttribPointer(shader->m_normHandle0, 3, GL_FLOAT, GL_FALSE, 18 * sizeof(float), (GLvoid*)(9 * sizeof(float) ) ) ; glEnableVertexAttribArray(shader->m_normHandle0); glVertexAttribPointer(shader->m_normHandle1, 3, GL_FLOAT, GL_FALSE, 18 * sizeof(float), (GLvoid*)(12 * sizeof(float) ) ) ; glEnableVertexAttribArray(shader->m_normHandle1); glVertexAttribPointer(shader->m_normHandle2, 3, GL_FLOAT, GL_FALSE, 18 * sizeof(float), (GLvoid*)(15 * sizeof(float) ) ) ; glEnableVertexAttribArray(shader->m_normHandle2); glVertexAttribDivisorInternal( shader->m_posHandle0, 1 ); glVertexAttribDivisorInternal( shader->m_posHandle1, 1 ); glVertexAttribDivisorInternal( shader->m_posHandle2, 1 ); glVertexAttribDivisorInternal( shader->m_normHandle0, 1 ); glVertexAttribDivisorInternal( shader->m_normHandle1, 1 ); glVertexAttribDivisorInternal( shader->m_normHandle2, 1 ); if( m_wireframe == false ) glDrawElementsInstancedInternal(GL_TRIANGLES, ( m_tessFactor * m_tessFactor ) * 3, GL_UNSIGNED_INT, 0, numFaces ); else glDrawElementsInstancedInternal(GL_LINES, ( ( ( m_tessFactor + 1 ) * m_tessFactor ) / 2 ) * 3 * 2, GL_UNSIGNED_INT, 0, numFaces ); glVertexAttribDivisorInternal( shader->m_posHandle0, 0 ); glVertexAttribDivisorInternal( shader->m_posHandle1, 0 ); glVertexAttribDivisorInternal( shader->m_posHandle2, 0 ); glVertexAttribDivisorInternal( shader->m_normHandle0, 0 ); glVertexAttribDivisorInternal( shader->m_normHandle1, 0 ); glVertexAttribDivisorInternal( shader->m_normHandle2, 0 ); glDisableVertexAttribArray(shader->m_posHandle0); glDisableVertexAttribArray(shader->m_posHandle1); glDisableVertexAttribArray(shader->m_posHandle2); glDisableVertexAttribArray(shader->m_normHandle0); glDisableVertexAttribArray(shader->m_normHandle1); glDisableVertexAttribArray(shader->m_normHandle2); glBindBuffer(GL_ARRAY_BUFFER, m_tessVboID[m_tessFactor-1] ); glDisableVertexAttribArray(shader->m_b01Handle); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }