GLSL着色器类帧率问题

时间:2011-12-03 14:03:28

标签: c++ glsl shader

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();

我没有正确地释放一些资源吗?任何帮助将不胜感激,谢谢!

2 个答案:

答案 0 :(得分:2)

每次切换时链接程序都是错误的。您应该根据需要创建任意数量的程序,所有着色器对象,然后链接您需要的所有内容。然后只需在交换机上调用glUseProgram(可能有一个调用glGet(GL_CURRENT_PROGRAM)的调试模式,并警告不必要的交换机,因为它们本质上就是错误。

答案 1 :(得分:1)

您不应该在每次循环迭代时不断地链接/使用着色器。只有在需要从一个切换到另一个时才这样做。

SLManager.use("shader.frag");
loop {
  makeSphere();
}
SLManager.end();

另外,请勿使用字符串来引用着色器。创建对象并将它们传递给管理器。