Opengl 为什么我会得到;纹理单元0作为sampler2D和samplerCube访问;两个不同的采样器?
我有一些OpenGL/Python代码:Opengl 为什么我会得到;纹理单元0作为sampler2D和samplerCube访问;两个不同的采样器?,opengl,textures,glsl,pyopengl,Opengl,Textures,Glsl,Pyopengl,我有一些OpenGL/Python代码: import sys from OpenGL.GL import * from OpenGL.GL import shaders from OpenGL.GLU import * from OpenGL.GLUT import * glutInit(sys.argv) glutInitDisplayMode(GLUT_RGBA) glutInitWindowSize(640, 480) window = glutCreateWindow("Test"
import sys
from OpenGL.GL import *
from OpenGL.GL import shaders
from OpenGL.GLU import *
from OpenGL.GLUT import *
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(640, 480)
window = glutCreateWindow("Test")
print glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS)
print glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS)
print glGetIntegerv(0x8872)
print glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
fs = (
"""
#version 130
uniform sampler2D foo;
uniform samplerCube bar;
void main()
{
vec4 c1 = texture2D(foo, vec2(0, 0));
vec4 c2 = textureCube(bar, vec3(0, 0, 0));
gl_FragColor = c1 + c2;
}
"""
)
shader = shaders.compileShader(fs, GL_FRAGMENT_SHADER)
program = shaders.compileProgram(shader)
print program
运行时,片段着色器无法编译:
$ python tex.py
16
16
16
48
Traceback (most recent call last):
File "tex.py", line 35, in <module>
program = shaders.compileProgram(shader)
File "/usr/local/lib/python2.7/dist-packages/OpenGL/GL/shaders.py", line 196, in compileProgram
program.check_validate()
File "/usr/local/lib/python2.7/dist-packages/OpenGL/GL/shaders.py", line 108, in check_validate
glGetProgramInfoLog( self ),
RuntimeError: Validation failure (0): Texture unit 0 is accessed both as sampler2D and samplerCube
$python tex.py
16
16
16
48
回溯(最近一次呼叫最后一次):
文件“tex.py”,第35行,在
程序=着色器。编译程序(着色器)
compileProgram中的文件“/usr/local/lib/python2.7/dist packages/OpenGL/GL/shaders.py”,第196行
program.check_validate()
文件“/usr/local/lib/python2.7/dist packages/OpenGL/GL/shaders.py”,第108行,在check\u validate中
glGetProgramInfoLog(自我),
运行时错误:验证失败(0):纹理单元0作为sampler2D和samplerCube访问
我不明白为什么两个采样器对象会绑定到相同的纹理单元?使用GLSL 1.30,我甚至不知道如何在编译程序之前指定纹理单位。而且应该可以使用多个采样器和纹理单元
我做错了什么?您可能将采样器统一值保留为默认值,或者将其中一个设置为0。这显然是错误的 图形纹理绑定代码应如下所示:
glActiveTexture(GL_TEXTURE0 + x)
glBindTexture(GL_TEXTURE_2D, …)
glUniform1i(uniform_location_of_foo, x)
glActiveTexture(GL_TEXTURE0 + y)
glBindTexture(GL_TEXTURE_CUBE_MAP, …)
glUniform1i(uniform_location_of_bar, y)
也就是说,采样器统一整数值必须与匹配纹理目标绑定到的纹理单元相对应。我最近刚开始学习OpenGL,所以我不熟悉它的所有细节。然而,我也遇到了同样的问题,这是因为在我将制服分配给各自的单位之前,我试图验证着色器。在我按照以下顺序完成所有操作后,问题得到了解决:
glLinkProgram(m_Program);
m_Uniforms[DIFFUSE_U] = glGetUniformLocation(m_Program, "diffuse");
m_Uniforms[NORMALMAP_U] = glGetUniformLocation(m_Program, "normalMap");
m_Uniforms[SHADOWMAP_U] = glGetUniformLocation(m_Program, "shadowMap");
glUseProgram(m_Program);
glUniform1i(m_Uniforms[DIFFUSE_U], 0);//sets the diffuse sampler to the texture bound as unit 0
glUniform1i(m_Uniforms[NORMALMAP_U], 1);
glUniform1i(m_Uniforms[SHADOWMAP_U], 2);
glValidateProgram(m_Program);
请注意,这发生在着色器编译之前。因此,程序和统一(位置)都还不存在……我感觉调用
glValidateProgram()
是PyOpenGL的错,这取决于OpenGL的状态。我将尝试跳过该步骤,并查看它在绑定纹理后是否正确验证。谢谢@维嘉德:那对PyOpenGL来说是糟糕的设计。我希望这种行为是可以失败的,因为程序不一定需要立即处于有效的工作状态。调用glUseProgram(…)
以及稍后设置纹理图像单元和其他支持状态是常见的场景。验证程序状态的最佳时间是在调用glDraw*(…)
之前-出于上述原因,在任何其他点进行验证都为时过早。您需要在glLinkProgram()
和glUniform1i()
调用之间进行glUseProgram()
调用glUniform1i()
适用于当前程序。谢谢,我编辑了代码以显示glUseProgram()的去向。