Перейду сразу к делу:
Я создал структуру для своих вершин:
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 настроен правильно, изображение текстуры загружается правильно, но не отображается.
Я пробовал искать и пробовать различные аспекты отладки, в том числе:
- убедиться, что glEnable(GL_TEXTURE_2D) настроен;
- добавление glEnable(GL_LIGHTING) и glDisable(GL_LIGHTING);
- используя glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); и glDisable(GL_SCISSOR_TEST); перед привязкой текстуры
- выборка на предмет ошибок
- поиск странных сообщений
- двойная проверка буфера вершин в памяти (буквально просмотр элементов и перекрестное сравнение того, что находится в файле *.dae)
ИЗМЕНИТЬ
Я использую CG Shaders с этим. Вот программа Vertex:
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;
}
Я мог бы добавить больше подробностей о своем проекте, если это необходимо, хотя, судя по тому, что я проследил, проблема, похоже, кроется где-то в рендеринге буферов вершин.
ИЗМЕНИТЬ
Я также обнаружил, что, поскольку я использую компьютерную графику, 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 (если это хорошее выражение). Я думаю, это как-то связано с тем, что я использую шейдеры компьютерной графики, а не шейдеры GLSL, хотя могу ошибаться. Код основан на нескольких примерах и пояснениях, которые я читал, но все они были основаны на шейдерах GLSL и работали, отсюда и посвящение. Во всяком случае, теперь это решено.
uniform sampler*
переменные в GLSL. - person Bartek Banachewicz   schedule 29.01.2013