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