Текстуры привязки OpenGL к объектам буфера вершин (с шейдерами компьютерной графики)

Перейду сразу к делу:

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

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


person karmalis    schedule 29.01.2013    source источник
comment
Я не вижу шейдеров. В этом может быть проблема с рендерингом буферов вершин. Вы указали атрибуты вершины (0, 1 и 2), но не придали им значения. И да, вы не привязываете текстуры к VBO; вы привязываете их к текстурным блокам и получаете доступ как uniform sampler* переменные в GLSL.   -  person Bartek Banachewicz    schedule 29.01.2013
comment
У меня есть шейдеры, но я не указал их в описании (при необходимости могу добавить и вершинные, и фрагментные шейдерные функции). Они включаются перед glEnableVertexAttribArray(0); и отключено после glDisableVertexAttribArray(2); Я также использую шейдеры компьютерной графики, но я полагаю, что они работают аналогичным образом.   -  person karmalis    schedule 29.01.2013
comment
Вы пытались визуализировать UV как цвет?   -  person Bartek Banachewicz    schedule 29.01.2013
comment
Пожалуйста, простите мое невежество, я не так хорош в этих вещах. Как снова сделать UV-развертку цветной?   -  person karmalis    schedule 29.01.2013
comment
@karmalis: Просто назначьте координату текстуры в качестве выходного цвета. Я также немного не уверен в том, как Cg назначает местоположение атрибута вершины параметрам VS_Main. с GLSL вам нужно либо использовать glGetAttributeLocation для получения индекса местоположения на основе его имени, либо назначить его явно в макете.   -  person datenwolf    schedule 29.01.2013
comment
Большое спасибо, я попробую это. Я также, вероятно, попытаюсь использовать шейдеры GLSL только для тестирования и посмотрю результат. Затем я обновлю вопрос своими выводами. Спасибо, парни.   -  person karmalis    schedule 29.01.2013
comment
Если я попытаюсь вывести textcoord непосредственно в цвет, что я должен увидеть?   -  person karmalis    schedule 29.01.2013
comment
Зависит от фактического кода, используемого для их вывода.   -  person Bartek Banachewicz    schedule 30.01.2013
comment
Я нашел решение проблемы. Большое спасибо за хороший толчок туда, где я должен был быть.   -  person karmalis    schedule 30.01.2013
comment
У меня похожая проблема (на карте показан только первый пиксель) с шейдерами Cg, но это происходит только в том случае, если я не использую кадровые программы. Эта проблема возникает только на компьютерах Mac с видеокартами Radeon. Если я включу простую фрагментную программу, подобную той, которую вы показали, она отлично отобразит текстуру.   -  person user642252    schedule 19.04.2013
comment
@user642252 user642252 Что я делаю, так это то, что приведенный выше код окружен данными, которые включают шейдеры Vertex и Fragment, а затем отключают их с помощью cgGLEnableProfile(), а затем cgGLBindProgram(). В CG также есть полезная функция cgGetLastErrorString, которую я всегда запускаю после каждого вызова функции CG, просто для проверки ошибок. Теперь, когда все отрендерено, я отключаю эти параметры. Есть еще одна вещь. Насколько я знаю, не все из CG поддерживается картами ATI radeon. Попробуйте примеры, вы увидите. Не знаю, поможет ли это вообще, но было бы хорошо узнать о проблеме больше.   -  person karmalis    schedule 24.04.2013


Ответы (1)