用于片段着色器的 OpenGL GLSL 绑定采样器

Posted

技术标签:

【中文标题】用于片段着色器的 OpenGL GLSL 绑定采样器【英文标题】:OpenGL GLSL Binding Sampler for Fragment Shader 【发布时间】:2014-06-10 01:36:50 【问题描述】:

我希望在 2D OpenGL 应用程序上实现着色器。我的计划是将场景渲染到帧缓冲区对象,然后使用着色器将该帧缓冲区对象渲染到屏幕。

这是场景,我已将其绘制到帧缓冲区对象,然后从那里绘制到屏幕。使用箭头键可以让月亮四处移动(我为此感到非常自豪!)

但是,当我尝试使用我的着色器程序将帧缓冲区对象渲染到屏幕时,我得到了:

非常难过。这个片段着色器是我从tutorial 得到的,我确信问题出在统一变量上。

这是片段着色器:

#version 330

in vec2 texCoord;
out vec4 outputColor;

uniform sampler2D gSampler;

void main()

   outputColor = texture2D(gSampler, texCoord);

这是我设置统一变量的方法:

gSampler = glGetUniformLocation(mProgramID, "gSampler");
glUniform1i(gSampler, GL_TEXTURE0);

这是我使用着色器程序 (mProgramID) 将帧缓冲区 (fbo_texture) 渲染到屏幕的方式

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,    0 ); 

glUseProgram(mProgramID);
glColor3f(1.0, 1.0, 1.0);
glEnable(GL_TEXTURE_2D);

glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, fbo_texture);

glBegin(GL_QUADS);x1= 0.0;x2= 400.0;y1= 0.0;y2 = 400.0;
    glTexCoord2f(0.0f, 1.0f); glVertex2f(x1, y1);
    glTexCoord2f(0.0f, 0.0f); glVertex2f(x1, y2);
    glTexCoord2f(1.0f, 0.0f); glVertex2f(x2, y2);
    glTexCoord2f(1.0f, 1.0f); glVertex2f(x2, y1);

glEnd();glDisable(GL_TEXTURE_2D);

SDL_GL_SwapBuffers();

所以我的问题是——纹理和采样器之间的联系是什么?如果着色器已经对纹理进行采样,我是否需要渲染纹理四边形?如果着色器正在对其进行纹理化,为什么不直接渲染一个空白四边形?

编辑:这是顶点着色器:

void main()


    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = ftransform();

【问题讨论】:

您正在顶点着色器中混合和匹配具有通用顶点属性的固定函数顶点函数。您要么需要使用glVertexAttrib2f (...),要么重新编写着色器以使用gl_MultiTexCoord0gl_Vertex。实际上,我刚刚意识到您甚至没有显示您的顶点着色器(即使用inout 的片段着色器)...您可以将其添加到您的问题中吗? 你说得对,那些 IN 和 OUT 线是完全没有必要的,它们应该与 Vertex Shader 对话吗? 嗯,在片段着色器中,in 变量来自顶点着色器的输出(或较新版本的 GLSL 中的几何/曲面细分评估),out 指的是颜色输出。我的评论更接近于如果你的 vertex 着色器使用inattribute 变量,那么你不应该使用固定函数顶点函数。但是现在你已经展示了你的顶点着色器,我可以看到它是没有必要的。但是你需要在片段着色器中匹配gl_TexCoord[0] 【参考方案1】:

你如何设置采样器的统一值确实有问题:

gSampler = glGetUniformLocation(mProgramID, "gSampler");
glUniform1i(gSampler, GL_TEXTURE0);

uniform需要设置的值是纹理单元的索引,而不是对应的枚举值。由于在这种情况下您使用的是纹理单元 0,因此您需要将 glUniform1i() 调用替换为:

glUniform1i(gSampler, 0);

【讨论】:

OHHH 现在可以使用了!着色器真的在渲染它!所以这意味着我的 glActiveTexture 设置为 0,但 GL_TEXTURE0 是别的东西,所以它没有找到纹理。太好了!!

以上是关于用于片段着色器的 OpenGL GLSL 绑定采样器的主要内容,如果未能解决你的问题,请参考以下文章

片段着色器不会在 OpenGL GLSL 中创建像光一样的渐变

顶点着色器的绘制操作

GLSL:采样器上传仅在删除未使用的采样器时有效

OpenGL和GLSL中的glTexParameter和过滤?

Unity ShaderGLSL

绑定 OpenGL 纹理采样器