c++ - 在 OpenGL/GLFW 中管理默认着色器

标签 c++ opengl glsl glfw

<分区>

我正在使用 glfw 编写一个 OpenGL 包装器库,我想将着色器与我的代码一起发布。这些着色器需要在创建 glfw 上下文后进行编译。我想将这些着色器作为类的静态变量。

我目前有一个“DefaultShaders”类,它存储在调用 init_shaders() 函数时分配的静态指针;

DefaultShaders.h

class DefaultShaders {
   private:
        static const std::string basic_vertex_source;
        static const std::string basic_fragment_source;

        static const std::string skybox_vertex_source;
        static const std::string skybox_fragment_source;


        static const std::string framebuffer_vertex_source;
        static const std::string framebuffer_fragment_source;

        static const ShaderProgram *default_program;
        static const ShaderProgram *skybox_program;
        static const ShaderProgram *framebuffer_program;

    public:

        static void init_shaders();

        static void delete_shaders();

        static const ShaderProgram &get_default_program();

        static const ShaderProgram &get_skybox_program();


        static const ShaderProgram&get_framebuffer_program();

    };

默认着色器.cpp

const std::string DefaultShaders::basic_vertex_source = "#version 330 core\n"
                                                            "layout (location = 0) in vec3 aPos;\n"
                                                            "layout (location = 1) in vec2 tex_coord;\n"
                                                            "layout (location = 2) in vec3 aNormal;\n"
                                                            "\n"
                                                            "uniform mat4 model;\n"
                                                            "uniform mat4 view;\n"
                                                            "uniform mat4 projection;\n"
                                                            "out vec2 TexCoord;\n"
                                                            "out vec3 Normal;\n"
                                                            "\n"
                                                            "void main()\n"
                                                            "{\n"
                                                            "    TexCoord=tex_coord;\n"
                                                            "    Normal=mat3(transpose(inverse(model))) * aNormal;\n"
                                                            "    mat4 mvp=projection*view*model;\n"
                                                            "    gl_Position = mvp*vec4(aPos, 1.0);\n"
                                                            "}";


    const std::string DefaultShaders::basic_fragment_source = "#version 330 core\n"
                                                              "out vec4 FragColor;\n"
                                                              "\n"
                                                              "in vec2 TexCoord;\n"
                                                              "\n"
                                                              "uniform sampler2D ourTexture;\n"
                                                              "in vec3 Normal;\n"
                                                              "\n"
                                                              "void main()\n"
                                                              "{\n"
                                                              "    vec3 norm = normalize(Normal);\n"
                                                              "    vec3 lightDir=vec3(0,1,0);\n"
                                                              "    float diff = max(dot(norm, lightDir), 0.4);\n"
                                                              "\n"
                                                              "\n"
                                                              "    FragColor = texture(ourTexture, TexCoord)*diff;\n"
                                                              "}";


    const std::string DefaultShaders::skybox_vertex_source = "#version 330 core\n"
                                                             "layout (location = 0) in vec3 aPos;\n"
                                                             "\n"
                                                             "out vec3 TexCoords;\n"
                                                             "\n"
                                                             "uniform mat4 pv;\n"
                                                             "\n"
                                                             "void main()\n"
                                                             "{\n"
                                                             "    TexCoords = aPos;\n"
                                                             "    vec4 pos=pv * vec4(aPos, 1.0);"
                                                             "    gl_Position =pos.xyww;\n"
                                                             "}";


    const std::string DefaultShaders::skybox_fragment_source = "#version 330 core\n"
                                                               "out vec4 FragColor;\n"
                                                               "\n"
                                                               "in vec3 TexCoords;\n"
                                                               "\n"
                                                               "uniform samplerCube skybox;\n"
                                                               "\n"
                                                               "void main()\n"
                                                               "{    \n"
                                                               "    FragColor = texture(skybox, TexCoords);\n"
                                                               "}";


    const std::string DefaultShaders::framebuffer_vertex_source = "#version 330 core\n"
                                                                  "layout (location = 0) in vec2 aPos;\n"
                                                                  "layout (location = 1) in vec2 aTexCoords;\n"
                                                                  "\n"
                                                                  "out vec2 TexCoords;\n"
                                                                  "\n"
                                                                  "void main()\n"
                                                                  "{\n"
                                                                  "    gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); \n"
                                                                  "    TexCoords = aTexCoords;\n"
                                                                  "} ";


    const std::string DefaultShaders::framebuffer_fragment_source = "#version 330 core\n"
                                                                    "out vec4 FragColor;\n"
                                                                    "  \n"
                                                                    "in vec2 TexCoords;\n"
                                                                    "\n"
                                                                    "uniform sampler2D screenTexture;\n"
                                                                    "\n"
                                                                    "void main()\n"
                                                                    "{ \n"
                                                                    "    FragColor = texture(screenTexture, TexCoords);\n"
                                                                    "}";


    const ShaderProgram *DefaultShaders::default_program;
    const ShaderProgram *DefaultShaders::skybox_program;
    const ShaderProgram *DefaultShaders::framebuffer_program;

    const ShaderProgram &DefaultShaders::get_default_program() {
        return *default_program;

    }

    const ShaderProgram &DefaultShaders::get_skybox_program() {
        return *skybox_program;
    }


    const ShaderProgram &DefaultShaders::get_framebuffer_program() {
        return *framebuffer_program;
    }

    void DefaultShaders::init_shaders() {
        VertexShader basic_vertex_shader(basic_vertex_source);
        FragmentShader basic_fragment_shader(basic_fragment_source);

        VertexShader skybox_vertex_shader(skybox_vertex_source);
        FragmentShader skybox_fragment_shader(skybox_fragment_source);


        VertexShader framebuffer_vertex_shader(framebuffer_vertex_source);
        FragmentShader framebuffer_fragment_shader(framebuffer_fragment_source);


        default_program = new ShaderProgram(basic_vertex_shader, basic_fragment_shader);
        skybox_program = new ShaderProgram(skybox_vertex_shader, skybox_fragment_shader);
        framebuffer_program = new ShaderProgram(framebuffer_vertex_shader, framebuffer_fragment_shader);
    }

    void DefaultShaders::delete_shaders() {
        delete default_program;
        delete skybox_program;
        delete framebuffer_program;
    }

是否有更好的方式将着色器与我的代码一起发布?

最佳答案

正如 HolyBlackCat 所说,原始字符串是在程序中存储字符串的更好方式。如果您仅针对 Windows,则可以使用资源文件来存储着色器。 This guide应该有帮助。如果您还想为 Mac 和 Linux 编译,您可以像现在一样继续存储着色器(或使用原始字符串只是为了提高可读性)或使用 SPIR-V 着色器。遗憾的是,最后这些在大多数计算机上都不可用,因为它们需要最新的 OpenGL 版本。它们也更难编码,因为它们的级别较低。

关于c++ - 在 OpenGL/GLFW 中管理默认着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57736195/

相关文章:

c++ - 如何遍历 std::vector<char> 并找到以 null 结尾的 c 字符串

c++ - c++和opencv生成奇怪的图片标题

opengl - GLSL 片段着色器输出类型

c++ - glDrawArrays 访问错误

c++ - ACE_OS::read_n() 返回 0 甚至接收到一些数据

c++ - 如何确定状态模式的状态

javascript - WebAssembly 和 OpenGL - 单一上下文,多个输出(到 Canvas )

opengl - 与 GL_MAX_TEXTURE_SIZE 混淆

c++ - QOpenGLWidget 的 resizeGL 不是调用 glViewport 的地方?

c++ - 将阴影添加到视差遮挡贴图