!我知道有更简单的方法来绘制到屏幕而不是这个,但我需要以这种特定的方式做到这一点!
我通过fbo绘制纹理。 然后我使用着色器将其重新绘制到屏幕上,使用sampler2D(纹理)并使着色器将gl_fragColor设置为片段着色器所在的特定点处的sampler2D的颜色。
我遇到的问题是显示缓冲区(着色器正在绘制fbo)只是一个纯蓝色,即使我用蓝色背景为fbo绘制白色方块。
我的代码:
主渲染循环:
while(!Display.isCloseRequested()){
//Drawing on the fbo a blue background and white square
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
glColor3f(0,0,1);
drawQuad(0,0,WIDTH,HEIGHT);
glColor3f(1,1,1);
drawQuad(0,0,50,50);
//Trying to draw the texture from the previous fbo
//on to the display buffer with a fragment shader,
//however it only draws a blue background, no white square.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texID);
glUseProgram(shaderProgram);
glUniform1i(glGetUniformLocation(shaderProgram, "tex"), 0);
glUniform1f(glGetUniformLocation(shaderProgram, "width"), WIDTH);
glUniform1f(glGetUniformLocation(shaderProgram, "height"), HEIGHT);
glBegin(GL_QUADS); {
glVertex2f(0, 0);
glVertex2f(0, HEIGHT);
glVertex2f(WIDTH, HEIGHT);
glVertex2f(WIDTH, 0);
} glEnd();
glUseProgram(0);
Display.update();
}
我的着色器:
uniform sampler2D tex;
uniform float width;
uniform float height;
void main() {
vec4 color = texture2D( tex, gl_FragCoord.xy / vec2(width, height));
gl_FragColor = color;
}
fbo的init方法:
texID=glGenTextures();
fboID=glGenFramebuffersEXT();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
glBindTexture(GL_TEXTURE_2D, texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, WIDTH, HEIGHT, 0,GL_RGBA, GL_INT, (java.nio.ByteBuffer) null);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, texID, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
我认为发生这种情况的一个原因可能是因为我没有正确地将Sampler2D传递给着色器但我不确定如何解决它。
如果有任何可以说明为什么会发生这种情况或如何解决它(或者甚至只是正确方向上的一点),我们将不胜感激!
(对不起英文不好!)
答案 0 :(得分:1)
glUniform1i (...)
和glUseProgram (...)
。执行glUniform1i(glGetUniformLocation(shaderProgram, "tex"), 0);
时,当前活动的程序 0 ,实际上应该会产生以下错误:
如果没有当前的程序对象,则生成
GL_INVALID_OPERATION
。
如果你交换上面提到的两行,那应该可以解决你的问题。将来,当某些东西不起作用时,你应该检查glGetError (...)
。
更新 :既然修复了原始问题,就不会正确设置纹理缩小过滤器。
要设置枚举,您必须使用glTexParameteri (...)
。 glTexParameterf (...)
将解释作为浮点数传递的值,GL_LINEAR
( 0x2601 )具有类型GLenum
(32位无符号整数)。幸运的是,所有核心OpenGL枚举仅使用较低的16位,因此它们可以精确地表示为32位浮点数(可以表示最多2 24 的所有整数),但是你可以看到为什么你不想要将整数常量转换为浮点数。
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
更新2 :使用texture2D (...)
时必须使用标准化纹理坐标。
gl_FragCoord.xy
的范围为[ 0 ,width
]和[ 0 ,height
],超出了标准化范围任何大于 1x1 的帧缓冲区的范围。要解决这个问题,你必须除以宽度和高度。
texelFetch (...)
允许您使用非标准化坐标,但它需要GLSL 1.30,您必须将gl_FragCoord.xy
强制转换为ivec2
才能使用它。如果你画的尺寸不同于窗户的FBO,也可能会给你带来不便。