Skip to content

Instantly share code, notes, and snippets.

@dlivingstone
Created October 15, 2010 14:59
Show Gist options
  • Save dlivingstone/628320 to your computer and use it in GitHub Desktop.
Save dlivingstone/628320 to your computer and use it in GitHub Desktop.
OpenGL 3.0+ Rendering Example - A complete and fairly minimal example of rendering with shaders
// Fragment Shader – file "minimal.frag"
#version 130
precision highp float; // needed only for version 1.30
in vec3 ex_Color;
out vec4 out_Color;
void main(void)
{
out_Color = vec4(ex_Color,1.0);
// Try replacing the above with the following:
//vec3 tmp_Color;
//tmp_Color = ex_Color.rrr;
//out_Color = vec4(tmp_Color,1.0);
}
// Vertex Shader – file "minimal.vert"
#version 130
in vec3 in_Position;
in vec3 in_Color;
out vec3 ex_Color;
void main(void)
{
ex_Color = in_Color;
gl_Position = vec4(in_Position, 1.0);
}
// Triangle_opengl_3_1
// A cross platform version of
// http://www.opengl.org/wiki/Tutorial:_OpenGL_3.1_The_First_Triangle_%28C%2B%2B/Win%29
// with some code from http://www.lighthouse3d.com/opengl/glsl/index.php?oglexample1
// and from the book OpenGL Shading Language 3rd Edition, p215-216
// Daniel Livingstone, October 2010
#include <GL/glew.h>
#define FREEGLUT_STATIC
#include <GL/freeglut.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
// Globals
// Real programs don't use globals :-D
// Data would normally be read from files
GLfloat vertices[] = { -1.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f };
GLfloat colours[] = { 1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f };
GLfloat vertices2[] = { 0.0f,0.0f,0.0f,
0.0f,-1.0f,0.0f,
1.0f,0.0f,0.0f };
// two vertex array objects, one for each object drawn
unsigned int vertexArrayObjID[2];
// three vertex buffer objects in this example
unsigned int vertexBufferObjID[3];
// loadFile - loads text file into char* fname
// allocates memory - so need to delete after use
// size of file returned in fSize
char* loadFile(char *fname, GLint &fSize)
{
ifstream::pos_type size;
char * memblock;
string text;
// file read based on example in cplusplus.com tutorial
ifstream file (fname, ios::in|ios::binary|ios::ate);
if (file.is_open())
{
size = file.tellg();
fSize = (GLuint) size;
memblock = new char [size];
file.seekg (0, ios::beg);
file.read (memblock, size);
file.close();
cout << "file " << fname << " loaded" << endl;
text.assign(memblock);
}
else
{
cout << "Unable to open file " << fname << endl;
exit(1);
}
return memblock;
}
// printShaderInfoLog
// From OpenGL Shading Language 3rd Edition, p215-216
// Display (hopefully) useful error messages if shader fails to compile
void printShaderInfoLog(GLint shader)
{
int infoLogLen = 0;
int charsWritten = 0;
GLchar *infoLog;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
// should additionally check for OpenGL errors here
if (infoLogLen > 0)
{
infoLog = new GLchar[infoLogLen];
// error check for fail to allocate memory omitted
glGetShaderInfoLog(shader,infoLogLen, &charsWritten, infoLog);
cout << "InfoLog:" << endl << infoLog << endl;
delete [] infoLog;
}
// should additionally check for OpenGL errors here
}
void init(void)
{
// Would load objects from file here - but using globals in this example
// Allocate Vertex Array Objects
glGenVertexArrays(2, &vertexArrayObjID[0]);
// Setup first Vertex Array Object
glBindVertexArray(vertexArrayObjID[0]);
glGenBuffers(2, vertexBufferObjID);
// VBO for vertex data
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjID[0]);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
// VBO for colour data
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjID[1]);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), colours, GL_STATIC_DRAW);
glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
// Setup second Vertex Array Object
glBindVertexArray(vertexArrayObjID[1]);
glGenBuffers(1, &vertexBufferObjID[2]);
// VBO for vertex data
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjID[2]);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vertices2, GL_STATIC_DRAW);
glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
}
void initShaders(void)
{
GLuint p, f, v;
char *vs,*fs;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
// load shaders & get length of each
GLint vlen;
GLint flen;
vs = loadFile("minimal.vert",vlen);
fs = loadFile("minimal.frag",flen);
const char * vv = vs;
const char * ff = fs;
glShaderSource(v, 1, &vv,&vlen);
glShaderSource(f, 1, &ff,&flen);
GLint compiled;
glCompileShader(v);
glGetShaderiv(v, GL_COMPILE_STATUS, &compiled);
if (!compiled)
{
cout << "Vertex shader not compiled." << endl;
printShaderInfoLog(v);
}
glCompileShader(f);
glGetShaderiv(f, GL_COMPILE_STATUS, &compiled);
if (!compiled)
{
cout << "Fragment shader not compiled." << endl;
printShaderInfoLog(f);
}
p = glCreateProgram();
glBindAttribLocation(p,0, "in_Position");
glBindAttribLocation(p,1, "in_Color");
glAttachShader(p,v);
glAttachShader(p,f);
glLinkProgram(p);
glUseProgram(p);
delete [] vs; // dont forget to free allocated memory
delete [] fs; // we allocated this in the loadFile function...
}
void display(void)
{
// clear the screen
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vertexArrayObjID[0]); // First VAO
glDrawArrays(GL_TRIANGLES, 0, 3); // draw first object
glBindVertexArray(vertexArrayObjID[1]); // select second VAO
glVertexAttrib3f((GLuint)1, 1.0, 0.0, 0.0); // set constant color attribute
glDrawArrays(GL_TRIANGLES, 0, 3); // draw second object
glBindVertexArray(0);
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
}
int main (int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(600,600);
glutCreateWindow("Triangle Test");
glewInit();
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
cout << "glewInit failed, aborting." << endl;
exit (1);
}
cout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << endl;
cout << "OpenGL version " << glGetString(GL_VERSION) << " supported" << endl;
init();
initShaders();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
@kcsaff
Copy link

kcsaff commented Jan 29, 2013

Thanks, this was really helpful -- I spent some time looking for a Linux GLEW hello world and this worked immediately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment