Reputation: 4026
VC++ 2010, SDL, OpenGL, GLSL
I am working on this class as a way to switch between shaders quick and easily. It seems to be working properly(functionality-wise), however the framerate drops severely after implementing it(from 60 to 40). Hopefully you guys can point me in the right direction.
Here is what I have so far:
namespace SL {
struct Shader_Manager {
struct shader_vect {
GLuint shader_type;
GLuint shader_handle;
char * filename;
};
struct search_vect
{
std::string target;
bool operator()(const shader_vect& vect) const
{
return vect.filename == target;
}
};
GLuint prog;
std::vector <shader_vect> shader_list;
GLuint vertex_shader;
GLuint fragment_shader;
Shader_Manager() {
prog = glCreateProgram();
};
~Shader_Manager() {};
void load(char * filename, int type) {
shader_vect shader;
shader.filename = filename;
shader.shader_type = type;
shader.shader_handle = glCreateShader(type);
char * fs = textFileRead(filename);
const char * vv = fs;
glShaderSource(shader.shader_handle, 1, &vv, NULL);
free(fs);
glCompileShader(shader.shader_handle);
shader_list.push_back(shader);
}
void use(char * filename) {
search_vect search;
search.target = filename;
std::vector<shader_vect>::iterator it =
std::find_if(shader_list.begin(), shader_list.end(), search);
glAttachShader(prog, it->shader_handle);
glLinkProgram(prog);
glUseProgram(prog);
}
void end() {
glLinkProgram(0);
glUseProgram(0);
}
};
} // namespace SL
inside my main function I use it like such:
SL::Shader_Manager SLManager;
SLManager.load("shader.frag", GL_FRAGMENT_SHADER);
and withing the game loop I am doing:
SLManager.use("shader.frag");
makeSphere();
SLManager.end();
Am I not properly free'ing up some resources? Any help would be appreciated, thanks!
Upvotes: 0
Views: 426
Reputation: 59841
Linking a program every time you switch is a mistake. You should create as many programs as you need, all shader objects and then link everything that you will need. Then just call glUseProgram
on a switch (possibly have a debug mode that calls glGet(GL_CURRENT_PROGRAM)
and alerts for unnecessary switches, because those are, essentially, bugs.
Upvotes: 2
Reputation: 53097
You shouldn't be constantly linking/using shaders every loop iteration. Only do so when you need to switch from one to another.
SLManager.use("shader.frag");
loop {
makeSphere();
}
SLManager.end();
Also, don't use strings to refer to shaders. Create objects and pass them into the manager.
Upvotes: 1