Проблемы с частотой кадров в классе шейдеров GLSL - PullRequest
0 голосов
/ 03 декабря 2011

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 ]

2 голосов
/ 03 декабря 2011

Связывание программы при каждом переключении является ошибкой. Вы должны создать столько программ, сколько вам нужно, все шейдерные объекты, а затем связать все, что вам нужно. Затем просто вызовите glUseProgram на коммутаторе (возможно, есть режим отладки, который вызывает glGet(GL_CURRENT_PROGRAM) и предупреждает о ненужных коммутаторах, потому что это, по сути, ошибки.

1 голос
/ 03 декабря 2011

Вы не должны постоянно связывать / использовать шейдеры на каждой итерации цикла. Делайте это только тогда, когда вам нужно переключиться с одного на другой.

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

Кроме того, не используйте строки для обозначения шейдеров. Создавайте объекты и передавайте их менеджеру.

...