私は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週間取り組んでおり、私の問題を本当に学びたいと思っています.