GLSL 4.10 Текстурное картографирование - PullRequest
2 голосов
/ 30 ноября 2011

Я пытаюсь понять, как сделать наложение текстур, используя GLSL версии 4.10.Я довольно новичок в GLSL и был счастлив получить сегодня рендеринг треугольников с выцветанием цветов на основе греха (времени) с использованием шейдеров.Теперь я заинтересован в использовании шейдеров с одной текстурой.

Множество уроков и даже ответы на переполнение стека предлагают использовать gl_MultiTexCoord0.Тем не менее, это не рекомендуется с GLSL 1.30, и последняя версия теперь 4.20.Моя видеокарта не поддерживает 4.20, поэтому я пытаюсь использовать 4.10.

Я знаю, что я генерирую и привязываю свою текстуру надлежащим образом, и у меня есть правильные координаты вершин и координаты текстуры, потому что моя карта высот отображаласьидеально, когда я использовал конвейер с фиксированными функциями, и он хорошо рендерится с цветом, а не с текстурой.

Вот мои GLSL-шейдеры и некоторый мой код рисования C ++:

---heightmap.vert (GLSL)---

in vec3 position;
in vec2 texcoord;

out vec2 p_texcoord;

uniform mat4 projection;
uniform mat4 modelview;

void main(void)
{
    gl_Position = projection * modelview * vec4(position, 1.0);
    p_texcoord = texcoord;
}


---heightmap.frag (GLSL)---

in vec2 p_texcoord;

out vec4 color;

uniform sampler2D texture;

void main(void)
{
    color = texture2D(texture, p_texcoord);
}


---Heightmap::Draw() (C++)---

// Bind Shader
// Bind VBO + IBO
// Enable Vertex and Texcoord client state

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);

// glVertexPointer(...)
// glTexCoordPointer(...)

glUniform4fv(projLoc, projection);
glUniform4fv(modelviewLoc, modelview);
glUniform1i(textureId, 0);

// glDrawElements(...)

// glDisable/unbind everything

В чем я также подозреваю, так это в том, что мне нужно передать материал координат текстуры фрагментному шейдеру как вариант, поскольку я не касаюсь его в вершинном шейдере.Кроме того, я понятия не имею, как он получит интерполированные текстовые координаты от этого.Кажется, что он просто получит 0.f или 1.f, а не интерполированную координату.Я не знаю достаточно о шейдерах, чтобы понять, как это работает.Если бы кто-то мог просветить меня, я был бы в восторге!

Правка 1:

@ Бахбар: Извините, это была опечатка.Я набираю код на одной машине, а читаю с другой.Как я уже сказал, все это работает с конвейером с фиксированной функцией.Хотя glEnableClientState и gl [Vertex | TexCoord] Pointer устарели, они все равно должны работать с шейдерами, не так ли?glVertexPointer вместо glVertexAttribPointer работал с цветами, а не с текстурами.Кроме того, я использую glBindAttribLocation (позиция в 0 и текскорд в 1).

Причина, по которой я все еще использую glVertexPointer, заключается в том, что я пытаюсь отменить одну вещь за раз.

1 Ответ

3 голосов
/ 30 ноября 2011

glBindTexture принимает объект текстуры в качестве второго параметра.

// Enable Vertex and Texcoord client state

Полагаю, вы имели в виду общие атрибуты вершин?Где установлены ваши атрибуты position и texcoord?Чтобы сделать это, вам нужно несколько вызовов glEnableVertexAttrib и glVertexAttribPointer вместо glEnableClientState и glVertex / TexCoordPointer (все они устарели так же, как gl_MultiTexCoord в glsl).

И, конечно, на рисункеатрибуты связаны, вам нужно либо вызвать glGetAttribLocation, чтобы выяснить, где GL выбрал размещение атрибута, либо определить его самостоятельно с помощью glBindAttribLocation (до связывания программы).

Изменить, чтобы добавить послеВаше добавление:

Что ж, 0 может закончиться извлечением данных из glVertexPointer (по причинам, на которые вы не должны полагаться. attrib 0 особенный, и большинство IHV заставляют его работать так же, как Vertex), но 1 очень вероятноне будет получать данные из glTexCoord.

Теоретически нет перекрытия между общими атрибутами (такими как ваша texcoord, которая получает свои данные из glVertexAttribPointer (1, XXX), 1 здесь является выбранным вами местоположением), и встроенными атрибутами (такими какgl_MultiTexCoord [0], которая получает свои данные из glTexCoordPointer).

Теперь известно, что nvidia не следует спецификации и даже псевдонимам атрибутов (насколько я знаю, это из модели Cg), и доходит до того, что говорит об использовании определенного местоположения атрибута дляglTexCoord (спецификация Cg предполагает, что он использует местоположение 8 для TexCoord0 - а местоположение 1 - это атрибут blendweight - см. таблицу 39, p242), но на самом деле вам просто нужно прикусить пулю и переключить ваш TexCoordPointer на вызовы VertexAttribPointer.

...