PDA

View Full Version : Having some trouble getting OpenGL 3.2 working



MistMage
04-20-2010, 01:46 AM
Hi. I've recently been trying to start learning OpenGL 3 but I end up with linker errors and I don't get what I'm doing wrong (guessing I've set it up wrong somewhere). I'm using MinGW with the gl3.h header from the repository and the latest version of freeglut. My graphics card is an NVIDIA GeForce 8800 GT with the latest drivers.

Here is the code:

#include <stdlib.h>
#include <stdio.h>

#define GLUT_DISABLE_ATEXIT_HACK
#define GL3_PROTOTYPES

#include <gl/glut.h>
#include <gl/gl3.h>

/* A simple function that will read a file into an allocated char pointer buffer */
char* filetobuf(char *file)
{
FILE *fptr;
long length;
char *buf;

fptr = fopen(file, "r"); /* Open file for reading */
if (!fptr) /* Return NULL on failure */
return NULL;
fseek(fptr, 0, SEEK_END); /* Seek to the end of the file */
length = ftell(fptr); /* Find out how many bytes into the file we are */
buf = (char*)malloc(length+1); /* Allocate a buffer for the entire length of the file and a null terminator */
fseek(fptr, 0, SEEK_SET); /* Go back to the beginning of the file */
fread(buf, length, 1, fptr); /* Read the contents of the file in to the buffer */
fclose(fptr); /* Close the file */
buf[length] = 0; /* Null terminator */

return buf; /* Return the buffer */
}

void renderScene()
{
/* Make our background black */
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* Invoke glDrawArrays telling that our data is a line loop and we want to draw 2-4 vertexes */
glDrawArrays(GL_LINE_LOOP, 0, 2);

glFlush();

/* Swap our buffers to make our changes visible */
glutSwapBuffers();
}

int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(20, 20);
glutInitWindowSize(800, 600);

int Window_ID = glutCreateWindow("Test02");
glutDisplayFunc(renderScene);

GLuint vao, vbo[2]; /* Create handles for our Vertex Array Object and two Vertex Buffer Objects */

/* We're going to create a simple diamond made from lines */
const GLfloat diamond[4][2] = {
{ 0.0, 1.0 }, /* Top point */
{ 1.0, 0.0 }, /* Right point */
{ 0.0, -1.0 }, /* Bottom point */
{ -1.0, 0.0 } }; /* Left point */

const GLfloat colors[4][3] = {
{ 1.0, 0.0, 0.0 }, /* Red */
{ 0.0, 1.0, 0.0 }, /* Green */
{ 0.0, 0.0, 1.0 }, /* Blue */
{ 1.0, 1.0, 1.0 } }; /* White */

/* These pointers will receive the contents of our shader source code files */
GLchar *vertexsource, *fragmentsource;

/* These are handles used to reference the shaders */
GLuint vertexshader, fragmentshader;

/* This is a handle to the shader program */
GLuint shaderprogram;

/* Allocate and assign a Vertex Array Object to our handle */
glGenVertexArrays(1, &amp;vao);

/* Bind our Vertex Array Object as the current used object */
glBindVertexArray(vao);

/* Allocate and assign two Vertex Buffer Objects to our handle */
glGenBuffers(2, vbo);

/* Bind our first VBO as being the active buffer and storing vertex attributes (coordinates) */
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);

/* Copy the vertex data from diamond to our buffer */
/* 8 * sizeof(GLfloat) is the size of the diamond array, since it contains 8 GLfloat values */
glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), diamond, GL_STATIC_DRAW);

/* Specify that our coordinate data is going into attribute index 0, and contains two floats per vertex */
glVertexAttribPointer((GLuint)0, 2, GL_FLOAT, GL_FALSE, 0, 0);

/* Enable attribute index 0 as being used */
glEnableVertexAttribArray(0);

/* Bind our second VBO as being the active buffer and storing vertex attributes (colors) */
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);

/* Copy the color data from colors to our buffer */
/* 12 * sizeof(GLfloat) is the size of the colors array, since it contains 12 GLfloat values */
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), colors, GL_STATIC_DRAW);

/* Specify that our color data is going into attribute index 1, and contains three floats per vertex */
glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, 0);

/* Enable attribute index 1 as being used */
glEnableVertexAttribArray(1);

/* Read our shaders into the appropriate buffers */
vertexsource = filetobuf("shader1.vert");
fragmentsource = filetobuf("shader1.frag");

/* Assign our handles a "name" to new shader objects */
vertexshader = glCreateShader(GL_VERTEX_SHADER);
fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);

/* Associate the source code buffers with each handle */
glShaderSource(vertexshader, 1, (const GLchar**)&amp;vertexsource, 0);
glShaderSource(fragmentshader, 1, (const GLchar**)&amp;fragmentsource, 0);

/* Compile our shader objects */
glCompileShader(vertexshader);
glCompileShader(fragmentshader);

/* Assign our program handle a "name" */
shaderprogram = glCreateProgram();

/* Attach our shaders to our program */
glAttachShader(shaderprogram, vertexshader);
glAttachShader(shaderprogram, fragmentshader);

/* Bind attribute index 0 (coordinates) to in_Position and attribute index 1 (color) to in_Color */
glBindAttribLocation(shaderprogram, 0, "in_Position");
glBindAttribLocation(shaderprogram, 1, "in_Color");

/* Link our program, and set it as being actively used */
glLinkProgram(shaderprogram);
glUseProgram(shaderprogram);

glutMainLoop();

/* Cleanup all the things we bound and allocated */
glUseProgram(0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDetachShader(shaderprogram, vertexshader);
glDetachShader(shaderprogram, fragmentshader);
glDeleteProgram(shaderprogram);
glDeleteShader(vertexshader);
glDeleteShader(fragmentshader);
glDeleteBuffers(2, vbo);
glDeleteVertexArrays(1, &amp;vao);
free(vertexsource);
free(fragmentsource);

glutDestroyWindow( Window_ID );

return 0;
}
... which is based on this (http://www.opengl.org/wiki/Tutorial2:_VAOs,_VBOs,_Vertex_and_Fragment_Shaders _%28C_/_SDL%29) tutorial but attempting to use freeglut instead of SDL.

The command line looks like so (edit: using Eclipse CDT by the way):

**** Internal Builder is used for build ****
gcc -O0 -g3 -Wall -c -fmessage-length=0 -omain.o ..\main.c
gcc -oGLTest02.exe main.o -lglut32 -lopengl32
main.o: In function `main':
...

... Followed by "undefined reference to" for all gl functions in main.

I've tried most everything I can think of other than a clean reinstall, so I though I'd ask for advice before that.

ZbuffeR
04-20-2010, 02:22 AM
As a simple check, try to compile this GL 1.1 simple code first :
http://www.sgi.com/products/software/opengl/examples/glut/examples/source/cube.c

It should work.

For GL3 : pure GL3 functions are not exposed in opengl32.dll : you have to get them at runtime, either by hand or simpler method : use GLEW or GLee.
http://www.opengl.org/wiki/Getting_started#OpenGL_2.0.2B_and_extensions

MistMage
04-20-2010, 02:45 AM
I gotcha. Let me just try that and I'll get back in a moment (example worked by the way).

Edit: Yes, that did the trick (after a bit of fiddling around).

I'm a bit embarrassed that I couldn't figure this out myself since it is in the getting started section of the wiki and all, but I think most programmers can relate so I won't make excuses. Thanks a lot for the help :)