Athena: OpenGL 3.0 Upgrade in Progress…

Building in progress...

I just upgraded to the latest version of gDEBugger, and it kept notifying me that a lot of my code is using deprecated functions as of OpenGL 3.0.

So I have begun the long task of converting code and shaders alike, hopefully in a positive step since it will mean my DirectX 10 port of the Athena engine will have little modifications to work like the OpenGL and vice versa.

These functions are the first on my list, they are used for rendering my geometry.

glTexCoordPointer()

glColorPointer()

glNormalPointer()

glVertexPointer()

These have been replaced with glVertexAttribPointer(), a more useful system so you can specify custom attributes a vertex has, and link them to attribute variables in shaders (shaders are required now for everything like DirectX 10). So for a simple array of vertices, I linked them to attribute variable in my shader which was bound to location 0.

//
// Bind VBO Object
glBindBuffer( GL_ARRAY_BUFFER, m_vertexBuffer );
 
//
// Enable vertex attribute streaming on location 0
glEnableVertexAttribArray( 0 /* location */ );
 
//
// Set attribute offset, size, and type details for location 0
glVertexAttribPointer(	0, /* location */
			4, /* components */
			GL_FLOAT, /* type */
			GL_FALSE, /* normalize */
			sizeof( float ) * 4, /* stride */
			0 ); /* buffer offset */

 

I found out shortly after however that the index I was using for my vertex attribute is a reserved index by nVidia for their built-in attributes, as are 12 others.

0 – gl_Vertex
2 – gl_Normal
3 – gl_Color
4 – gl_SecondaryColor
5 – gl_FogCoord
8 – gl_MultiTexCoord0
9 – gl_MultiTexCoord1
10 – gl_MultiTexCoord2
11 – gl_MultiTexCoord3
12 – gl_MultiTexCoord4
13 – gl_MultiTexCoord5
14 – gl_MultiTexCoord6
15 – gl_MultiTexCoord7

So in the interest of keeping things sane I changed the location index to be 16, all that was needed was updating my shaders to use attributes rather than gl_Position, etc.

//
// Vertex Attributes
attribute vec4 a_vertex;
attribute vec2 a_texCoord0;
 
//
// Vertex Shader Entry Point
void main()
{
	//gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
	gl_TexCoord[0].xy = a_texCoord0;
 
	//gl_Position = gl_Vertex;
	gl_Position = a_vertex;
}

 

You may have noticed that I don’t multiply my vertex by any transformation matrices, this is because my vertex coordinates for 2D are always in the range of -1.0 to 1.0. Doing it this way saves me changing projection matrix states whenever I want to draw 2D, so my projection matrix is always setup for 3D. Also, the source for this vertex shader program contains another attribute for the texture coordinate as well since I just copy-pasta’d my Bloom shader.

Now just two simple calls were needed to be added to my  shader program before it was linked, so that the vertex attribute is bound to the correct location.

glBindAttribLocation( m_program, 16 /* location */, "a_vertex" );
glBindAttribLocation( m_program, 17 /* location */, "a_texCoord0" );
glLinkProgram( m_program );

 

As you can see my vertex shader has a texture coordinate as well (I’m using my Bloom vertex shader as an example), so the final code for setting up the VBO for this is.

//
// VBO layout
struct TexturedVertex
{
	float texCoord[2];
	float position[4];
};
 
//
// Bind VBO Object
glBindBuffer( GL_ARRAY_BUFFER, myVBO );
 
//
// Enable vertex attribute streaming on location 0
glEnableVertexAttribArray( 16 );
glEnableVertexAttribArray( 17 );
 
//
// Set attribute offset, size, and type details for location 0
glVertexAttribPointer( 17, 2, GL_FLOAT, GL_FALSE, sizeof( TexturedVertex ), 0 );
glVertexAttribPointer( 16, 4, GL_FLOAT, GL_FALSE, sizeof( TexturedVertex ), sizeof( float ) * 2 );

 

I’m sure there is a preprocessor command to get the offset of a variable within a structure, but “sizeof( float ) * 2” works as well. My code is a bit more complex than is shown here (I have a vertex format class that manages what needs to be set where, and something to managed state changes et cetera), but you get the idea of how it all works.

Well that was one big change down, on the next page of this blog entry will be another big change, replacing glMatrixMode() and glLoadMatrix().