6

I'm attempting to convert my program from GLfloat to GLshort for vertex positions and I'm not sure how to represent this in the shader. I was using a vec3 datatype in the shader but vec3 represents 3 floats. Now I need to represent 3 shorts. As far as I can tell OpenGL doesn't have a vector for shorts so what am I supposed to do in this case?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Xavier
  • 8,828
  • 13
  • 64
  • 98

1 Answers1

16

I'm not sure how to represent this in the shader.

That's because this information doesn't live in the shader.

All values provided by glVertexAttribPointer will be converted to floating-point GLSL values (if they're not floats already). This conversion is essentially free. So you can use any of these glVertexAttribPointer definitions with a vec4 attribute type:

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, ...);
glVertexAttribPointer(0, 4, GL_UNSIGNED_SHORT, GL_TRUE, ...);
glVertexAttribPointer(0, 4, GL_SHORT, GL_TRUE, ...);
glVertexAttribPointer(0, 4, GL_SHORT, GL_FALSE, ...);

All of these will be converted into a vec4 automatically. Your shader doesn't have to know or care that it's being fed shorts, bytes, integers, floats, etc.

The first one will be used as is. The second one will convert the unsigned short range [0, 65535] to the [0.0, 1.0] floating-point range. The third will convert the signed short range [-32768, 32767] to the [-1.0, 1.0] range (though the conversion is a bit odd and differs for certain OpenGL versions, so as to allow the integer 0 to map to the floating point 0.0). The fourth will convert [-32768, 32767] to [-32768.0, 32767.0], as a floating-point range.

The GLSL type you use for attributes only changes if you use glVertexAttribIPointer or glVertexAttribLPointer, neither of which is available in OpenGL ES 2.0.

In short: you should always use float GLSL types for attributes. OpenGL will do the conversion for you.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • I was under the impression I could after reading the answers at: http://stackoverflow.com/a/1316494/256062 and http://stackoverflow.com/a/5721102/256062 – Xavier Jul 26 '12 at 22:41
  • 1
    @Xavier: You're missing the point. The size of your vertex data is defined by `glVertexAttribPointer`, *not* the GLSL attribute variable. You don't *need* to represent smaller components in the shader; the hardware will *convert* from smaller components to larger ones. – Nicol Bolas Jul 26 '12 at 23:09
  • @nicol-bolas For signed data types, are you sure the converted range is for example (for `short`) `[-32768, 32767]` and not `[-32767, 32767]` ? This [article](http://www.informit.com/articles/article.aspx?p=2033340&seqNum=3), supposedly taken from the Orange Book, seems to teach differently. It says the conversion is just a division for signed types. In that case, the short value `-32768` would be converted to floating-point GLSL value `-32768 / 32767 = -1.000305185..` . I cannot find in the spec where to determine which is correct. – wip Apr 18 '14 at 06:06
  • 1
    @wil: The range is correct. It's simply not a linear transformation; -32768 and -32767 both produce -1.0. The OpenGL spec is very clear on this. – Nicol Bolas Jun 24 '16 at 20:49