1 /** 2 Copyright: Copyright (c) 2017-2018 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 voxelman.graphics.gl; 10 import voxelman.graphics.irenderer; 11 import voxelman.graphics.shaderprogram; 12 import voxelman.math; 13 14 15 string solid_frag_shader = ` 16 #version 330 17 smooth in vec4 frag_color; 18 out vec4 out_color; 19 20 void main() { 21 out_color = frag_color; 22 } 23 `; 24 25 string color_frag_shader_transparent = ` 26 #version 330 27 smooth in vec4 frag_color; 28 out vec4 out_color; 29 uniform float transparency; 30 31 void main() { 32 out_color = vec4(frag_color.xyz, transparency); 33 } 34 `; 35 36 string vert_shader_2d = ` 37 #version 330 38 layout(location = 0) in vec2 position; 39 layout(location = 1) in vec4 color; 40 41 smooth out vec4 frag_color; 42 uniform mat4 projection; 43 44 void main() { 45 gl_Position = projection * vec4(position.xy, 0, 1); 46 frag_color = color; 47 } 48 `; 49 50 string solid_vert_shader = ` 51 #version 330 52 layout(location = 0) in vec4 position; 53 layout(location = 1) in vec4 color; 54 uniform mat4 projection; 55 uniform mat4 view; 56 uniform mat4 model; 57 smooth out vec4 frag_color; 58 void main() { 59 gl_Position = projection * view * model * position; 60 frag_color = color; 61 } 62 `; 63 64 string tex_col_pos_vert_shader_2d = ` 65 #version 330 66 uniform mat4 projection_uniform; 67 layout(location = 0) in vec4 position; 68 layout(location = 1) in vec2 uv; 69 layout(location = 2) in vec4 color; 70 out vec2 frag_uv; 71 smooth out vec4 frag_color; 72 73 void main() { 74 frag_uv = uv; 75 frag_color = color; 76 gl_Position = projection_uniform * position; 77 } 78 `; 79 80 string tex_col_frag_shader = ` 81 #version 330 82 uniform sampler2D tex_uniform; 83 in vec2 frag_uv; 84 smooth in vec4 frag_color; 85 out vec4 out_color; 86 87 void main() { 88 vec4 color = frag_color * texture(tex_uniform, frag_uv.st / textureSize(tex_uniform, 0)); 89 if (color.a == 0) 90 discard; 91 out_color = color; 92 } 93 `; 94 95 immutable Matrix4f matrix4fIdentity = Matrix4f.identity; 96 97 mixin template ModelSetter() 98 { 99 void setModel(Matrix4f model) { 100 checkgl!glUniformMatrix4fv(model_location, 1, GL_FALSE, model.arrayof.ptr); 101 } 102 103 void setModel() { 104 checkgl!glUniformMatrix4fv(model_location, 1, GL_FALSE, Matrix4f.identity.arrayof.ptr); 105 } 106 } 107 108 mixin template ViewSetter() 109 { 110 void setView(Matrix4f view) { 111 checkgl!glUniformMatrix4fv(view_location, 1, GL_FALSE, view.arrayof.ptr); 112 } 113 114 void setView() { 115 checkgl!glUniformMatrix4fv(view_location, 1, GL_FALSE, Matrix4f.identity.arrayof.ptr); 116 } 117 } 118 119 mixin template ProjectionSetter() 120 { 121 void setProjection(Matrix4f projection) { 122 checkgl!glUniformMatrix4fv(projection_location, 1, GL_FALSE, projection.arrayof.ptr); 123 } 124 125 void setProjection() { 126 checkgl!glUniformMatrix4fv(projection_location, 1, GL_FALSE, Matrix4f.identity.arrayof.ptr); 127 } 128 } 129 130 mixin template TransparencySetter() { 131 void setTransparency(float transparency) { 132 checkgl!glUniform1f(transparency_location, transparency); 133 } 134 } 135 136 mixin template TextureSetter() { 137 void setTexture(int textureUnit) { 138 checkgl!glUniform1i(uv_location, textureUnit); 139 } 140 } 141 142 mixin template MvpSetter() 143 { 144 void setMVP(Matrix4f model, Matrix4f view, Matrix4f projection) { 145 checkgl!glUniformMatrix4fv(model_location, 1, GL_FALSE, model.arrayof.ptr); 146 checkgl!glUniformMatrix4fv(view_location, 1, GL_FALSE, view.arrayof.ptr); 147 checkgl!glUniformMatrix4fv(projection_location, 1, GL_FALSE, projection.arrayof.ptr); 148 } 149 } 150 151 mixin template VpSetter() 152 { 153 void setVP(Matrix4f view, Matrix4f projection) { 154 checkgl!glUniformMatrix4fv(view_location, 1, GL_FALSE, view.arrayof.ptr); 155 checkgl!glUniformMatrix4fv(projection_location, 1, GL_FALSE, projection.arrayof.ptr); 156 } 157 } 158 159 struct SolidShader3d 160 { 161 ShaderProgram shader; 162 alias shader this; 163 164 mixin MvpSetter; 165 mixin VpSetter; 166 mixin ModelSetter; 167 mixin ViewSetter; 168 mixin ProjectionSetter; 169 170 GLint model_location = -1; 171 GLint view_location = -1; 172 GLint projection_location = -1; 173 174 void compile(IRenderer renderer) { 175 shader = renderer.createShaderProgram(solid_vert_shader, solid_frag_shader); 176 177 model_location = checkgl!glGetUniformLocation(handle, "model"); 178 view_location = checkgl!glGetUniformLocation(handle, "view"); 179 projection_location = checkgl!glGetUniformLocation(handle, "projection"); 180 } 181 } 182 183 struct TransparentShader3d 184 { 185 ShaderProgram shader; 186 alias shader this; 187 188 mixin MvpSetter; 189 mixin VpSetter; 190 mixin ModelSetter; 191 mixin ViewSetter; 192 mixin ProjectionSetter; 193 mixin TransparencySetter; 194 195 GLint model_location = -1; 196 GLint view_location = -1; 197 GLint projection_location = -1; 198 GLint transparency_location = -1; 199 200 void compile(IRenderer renderer) { 201 shader = renderer.createShaderProgram(solid_vert_shader, color_frag_shader_transparent); 202 203 model_location = checkgl!glGetUniformLocation(handle, "model"); 204 view_location = checkgl!glGetUniformLocation(handle, "view"); 205 projection_location = checkgl!glGetUniformLocation(handle, "projection"); 206 transparency_location = checkgl!glGetUniformLocation(handle, "transparency"); 207 } 208 } 209 210 struct SolidShader2d 211 { 212 ShaderProgram shader; 213 alias shader this; 214 215 mixin ProjectionSetter; 216 217 GLint projection_location = -1; 218 219 void compile(IRenderer renderer) { 220 shader = renderer.createShaderProgram(vert_shader_2d, solid_frag_shader); 221 222 projection_location = checkgl!glGetUniformLocation(handle, "projection"); 223 } 224 } 225 226 struct ColUvShader2d 227 { 228 ShaderProgram shader; 229 alias shader this; 230 231 mixin ProjectionSetter; 232 mixin TextureSetter; 233 234 GLint projection_location = -1; 235 GLint uv_location = -1; 236 237 void compile(IRenderer renderer) { 238 shader = renderer.createShaderProgram(tex_col_pos_vert_shader_2d, tex_col_frag_shader); 239 240 projection_location = checkgl!glGetUniformLocation(handle, "projection_uniform"); 241 uv_location = checkgl!glGetUniformLocation(handle, "tex_uniform"); 242 } 243 }