Introducing three common techniques.
1. Using Variadic Macros
| 12
 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__
 
 
 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
| 12
 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| 12
 3
 4
 5
 
 | #version 330 corelayout(location = 0) in vec3 aPos;
 void main() {
 gl_Position = vec4(aPos, 1.0);
 }
 
 | 
 
Read file in C++:
| 12
 3
 4
 
 | std::ifstream file("vertexShader.glsl");std::stringstream buffer;
 buffer << file.rdbuf();
 std::string vertexShaderSource = buffer.str();
 
 |