I've had problems like this in the past am I'm getting sick and tierd of not knowing how to correct my app. The problem is that when I try to implement shaders in my app they work only some of the time. A few weeks ago I made a simple level editor / game program which both had the same exact shader.h and shader.cpp source. When I run the level editor program the shaders work while when I run the game program the shaders magicly don't work :(. I'm implementing lighting in my game engine so I've been messing around with glsl. I made a very simple shader which takes in 4 uniform values
LightColor, LightRadius, LightPosition, DiffuseTex. I'm not even using normals to calculate lighting, its just a very basic glsl program.
//VERTEX PROGRAM
varying vec2 texCoord;
varying vec3 vertPos;
void main(void)
{
texCoord = gl_MultiTexCoord0.xy;
gl_Position = ftransform();
vertPos = gl_Position.xyz;
}
//FRAGMENT PROGRAM
uniform sampler2D diffuseTex;
uniform vec3 LightPosition;
uniform vec4 LightColor;
uniform float LightRadius;
varying vec2 texCoord;
varying vec3 vertPos;
void main(void)
{
vec4 diffuseColor = texture2D(diffuseTex, texCoord);
float percentLit = 1.0f - (distance(LightPosition, vertPos) / LightRadius);
gl_FragColor = diffuseColor * percentLit * LightColor;
}
So its a pretty basic shader, and yet, it doesn't work in my application. A few months ago I made a shader class and it seems to be functioning. (In some apps, not in others)
Here's my shader class
// HEADER FILE
#ifndef SHADER_H
#define SHADER_H
#include <GL/glew.h>
#include <string>
#include <fstream>
using std::string;
class Shader
{
public:
Shader( string vertexFile, string fragFile );
void useShader(void);
static void disableShader(void);
void setAttribute1i( string name, int x );
void setAttribute2i( string name, int x, int y );
void setAttribute3i( string name, int x, int y, int z );
void setAttribute4i( string name, int x, int y, int z, int w );
void setAttribute1f( string name, float x );
void setAttribute2f( string name, float x, float y );
void setAttribute3f( string name, float x, float y, float z );
void setAttribute4f( string name, float x, float y, float z, float w );
void setAttributeMat4( string name, float mat4[16] );
private:
char * readFile(const char *fn);
private:
GLhandleARB vertexShader;
GLhandleARB fragmentShader;
GLhandleARB program;
};
#endif
//CPP FILE
#include "shader.h"
Shader::Shader( string vertexFile, string fragFile )
{
vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
const char *vv = readFile(vertexFile.data());
const char *ff = readFile(fragFile.data());
if ( vv != NULL && ff != NULL )
{
glShaderSourceARB( vertexShader, 1, &vv, NULL );
glShaderSourceARB( fragmentShader, 1, &ff, NULL );
delete [] vv;
delete [] ff;
glCompileShaderARB(vertexShader);
glCompileShaderARB(fragmentShader);
program = glCreateProgramObjectARB();
glAttachObjectARB(program, vertexShader); //attach shader into program
glAttachObjectARB(program, fragmentShader);
glLinkProgramARB(program);
}
}
void Shader::useShader(void)
{
glUseProgramObjectARB(program);
}
void Shader::disableShader(void)
{
glUseProgramObjectARB(NULL);
}
void Shader::setAttribute1i( string name, int x )
{
glUniform1iARB( glGetUniformLocationARB(program, name.data()), x );
}
void Shader::setAttribute2i( string name, int x, int y )
{
glUniform2iARB( glGetUniformLocationARB(program, name.data()), x, y );
}
void Shader::setAttribute3i( string name, int x, int y, int z )
{
glUniform3iARB( glGetUniformLocationARB(program, name.data()), x, y, z );
}
void Shader::setAttribute4i( string name, int x, int y, int z, int w )
{
glUniform4iARB( glGetUniformLocationARB(program, name.data()), x, y, z, w );
}
void Shader::setAttribute1f( string name, float x )
{
glUniform1fARB( glGetUniformLocationARB(program, name.data()), x );
}
void Shader::setAttribute2f( string name, float x, float y )
{
glUniform2fARB( glGetUniformLocationARB(program, name.data()), x, y );
}
void Shader::setAttribute3f( string name, float x, float y, float z )
{
glUniform3fARB( glGetUniformLocationARB(program, name.data()), x, y, z );
}
void Shader::setAttribute4f( string name, float x, float y, float z, float w )
{
glUniform4fARB( glGetUniformLocationARB(program, name.data()), x, y, z, w );
}
void Shader::setAttributeMat4( string name, float mat4[16] )
{
glUniformMatrix4fvARB( glGetUniformLocationARB(program, name.data()), 16, false, mat4 );
}
//TODO PASS ARRAYS TO SHADER
//glUniform3fvARB( this will pass an array of values to the shader
char * Shader::readFile(const char *fn)
{
int length;
char *buffer;
std::ifstream file;
file.open(fn, std::ios::binary);
if ( file.is_open() == false )
return NULL;
file.seekg(0, std::ios::end);
length = file.tellg();
file.seekg(0, std::ios::beg);
buffer = new char[length];
file.read( buffer, length );
file.close();
return buffer;
}
It looks like it should work, at least to me it does.
In my main program I'm Initializing the window and the shaders, then I'm starting the main loop and in there I handle events and render. I'll show you my InitShaders and my render function (cut down though)
//INIT SHADERS
if ( GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader ) //if shaders work
{
//setup shaders
lightShader = new Shader("lightShader.vert", "lightShader.frag");
lightShader->useShader();
lightShader->setAttribute1i("diffuseTex", 0);
lightShader->setAttribute3f("LightPosition", 0.0f, 3.0f, 10.0f);
lightShader->setAttribute4f("LightColor", 1.0f, 1.0f, 1.0f, 1.0f);
lightShader->setAttribute1f("LightRadius", 0.5f);
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
}
//RENDER THE SCENE
lightShader->useShader();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
cam->Update(keystate); //this just updates the camera position and rotation
cam->SetMatrix(); //this sets up the projection and modelview matrix
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
//draw the carpet
carpet->bindTexture();
glBegin(GL_QUADS);
//texCoords and Vertices
glEnd();
//draw the walls
wall->bindTexture();
glBegin(GL_QUADS);
//texCoords and Vertices
glEnd();
//draw ceiling
ceiling->bindTexture();
glBegin(GL_QUADS);
//texCoords and Vertices
glEnd();
lightShader->disableShader();
glFlush();
SDL_GL_SwapBuffers();
So I'm not sure what the problem is. As I said before, I've had this problem in the past and this problem only happens in some apps while other apps run fine. And the apps that run fine have the same exact shader class source files so that makes everything really confusing. However what you could draw from that I guess is that there's nothing wrong with the shader class, just the way I'm using it.
Hopefully you can help me solve this headache of a problem. Thanks!
[Edited by - zaneski13 on February 18, 2010 2:05:37 AM]