Setting up a program to run OpenGL GLSL

Setting up to starting with GLSL can be little complicated. This requires a few library setups and using OpenGL API to setup the pipeline. First you will need an IDE like Windows Visual Studios 2010 C++ express. You will than need to set OpenGL Extension Wrangler Library (GLEW) for the OpenGL API project. Next you will need windows management library like freeglut. Freeglut is an updated version of GLUT (OpenGL Unility Toolkit) which allows users to create and manage windows for OpenGL. Freeglut can read mouse, keyboard, and joysticks functions. Lastly you will need a math Library like GLM (OpenGL Mathematics). Here is a great link to set up GLEW and freglut.

Before we start it is handy to know what GLSL version your GPU is using. Calling glGetString( GL_SHADING_LANGUAGE_VERSION), will return the version number. You will also need to make a call to glewInit() to initialize the GLEW extension entry points which will return GLEW_OK if it succeeds.

void Initialize(int argc, char* argv[])
{
InitWindow(argc, argv);
fprintf(stdout, "INFO: GLSL Version: %s\n",
glGetString( GL_SHADING_LANGUAGE_VERSION)
);
glewInit();
if (GLEW_OK != err){
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
}
// some GL settings
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_MULTISAMPLE);
}

This is the heart of the OpenGL program, it reads the source file(shader text file), compiles the shader, and links the shaders together with the program. We will discuss function printLog(GLuint) toward the end.

GLint status; // handle error reporting

/* Read shaders */
char *vsSource = textFileRead("example.vert");
char *fsSource = textFileRead("example.frag");
/* Compile and load the program */
GLuint vs, /* Vertex Shader */
fs, /* Fragment Shader */
sp; /* Shader Program */
vs = glCreateShader(GL_VERTEX_SHADER); // create an empty shader object
glShaderSource(vs, 1, &vsSource, NULL); // sets the source code
glCompileShader(vs); // compiles the source code
glGetShaderiv(vs, GL_COMPILE_STATUS, &status); // gets the sourse code
if (status == GL_FALSE)
{
printError(vs); 
}
if (status == GL_TRUE)
{
printf("Vertex shader compiled");
}
fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fsSource, NULL);
glCompileShader(fs);
glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
printError(fs);
}
if (status == GL_TRUE)
{
printf("Vertex fragment compiled");
}

free(vsSource);
free(fsSource);
sp = glCreateProgram(); // creates an empty program object
glAttachShader(sp, vs); // tells what what will be linked
glAttachShader(sp, fs);
glLinkProgram(sp); // link programs 
glGetProgramiv(sp, GL_LINK_STATUS, &status); defines a status
if (status == GL_FALSE)
{
printf("program error");
printError(sp);
}
if (status == GL_TRUE)
{
printf("Program compiled");
}
glUseProgram(sp); //install program

Now it is time to send attributes to the vertex shader. You can send attributes like mentioned above like position, color and normals but also custom attributes. This example is sending only position attributes of the vertices in the shape of a triangle. Two things you need to know is the Vertex Buffer Object (vbo) and Vertex Array Object (vao). The VBO stores the data to the GPU for fast access and VAO saves the link between the VBO and the attributes.

Gluint vbo, vao; // unsigned int 
// vertex position (x, y)
float vertices[] = { 0.0f, 0.5f, 
0.5f, -0.5f, 
-0.5f, -0.5f }; 
// bind index 0 to the program and name it “VertexPosition”
glBindAttribLocation(sp, 0, "VertexPosition"); 
// location and type of data to store 
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
// generates VAO
glGenBuffers(1, &vbo); 
// use the VAO
glBindBuffer (GL_ARRAY_BUFFER, vbo);

// creates a new data store
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW);

//generate vertex array object names
glGenVertexArrays( 1, &vao);
glBindVertexArray ( vao );
glDrawArrays( GL_TRIANGLES, 0, 3);

