Я сразу перейду к делу:
Я создал структуру для моих вершин:
struct Vertex3D
{
Vector3D position;
Vector2D textureCoordinate;
Vector3D normal;
}
Затем я импортирую определенный файл * .dae и связываю его с буфером вершин OpenGL, который составлен из списка структурированных вершин Vertex3D. Все идет хорошо, сетка импортируется и отображается, я могу манипулировать ею с помощью шейдеров, но у меня проблема.
Я также загружаюсь и присваиваю ему текстуру. Потом я пытаюсь отобразить это так:
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(8);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, this->_entries[i].VB);
glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), 0); // Vertices
glVertexAttribPointer(8,2, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), (const GLvoid*)sizeof(RomCommon::Vector3D)); // Supposed texture position
glVertexAttribPointer(2,3, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), (const GLvoid*)(sizeof(RomCommon::Vector2D) + sizeof(RomCommon::Vector3D))); // Supposed normal position
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->_entries[i].IB);
glBindTexture(GL_TEXTURE_2D, 3);
glDrawElements(GL_TRIANGLES, this->_entries[i]._indexCount, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(8);
glDisableVertexAttribArray(2);
Моя проблема в том, что текстура не отображается. Только цвет от первого пикселя текстуры назначен (в моем случае это синий). Я использовал gDEBugger для отладки всего процесса, и я могу сказать, что VertexBuffer, кажется, настроен правильно, изображение текстуры загружено правильно, но оно не будет отображаться.
Я попытался найти и опробовать различные аспекты отладки, в том числе:
РЕДАКТИРОВАТЬ
Я использую шейдеры CG с этим. Вот вершинная программа:
struct vsOutput {float4 position : POSITION;
float2 texCoord : TEXCOORD0;
float3 color : COLOR;
};
vsOutput VS_Main( float4 position : POSITION,
float2 texCoord : TEXCOORD0,
float3 color : COLOR,
uniform float4x4 ModelViewProj
)
{
vsOutput OUT;
OUT.position = mul(ModelViewProj, position);
OUT.texCoord = texCoord;
OUT.color = color;
return OUT;
}
И фрагмент программы:
struct fsOutput {
float4 color : COLOR;
};
fsOutput FS_Main(
float2 texCoord : TEXCOORD0,
uniform sampler2D decal : TEX0
)
{
fsOutput OUT;
OUT.color = tex2D(decal,texCoord);
return OUT;
}
Я мог бы добавить больше деталей о моем проекте, если необходимо, хотя из того, что я проследил, проблема, кажется, где-то в рендеринге буферов вершин.
РЕДАКТИРОВАТЬ
Я также обнаружил, что, поскольку я использую CG, vertexAttribPointers должен быть другим (8 для TEXCOORD0), поэтому я изменил общее описание, основываясь на этом.
РЕШЕНИЕ РЕДАКТИРОВАТЬ
Большое спасибо за несколько глав в комментариях, которые позволили мне взглянуть на проблему с другой точки зрения и даже немного почитать. Вот решение:
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(8);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, this->_entries[i].VB);
glVertexAttribPointer(0,3, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), 0); // Vertices
glVertexAttribPointer(8,2, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), (const GLvoid*)sizeof(RomCommon::Vector3D)); // Supposed texture position
glVertexAttribPointer(2,3, GL_FLOAT, GL_FALSE, sizeof(RomCommon::Vertex3D), (const GLvoid*)(sizeof(RomCommon::Vector2D) + sizeof(RomCommon::Vector3D))); // Supposed normal position
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->_entries[i].IB);/* Solution start */
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(RomCommon::Vertex3D), (const GLvoid*)12);
glBindTexture(GL_TEXTURE_2D, 3);
glDrawElements(GL_TRIANGLES, this->_entries[i]._indexCount, GL_UNSIGNED_INT, 0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
/* Solution end */glDisableVertexAttribArray(0);
glDisableVertexAttribArray(8);
glDisableVertexAttribArray(2);
Моя проблема заключалась в том, что я только передавал координаты текстуры в шейдер, но не передавал их на конечный автомат OpenGL (если это хорошее выражение).
Я думаю, что это как-то связано с тем, что я использую шейдеры CG, а не шейдеры GLSL, хотя могу ошибаться. Код основан на нескольких примерах и объяснениях, которые я прочитал, но все они были основаны на шейдерах GLSL, и они работали, отсюда и цель.
Во всяком случае, теперь это решено.
glBindTexture(GL_TEXTURE_2D, 3);
Я бы с осторожностью применял идентификаторы объектов текстуры в OpenGL. Технически это должен работать, но используя glGenTextures()
получить идентификаторы текстуры — лучшая идея.
Других решений пока нет …