GLSL 4.10纹理映射

时间:2011-11-29 20:25:16

标签: c++ opengl glsl shader fragment-shader

我正试图弄清楚如何使用GLSL版本4.10进行纹理映射。我对GLSL很陌生,并且很高兴今天使用着色器获得基于sin(时间)的颜色渐变的三角形渲染。现在我对使用单个纹理的着色器很感兴趣。

许多教程甚至Stack Overflow答案建议使用gl_MultiTexCoord0。但是,由于GLSL 1.30和最新版本现在为4.20,因此已被弃用。我的显卡不支持4.20,这就是我尝试使用4.10的原因。

我知道我正在适当地生成和绑定我的纹理,并且我有适当的顶点坐标和纹理坐标,因为当我使用固定功能管道时我的高度图呈现完美,并且它使用颜色而不是纹理渲染得很好。

这是我的GLSL着色器和一些我的C ++绘图代码:

---heightmap.vert (GLSL)---

in vec3 position;
in vec2 texcoord;

out vec2 p_texcoord;

uniform mat4 projection;
uniform mat4 modelview;

void main(void)
{
    gl_Position = projection * modelview * vec4(position, 1.0);
    p_texcoord = texcoord;
}


---heightmap.frag (GLSL)---

in vec2 p_texcoord;

out vec4 color;

uniform sampler2D texture;

void main(void)
{
    color = texture2D(texture, p_texcoord);
}


---Heightmap::Draw() (C++)---

// Bind Shader
// Bind VBO + IBO
// Enable Vertex and Texcoord client state

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);

// glVertexPointer(...)
// glTexCoordPointer(...)

glUniform4fv(projLoc, projection);
glUniform4fv(modelviewLoc, modelview);
glUniform1i(textureId, 0);

// glDrawElements(...)

// glDisable/unbind everything

我也怀疑的是我是否必须将纹理坐标输入到片段着色器中作为变化,因为我没有在顶点着色器中触摸它。另外,我不知道它是如何从中得到内插的texcoords。看起来它只是得到0.f或1.f,而不是插值坐标。我不了解着色器,了解它是如何工作的。如果有人能够启发我,我会很激动!

编辑1:

@Bahbar:很抱歉,这是一个错字。我正在一台机器上键入代码而从另一台机器上读取代码。就像我说的,它都与固定功能管道一起工作。虽然不推荐使用glEnableClientState和gl [Vertex | TexCoord]指针,但它们仍应使用着色器,不是吗? glVertexPointer而不是glVertexAttribPointer使用颜色而不是纹理。另外,我使用的是glBindAttribLocation(位置为0,texcoord为1)。

我仍在使用glVertexPointer的原因是我试图一次弃用一件事。

1 个答案:

答案 0 :(得分:3)

glBindTexture将纹理对象作为第二个参数。

// Enable Vertex and Texcoord client state

我假设你的意思是通用的顶点属性?您的positiontexcoord属性设置在哪里?要做到这一点,你需要调用glEnableVertexAttrib和glVertexAttribPointer而不是glEnableClientState和glVertex / TexCoordPointer(所有这些都被抛弃,就像gl_MultiTexCoord在glsl中一样)。

当然,要确定绑定属性的位置,您需要调用glGetAttribLocation来确定GL选择放置attrib的位置,或者使用glBindAttribLocation自定义它(在链接程序之前)。

编辑添加,添加后:

好吧,0最终可能会从glVertexPointer中提取数据(原因你不应该依赖.attrib 0很特殊,大多数IHV使它像Vertex一样工作),但很可能不会从glTexCoord中提取数据。

理论上,通用属性之间没有重叠(比如你的texcoord,它从glVertexAttribPointer(1,XXX)获取数据,1这里是你选择的位置),以及内置属性(如gl_MultiTexCoord [0 ]从glTexCoordPointer获取数据)。

现在,众所周知,nvidia不遵循规范,实际上是别名属性(据我所知,这来自Cg模型),并且甚至会说使用glTexCoord的特定属性位置( Cg spec表示它使用TexCoord0的位置8 - 而位置1是属性混合权重 - 请参阅表39,p242),但实际上您应该咬住子弹并将TexCoordPointer切换为VertexAttribPointer调用。