We now have the vertices of a triangle into the GPU buffer and being sent to the vertex shader. Next we will show you an example of handling shader compiler error using the GLEW library.

void printError(GLuint obj)
{
int infologLength = 0;
char infoLog[1024];
/** gets error log depending if shader or program **/
if (glIsShader(obj)) 
glGetShaderInfoLog(obj, 1024, &infologLength, infoLog);
else
glGetProgramInfoLog(obj, 1024, &infologLength, infoLog);
/** if error occurs then print error log **/ 
if (infologLength > 0)
printf("%s\n", infoLog);
}

Now we almost have everything in order to run a simple example. There are a few more functions that you should know about. The function glutSwapBuffers() is used when there is two buffers like a depth buffer. When using the swap buffer feature you should always clear the buffer using:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT).
The function glutMainloop will loop through your main method which should include clearing the buffering rendering your window and shaders. To delete a shader/shader and free memory use either glDeleteShader( Gluint shader) or glDeleteProgram(GLuint program ) .

The above setup does not show how to set up a windows management library (e.g. freeglut) , how to use mouse or keyboard functions, or adding GLEW and a math library.

 

Here is a GLSL program that runs GLUT which is out dated. It can use up to 4 sets of shaders at once.  It was fully coded by Greg Turk at Georgia Tech.

 

/*

Simple GLUT and GLSL example.

Greg Turk, March 2011

*/

#include 
#include 
#include 
#include 
//#include 
#include 
#include 
#include 
//#include 
 #include 

/* global variables */

int win_x = 500;
int win_y = 500;

static int mouse_down[3];
static int omx, omy, mx, my;

GLuint p0,p1,p2,p3,p4;
GLuint duck_texture;

float lpos[4] = {1,0.5,1,0};
float theta;

// read in a text file that contains a shader
char *textFileRead(char *fn) {
	
	FILE *fp;
	char *content = NULL;
	
	int count=0;
	
	if (fn != NULL) {
		fp = fopen(fn,"rt");
		
		if (fp != NULL) {
			
			fseek(fp, 0, SEEK_END);
			count = ftell(fp);
			rewind(fp);
			
			if (count > 0) {
				content = (char *)malloc(sizeof(char) * (count+1
														 ));     
				count = fread(content,sizeof(char),count,fp);
				content[count] = '\0';
			}
			fclose(fp);
		}
	}
	return content;
}


// load a 256x256 RGB .RAW file as a texture
GLuint LoadTextureRAW( const char * filename, int wrap )
{
  GLuint texture;
  int width, height;
  unsigned char * data;
  FILE * file;
    int i;
  
  // open texture data
  file = fopen( filename, "rb" );
  if ( file == NULL ) {
    fprintf (stderr, "Problem loading texture file\n");
    return 0;
  }
  
  // allocate buffer
  width = 256;
  height = 256;
  data = (unsigned char*) malloc( width * height * 3 );
  
  // read texture data
  fread( data, 54, 1, file );
  fread( data, width * height * 3, 1, file );
  fclose( file );

  // swap red and blue color components (yuck)
  for (i = 0; i < width * height; i++) {
    unsigned char temp = data[i*3];
    data[i*3] = data[i*3+2];
    data[i*3+2] = temp;
  }
  
  // allocate a texture name
  glGenTextures( 1, &texture );
  
  // select our current texture
  glBindTexture( GL_TEXTURE_2D, texture );
  
  // select modulate to mix texture with color for shading
  glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
  
  // when texture area is small, bilinear filter the closest mipmap
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                  GL_LINEAR_MIPMAP_NEAREST );
  // when texture area is large, bilinear filter the first mipmap
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  
  // if wrap is true, the texture wraps over at the edges (repeat)
  //       ... false, the texture ends at the edges (clamp)
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
                  wrap ? GL_REPEAT : GL_CLAMP );
  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
                  wrap ? GL_REPEAT : GL_CLAMP );
  
  // build our texture mipmaps
  gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,
                    GL_RGB, GL_UNSIGNED_BYTE, data );
  
  // free buffer
  free( data );
  
  return texture;
}


