Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我应该将着色器代码保存在哪里?_C++_Opengl_Glsl_Shader - Fatal编程技术网

C++ 我应该将着色器代码保存在哪里?

C++ 我应该将着色器代码保存在哪里?,c++,opengl,glsl,shader,C++,Opengl,Glsl,Shader,这是一个哲学问题 我想知道,在标准的QtCreator项目中是否有优雅的方式包含着色器代码。我只知道两种方法: 着色器代码位于单独的文件中,例如“fragmentshader.frag”,该文件在运行时读取,着色器代码被编译和链接 着色器代码是项目中包含的一个源文件中的硬编码字符串 这两种方式对我来说都有点烦人。第一种可能要求硬盘上的文件必须与可执行文件位于同一目录中(因此我必须将它们放在每个调试/发布目录中,并最终得到我的着色器文件的多个副本),或者位于硬盘上的特定硬编码目录中,这似乎不利于可

这是一个哲学问题

我想知道,在标准的QtCreator项目中是否有优雅的方式包含着色器代码。我只知道两种方法:

  • 着色器代码位于单独的文件中,例如“fragmentshader.frag”,该文件在运行时读取,着色器代码被编译和链接

  • 着色器代码是项目中包含的一个源文件中的硬编码字符串

  • 这两种方式对我来说都有点烦人。第一种可能要求硬盘上的文件必须与可执行文件位于同一目录中(因此我必须将它们放在每个调试/发布目录中,并最终得到我的着色器文件的多个副本),或者位于硬盘上的特定硬编码目录中,这似乎不利于可移植性

    第二种可能性让我很烦,因为您必须在着色器代码中包含
    \n
    之类的内容,这使得格式有点难看

    “正确”的方法是如何做到这一点的?如果有什么意义的话,我正在用c/c++、OpenGL和GLSL进行编码

    编辑:
    我一直在谷歌上搜索这个。。。例如,我注意到一个图标文件可以保存在项目的一个特殊资源文件夹中。这样,它就是一个文件,可以进行编辑,但仍然不需要在运行时加载。有没有一种方法可以用着色器实现这一点?

    我觉得这不是一个正确的答案,但它也太长,无法发表评论

    粗略地说,您是对的——要么在编译时提供着色器并进行硬编码,要么在运行时加载。我将详细介绍实现这一目标的各种方法。请注意,所说的一切都可以应用于程序需要运行的任何其他类型的数据资源

    硬编码可以以一种更优雅的方式完成:将资源保存在单独的文件中,但设置构建系统,使其自动生成带有硬编码资源的源文件(例如,作为
    std::uint8\t
    char
    )的静态或动态数组),并将生成的文件编译到程序中。在这里,您可能需要一个从二进制数据生成C++源文件的实用程序。我不知道有这么好的特色节目;当我需要的时候,我自己写,因为它很简单

    要使运行时加载更具可移植性,可以使用选项加载,但似乎最重要的是使文件系统上的资源位置可配置;在运行时或编译时,这取决于您。它可以是一个编译标志(例如,由生成系统设置的宏
    运行时\资源\路径
    )。它可以是一个具有合理默认值的命令行选项

    我不知道哪条路是正确的。应根据用例选择一个


    硬编码数据简化了部署(更少的文件,更少的显式io,更少的错误),而单独文件中的资源使您能够在不接触程序本身的情况下更新它们,包括用户修改。

    如果您有C++11,您可以做的另一件事是使用原始字符串:

    const char shaderSource[] = R"glsl(
    #version 450 core
    
    ...    
    
    void main() {
        ...
    }
    )glsl";
    

    看不到
    \n
    :)

    这很有趣!我一定会试试的!是否必须在每一行的开头添加
    ”?只需将我的pro文件配置为使用c++11,并且在字符数组中,如果我按enter键,它会自动给我一个引号。(另外,测试着色器没有按照您在此处发布的方式工作)但是它工作了,没有
    glsl()
    ,每行前后都有引号。您可以在此处阅读有关字符串文字的更多信息。左括号和右括号旁边的“glsl”是可选的。它们只会使结束序列变长,以便您的字符串可以包含“”“”没有结束。我强烈建议这样做。«虽然单独文件中的资源使您能够在不接触程序本身的情况下更新它们»-也就是说,着色器代码也是一个程序。。。我们在这里进行即时编译。