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); }
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; }