Common Techniques for Defining Shader Code

Introducing three common techniques.

1. Using Variadic Macros

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define VERTEX_SHADER(...) "#version 300 es\n" #__VA_ARGS__
#define FRAGMENT_SHADER(...) "#version 300 es\n" #__VA_ARGS__

// Triangle Shader
const char* TriangleVertexShader = VERTEX_SHADER(
layout(location = 0) in vec4 vPosition;
void main() {
gl_Position = vPosition;
}
);

const char* TriangleFragmentShader = FRAGMENT_SHADER(
precision mediump float;
out vec4 FragColor;
void main() {
FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
);

2. Using Raw String Literal

1
2
3
4
5
6
7
const char* vertexShaderSource = R"(
#version 330 core
layout(location = 0) in vec3 aPos;
void main() {
gl_Position = vec4(aPos, 1.0);
}
)";

3. Shader Files

vertexShader.glsl
1
2
3
4
5
#version 330 core
layout(location = 0) in vec3 aPos;
void main() {
gl_Position = vec4(aPos, 1.0);
}

Read file in C++:

1
2
3
4
std::ifstream file("vertexShader.glsl");
std::stringstream buffer;
buffer << file.rdbuf();
std::string vertexShaderSource = buffer.str();

Common Techniques for Defining Shader Code

http://chuzcjoe.github.io/CGV/cgv-define-shaders/

Author

Joe Chu

Posted on

2025-03-20

Updated on

2025-03-20

Licensed under

Comments