1 /** 2 Copyright: Copyright (c) 2017 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 7 module voxelman.graphics.shaders; 8 9 import derelict.opengl3.gl3; 10 import anchovy.irenderer; 11 import anchovy.shaderprogram; 12 import anchovy.glerrors; 13 import voxelman.math; 14 15 16 string solid_frag_shader = ` 17 #version 330 18 smooth in vec4 frag_color; 19 out vec4 out_color; 20 21 void main() { 22 out_color = frag_color; 23 } 24 `; 25 26 string color_frag_shader_transparent = ` 27 #version 330 28 smooth in vec4 frag_color; 29 out vec4 out_color; 30 uniform float transparency; 31 32 void main() { 33 out_color = vec4(frag_color.xyz, transparency); 34 } 35 `; 36 37 string vert_shader_2d = ` 38 #version 330 39 layout(location = 0) in vec2 position; 40 layout(location = 1) in vec4 color; 41 42 smooth out vec4 frag_color; 43 uniform mat4 projection; 44 45 void main() { 46 gl_Position = projection * vec4(position.xy, 0, 1); 47 frag_color = color; 48 } 49 `; 50 51 string solid_vert_shader = ` 52 #version 330 53 layout(location = 0) in vec4 position; 54 layout(location = 1) in vec4 color; 55 uniform mat4 projection; 56 uniform mat4 view; 57 uniform mat4 model; 58 smooth out vec4 frag_color; 59 void main() { 60 gl_Position = projection * view * model * position; 61 frag_color = color; 62 } 63 `; 64 65 immutable Matrix4f matrix4fIdentity = Matrix4f.identity; 66 67 mixin template ModelSetter() 68 { 69 void setModel(Matrix4f model) { 70 checkgl!glUniformMatrix4fv(model_location, 1, GL_FALSE, model.arrayof.ptr); 71 } 72 73 void setModel() { 74 checkgl!glUniformMatrix4fv(model_location, 1, GL_FALSE, Matrix4f.identity.arrayof.ptr); 75 } 76 } 77 78 mixin template ViewSetter() 79 { 80 void setView(Matrix4f view) { 81 checkgl!glUniformMatrix4fv(view_location, 1, GL_FALSE, view.arrayof.ptr); 82 } 83 84 void setView() { 85 checkgl!glUniformMatrix4fv(view_location, 1, GL_FALSE, Matrix4f.identity.arrayof.ptr); 86 } 87 } 88 89 mixin template ProjectionSetter() 90 { 91 void setProjection(Matrix4f projection) { 92 checkgl!glUniformMatrix4fv(projection_location, 1, GL_FALSE, projection.arrayof.ptr); 93 } 94 95 void setProjection() { 96 checkgl!glUniformMatrix4fv(projection_location, 1, GL_FALSE, Matrix4f.identity.arrayof.ptr); 97 } 98 } 99 100 mixin template TransparencySetter() { 101 void setTransparency(float transparency) { 102 checkgl!glUniform1f(transparency_location, transparency); 103 } 104 } 105 106 mixin template MvpSetter() 107 { 108 void setMVP(Matrix4f model, Matrix4f view, Matrix4f projection) { 109 checkgl!glUniformMatrix4fv(model_location, 1, GL_FALSE, model.arrayof.ptr); 110 checkgl!glUniformMatrix4fv(view_location, 1, GL_FALSE, view.arrayof.ptr); 111 checkgl!glUniformMatrix4fv(projection_location, 1, GL_FALSE, projection.arrayof.ptr); 112 } 113 } 114 115 mixin template VpSetter() 116 { 117 void setVP(Matrix4f view, Matrix4f projection) { 118 checkgl!glUniformMatrix4fv(view_location, 1, GL_FALSE, view.arrayof.ptr); 119 checkgl!glUniformMatrix4fv(projection_location, 1, GL_FALSE, projection.arrayof.ptr); 120 } 121 } 122 123 struct SolidShader3d 124 { 125 ShaderProgram shader; 126 alias shader this; 127 128 mixin MvpSetter; 129 mixin VpSetter; 130 mixin ModelSetter; 131 mixin ViewSetter; 132 mixin ProjectionSetter; 133 134 GLint model_location = -1; 135 GLint view_location = -1; 136 GLint projection_location = -1; 137 138 void compile(IRenderer renderer) { 139 shader = renderer.createShaderProgram(solid_vert_shader, solid_frag_shader); 140 141 model_location = checkgl!glGetUniformLocation(shader.handle, "model"); 142 view_location = checkgl!glGetUniformLocation(shader.handle, "view"); 143 projection_location = checkgl!glGetUniformLocation(shader.handle, "projection"); 144 } 145 } 146 147 struct TransparentShader3d 148 { 149 ShaderProgram shader; 150 alias shader this; 151 152 mixin MvpSetter; 153 mixin VpSetter; 154 mixin ModelSetter; 155 mixin ViewSetter; 156 mixin ProjectionSetter; 157 mixin TransparencySetter; 158 159 GLint model_location = -1; 160 GLint view_location = -1; 161 GLint projection_location = -1; 162 GLint transparency_location = -1; 163 164 void compile(IRenderer renderer) { 165 shader = renderer.createShaderProgram(solid_vert_shader, color_frag_shader_transparent); 166 167 model_location = checkgl!glGetUniformLocation(shader.handle, "model"); 168 view_location = checkgl!glGetUniformLocation(shader.handle, "view"); 169 projection_location = checkgl!glGetUniformLocation(shader.handle, "projection"); 170 transparency_location = checkgl!glGetUniformLocation(shader.handle, "transparency"); 171 } 172 } 173 174 struct SolidShader2d 175 { 176 ShaderProgram shader; 177 alias shader this; 178 179 mixin ProjectionSetter; 180 181 GLint projection_location = -1; 182 183 void compile(IRenderer renderer) { 184 shader = renderer.createShaderProgram(vert_shader_2d, solid_frag_shader); 185 186 projection_location = checkgl!glGetUniformLocation(shader.handle, "projection"); 187 } 188 }