将 Sampler2D 与着色器一起使用时出现问题

Issue with using Sampler2D with a Shader

!我知道有比这更容易绘制到屏幕上的方法,但我需要以这种特定方式进行!

我正在通过 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 的初始化方法:

    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 传递给着色器,但我不确定如何修复它。

如果有人能说出为什么会发生这种情况或如何解决它(甚至只是正确方向上的一点),我们将不胜感激!

(抱歉英语不好!)

您已将呼叫转接到 glUniform1i (...)glUseProgram (...)

在执行 glUniform1i(glGetUniformLocation(shaderProgram, "tex"), 0); 时,当前活动的程序是 0 实际上应该会产生以下错误:

GL_INVALID_OPERATION is generated if there is no current program object.

如果你交换上面提到的两行,那应该可以解决你的问题。将来你应该在某些东西不工作时检查 glGetError (...)


更新:既然原来的问题已经解决,你没有正确设置纹理缩小过滤器。

要设置枚举数,您必须使用glTexParameteri (...)glTexParameterf (...) 会将传递的值解释为浮点数,并且 GL_LINEAR (0x2601) 的类型为 GLenum(32 位无符号整数).幸运的是,所有核心 OpenGL 枚举只使用低 16 位,因此它们可以精确地表示为 32 位浮点数(可以表示最大为 224 的所有整数),但你可以明白为什么不想将整数常量转换为浮点数。

因此,下面一行:

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 尺寸与您的 window.

不同,也可能会带来不便