// print error messsages

#define printOpenGLError() printOglError(__FILE__, __LINE__)

int printOglError(char *file, int line)
{
    //
    // Returns 1 if an OpenGL error occurred, 0 otherwise.
    //
    GLenum glErr;
    int    retCode = 0;
	
    glErr = glGetError();
    while (glErr != GL_NO_ERROR)
    {
        printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr));
        retCode = 1;
        glErr = glGetError();
    } return retCode;
}

void printShaderInfoLog(GLuint obj)
{
    int infologLength = 0;
    int charsWritten  = 0;
    char *infoLog;
	
	glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
	
    if (infologLength > 0)
    {
        infoLog = (char *)malloc(infologLength);
        glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
		printf("%s\n",infoLog);
        free(infoLog);
    }
}

void printProgramInfoLog(GLuint obj)
{
    int infologLength = 0;
    int charsWritten  = 0;
    char *infoLog;
	
	glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
	
    if (infologLength > 0)
    {
        infoLog = (char *)malloc(infologLength);
        glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
		printf("%s\n",infoLog);
        free(infoLog);
    }
}


// read shaders from a file and associate them with an integer identifier
int setShaders(char *vert_file, char *frag_file)
{
	GLuint v,f;
	GLuint prog;
	char *vs_file = NULL;
	char *fs_file = NULL;
	
	v = glCreateShader(GL_VERTEX_SHADER);
	f = glCreateShader(GL_FRAGMENT_SHADER);
	
	vs_file = textFileRead(vert_file);
	fs_file = textFileRead(frag_file);
	
	const char *vv = vs_file;
	const char *ff = fs_file;
	
	glShaderSource(v, 1, &vv, NULL);
	glShaderSource(f, 1, &ff, NULL);
	
	free(vs_file);
	free(fs_file);
	
	glCompileShader(v);
	glCompileShader(f);
	
	printShaderInfoLog(v);
	printShaderInfoLog(f);
	
	prog = glCreateProgram();
	glAttachShader(prog,v);
	glAttachShader(prog,f);
	
	glLinkProgram(prog);
	printProgramInfoLog(prog);
  
	return (prog);
}



/*
  ----------------------------------------------------------------------
   GLUT callback routines
  ----------------------------------------------------------------------
*/


// process keystrokes
static void key_func ( unsigned char key, int x, int y )
{
	
	switch ( key ) {
		case 'q':
		case 'Q':
			exit ( 0 );
			break;
		case 27:   // escape
			exit (0);
			break;
  }
}

// mouse event
static void mouse_func ( int button, int state, int x, int y )
{
	omx = mx = x;
	omy = my = y;
	
	theta = 80 * (mx - 0.5 * win_x) / (float) win_x;

	mouse_down[button] = state == GLUT_DOWN;
}

// mouse motion
static void motion_func ( int x, int y )
{
	mx = x;
	my = y;
	
    theta = 80 * (mx - 0.5 * win_x) / (float) win_x;
}

// resize the window
void changeSize(int w, int h) {
	
	// Prevent a divide by zero, when window is too short
	// (you cant make a window of zero width).
	if(h == 0)
		h = 1;  
	
	float ratio = 1.0* w / h;
	
	// Reset the coordinate system before modifying
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	// Set the viewport to be the entire window
    glViewport(0, 0, w, h);
	
	// Set the correct perspective.
	gluPerspective(45,ratio,1,1000);
	glMatrixMode(GL_MODELVIEW);
	
	win_x = w;
	win_y = h;
}

// draw one upright rectangle
void draw_card()
{
	float d = 0.7;
	
	glBegin(GL_POLYGON);
	glNormal3f (0.0, 0.0, 1.0);
	glTexCoord2f (0.0, 0.0);	glVertex3f (-d, 0, 0.0);
	glTexCoord2f (1.0, 0.0);	glVertex3f ( d, 0, 0.0);
	glTexCoord2f (1.0, 1.0);	glVertex3f ( d, 2*d, 0.0);
	glTexCoord2f (0.0, 1.0);	glVertex3f (-d, 2*d, 0.0);
	glEnd();
}

