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;
}
示例#2
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);
}
示例#3
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;
}
示例#4
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);
}
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;
}