Creating a simple “hello world”-like example using OpenGL 3.2 using Core Profile can be surprisingly complicated. I’ll here show my simple example. The C++ example is based on the Cocoa-GL-Tutorial for OS/X.
The example includes a Visual Studio 2010 solution and project, but requires that FreeGlut and GLEW has been installed on properly. The application uses a few simple helper-files from the book “Interactive Computer Graphics – A Top-Down Approach with OpenGL” by Edward Angel and Dave Shreiner (Sixth Edition, Addison-Wesley 2012) (Amazon link) (Book website).
Download
Download the full project on GitHub: https://github.com/mortennobel/OpenGL_3.2_VS_2010_freeglut
Vertex shader
The vertex shader has no matrix transformations, but instead translates the quad using a simple offset-vector (the uniform p).
#version 150 uniform vec2 p; in vec4 position; in vec4 colour; out vec4 colourV; void main (void) { colourV = colour; gl_Position = vec4(p, 0.0, 0.0) + position; }
Fragment shader
A very simple fragment shader that colors the the pixel to a constant color (using Gouraud shading).
#version 150 in vec4 colourV; out vec4 fragColour; void main(void) { fragColour = colourV; }
main.cpp
[Click below to expand the source code].
#include #include #include <GL/glew.h> #include <GL/freeglut.h> #include "Angel.h" using namespace std; using namespace Angel; int WINDOW_WIDTH = 800; int WINDOW_HEIGHT = 800; GLuint shaderProgram; GLuint positionUniform; GLuint colourAttribute, positionAttribute; GLuint vertexArrayObject, vertexBuffer; typedef struct { vec4 position; vec4 colour; } Vertex; void loadShader(); void display(); void loadBufferData(){ Vertex vertexData[4] = { { vec4(-0.5, -0.5, 0.0, 1.0 ), vec4( 1.0, 0.0, 0.0, 1.0 ) }, { vec4(-0.5, 0.5, 0.0, 1.0 ), vec4( 0.0, 1.0, 0.0, 1.0 ) }, { vec4( 0.5, 0.5, 0.0, 1.0 ), vec4( 0.0, 0.0, 1.0, 1.0 ) }, { vec4( 0.5, -0.5, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) } }; glGenVertexArrays(1, &vertexArrayObject); glBindVertexArray(vertexArrayObject); glGenBuffers(1, &vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(Vertex), vertexData, GL_STATIC_DRAW); glEnableVertexAttribArray(positionAttribute); glEnableVertexAttribArray(colourAttribute); glVertexAttribPointer(positionAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)0); glVertexAttribPointer(colourAttribute , 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)sizeof(vec4)); } void loadShader(){ shaderProgram = InitShader("beelsebob.vert", "beelsebob.frag", "fragColour"); positionUniform = glGetUniformLocation(shaderProgram, "p"); if (positionUniform < 0) { cerr << "Shader did not contain the 'p' uniform."<<endl; } colourAttribute = glGetAttribLocation(shaderProgram, "colour"); if (colourAttribute < 0) { cerr << "Shader did not contain the 'colour' attribute." << endl; } positionAttribute = glGetAttribLocation(shaderProgram, "position"); if (positionAttribute < 0) { cerr << "Shader did not contain the 'position' attribute." << endl; } } void display() { glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); const float timeScale = 0.008f; glUseProgram(shaderProgram); GLfloat timeValue = glutGet(GLUT_ELAPSED_TIME)*timeScale; vec2 p( 0.5f * sinf(timeValue), 0.5f * cosf(timeValue) ); glUniform2fv(positionUniform, 1, (const GLfloat *)&p); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glutSwapBuffers(); } void reshape(int W, int H) { WINDOW_WIDTH = W; WINDOW_HEIGHT = H; glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); } void animate() { glutPostRedisplay(); } void visible(int vis) { if (vis == GLUT_VISIBLE) glutIdleFunc(animate); else glutIdleFunc(0); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitContextVersion(3, 2); glutInitContextFlags(GLUT_FORWARD_COMPATIBLE); glutInitContextProfile(GLUT_CORE_PROFILE); glutSetOption( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS ); glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); glutCreateWindow("02561"); glutDisplayFunc(display); glutReshapeFunc(reshape); glutVisibilityFunc(visible); glutIdleFunc(animate); glutReshapeWindow(WINDOW_WIDTH, WINDOW_HEIGHT); glewExperimental = GL_TRUE; // Added because of http://openglbook.com/glgenvertexarrays-access-violationsegfault-with-glew/ GLint GlewInitResult = glewInit(); if (GlewInitResult != GLEW_OK) { printf("ERROR: %s\n", glewGetErrorString(GlewInitResult)); } glEnable(GL_DEPTH_TEST); loadShader(); loadBufferData(); glutMainLoop(); }
Similar projects:
Thank you for your post.
Your codes is very useful for beginning OpenGL3.x/GLSL on Windows.
I have a comment.
When I executed your codes at the first time, I got an error on the line:
[main.cpp – line 40] glGenVertexArrays(1, &vertexArrayObject);
I found the following solution for this issue, and I hope you to update the codes for others.
// Add this code before ‘glewInit()’
glewExperimental = GL_TRUE;
By: Min-Hyuk Sung on September 24, 2012
at 03:48