0

I am confused about textures and cubemaps in OpenGL.

Let's say I want basic texture mapping. I do:

  GLuint texture0;
  glGenTextures(1, &texture0);
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, texture0);

and then I set up glTexImage2D and call glUniform1i(glGetUniformLocation(shader_program, "texture_sampler"), GL_TEXTURE0) and all is well.

Now, I also want to use a cubemap for environment mapping. I thought, also using this post as reference, that I should do like this:

  GLuint texture1;
  glGenTextures(1, &texture1);
  glActiveTexture(GL_TEXTURE0+1); 
  glBindTexture(GL_TEXTURE_CUBE_MAP, texture1);

and then glUniform1i(glGetUniformLocation(shader_program, "cubemap_sampler"), GL_TEXTURE0+1).

However, this does not work, and only renders a black object. On the other hand, if I do not run glActiveTexture(GL_TEXTURE0+1) but instead stick to GL_TEXTURE0 everything is fine.

According to my understanding, this is not how it should be...

Can anyone shed some light as to what is going on?

I am using GLSL #version 440.

Supernormal
  • 831
  • 7
  • 14
  • 2
    Shouldn't the argument to `glUniform1i` be the *offset* from `GL_TEXTURE0`? So `glUniform1i(glGetUniformLocation(shader_program, "cubemap_sampler"), 1)` . See ["Binding textures to samplers"](https://www.khronos.org/opengl/wiki/Sampler_(GLSL)#Binding_textures_to_samplers). – G.M. Nov 13 '20 at 11:22

1 Answers1

1

glUniform1i(glGetUniformLocation(shader_program, "texture_sampler"), GL_TEXTURE0+1) is a strange idea.

The texture unit is the integral binding point between the texture object and the texture sampler. GL_TEXTURE0 is an enumerator constant for the use with glActiveTexture. GL_TEXTURE0 address the texture unit 0.
The value you need to set on the texture sampler uniform is the texture unit not, the "name" of the texture unit. Hence you have to set 0 rather then GL_TEXTURE0:

glUniform1i(glGetUniformLocation(shader_program, "texture_sampler"), GL_TEXTURE0+1)

glUniform1i(glGetUniformLocation(shader_program, "texture_sampler"), 1)

Note that the sampler bind point is 0 by default. The instruction glUniform1i(..., GL_TEXTURE0+1) causes an INVALID_VALUE error and does not change the binding point at all.
See OpenGL Shading Language 4.60 Specification - 7.6.1 Loading Uniform Variables In The Default Uniform Block

An INVALID_VALUE error is generated if Uniform1i{v} is used to set a sampler uniform to a value less than zero or greater than or equal to the value of MAX_COMBINED_TEXTURE_IMAGE_UNITS.

Rabbid76
  • 142,694
  • 23
  • 71
  • 112
  • Thanks. However, also `glActiveTexture(GL_TEXTURE0+1); glUniform1i(env_sampler_location, 1);` renders a black object. But if I change it to `glActiveTexture(GL_TEXTURE0); glUniform1i(env_sampler_location, 0);`, it works. – Supernormal Nov 13 '20 at 15:30
  • @Supernormal You are not a new user. You now that the comment section is not intended to ask additional question. You know that you have [Ask a public question](https://stackoverflow.com/questions/ask). Anyway, you are not providing enough information in the question to spot the new issue. – Rabbid76 Nov 13 '20 at 16:01