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;
}
Exemple #4
0
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);
}
Exemple #5
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;
}
Exemple #6
0
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);
}