Example #1
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::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();
}
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;
}