GLSL 4.10 Отображение текстур

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

Многие учебники и даже ответы на вопросы Stack Overflow предлагают использовать 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:

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

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


person Andrew Rasmussen    schedule 29.11.2011    source источник


Ответы (1)


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.

person Bahbar    schedule 29.11.2011
comment
Я читал в Интернете, и похоже, что вы определенно правы, что TexCoordPointer не обязательно будет делать то же самое, что и VertexAttribPointer, поэтому я переключусь сегодня вечером и согласен, если он работает. Спасибо! :) - person Andrew Rasmussen; 30.11.2011