OpenGL связывает текстуры с объектами буфера вершин (с помощью CG Shaders)

Я сразу перейду к делу:

Я создал структуру для моих вершин:

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); перед связыванием текстуры
  • поиск ошибок
  • в поисках странных сообщений
  • двойная проверка буфера вершин в памяти (буквально проходя через elemnts и сравнивая, что находится в файле * .dae)

РЕДАКТИРОВАТЬ

Я использую шейдеры 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, и они работали, отсюда и цель.
Во всяком случае, теперь это решено.

3

Решение

glBindTexture(GL_TEXTURE_2D, 3);

Я бы с осторожностью применял идентификаторы объектов текстуры в OpenGL. Технически это должен работать, но используя glGenTextures() получить идентификаторы текстуры — лучшая идея.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]