// draw the scene
void renderScene() {
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	gluPerspective (60.0, 1.0, 0.01, 1000.0);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();  
	
	gluLookAt(0.0,2.0,4.0,
            0.0,-1.0,0.0,
            0.0,1.0,0.0);
	
	glLightfv(GL_LIGHT0, GL_POSITION, lpos);
	
	glUseProgram(p1);
	
	glPushMatrix();
	glRotatef(theta,0,1,0);            // spin the scene according to mouse position
	glTranslatef (0.0, -1.0, 0.0);
  
    // floor
	glUseProgram(p0);
	glBegin(GL_POLYGON);
	glNormal3f (0.0, 1.0, 0.0);
	glVertex3f (-2.0, 0.0, -2.0);
	glVertex3f ( 2.0, 0.0, -2.0);
	glVertex3f ( 2.0, 0.0,  2.0);
	glVertex3f (-2.0, 0.0,  2.0);
	glEnd();
    
    // mandelbrot
	glUseProgram(p2);
	glPushMatrix();
	glTranslatef (-1, 0, -1);
	draw_card();
	glPopMatrix();
	
    // edge detection
    int tindex = 0;
    glUseProgram(p3);
    GLint my_sampler_uniform_location = glGetUniformLocation(p3, "my_color_texture");
    glActiveTexture(GL_TEXTURE0 + tindex);
    glBindTexture(GL_TEXTURE_2D, duck_texture);
    glUniform1i(my_sampler_uniform_location, tindex);
  
    glPushMatrix();
	glTranslatef ( 1, 0, -1);
	draw_card();
	glPopMatrix();
	
    // wavy
	glUseProgram(p4);
	glPushMatrix();
	glTranslatef ( 1, 0, 1);
	draw_card();
	glPopMatrix();
	
    // swiss cheese
	glUseProgram(p1);
	glPushMatrix();
	glTranslatef (-1, 0,  1);
	draw_card();
	glPopMatrix();
	
	glPopMatrix();
  
	glPopMatrix();
	
	glutSwapBuffers();
}


//    main routine

int main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100
	glutInitWindowSize(win_x,win_y);
	glutCreateWindow("simple_glut");
	
	glutDisplayFunc(renderScene);
	glutIdleFunc(renderScene);
	glutReshapeFunc(changeSize);
	glutMouseFunc (mouse_func );
	glutMotionFunc (motion_func);
	glutKeyboardFunc (key_func);

	glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
	glClearColor(0.0,0.0,0.0,0.0);

	
	glewInit();
	if (glewIsSupported("GL_VERSION_2_0"))
		printf("Ready for OpenGL 2.0\n");
	else {
		printf("OpenGL 2.0 not supported\n");
		exit(1);
	}
	 
	
    // load the shaders
	p0 = setShaders((char*)"card0.vert", (char*)"card0.frag");
	p1 = setShaders((char*)"card1.vert", (char*)"card1.frag");
	p2 = setShaders((char*)"card2.vert", (char*)"card2.frag");
	p3 = setShaders((char*)"card3.vert", (char*)"card3.frag");
	p4 = setShaders((char*)"card4.vert", (char*)"card4.frag");
  
    // load duck texture
    duck_texture = LoadTextureRAW ("duck.bmp", 0);
	
    // call event loop
	glutMainLoop();
	
	return 0;
}


Graveyard Database Logo

Has everything you want to know about grave yards. Plus has many celebrites and world leaders graves. Pssst it is my other site

Google + Profile
Check out Android Photo Mapping, its a app/site I been working on

  • wholesale nfl jerseys
  • wholesale nfl jerseys china
  • wholesale sports jerseys