GLSL着色器类帧速率问题

GLSL shader class framerate issues

本文关键字:帧速率 问题 GLSL      更新时间:2023-10-16

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

我没有适当地腾出一些资源吗?任何帮助都将不胜感激,谢谢!

每次切换时链接程序都是错误的。您应该创建尽可能多的程序,所有着色器对象,然后链接您需要的所有内容。然后只需在交换机上调用glUseProgram(可能有一个调试模式,该模式会调用glGet(GL_CURRENT_PROGRAM)并对不必要的交换机发出警报,因为这些交换机本质上是错误

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

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

此外,不要使用字符串来引用着色器。创建对象并将其传递给管理器。