我正在使用freeglut,GLEW and DevIL到render a textured teapot使用顶点和片段着色器。这在Ubuntu 14.04上的OpenGL 2.0和GLSL 1.2中都运行良好。
现在,我想将凹凸贴图应用于茶壶。我的讲师显然没有自己酿造茶,所以不知道他们应该是smooth。无论如何,我发现a nice-looking tutorial on old-school bump mapping包含一个开始的片段着色器:
uniform sampler2D DecalTex; //The texture
uniform sampler2D BumpTex; //The bump-map
他们没有提到的是如何首先将两个纹理传递到着色器。
以前我
//OpenGL cpp file
glBindTexture(GL_TEXTURE_2D, textureHandle);
//Vertex shader
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
//Fragment shader
gl_FragColor = color * texture2D(DecalTex,gl_TexCoord[0].xy);
所以现在我
//OpenGL cpp file
glBindTexture(GL_TEXTURE_2D, textureHandle);
glBindTexture(GL_TEXTURE_2D, bumpHandle);
//Vertex shader
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_MultiTexCoord1;
//Fragment shader
gl_FragColor = color * texture2D(BumpTex,gl_TexCoord[0].xy);
//no bump logic yet, just testing I can use texture 1 instead of texture 0
但这不起作用。纹理完全消失(茶壶是白色的)。我已经尝试了GL_TEXTURE_2D_ARRAY,glActiveTexture以及其他一些可能看似但毫无结果的选项。
在筛选出通常的OpenGL和新旧GLSL的混合包之后,我得出的结论是我可能需要glGetUniformLocation
。我究竟如何在OpenGL cpp文件中使用 将已经填充的纹理句柄传递给片段着色器?
(这是作业,所以请用最少的代码片段回答(如果有的话)。谢谢!)
如果不这样做,有没有人有茶舒适的网格?
答案 0 :(得分:33)
这很简单,真的。您所需要的只是将采样器绑定到具有glUniform1i
的纹理单元。因此,对于您的代码示例,假设有两个统一的采样器:
uniform sampler2D DecalTex; // The texture (we'll bind to texture unit 0)
uniform sampler2D BumpTex; // The bump-map (we'll bind to texture unit 1)
在初始化代码中:
// Get the uniform variables location. You've probably already done that before...
decalTexLocation = glGetUniformLocation(shader_program, "DecalTex");
bumpTexLocation = glGetUniformLocation(shader_program, "BumpTex");
// Then bind the uniform samplers to texture units:
glUseProgram(shader_program);
glUniform1i(decalTexLocation, 0);
glUniform1i(bumpTexLocation, 1);
好的,着色器制服设置,现在我们渲染。为此,您需要通常的glBindTexture
加glActiveTexture
:
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
glBindTexture(GL_TEXTURE_2D, decalTexHandle);
glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1
glBindTexture(GL_TEXTURE_2D, bumpHandle);
// Done! Now you render normally.
在着色器中,您将像使用纹理采样器一样使用纹理采样器:
vec4 a = texture2D(DecalTex, tc);
vec4 b = texture2D(BumpTex, tc);
注意:对于像凹凸贴图这样的技术,您只需要一组纹理坐标,因为纹理是相同的,只包含不同的数据。所以你应该将纹理坐标传递为vertex attribute。
答案 1 :(得分:-1)
而不是使用:
glUniform1i(decalTexLocation, 0);
glUniform1i(bumpTexLocation, 1);
在你的代码中你可以:
layout(binding=0) uniform sampler2D DecalTex;
// The texture (we'll bind to texture unit 0)
layout(binding=1)uniform sampler2D BumpTex;
// The bump-map (we'll bind to texture unit 1)
着色器中的。这也意味着您不必查询该位置。