问题描述
我正在使用freeglut,GLEW 和DevIL 来使用顶点和片段着色器渲染纹理茶壶.在Ubuntu 14.04上的OpenGL 2.0和GLSL 1.2中,一切正常.
I am using freeglut, GLEW and DevIL to render a textured teapot using a vertex and fragment shader. This is all working fine in OpenGL 2.0 and GLSL 1.2 on Ubuntu 14.04.
现在,我想将凹凸贴图应用于茶壶.我的讲师显然不会自己泡茶,因此也不知道它们应该光滑一个>.无论如何,我发现关于老式凹凸贴图的漂亮教程,其中包括片段着色器始于:
Now, I want to apply a bump map to the teapot. My lecturer evidently doesn't brew his own tea, and so doesn't know they're supposed to be smooth. Anyway, I found a nice-looking tutorial on old-school bump mapping that includes a fragment shader that begins:
uniform sampler2D DecalTex; //The texture
uniform sampler2D BumpTex; //The bump-map
他们没有提到的是如何首先将两个纹理传递给着色器.
What they don't mention is how to pass two textures to the shader in the first place.
以前是我
//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和其他一些看起来似乎无济于事的选择.
but this doesn't work. The texture disappears completely (effectively the teapot is white). I've tried GL_TEXTURE_2D_ARRAY, glActiveTexture and few other likely-seeming but fruitless options.
在对新旧的OpenGL和GLSL的常规引用进行筛选之后,我得出的结论是我可能需要glGetUniformLocation
.如何在OpenGL cpp文件中使用此 将已经填充的纹理句柄传递给片段着色器?
After sifting through the usual mixed bag of references to OpenGL and GLSL new and old, I've come to the conclusion that I probably need glGetUniformLocation
. How exactly do I use this in the OpenGL cpp file to pass the already-populated texture handles to the fragment shader?
- How to pass an array of textures with different sizes to GLSL?
- Passing Multiple Textures from OpenGL to GLSL shader
- Multiple textures in GLSL - only one works
(这是家庭作业,因此请以最少的代码片段(如果有的话)进行回答.谢谢!)
(This is homework so please answer with minimal code fragments (if at all). Thanks!)
失败了,有人能喝茶吗?
推荐答案
真的很简单.您所需要做的就是使用 glUniform1i
将采样器绑定到某个纹理单元.因此,对于您的代码示例,假设有两个统一的采样器:
It is very simple, really. All you need is to bind the sampler to some texture unit with glUniform1i
. So for your code sample, assuming the two uniform samplers:
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
:
OK, shader uniforms set, now we render. To do so, you will need the usual glBindTexture
plus 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.
在着色器中,您将像已经使用的那样使用纹理采样器:
And in the shader, you will use the textures samplers just like you already do:
vec4 a = texture2D(DecalTex, tc);
vec4 b = texture2D(BumpTex, tc);
注意:对于凹凸贴图等技术,您仅需要一组纹理坐标,因为纹理相同,只包含不同的数据.因此,您应该将纹理坐标传递为顶点属性.
Note: For techniques like bump-mapping, you only need one set of texture coordinates, since the textures are the same, only containing different data. So you should probably pass texture coordinates as a vertex attribute.
这篇关于如何将多个纹理传递给单个着色器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!