5

私はopenGLを数か月間使用しており、自分ですべてを学んでいます。これで、位置、テクスチャ座標モデルをレンダリングできるようになりました

グラフィックカードでアニメーションスキニングプロセスを行うアニメーションモデルを使用しようとしています。

ところで、誰かが私を 1 対 1 で助けたいと思っている場合は、もっと直接的なアプローチでもかまわないことを知らせてください。

ここに私の頂点フォーマットがあります

struct VERTEX_ANIMATED
{
    float3 position;
    float3 normal;
    float2 texCoord;
    float weights[4];
    unsigned boneIndices[4];
};

これは、頂点を gpu バッファー ハンドルに追加する方法です (これらの関数の初期化されていない変数はすべて ".h" にあります)。

bool CVertexBuffer::IncreaseVerts( const unsigned int uiNumVerts )
{
    //create our increase by value
    unsigned uiIncrement = (uiNumVerts / BUFFER_INCREASE_SIZE) * BUFFER_INCREASE_SIZE + BUFFER_INCREASE_SIZE;
    m_uiNumVerts += uiIncrement;

    //bind to our buffer
    void* buffer1; 
    if (GLEW_ARB_vertex_shader)
    {
        glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_uiVertBufferHandle );

        //make sure our buffer exists
        buffer1 = glMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_READ_WRITE );
    }
    else
    {
        glBindBuffer( GL_ARRAY_BUFFER, m_uiVertBufferHandle );

        //make sure our buffer exists
        buffer1 = glMapBuffer( GL_ARRAY_BUFFER, GL_READ_WRITE );
    }

    if( buffer1 )
    {
        //collection of all our data
        void* buffer2 = new char[ (m_uiNumVerts)*sizeof(VertexFormat) ];
        memset( buffer2, 0, (m_uiNumVerts)*sizeof(VertexFormat) );
        memcpy( buffer2, buffer1, (m_uiNumVerts - uiIncrement)*sizeof(VertexFormat)     );

        //create a new buffer
        //unsigned uiNewHandle;

        if (GLEW_ARB_vertex_shader)
        {
            //allocate our new storage space, and store our data in there
            glBufferDataARB( GL_ARRAY_BUFFER_ARB, (m_uiNumVerts*sizeof(VertexFormat)), buffer2, GL_DYNAMIC_READ );

            //lock our buffer
            //void* buffer2 = glMapBuffer( GL_ARRAY_BUFFER_ARB, GL_READ_WRITE );    

            //unlock our buffer2
            //if( glUnmapBufferARB( GL_ARRAY_BUFFER_ARB ) == GL_FALSE )
            //  return false;
            //}

            //reset what we are bound to
            glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
        }
        else
        {
            //allocate our new storage space, and store our data in there
            glBufferDataARB( GL_ARRAY_BUFFER_ARB, (m_uiNumVerts*sizeof(VertexFormat)), buffer2, GL_DYNAMIC_READ );

            //reset what we are bound to
            glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
        }

        //delete our buffer
        free( buffer2 );

        //Unmap our currently mapped buffer
        glUnmapBuffer( GL_ARRAY_BUFFER );

    return true;
}

unsigned int CVertexBuffer::AddVerts(const VERTEX_ANIMATED* pVerts, unsigned int iNumVerts)
{
    //Save the location to copy to
    unsigned int uiVertLocation = m_uiVertsUsed;

    m_uiVertsUsed += iNumVerts;

    if(m_uiVertsUsed > m_uiNumVerts)
    {
        IncreaseVerts(m_uiVertsUsed - m_uiNumVerts);
    }

    if(GLEW_ARB_vertex_program)
    {
        //bind the buffer we're gonna mess with
        glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_uiVertBufferHandle );

        //get the pointer position where we can add verts
        void* pPositionBuffer = glMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_READ_WRITE     );

        //now copy into our memory spot
        //which we need to move to the right position
        memcpy( ((char*)pPositionBuffer) + ( uiVertLocation*sizeof(VertexFormat) ), pVerts, iNumVerts*sizeof(VertexFormat));

        //now stop mapping
        glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
    }
    else
    {
        //bind the buffer we're gonna mess with
        glBindBuffer( GL_ARRAY_BUFFER, m_uiVertBufferHandle );

        //get the pointer position where we can add verts
        void* pPositionBuffer = glMapBuffer( GL_ARRAY_BUFFER, GL_READ_WRITE );

        //now copy into our memory spot
        //which we need to move to the right position
        memcpy( ((char*)pPositionBuffer) + ( uiVertLocation*sizeof(VertexFormat) ), pVerts, iNumVerts*sizeof(VertexFormat));

        //now stop mapping
        glUnmapBuffer(GL_ARRAY_BUFFER);
    }

    return uiVertLocation;
}

エラーは、データの初期化方法またはデータをシェーダーに渡す方法に起因すると想定しています。

