Difference between revisions of "Generic Vertex Attribute - examples"

From OpenGL Wiki
Jump to: navigation, search
m
m (moved GlVertexAttribPointer to Generic Vertex Attribute - examples: it's getting in the way of searches for `glVertexAttribPointer`'s documentation.)
 
(4 intermediate revisions by one other user not shown)
Line 1: Line 1:
With GL 2.0, a new way to specify your vertex information became available: glVertexAttribPointer<br>
+
With GL 2.0, a new way to specify your vertex information became available: glVertexAttribPointer
You could of course continue to use glVertexPointer, glTexCoordPointer, glNormalPointer, glColorPointer.<br>
+
 
If you create a GL 3.0 forward context, you won't be able to use glVertexPointer, glTexCoordPointer, glNormalPointer, glColorPointer.<br>
+
You could of course continue to use glVertexPointer, glTexCoordPointer, glNormalPointer, glColorPointer.
<b>You must use the generic version in this case: glVertexAttribPointer</b><br>
+
 
<br>
+
If you create a GL 3.0 forward context, you won't be able to use glVertexPointer, glTexCoordPointer, glNormalPointer, glColorPointer.
 +
 
 +
<b>You must use the generic version in this case: glVertexAttribPointer</b>
 +
 
 +
 
 
One of the requirements is to use shaders. Here is a GLSL example.
 
One of the requirements is to use shaders. Here is a GLSL example.
   //Vertex Shader
+
<pre>
 +
   //VERTEX SHADER
 +
  #version 110
 +
 
 
   uniform mat4 ProjectionModelviewMatrix;
 
   uniform mat4 ProjectionModelviewMatrix;
 
   uniform mat4 ModelviewMatrix;
 
   uniform mat4 ModelviewMatrix;
Line 17: Line 24:
 
     gl_Position = ProjectionModelviewMatrix * InVertex;
 
     gl_Position = ProjectionModelviewMatrix * InVertex;
 
     OutTexCoord0 = InTexCoord0;
 
     OutTexCoord0 = InTexCoord0;
     vec3 normal = vec3(ModelviewMatrix * vec4(InNormal, 0.0);
+
     vec3 normal = vec3(ModelviewMatrix * vec4(InNormal, 0.0));
 
     //Do lighting computation
 
     //Do lighting computation
 
     XXXXX
 
     XXXXX
 
   }
 
   }
 +
</pre>
  
 
Once you compile and link your GLSL shader, you can query the attrib locations :
 
Once you compile and link your GLSL shader, you can query the attrib locations :
Line 47: Line 55:
 
   glGetProgramInfoLog(MyShader, maxLength, &maxLength, pLinkInfoLog);
 
   glGetProgramInfoLog(MyShader, maxLength, &maxLength, pLinkInfoLog);
  
For rendering, of course, there are many methods in OpenGL : immediate mode, display list, standard vertex arrays, VBO.<br>
+
For rendering, of course, there are many methods in OpenGL : immediate mode, display list, standard vertex arrays, VBO.
VBO is always recommended for modern programs.<br>
+
 
See the VBO page for more info : http://www.opengl.org/wiki/General_OpenGL<br>
+
VBO is always recommended for modern programs.
<br>
+
 
 +
See the VBO page for more info : http://www.opengl.org/wiki/General_OpenGL
 
   glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
 
   glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
 
   //-------------------
 
   //-------------------
 
   //Vertices, XYZ, FLOAT. We give GL_FALSE since we don't want normalization
 
   //Vertices, XYZ, FLOAT. We give GL_FALSE since we don't want normalization
   glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), XXX);
+
   glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));
 
   //Normals, XYZ, FLOAT.
 
   //Normals, XYZ, FLOAT.
   glVertexAttribPointer(normalLoc, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), XXX);
+
   glVertexAttribPointer(normalLoc, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(sizeof(float)*3));
 
   //TexCoord0, XY (Also called ST. Also called UV), FLOAT.  
 
   //TexCoord0, XY (Also called ST. Also called UV), FLOAT.  
   glVertexAttribPointer(texCoord0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(MyVertex), XXX);
+
   glVertexAttribPointer(texCoord0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(sizeof(float)*6));
 +
  //BUFFER_OFFSET is defined as #define BUFFER_OFFSET(i) ((char *)NULL + (i))
 +
  //Put that in one of your header files.
 +
 
 +
