2011-12-03 57 views
0

VC++ 2010,SDL,OpenGL中,GLSLGLSL Shader类帧率问题

我对这个类的工作作为一种快速和容易着色器之间切换。它似乎工作正常(功能方面),但是帧率在实施后会严重下降(从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); 

和withing游戏圈我做:

SLManager.use("shader.frag"); 
    makeSphere(); 
SLManager.end(); 

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

回答

2

每次切换链接程序都是一个错误。你应该创建尽可能多的程序,所有着色器对象,然后链接你需要的所有东西。然后在一个交换机上调用glUseProgram(可能有一个调试模式,调用glGet(GL_CURRENT_PROGRAM)并警告不必要的交换机,因为这些实质上是bug)

+0

啊,好吧,为每个程序存储单独的程序,将必要的着色器附加到该程序,可能会给它一个名字,然后切换程序。问:我怎么禁用程序?(停止它的使用?) – grep

+0

@Headspin'glUseProgram(0)' – pmr

+0

它怎么知道我指的是哪个程序? – grep

1

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

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

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