我有一个小程序,它会渲染一个黄色三角形两次,一次在帧缓冲的左半部分,一次在右侧。
转储纹理
现在,之后我在屏幕上渲染此帧缓冲区的内容。
如果我在framebuffer构造函数中使用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并且我在fs中使用sample2D,我会在显示结束时获得一个完整的黑色图像(),尽管纹理的转储始终显示正确的图像......我想知道原因。
答案 0 :(得分:9)
纹理坐标在类型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);
}