Sunday, February 6, 2011

A C++ class for GLSLShader

I had written a pure C++ class called GLSLShader for handling the common GLSLShader compilation and linking chores. Here are the details:

The Class Interface

#pragma once
#include <GL/glew.h>
#include <map>
#include <string>

using namespace std;

class GLSLShader
 void LoadFromString(GLenum whichShader, const string& source);
 void LoadFromFile(GLenum whichShader, const string& filename);
 void CreateAndLinkProgram();
 void Use();
 void UnUse();
 void AddAttribute(const string& attribute);
 void AddUniform(const string& uniform);
 GLuint GetProgram() const;
 //An indexer that returns the location of the attribute/uniform
 GLuint operator[](const string& attribute);
 GLuint operator()(const string& uniform);

 GLuint _program;
 int _totalShaders;
 GLuint _shaders[3];//0-> vertexshader, 1-> fragmentshader, 2-> geometryshader
 map<string,gluint> _attributeList;
 map<string,gluint> _uniformLocationList;

The attributes and uniform locations are stored in a map which are populated once so that we dont get the locations of the attributes and uniforms everytime. Then using an indexer (using () or [] operator), the locations of the attribute and uniform are accessed so that client application can modify them as needed.

Typical usage
Create a reference first and then call the LoadFromFile function to load a GLSLShader from a text file or call LoadFromString to load a GLSL shader from a string. The first parameter is the shader type which may be (GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, GL_GEOMETRY_SHADER). The second parameter is either the file name (for LoadFromFile function) or a string containing the shader contents (for LoadFromString function).
GLSLShader shader;

Next the call to compile and link is issued.

Once compiled we may use the shader and then add the uniforms and attributes as needed. For one time uniforms, we may set their values here.


When we want to get the location of any attribute for the vertex buffers, we may use the indexers as follows,
glVertexAttribPointer(shader["vVertex"],  4, GL_FLOAT, GL_FALSE, 0, 0);

Note that shader["vVertex"] returns the attribute location of "vVertex" attribute from the shader. Likewise, for handling of uniforms, we may do something like this in the render function,
   glUniformMatrix4fv(shader("MVP"), 1, GL_FALSE,  glm::value_ptr(MVP)); 
   glDrawElements(GL_TRIANGLES, ...);

The class also handles the deletion of program and shaders on exit making this a very compact class for handling of GLSLShaders. Here are the source files.


Korak said...

nice, but can you share sources?

Mobeen said...

Hi Korak,
Well the sources are shared in my OpenSource project opencloth. Check the GLSL cloth code in this project.

Korak said...

Some performance notice:
* pass std::strings by reference
* use binary search in sorted std::vector rather then std::map (or even better to use hash_map)

Mobeen said...

Thanks Korak,
I have noted your corrections.

Popular Posts

Copyright (C) 2011 - Movania Muhammad Mobeen. Awesome Inc. theme. Powered by Blogger.