mrkd
10/15/2010 - 2:59 PM

## OpenGL 3.0+ Rendering Example - A complete and fairly minimal example of rendering with shaders

OpenGL 3.0+ Rendering Example - A complete and fairly minimal example of rendering with shaders

``````// 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);
}``````
``````// 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);
}
``````
``````// 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];

// allocates memory - so need to delete after use
// size of file returned in 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.close();
cout << "file " << fname << " loaded" << endl;
text.assign(memblock);
}
else
{
cout << "Unable to open file " << fname << endl;
exit(1);
}
return memblock;
}

// From OpenGL Shading Language 3rd Edition, p215-216
// Display (hopefully) useful error messages if shader fails to compile
{
int infoLogLen = 0;
int charsWritten = 0;
GLchar *infoLog;

// should additionally check for OpenGL errors here

if (infoLogLen > 0)
{
infoLog = new GLchar[infoLogLen];
// error check for fail to allocate memory omitted
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);
}

{
GLuint p, f, v;

char *vs,*fs;

GLint vlen;
GLint flen;

const char * vv = vs;
const char * ff = fs;

GLint compiled;

if (!compiled)
{
cout << "Vertex shader not compiled." << endl;
}

if (!compiled)
{
cout << "Fragment shader not compiled." << endl;
}

p = glCreateProgram();

glBindAttribLocation(p,0, "in_Position");
glBindAttribLocation(p,1, "in_Color");

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();