Constantin
Constantin

Reputation: 8961

The difference between a color attribute and using gl_Color

Most GLSL shaders are using a attribute for the color in the vertex shader, which will be forwarded as varying to the fragment shader. Like this:

attribute vec4 position;
attribute vec4 color;
uniform mat4 mvp;
varying vec4 destinationColor;

void main(){
  destinationColor = color;
  gl_Position = mvp * position;
};

Setting the color can be done with glVertexAtribPointer() to pass one color per vertex or with glVertexAttrib4fv() to pass a global color for all vertexes. I try to understand the difference to the predefined variable gl_Color in the vertex shader (if there is any difference at all). i.e.

attribute vec4 position;
uniform mat4 mvp;
varying vec4 destinationColor;

void main(){
  destinationColor = gl_Color;
  gl_Position = mvp * position;
};

and using glColorPointer() to pass one color per vertex or glColor4fv() to use a global color for all vertexes. To me the second shader looks better (= more efficient?), because it uses less attributes. But all tutorials & online resources are using the first approach - so I wonder if I missed anything or if there is no difference at all. What is better practice when writing GLSL shaders?

Upvotes: 1

Views: 2687

Answers (2)

Spektre
Spektre

Reputation: 51835

if I remember correctly gl_Color is deprecated remnant from the old style API without VAO/VBO using glBegin() ... glEnd(). If you go to core profile there is no gl_Color anymore ... so I assume you use old OpenGL version or compatibility profile.

If you try to use gl_Color in core profile (for example 4.00) you got:

0(35) : error C7616: global variable gl_Color is removed after version 140

Which means gl_Color was removed from GLSL 1.4

It is not entirely matter of performance but the change in graphic rendering SW architecture or hierarchy of the GL calls if you want.

Upvotes: 1

Nicol Bolas
Nicol Bolas

Reputation: 473192

To me the second shader looks better (= more efficient?), because it uses less attributes.

It does not use fewer attributes. It just uses fewer explicit attribute declarations. All of the work needed to get that color value to OpenGL is still there. It's still being done. The hardware is still fetching data from a buffer object or getting it from the glColor context value or whatever.

You just don't see it in your shader's text. But just because you don't see it doesn't mean that it happens for free.

User-defined attributes are preferred for the following reasons:

  • User-defined attributes make it clear how many resources your shaders are using. If you want to know how many attributes you need to provide to a shader, just look at the global declarations. But with predefined attributes, you can't do this; you have to scan through the entire vertex shader for any gl_* names that name a predefined attribute.
  • User-defined attributes can do more things. If you want to pass integer values as integers to the vertex shader, you must use a user-defined attribute. If you need to pass a double-precision float to the vertex shader, again, a predefined attribute cannot help you.
  • Predefined attributes were removed from core OpenGL contexts. OSX, for example, does not allow the compatibility profile. You can still use OpenGL 2.1, but if you want to use any OpenGL version 3.2 or greater on OSX, you cannot use removed functionality. And the built-in vertex attributes were removed in OpenGL 3.1.
  • Predefined attributes were never a part of OpenGL ES 2.0+. So if you want to write shaders that can work in OpenGL ES, you again cannot use them.

So basically, there's no reason to use them these days.

Upvotes: 3

Related Questions