mike
mike

Reputation: 55

texture1D and texture 2D in the same GLSL shader

I would like to pass two textures to my fragment shader. I succeed with two 2D textures, but not with one 1D and one 2D.

Here is a piece of the fragment shader code:

uniform sampler2D heights;
uniform sampler1D bboxes;
....
vec4 t2 = texture2D(heights, vec2(0.0, 0.0));
vec4 t1 = texture1D(bboxes, 0.0);

Here a piece of the main program code (notice the "print 'here'":

sh = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
shaders.glUseProgram(sh)
print 'here'

glEnable(GL_TEXTURE_2D)
glEnable(GL_TEXTURE_1D)

glActiveTexture(GL_TEXTURE0)
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
t_h = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, t_h)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 800, 600, 0, GL_RGB, GL_FLOAT, pts)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)


glActiveTexture(GL_TEXTURE0 + 2)
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
t_bb = glGenTextures(1)
glBindTexture(GL_TEXTURE_1D, t_bb)
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, len(bboxes), 0, GL_RGB, GL_FLOAT, bboxes)
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP)
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

loc_h = glGetUniformLocation(sh, "heights")
loc_bb = glGetUniformLocation(sh, "bboxes")
glUniform1i(loc_h, 0)
glUniform1i(loc_bb, 1)

The error I have is:

File "forth.py", line 282, in <module>
shader = setup()
File "forth.py", line 128, in setup
sh = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
File "/Library/Python/2.7/site-packages/PyOpenGL-3.0.2-py2.7.egg/OpenGL/GL/shaders.py", line 196, in compileProgram
program.check_validate()
File "/Library/Python/2.7/site-packages/PyOpenGL-3.0.2-py2.7.egg/OpenGL/GL/shaders.py", line 108, in check_validate
glGetProgramInfoLog( self ),
RuntimeError: Validation failure (0): Validation Failed: Sampler error:
Samplers of different types use the same texture image unit.
- or -
A sampler's texture unit is out of range (greater than max allowed or negative).

And the 'here' is not printed.

Please, any idea ?

Upvotes: 0

Views: 889

Answers (1)

246tNt
246tNt

Reputation: 2170

First issue is you seem to be using texture unit 2 for the 1D texture: glActiveTexture(GL_TEXTURE0 + 2)

But you're setting the uniform to 1 with glUniform1i(loc_bb, 1)

Make them consistent.

The second problem is that the PyOpenGL wrapper tries to validate the shader right after linking and that won't work because at that point you haven't configured the Uniforms yet and so there is a conflict of texture units. And if your GLSL version doesn't support layout to set a default binding, it can't possibly validate.

The only way I see around this is to create your own helper function to compile the program and skip the 'validate' step :

from OpenGL.GL.shaders import ShaderProgram

def myCompileProgram(*shaders):
  program = glCreateProgram()
  for shader in shaders:
    glAttachShader(program, shader)
  program = ShaderProgram( program )
  glLinkProgram(program)
  program.check_linked()
  for shader in shaders:
    glDeleteShader(shader)
  return program

Upvotes: 1

Related Questions