1
$\begingroup$

The background of this question is that I am trying to write an automatic binding system, where for each uniform variable I want to declare in my GLSL code, I call a method declareUniform which is counting up the location value, saving the type and name of the uniform to a list which will be saved within my shaderobject...

I already did something similar with varyings, where I save the varying information (location, type, name, shader stage from, shader stage to, isarray, arraycount) and of cause also generating glsl string which is working fine.

I am trying to bind several things to a shader, which does not work right now. I've read, that uniform block binding indices have nothing to do with sampler binding locations here, which is totally confusing me... I also read the Explicit_uniform_location site from khronos here. I am trying to bind some sampler2D, image2D and other uniforms in one shader.

layout(location = 0) in  vec2 texCoordIn; //value from VBO
layout(binding = 0, rgba32f) uniform  image2D writeColorTexture;
layout(binding = 1) uniform  sampler2D readColorTexture;
layout(location = 0) uniform  float u_apature;
layout(location = 1) uniform  float u_focalDistance;
...

On CPU it looks like this:

GLint readColorTextureLoc = glGetUniformLocation(glShaderHandle, "readColorTexture");
GLint writeColorTextureLoc = glGetUniformLocation(glShaderHandle, "writeColorTexture");

trying to bind the samper2D:

glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glUniform1i(readColorTextureLoc, 0);
glBindTexture(GL_TEXTURE_2D, colorTexture->id());

trying to bind the image2D:

glBindImageTexture(writeColorTextureLoc, colorImage->id(), 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA32F);

when using glGetUniformLocation(glShaderHandle, "readColorTexture"); I get the value 31 which also confuses me. This brought me to understand it to the following way: layout(location = ...) uniform is the value which will be returned by glGetUniformLocation.

The binding qualifier maps the uniform variable to a (I'll call it) "background list", which can be addressed by glActiveTexture for example if it is a sampler. As far as I understood (please correct me if I am wrong!) there are several of these "background lists". One for samplers, one for block bindings, one for images... and each of them starts with 0.

Now my question: Am I right? Did I understand it correctly? If so: which "background lists" are available and how can I bind a sampler together with an Image?

$\endgroup$
2
  • $\begingroup$ I don't want this example to just work... I want it to be perfect, so when adding another shader, that no effects start to appear, which needs a lot of time to debug. So it need to be a closed concept, which fully controls each binding slot $\endgroup$
    – Thomas
    Jan 13 at 9:35
  • $\begingroup$ "automatic binding system" Don't do that. If your shader has hard-coded into it an image binding point, just use that. There's no need to query what you already know is there. $\endgroup$ Jan 13 at 14:54

1 Answer 1

3
$\begingroup$

While OpenGL's organic growth as an API has led to some inconsistencies regarding the naming of things, the API here means what it says. location means location, and binding means binding. As such, a function named glGetUniformLocation should be expected to return the location of the uniform, not the binding.

When introspecting GLSL, there are several quantities to consider. For a particular kind of thing (program inputs, uniforms, etc. In the modern introspection API, these are called "interfaces"), all of the introspectable variables (called "resources") are given an index as if they're all in an array. This index is from 0 to the number of active resources in this interface.

You can then query properties about a resource (name, etc) by its index. But the index of a resource is neither its location nor its binding; it is merely an identifier for the resource.

Some resources have a location; a number used by the API to directly affect the value it gets or gives. Program inputs use locations to determine which variable gets when data from the VAO (or prior program stage if the program doesn't contain a VS). Uniform locations are how you set values into the uniform via glProgramUniform* calls. And so forth.

Some resources have a binding; a number which represents the index in a table (in the OpenGL context) for how the resource is used to access memory of some kind. The binding for opaque types determine which binding slot the given object represents. To make a memory object (texture or buffer) available to this resource, you bind that object to the binding index for that kind of access (image load/store, texture, etc).

So if you have an image uniform, the location determines how you would set its binding from the API via glProgramUniform1i. But the binding determines which index in the OpenGL context the OpenGL object you're trying to access will be bound to. If you do not assign a location to a uniform in the shader, the API will assign one itself, which you would have to query (if you need to change the binding for some reason. Which you shouldn't).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.