Shader loading class
By Hugo on Wednesday, October 1 2008, 22:52 - C++ - Permalink
For a little project I'll probably speak about here someday, I wrote a shader loading class to ease my pain, as i was discovering shaders...
I didn't wan't to bother loading shaders to try them, so I decided to write a class to do this for me once and for all.
Just as a reminder, a shader is a piece of code that will be executed by your graphical controller, instead of what's called the fixed function pipeline, which consists of a set of instructions for the vertice (object space to screen space, basic lighting), and a set of instructions for the fragments -aka pixels- (applying textures, fog, color blending).
You can write your shader in GLSL (openGL Shading Language), HLSL (High Level Shader Language, for DirectX), and CG (C for Graphics), which is the nvidia language, that will be compiled in binary code that can match with the ones generated by GLSL or HLSL compiler (but it does fail to sometimes :p )
The language i used at this time was GLSL, because it seemed to me that it would be easier to apprehend than HLSL, and I didn't really knew what CG was about...
This is basic c++, no killer language feature here, no pownage algorithm. Source can be found at the bottom.
It can be used like this :
Shaders* shad = new Shaders(); shad->setPixelShader("lightPS.glsl"); shad->setVertexShader("lightVS.glsl"); shad->makeAll(); //...... shad->enable(); glBegin(GL_QUADS); glColor3ub(0,0,255); //face bleue glNormal3f(0.f, 1.f, 0.f); glVertex3d(-10, -1, 10); glNormal3f(0.f, 1.f, 0.f); glVertex3d(-10, -1, -10); glNormal3f(0.f, 1.f, 0.f); glVertex3d(10, -1, -10); glNormal3f(0.f, 1.f, 0.f); glVertex3d(10, -1, 10); glEnd(); shad->disable();
and here is the test lighting shader i used for test :
Vertex shader :
varying vec3 normal; varying vec3 vl; void main(void) { vec4 light = vec4(0.0, 1.f, 0.0, 1.0); /// Putting the normal in the world space normal = gl_NormalMatrix * gl_Normal; /// Calculating the vertex position in world space vec3 point = gl_ModelViewMatrix * gl_Vertex; /// calculating the vertex-light ray vl = (gl_ModelViewMatrix * light).xyz - point; /// Calculating the vertex position in the projection space gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; /// Passing the color of the vertex to the fragment shader gl_FrontColor = gl_Color; }
Fragment/Pixel shader :
varying vec3 normal; varying vec3 vl; void main(void) { /// normalizing both vectors to have a correct dot product result vec3 n = normalize(normal); vec3 lvect = normalize(vl); /// We get the angle between both vectors by using dot product, and clamping it between 0 and 1 to be sure float factor = clamp(dot(n, lvect), 0.0, 1.0); /// Finally, this angle is used to tweak the color, simulating the light gl_FragColor = gl_Color * factor; }
with proper opengl initialisation and render, here is what we get :
Et voila ! o//