I have seen many samples to hard code the number of texture unit in the program. For example:
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, object1BaseImage);
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_2D, object1NormalMap);
glActiveTexture(GL_TEXTURE0 + 4);
glBindTexture(GL_TEXTURE_2D, shadowMap);
The problem is that two simultaneously used textures may conflict with each other by using the same texture unit when rendering a scene. my question is how to automatically allocate the texture unit in OpenGL by implementing a class or function? since there are many different constants that define how many sampler object I can use:
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS,
GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS,
GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS,
GL_MAX_TEXTURE_IMAGE_UNITS and
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS.
I am confused by the constants, isn't there should be a constant like GL_MAX_FRAGMENT_TEXTURE_IMAGE_UNITS
? I think I need to get the max number of texture unit when allocating it.
So there are two questions:
GL_MAX_FRAGMENT_TEXTURE_IMAGE_UNITS
.Any ideas? code snippet would be very appreciated.
How to write a class or function automatically allocate the texture unit using the constants.
This is easy: don't.
The "allocation" of texture image units is typically done by a convention set down by the program(s) you intend to use. You decide that unit 0 is where the diffuse texture goes; if a particular mesh&shader don't have a diffuse texture, you don't put something in unit 0. Unit 12 could be where shadow maps go.
This is why shading_language_420pack allows you to set the texture unit directly within the shader. Even without that, you should generally set the sampler's texture unit after compiling the shader and don't move it.
No point in changing program state when you don't have to.
On 3.3+ hardware, you have no less than 48+ texture units available. You're not likely to run out.
since there are many different constants that define how many sampler object I can use:
No, there is one constant that defines how many "sampler object" you can use: GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
. That is the hard limit on the total number of texture image units that OpenGL provides. glActiveTexture
takes a number between GL_TEXTURE0
and GL_TEXTURE0+GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
.
The individual ones are the maximum number of GLSL sampler types that can be active in a single shader stage. As for which one you use for fragment shaders, it's GL_MAX_TEXTURE_IMAGE_UNITS
. This is for legacy reasons, since initially only fragment shaders could access textures.