可以用 xxd 、脚本等工具。但是要多一个阶段。
实际上标准委员会的人也为编译时嵌入二进制文件感到困扰。我们知道 C/C++ 预处理器可以包含文件,也可把记号串变成字符串字面量,但这两个功能不能组合到一起。
于是有人提出了编译时嵌入的提案,现在分成两个部分:
从作者的测试数据可以看出为编译器增设该功能还是有编译性能优势的。
这个问题我研究过。我的结论是没有完美方法,只有折衷方法,需要稍微修改原始文本。
比如原始 test.glsl 内容为
test.glsl
vec4 mainImage(vec4 fragColor, vec2 fragCoord ) // Output to screen fragColor = vec4(1.0, 0.0, 0.0, 1.0); return fragColor; }
稍微修改,将文本变成 raw string,注意第一行和最后一行
R"( vec4 mainImage(vec4 fragColor, vec2 fragCoord ) // Output to screen fragColor = vec4(1.0, 0.0, 0.0, 1.0); return fragColor; )"
之后就可以在 C++ 源码中直接 #include
#include
const char *s_shadertoy = #include "test.glsl"
s_shadertoy 存放的就是原来的文本内容,只是前后各多了一个空行。在实际工程中,需要这样 include 的文本很多都是 json 、 xml OpenGL Shader 等,多了空行没有所谓。
s_shadertoy
json
xml
假如不想额外多空行,可以这样写。
// test.glsl R"( vec4 mainImage(vec4 fragColor, vec2 fragCoord ) // Output to screen fragColor = vec4(1.0, 0.0, 0.0, 1.0); return fragColor; // main.cpp const char *s_shadertoy = (char*) #include "test.glsl" + 1;
另外也可以在原始文本中前后添加一点东西,比如可写成
const char *s_shadertoy = varying vec2 vTexCoord; uniform vec3 iResolution; // viewport resolution (in pixels) uniform float iTime; // shader playback time (in seconds) uniform sampler2D iChannel0; uniform sampler2D iChannel1; uniform sampler2D iChannel2; uniform sampler2D iChannel3; #define texture texture2D #include "test.glsl" // 文本插入字符串中间 void main() { vec4 fragColor = vec4(0.0, 0.0, 0.0, 1.0); vec2 fragCoord = vec2(vTexCoord.x, 1.0 - vTexCoord.y) * iResolution.xy; gl_FragColor = mainImage(fragColor, fragCoord);