我应该在哪里保留着色器代码?

时间:2015-10-15 23:57:13

标签: c++ opengl glsl shader

这是一个哲学问题。

我想知道,如果有任何优雅的方法在标准的QtCreator项目中包含着色器代码。我所知道的唯一两种方式是:

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

  2. 着色器代码是项目中包含的源文件之一的硬编码字符串。

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

    第二种可能性让我感到困惑,因为你必须在你的着色器代码中包含\n之类的内容,这会使格式变得难看。

    “正确”的方式如何做到这一点?如果它有任何意义,我用c / c ++,OpenGL和GLSL编码。

    编辑: 我继续谷歌搜索这个...我注意到例如一个图标文件可以保存在项目的特殊资源文件夹中。这样它就是一个文件,可以这样编辑,但仍然不能在运行时加载。有没有办法用着色器做到这一点?

2 个答案:

答案 0 :(得分:5)

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

const char shaderSource[] = R"glsl(
#version 450 core

...    

void main() {
    ...
}
)glsl";

看不到\n:)

答案 1 :(得分:1)

我觉得这不是一个正确的答案,但是评论的时间也太长了。

粗略地说,你是对的 - 你可以在编译时使用着色器并进行硬编码,或者在运行时加载。我将详细说明你可以通过各种方式实现这一目标。请注意,所说的所有内容都可以应用于您的程序需要运行的任何其他类型的数据资源。

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

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

我没有回答right的方式。应该考虑用例来选择一个。

硬编码数据简化了部署(文件更少,显式更少,错误更少),而单独文件中的资源使您可以更新它们而无需触及程序本身,包括用户修改。