Here you go:
/*****************************************************************************/
/* arb_vertex_program.c - An example of defining and using an ARB vertex */
/* program. */
/* */
/* Derived from article: http://www.devmaster.net/main.php?showtid=280 */
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
GLuint VP_handle = 0;
const char VP_source[] =
"!!ARBvp1.0
"
"
"
"#Input
"
"ATTRIB InPos = vertex.position;
"
"ATTRIB InColor = vertex.color;
"
"
"
"#Output
"
"OUTPUT OutPos = result.position;
"
"OUTPUT OutColor = result.color;
"
"
"
"PARAM MVP[4] = { state.matrix.mvp }; # Modelview Projection Matrix
"
"TEMP Temp;
"
"
"
"# Transform vertex to clip space
"
"DP4 Temp.x, MVP[0], InPos;
"
"DP4 Temp.y, MVP[1], InPos;
"
"DP4 Temp.z, MVP[2], InPos;
"
"DP4 Temp.w, MVP[3], InPos;
"
"
"
"#Output
"
"MOV OutPos, Temp;
"
"MOV OutColor, InColor;
"
"
"
"END
";
void checkGLError( const char hdr[] )
{
int err = glGetError();
if( err )
{
fprintf(stderr, "ERROR %s: %s
", hdr, gluErrorString(err));
exit(1);
}
}
void initVertexProgram()
{
int err = 0;
glGenProgramsARB( 1, &VP_handle ); // Allocate
checkGLError( "Allocating Vertex Program" );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, VP_handle ); // Activate
checkGLError( "Binding Vertex Program" );
glProgramStringARB( GL_VERTEX_PROGRAM_ARB, // Compile
GL_PROGRAM_FORMAT_ASCII_ARB,
strlen( VP_source ), VP_source );
if ( glGetError() == GL_INVALID_OPERATION )
{
fprintf( stderr, "ERROR Compiling Vertex Program:
" );
// Find the error position
GLint errPos;
glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &errPos );
// Print implementation-dependent program errors and warnings
const GLubyte *errString = glGetString( GL_PROGRAM_ERROR_STRING_ARB );
fprintf( stderr, "Error at position: %d
%s
", errPos, errString );
exit(1);
}
checkGLError( "Compiling Vertex Program" );
}
void activateVertexProgram()
{
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, VP_handle );
checkGLError( "Binding Vertex Program" );
glEnable( GL_VERTEX_PROGRAM_ARB );
checkGLError( "Enabling Vertex Program" );
}
void deactivateVertexProgram()
{
glDisable( GL_VERTEX_PROGRAM_ARB );
checkGLError( "Disabling Vertex Program" );
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
}
void display()
{
int err=0;
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1,1,-1,1,-1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(30.0, 0,0,1);
glColor4f(1,0,0,1);
activateVertexProgram();
glRectf(-.5,-.5,.5,.5);
deactivateVertexProgram();
glutSwapBuffers();
checkGLError( "End of display()" );
}
int main (int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE);
glutCreateWindow(argv[0]);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutReshapeWindow(400,400);
printf("GL_RENDERER = %s
",glGetString(GL_RENDERER));
glClearColor(0,0,0,0);
initVertexProgram();
glutMainLoop();
return 0;
}
Compile using:
gcc -o arb_vertex_program arb_vertex_program.c -lglut -lGLU -lGL