1 /*
2 Copyright (c) 2019-2022 Timur Gafarov
3 
4 Boost Software License - Version 1.0 - August 17th, 2003
5 Permission is hereby granted, free of charge, to any person or organization
6 obtaining a copy of the software and accompanying documentation covered by
7 this license (the "Software") to use, reproduce, display, distribute,
8 execute, and transmit the Software, and to prepare derivative works of the
9 Software, and to permit third-parties to whom the Software is furnished to
10 do so, all subject to the following:
11 
12 The copyright notices in the Software and this entire statement, including
13 the above license grant, this restriction and the following disclaimer,
14 must be included in all copies of the Software, in whole or in part, and
15 all derivative works of the Software, unless such copies or derivative
16 works are solely in the form of machine-executable object code generated by
17 a source language processor.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 */
27 
28 module dagon.render.shaders.geometry;
29 
30 import std.stdio;
31 import std.math;
32 
33 import dlib.core.memory;
34 import dlib.core.ownership;
35 import dlib.math.vector;
36 import dlib.math.matrix;
37 import dlib.math.transformation;
38 import dlib.math.interpolation;
39 import dlib.image.color;
40 import dlib.text.str;
41 
42 import dagon.core.bindings;
43 import dagon.graphics.entity;
44 import dagon.graphics.material;
45 import dagon.graphics.shader;
46 import dagon.graphics.state;
47 
48 class GeometryShader: Shader
49 {
50     String vs, fs;
51 
52     this(Owner owner)
53     {
54         vs = Shader.load("data/__internal/shaders/Geometry/Geometry.vert.glsl");
55         fs = Shader.load("data/__internal/shaders/Geometry/Geometry.frag.glsl");
56 
57         auto prog = New!ShaderProgram(vs, fs, this);
58         super(prog, owner);
59     }
60 
61     ~this()
62     {
63         vs.free();
64         fs.free();
65     }
66 
67     override void bindParameters(GraphicsState* state)
68     {
69         Material mat = state.material;
70         
71         setParameter("modelViewMatrix", state.modelViewMatrix);
72         setParameter("projectionMatrix", state.projectionMatrix);
73         setParameter("normalMatrix", state.normalMatrix);
74         setParameter("viewMatrix", state.viewMatrix);
75         setParameter("invViewMatrix", state.invViewMatrix);
76         setParameter("prevModelViewMatrix", state.prevModelViewMatrix);
77 
78         setParameter("opacity", state.opacity * mat.opacity);
79         setParameter("textureScale", mat.textureScale);
80         
81         setParameter("gbufferMask", state.gbufferMask);
82         setParameter("blurMask", state.blurMask);
83         
84         setParameter("sphericalNormal", cast(int)mat.sphericalNormal);
85         
86         setParameter("clipThreshold", mat.alphaTestThreshold);
87 
88         // Diffuse
89         glActiveTexture(GL_TEXTURE0);
90         setParameter("diffuseTexture", cast(int)0);
91         setParameter("diffuseVector", mat.baseColorFactor);
92         if (mat.baseColorTexture)
93         {
94             mat.baseColorTexture.bind();
95             setParameterSubroutine("diffuse", ShaderType.Fragment, "diffuseColorTexture");
96         }
97         else
98         {
99             glBindTexture(GL_TEXTURE_2D, 0);
100             setParameterSubroutine("diffuse", ShaderType.Fragment, "diffuseColorValue");
101         }
102         
103         // Normal
104         glActiveTexture(GL_TEXTURE1);
105         setParameter("normalTexture", cast(int)1);
106         setParameter("normalVector", mat.normalFactor);
107         if (mat.normalTexture)
108         {
109             mat.normalTexture.bind();
110             setParameterSubroutine("normal", ShaderType.Fragment, "normalMap");
111             setParameter("generateTBN", cast(int)1);
112         }
113         else
114         {
115             glBindTexture(GL_TEXTURE_2D, 0);
116             setParameterSubroutine("normal", ShaderType.Fragment, "normalValue");
117             setParameter("generateTBN", cast(int)0);
118         }
119         
120         if (state.material.invertNormalY)
121             setParameter("normalYSign", -1.0f);
122         else
123             setParameter("normalYSign", 1.0f);
124         
125         // PBR
126         glActiveTexture(GL_TEXTURE2);
127         setParameter("roughnessMetallicTexture", cast(int)2);
128         setParameter("roughnessMetallicFactor", Vector4f(1.0f, mat.roughnessFactor, mat.metallicFactor, 0.0f));
129         if (mat.roughnessMetallicTexture)
130         {
131             mat.roughnessMetallicTexture.bind();
132             setParameterSubroutine("roughness", ShaderType.Fragment, "roughnessMap");
133             setParameterSubroutine("metallic", ShaderType.Fragment, "metallicMap");
134         }
135         else
136         {
137             glBindTexture(GL_TEXTURE_2D, 0);
138             setParameterSubroutine("roughness", ShaderType.Fragment, "roughnessValue");
139             setParameterSubroutine("metallic", ShaderType.Fragment, "metallicValue");
140         }
141         
142         // Emission
143         glActiveTexture(GL_TEXTURE3);
144         setParameter("emissionTexture", cast(int)3);
145         setParameter("emissionFactor", mat.emissionFactor);
146         if (mat.emissionTexture)
147         {
148             mat.emissionTexture.bind();
149             setParameterSubroutine("emission", ShaderType.Fragment, "emissionColorTexture");
150         }
151         else
152         {
153             glBindTexture(GL_TEXTURE_2D, 0);
154             setParameterSubroutine("emission", ShaderType.Fragment, "emissionColorValue");
155         }
156         setParameter("energy", mat.emissionEnergy);
157         
158         // Height and parallax
159         int parallaxMethod = mat.parallaxMode;
160         if (parallaxMethod > ParallaxOcclusionMapping)
161             parallaxMethod = ParallaxOcclusionMapping;
162         if (parallaxMethod < 0)
163             parallaxMethod = 0;
164         
165         glActiveTexture(GL_TEXTURE4);
166         if (mat.heightTexture)
167         {
168             mat.heightTexture.bind();
169             setParameter("heightTexture", cast(int)4);
170             setParameterSubroutine("height", ShaderType.Fragment, "heightMap");
171         }
172         else
173         {
174             glBindTexture(GL_TEXTURE_2D, 0);
175             setParameter("heightTexture", cast(int)4);
176             setParameter("heightScalar", mat.heightFactor);
177             setParameterSubroutine("height", ShaderType.Fragment, "heightValue");
178             parallaxMethod = ParallaxNone;
179         }
180         
181         if (parallaxMethod == ParallaxSimple)
182             setParameterSubroutine("parallax", ShaderType.Fragment, "parallaxSimple");
183         else if (parallaxMethod == ParallaxOcclusionMapping)
184             setParameterSubroutine("parallax", ShaderType.Fragment, "parallaxOcclusionMapping");
185         else
186             setParameterSubroutine("parallax", ShaderType.Fragment, "parallaxNone");
187         
188         setParameter("parallaxScale", mat.parallaxScale);
189         setParameter("parallaxBias", mat.parallaxBias);
190         
191         glActiveTexture(GL_TEXTURE0);
192 
193         super.bindParameters(state);
194     }
195 
196     override void unbindParameters(GraphicsState* state)
197     {
198         super.unbindParameters(state);
199 
200         glActiveTexture(GL_TEXTURE0);
201         glBindTexture(GL_TEXTURE_2D, 0);
202 
203         glActiveTexture(GL_TEXTURE1);
204         glBindTexture(GL_TEXTURE_2D, 0);
205 
206         glActiveTexture(GL_TEXTURE2);
207         glBindTexture(GL_TEXTURE_2D, 0);
208 
209         glActiveTexture(GL_TEXTURE3);
210         glBindTexture(GL_TEXTURE_2D, 0);
211         
212         glActiveTexture(GL_TEXTURE4);
213         glBindTexture(GL_TEXTURE_2D, 0);
214 
215         glActiveTexture(GL_TEXTURE0);
216     }
217 }