OpenGL 纹理不渲染
纹理根本没有显示出来,所有的几何图形都是黑色的。
截图: https://i.stack.imgur.com/QE1QU.png
代码: http://pastebin.com/SvB8rxxt
我还想链接我正在尝试渲染的纹理和transformations.py模块,但因为我的信誉不够,不能放超过两个链接。你可以在网上搜索“modern opengl 02”,找到我获取前者的教程,搜索“transformations py”可以找到后者。
搜索“TEXTURE STUFF START”可以找到纹理设置的地方。
我尝试检查所有部分(图像加载、纹理加载、纹理坐标数据、着色器),但我不知道怎么确定到底是哪个出了问题,按我所能看出来的,所有部分似乎都没问题。
更新:更新了代码,修复了一些可能的问题,但仍然出现同样的情况。
1 个回答
我对Python不太熟悉,所以可能漏掉了一些东西。
如果所有的片段都显示成黑色,可能是以下几个原因:
- 纹理数据没有加载
- 纹理没有绑定到那个着色器的采样器上
- 光照计算有问题
- Uniform变量没有正确发送到着色器
- 法线属性有问题(比如它们都是0)。
因为你的着色器代码是 finalColor = texture(tex, fragTexCoord);
,所以可以排除光照计算和uniform变量的问题。那就说明你的纹理采样器可能有问题。
在iOS上,当我绑定一个纹理时,我需要做以下操作:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glUniforms[U_textureSampler], 0);
我想你也需要执行相同的步骤。也许 texturebuffer.bind()
会为你完成其中的一些步骤。但不然的话,你需要在某个地方激活纹理采样器、绑定它,并设置uniform变量。
一个未激活的纹理可能会显示为黑色。如果uniform设置不正确,可能会返回0。
你需要在某个地方将着色器中的 `uniform sampler2D tex` 连接到你在渲染时绑定的纹理。
我觉得把纹理ID叫做 tex
可能会让人困惑,而且这不是一个好习惯(这个ID是通过 glGenTextures
返回的),同时又把uniform叫做 `tex`。它们是两个不同的东西,一个是纹理ID,另一个是uniform变量。
我建议你把ID的名字从 tex
改成 texID
,这样可以更清楚地分开它们。然后你可能会发现你的代码中没有获取glsl uniform变量 tex
的位置(glGetUniformLocation),而且这必须在着色器编译后进行。也许在Python中有我没看到的帮助。
但是当你执行 texture buffer.bind
时,在哪里连接到uniform变量 'tex' 呢?
* 更新 1 *
这里有个建议,告诉你如何获取那个uniform位置并使用它。要在着色器编译后执行这个操作。它会把一个uniform位置ID返回给你的应用:
u_tex = glGetUniformLocation(shader, "tex")
把那个纹理ID变量改成 texID
,像这样:
texID = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texID)
然后在你的显示循环中,当你绑定纹理使用时,执行:
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, texID)
glUniform1i(u_tex, 0)
我得承认我不知道 texturebuffer.bind()
做了什么。所以最好在那行之前或之后尝试上面的三行代码。
* 更新 2 *
我刚注意到你还缺少 glEnable(GL_TEXTURE_2D)
,它应该和你的 glTexParameter 代码在一起。把它加到那些行的上面。
* 更新 3 *
作为测试,在你的着色器中把 finalColor = texture(tex, fragTexCoord);
替换为 finalColor = vec4(1.0,0.0,0.0,1.0);
,看看盒子是否变成红色。因为现在我想起来我不知道 finalColor
是什么。它应该是 gl_FragColor =
。
* 更新 4 *
做上述测试,确保你可以手动设置片段的颜色。我之前没意识到你在使用OpenGL 3.0。我以为是2.0。输出变量的名称取决于你的glsl版本。你已经把版本设置为1.3。查看这个帖子,确保你在这部分做得正确:片段着色器如何知道使用哪个变量来表示像素的颜色?