The engine automatically sets the uniforms texture0…texturen to 0,1,2, etc., and each material has slots 0 to maxtexture-1 where textures can be assigned:
Material::SetTexture( Texture* texture, int index )
This works well, but people are complaining about having to use these names for texture sampler variables in the shader. I propose the following solution.
An integer can be used as a default value for sampler uniforms:
I think it would perhaps be better to use they existing layout qualifier stuff?
Better in what way? If you’re going to do it, I’d prefer it be done in a way that adds only 4 characters to a definition instead of 16. Also, samplers cannot be given initializers, so it wouldn’t break anything to define sampler initializers to mean, well, initializing them to a sampler in GL.
I would still like to see separate texture and sampler units exposed to GLSL given that they exist now in the C API.
That’s not what sampler_objects does. It doesn’t create “sampler units”; it simply allows you to separate the state that a texture is sampled with from the texture object itself. You still bind sampler objects to texture units.
It would be consistent with the way shader’s intputs/outputs are explicitly connected to attributes/draw buffers.
Now as far as im concerned they could go ’ = 7’ for all these instead of more verbose ‘layout(location = 7)’, but its kinda too late.
Now as far as im concerned they could go ’ = 7’ for all these instead of more verbose ‘layout(location = 7)’, but its kinda too late.
Here’s why they did it that way.
You can initialize uniform and constant variables:
uniform vec3 myUniform = vec3(1.0, 0.0, 0.0);
For uniforms, this is the behavioral equivalent of calling glLinkProgram, immediately getting the uniform location for ‘myUniform’, and setting its value with glUniform3f.
If you were to then have this:
in vec3 myAttrib = 0;
This looks like an initializer. But it isn’t; it’s specifying the attribute index. Therefore, it is overloading the initializer syntax for something that isn’t really initializing the variable to a value.
Allowing sampler uniforms to be initialized with a texture unit is initialization. It’s exactly analogous to initializing uniform values. After glLinkProgram, you get the uniform location and use glUniform1i to set its value. It’s the same thing as other uniform initialization.
The only inconsistency that this would cause is that you are not normally allowed to set values to a sampler in GLSL. But this is a pretty minor issue compared to the way it perfectly works with the rest of GLSL.
I’d like to initialize sampler uniforms this way as well.
With the old method, I already got a schizophrenic linker warning on ATI cards, if I used cubemaps and 2d textures in the same shader; something like “two or more samplers of different types bound to unit 0”. The driver obviously used default value 0 for all samplers internally and then moaned about it… with me never having had a chance to assign sane values before the very first link.
I’d like to initialize sampler uniforms this way as well.
[/QUOTE]
Ditto and definitely the above syntax as it is consistent (you are setting what texture unit the sampler takes data from, which is the value set via glUniform1i).
Output from shader Fragment shader(s) linked, vertex shader(s) linked.
Validation failed - samplers of different types are bound to the same texture image unit.