これは、頂点シェーダー ファイル名とフラグメント シェーダー ファイル名、次に「位置、法線、texCoords」などの指定が必要な主な変数の変数を受け取るシェーダー プログラム作成への単純な呼び出しです。

CreateProgram( "animTriangle.vp",
               "animTriangle.fp",
               5,
               VERTEX_ATTRIB, "vVertexPos",
               NORMAL_ATTRIB, "vVertexNormal",
               TEXTURE_COORD_ATTRIB0, "vTexCoord",
               COLOR_ATTRIB, "vBlendWeights",
               COLOR2_ATTRIB, "vBoneIndices" );

この関数の中で、シェーダープログラムを作成してコンパイルした後、パラメーターの解析を行います

 //make sure to use our program to setup our handles
glUseProgram( m_uiProgramHandle );

//start from this parameter
va_start( parseList, szFragmentShaderName );

//read in number of variables if any
uiNum = va_arg( parseList, unsigned );

//for loop through our attribute pairs
int enumType = 0;
for( unsigned x = 0; x < uiNum; ++x )
{
    //specify our attribute locations
    enumType = va_arg( parseList, int );
    char* name = va_arg( parseList, char* );
    glBindAttribLocation( m_uiProgramHandle, enumType, name );
}

//end our list parsing
va_end( parseList );

ここに私の頂点シェーダーの先頭にある私の変数リストがあります

in vec3 vVertexPos;     // position
in vec3 vVertexNormal;  // normal
in vec2 vTexCoord;      // texture coordinate....
in vec4 vBlendWeights;  // the weights pull of the related bone
in ivec4 vBoneIndices;  // the indicators of which bones we are influenced by

これが私の頂点ストライドです

 //set which vertices we will be using
 glBindBuffer( GL_ARRAY_BUFFER, m_uiVertBufferHandle );

 //enable these vertex attributes
 glEnableVertexAttribArray( VERTEX_ATTRIB );
 glEnableVertexAttribArray( NORMAL_ATTRIB );
 glEnableVertexAttribArray( TEXTURE_COORD_ATTRIB0 );
 glEnableVertexAttribArray( COLOR_ATTRIB );
 glEnableVertexAttribArray( COLOR2_ATTRIB );

 //specify our vertex attribute
 glVertexAttribPointer( VERTEX_ATTRIB, 3, GL_FLOAT, GL_FALSE, sizeof( VERTEX_ANIMATED ), BUFFER_OFFSET(0) );

 //specify our normal attribute
 glVertexAttribPointer( NORMAL_ATTRIB, 3, GL_FLOAT, GL_FALSE, sizeof( VERTEX_ANIMATED ), BUFFER_OFFSET(12) );

 //specify our texture attribute
 glVertexAttribPointer( TEXTURE_COORD_ATTRIB0, 2, GL_FLOAT, GL_FALSE, sizeof( VERTEX_ANIMATED ), BUFFER_OFFSET(24) );

 //specify our bone weight attribute location
 glVertexAttribPointer( COLOR_ATTRIB, 4, GL_FLOAT, GL_FALSE, sizeof( VERTEX_ANIMATED ), BUFFER_OFFSET(32) );

 //specify our bone indice attribute location
 glVertexAttribPointer( COLOR2_ATTRIB, 4, GL_INT, GL_FALSE, sizeof( VERTEX_ANIMATED ), BUFFER_OFFSET(48) );

静的モデルを問題なくロードできるようになりました。アニメーション化されたモデルをロードすると、モデルの半分またはモデルの半分のようになり、その半分にはいくつかのチャンクがありません。以前に DirectX を使用したことがありますが、GPU がバッファーを正しく読み取っていたときにのみ、その問題に遭遇しました。

さらに情報が必要な場合は、お知らせください。私はこの奇妙な問題にほぼ2週間取り組んでおり、私の問題を本当に学びたいと思っています.

4

2 に答える 2

3

コードで初期化するのを忘れているようですNORMAL_ATTRIB。への呼び出しには、頂点シェーダーにとCreateProgram (...)の関連付けが含まれていません。NORMAL_ATTRIBvVertexNormal

頂点シェーダーがアニメーションの目的で頂点法線を必要とし、この頂点ポインターを適切な属性スロットに正しく接続していない場合、結果は未定義になります。

同様に、問題は、NORMAL_ATTRIB初期化されていないままにしておくことによる別の属性へのエイリアシングが原因である可能性もあります。たとえば、通常、頂点属性 0 は位置です。NORMAL_ATTRIBこのコードで初期化しないままにしておくと、頂点位置ポインターを通常のポインターで再定義する可能性があります。

于 2013-08-27T08:46:19.070 に答える
0

私の全体的な問題は、ドローコールにあることが判明しました。「三角形の数 * 3」になるインデックスの数ではなく、描画するプリミティブ三角形の数を指定していました。

これは、モデルの一部が表示される理由を説明しますが、それはチャンクアップされます.

于 2014-08-18T15:49:53.490 に答える