GL_TEXTURE_2D против GL_TEXTURE_RECTANGLE

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

Дамп текстуры

введите здесь описание изображения

Теперь, после этого, я визуализирую содержимое этого фреймбуфера на экране.

Это работает, если я использую GL_TEXTURE_RECTANGLE в конструкторе фреймбуфера:

https://github.com/elect86/Joglus/blob/master/Joglolus/src/joglus/example1/FrameBuffer.java

При привязке текстуры функция renderFullScreenQuad, строка 372:

https://github.com/elect86/Joglus/blob/master/Joglolus/src/joglus/example1/GlViewer.java

И используя sampler2DRect во фрагментном шейдере:

#version 330

out vec4 outputColor;
uniform sampler2DRect texture0;

void main() {
    outputColor = texture(texture0, gl_FragCoord.xy);
}

Но если я изменю все RECTANGLE на 2D и использую sample2D в fs, я получаю полное черное изображение в конце display(), хотя дамп текстуры показывает всегда правильное изображение... Я хотел бы знаю, почему.


person elect    schedule 06.08.2014    source источник


Ответы (1)


Координаты текстур работают по-разному для текстур типов GL_TEXTURE_RECTANGLE и GL_TEXTURE_2D:

  • Для GL_TEXTURE_RECTANGLE диапазон координат текстуры, соответствующий всему изображению текстуры, равен [0,0, ширина] x [0,0, высота]. Другими словами, координаты текстуры измеряются в пикселях изображения текстуры.
  • Для GL_TEXTURE_2D диапазон координат текстуры составляет [0,0, 1,0] x [0,0, 1,0].

С этим утверждением в вашем фрагментном шейдере:

outputColor = texture(texture0, gl_FragCoord.xy);

вы используете координаты в пикселях в качестве координат текстуры. Исходя из вышеизложенного, это будет работать для текстуры RECTANGLE, но не для 2D.

Поскольку ваши исходные входные координаты в вершинном шейдере находятся в диапазоне [0.0, 1.0], самый простой способ исправить это — передать непреобразованные координаты из вершинного шейдера во фрагментный шейдер и использовать их в качестве координат текстуры. Тогда вершинный шейдер будет выглядеть так:

#version 330

layout (location = 0) in vec2 position;
out vec2 texCoord;
uniform mat4 modelToClipMatrix;

void main() {
    gl_Position = modelToClipMatrix * vec4(position, 0, 1);
    texCoord = position;
}

И фрагментный шейдер:

#version 330

in vec2 texCoord;
out vec4 outputColor;
uniform sampler2D texture0;

void main() {
    outputColor = texture(texture0, texCoord);
}
person Reto Koradi    schedule 07.08.2014
comment
Спасибо, я этого не знал.. Я собираюсь попробовать это прямо сейчас.. Просто вопрос, в fs sampler2D sampler2DRect применяется та же логика? - person elect; 07.08.2014
comment
Это работает как шарм, спасибо за ваш яркий ответ :) - person elect; 07.08.2014