Also, don't forget to enable the arrays that you need and disable the arrays that you don't.
 +
 
 +
Enable is done with glEnableVertexAttribArray(index) and disable is done with glDisableVertexAttribArray(index).
 +
 
  
Also, don't forget to enable the arrays that you need and disable the arrays that you don't.<br>
+
and the vertex structure would look like this since in this example, we only have VNT (vertex, normal and texcoord0):
Enable is done with glEnableVertexAttrib(index) and disable is done with glDisableVertexAttrib(index).<br>
 
<br>
 
<br>
 
and the vertex structure would look like this since in this example, we only have VNT (vertex, normal and texcoord0): <br>
 
 
   struct MyVertex
 
   struct MyVertex
 
   {
 
   {

Latest revision as of 20:33, 16 March 2012

With GL 2.0, a new way to specify your vertex information became available: glVertexAttribPointer

You could of course continue to use glVertexPointer, glTexCoordPointer, glNormalPointer, glColorPointer.

If you create a GL 3.0 forward context, you won't be able to use glVertexPointer, glTexCoordPointer, glNormalPointer, glColorPointer.

You must use the generic version in this case: glVertexAttribPointer


One of the requirements is to use shaders. Here is a GLSL example.

  //VERTEX SHADER
  #version 110

  uniform mat4 ProjectionModelviewMatrix;
  uniform mat4 ModelviewMatrix;
  attribute vec4 InVertex;  //w will be set to 1.0 automatically
  attribute vec2 InTexCoord0;
  attribute vec3 InNormal;
  varying vec2 OutTexCoord0;
  //-------------------
  void main()
  {
    gl_Position = ProjectionModelviewMatrix * InVertex;
    OutTexCoord0 = InTexCoord0;
    vec3 normal = vec3(ModelviewMatrix * vec4(InNormal, 0.0));
    //Do lighting computation
    XXXXX
  }

Once you compile and link your GLSL shader, you can query the attrib locations :

 vertexLoc = glGetAttribLocation(MyShader, "InVertex");
 texCoord0Loc = glGetAttribLocation(MyShader, "InTexCoord0");
 normalLoc = glGetAttribLocation(MyShader, "InNormal");

The alternative way is to specify the locations yourself :

 glBindAttribLocation(MyShader, 0, "InVertex");
 glBindAttribLocation(MyShader, 1, "InNormal");
 glBindAttribLocation(MyShader, 2, "InTexCoord0");

but in this case you must link the shader AFTER those glBindAttribLocation calls :

 glLinkProgram(MyShader);

and don't forget to check for errors.

 int linked;
 glGetProgramiv(MyShader, GL_LINK_STATUS, &linked);
 //Make sure linked==TRUE
 //If linked==FALSE, the log contains information on what went wrong
 int maxLength;
 glGetProgramiv(MyShader, GL_INFO_LOG_LENGTH, &maxLength);
 maxLength = maxLength + 1;
 uchar *pLinkInfoLog = new uchar[maxLength];
 glGetProgramInfoLog(MyShader, maxLength, &maxLength, pLinkInfoLog);

For rendering, of course, there are many methods in OpenGL : immediate mode, display list, standard vertex arrays, VBO.

VBO is always recommended for modern programs.

See the VBO page for more info : http://www.opengl.org/wiki/General_OpenGL

 glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
 //-------------------
 //Vertices, XYZ, FLOAT. We give GL_FALSE since we don't want normalization
 glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));
 //Normals, XYZ, FLOAT.
 glVertexAttribPointer(normalLoc, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(sizeof(float)*3));
 //TexCoord0, XY (Also called ST. Also called UV), FLOAT. 
 glVertexAttribPointer(texCoord0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(sizeof(float)*6));
 //BUFFER_OFFSET is defined as #define BUFFER_OFFSET(i) ((char *)NULL + (i))
 //Put that in one of your header files.

Also, don't forget to enable the arrays that you need and disable the arrays that you don't.

Enable is done with glEnableVertexAttribArray(index) and disable is done with glDisableVertexAttribArray(index).


and the vertex structure would look like this since in this example, we only have VNT (vertex, normal and texcoord0):

 struct MyVertex
 {
   float x, y, z;
   float nx, ny, nz;
   float s0, t0;
 };

Additional : glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &MaxVertexAttribs) tells you the maximum number that the implementation supports and this is typically 16.