VC ++ 2010,SDL,OpenGL,GLSL
我正在研究这个类,以便快速轻松地在着色器之间切换。它似乎工作正常(功能方面),但帧率在实现后严重下降(从60到40)。希望你们能指出我正确的方向。
这是我到目前为止所做的:
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
在我的主要功能中我使用它如下:
SL::Shader_Manager SLManager;
SLManager.load("shader.frag", GL_FRAGMENT_SHADER);
并且正在进行游戏循环:
SLManager.use("shader.frag");
makeSphere();
SLManager.end();
我没有正确地释放一些资源吗?任何帮助将不胜感激,谢谢!
答案 0 :(得分:2)
每次切换时链接程序都是错误的。您应该根据需要创建任意数量的程序,所有着色器对象,然后链接您需要的所有内容。然后只需在交换机上调用glUseProgram
(可能有一个调用glGet(GL_CURRENT_PROGRAM)
的调试模式,并警告不必要的交换机,因为它们本质上就是错误。
答案 1 :(得分:1)
您不应该在每次循环迭代时不断地链接/使用着色器。只有在需要从一个切换到另一个时才这样做。
SLManager.use("shader.frag");
loop {
makeSphere();
}
SLManager.end();
另外,请勿使用字符串来引用着色器。创建对象并将它们传递给管理器。