3

I'm trying to create an übershader to represent some wavefront data which might or might not contain some properties, e.g.:

  1. one or more objects might contain uv coordinates and a texture
  2. one or more objects might contain normal mapping for each vertex
  3. one or more materials might be rendered with a different illumination type, and contain a texture for bump mapping

and so on.

Now, it might or might not be a good idea to create an übershader for this (I'm experimenting), but I'm facing the problem that some attributes are specified and some are not (missing uniforms, like texture samplers not set are handled with boolean uniforms that turn on and off the sampling feature).

What does happen in a GLSL v 3.00 when an attribute is both not assigned (which means no glEnableVertexAttribArray, for instance, but also no buffer bound/anything) and not used in the GLSL program for reading (e.g. I'll use a uniform boolean to turn texture lookup off, when UV coordinates are missing, though I might still interpolate the coordinates as in/out between vertex and fragment shaders, like this:

// Vertex shader
in vec3 vn;
out vec3 fvn;

[...]

fvn = vn;

...)?

Is this a legal use of the glsl, or will I incur in weird compatibility problems (I'm developing for mobile, as the OpenGL ES3.0 tag implies)?

I'm looking for either first hand experiences or an authoritative source,

Thank you!

Rick77
  • 3,121
  • 25
  • 43
  • 1
    What do you mean by "both not specified and not used"? Specifically by "not specified"? – Nicol Bolas Jan 03 '16 at 17:42
  • @NicolBolas thank you for the remark (my explanation is not clear)! I'll correct the question immediately, even though I think that the answer from Reto nailed my problem. – Rick77 Jan 03 '16 at 19:42

1 Answers1

8

Attributes are always specified. You get to choose if they are fetched from an array, or if the current value is used.

To use data from an array, you call:

glEnableVertexAttribArray(loc);

While the attribute array is enabled, the attribute is fetched from the buffer that was bound as the GL_ARRAY_BUFFER when the last glVertexAttribPointer() call was made.

To use the current attribute value, you call:

glDisableVertexAttribArray(loc);

While the attribute array is disabled, the value used for the attribute is given by the last call to glVertexAttrib4f(), or another function from the same glVertexAttrib*() family, where the default is (0.0, 0.0, 0.0, 1.0) if you never call any of those functions.

So having an attribute "not specified" is not a concern, since it never really unspecified. The only thing you have to be careful about is that you don't enable the attribute array without specifying a valid array with glVertexAttribPointer(). The safest approach is that you call glDisableVertexAttribArray() for the attributes that you're not using.

Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • Thank you very much for the very clear and exhaustive explanation: that was exactly what I was looking for! The "fallback" on `glVertexAttrib*` in particular it's what I was searching for, and it's a nice thing to know. – Rick77 Jan 03 '16 at 19:54