11 // ////////////////////////////////////////////////////////////////////////// //
16 __gshared SimpleWindow sdwindow
;
19 public enum vlWidth
= 800;
20 public enum vlHeight
= 600;
21 public enum scale
= 1;
22 __gshared
bool scanlines
= false;
24 public enum vlEffectiveWidth
= vlWidth
*scale
;
25 public enum vlEffectiveHeight
= vlHeight
*scale
;
28 // ////////////////////////////////////////////////////////////////////////// //
29 __gshared Texture texMain
;
30 __gshared Texture lightDot
;
32 __gshared FBO fboOccluders
, fboShadowMap
;
34 __gshared Shader shadScanlines
, shadToPolar
, shadBlur
;
37 // ////////////////////////////////////////////////////////////////////////// //
41 // ////////////////////////////////////////////////////////////////////////// //
43 glEnable(GL_TEXTURE_2D
);
44 glDisable(GL_LIGHTING
);
47 glDisable(GL_DEPTH_TEST
);
50 texMain
= new Texture("shadow_experiment/cat4.png");
51 //lightDot = new Texture("shadow_experiment/dot.png");
52 lightDot
= new Texture("shadow_experiment/light.png");
55 shadScanlines
= new Shader("scanlines", loadTextFile("data/shaders/srscanlines.frag"));
56 shadToPolar
= new Shader("topolar", loadTextFile("data/shaders/srlight_topolar.frag"));
57 shadBlur
= new Shader("blur", loadTextFile("data/shaders/srlight_blur.frag"));
59 // create occluders FBO
60 fboOccluders
= new FBO(LightSize
, LightSize
);
62 // create 1d shadowmap FBO
63 fboShadowMap
= new FBO(LightSize
, 1, Texture
.Option
.Clamp
);
66 glMatrixMode(GL_MODELVIEW
);
69 glActiveTexture(GL_TEXTURE0
+0);
70 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, 0);
71 orthoCamera(vlWidth
, vlHeight
);
75 // ////////////////////////////////////////////////////////////////////////// //
76 void renderLight (int lightX
, int lightY
) {
77 // //////////////////////////////////////////////////////////////////// //
78 // draw shadow casters to fboOccludersId, light should be in the center
81 glColor3f(0.0f, 0.0f, 0.0f);
83 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
84 //glDisable(GL_BLEND);
85 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
86 glClear(GL_COLOR_BUFFER_BIT
);
87 //orthoCamera(vlWidth, vlHeight);
88 orthoCamera(LightSize
, LightSize
);
89 drawAtXY(texMain
, LightSize
/2-lightX
, LightSize
/2-lightY
);
90 //drawAtXY(texMain.tid, LightSize/2-lightX, LightSize/2-lightY, texMain.width/2, texMain.height/2);
93 //orthoCamera(fboOccluders.width, fboOccluders.height);
94 //drawAtXY(texMain.tid, -lightX/2+LightSize/2, lightY/2-LightSize/2, LightSize/2, LightSize/2, mirrorX:false, mirrorY:true);
95 //drawAtXY(texMain.tid, 0, 0, fboOccluders.width, fboOccluders.height, mirrorX:false, mirrorY:true, scale:2.0f);
96 //drawAtXY(texMain.tid, 0, 0, fboOccluders.width, fboOccluders.height, mirrorX:false, mirrorY:true);
99 // //////////////////////////////////////////////////////////////////// //
100 // build 1d shadow map to fboShadowMapId
103 //glDisable(GL_BLEND);
104 glColor3f(0.0f, 0.0f, 0.0f);
105 //glUniform2f(shadToPolar["lightTexSize"], LightSize, LightSize);
106 shadToPolar
["lightTexSize"] = SVec2F(LightSize
, LightSize
);
107 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
108 glClear(GL_COLOR_BUFFER_BIT
);
109 orthoCamera(LightSize
, 1);
110 //drawFullViewTextureUD(fboOccluders.tid, LightSize, 1/*LightSize*/);
111 drawAtXY(fboOccluders
.tex
.tid
, 0, 0, LightSize
, 1);
115 // //////////////////////////////////////////////////////////////////// //
117 shadBlur
["shadowDoBloor"] = true;
118 shadBlur
["scanlines"] = scanlines
;
119 shadBlur
["lightTexSize"] = SVec2F(LightSize
, LightSize
);
121 glBlendFunc(GL_SRC_ALPHA
, GL_ONE
);
123 glColor3f(1.0f, 1.0f, 0.0f);
124 //orthoCameraTr(vlWidth, vlHeight, cast(float)lightX-cast(float)LightSize/2.0f, cast(float)lightY-cast(float)LightSize/2.0f);
125 //drawFullViewTextureSS(fboShadowMap.tid, LightSize, LightSize);
126 orthoCamera(vlWidth
, vlHeight
);
127 drawAtXY(fboShadowMap
.tex
.tid
, lightX
-LightSize
/2, lightY
-LightSize
/2, LightSize
, LightSize
);
132 // ////////////////////////////////////////////////////////////////////////// //
133 __gshared
int lightX
= vlWidth
/2, lightY
= vlHeight
/2;
136 public void main () {
137 static void setDP () {
141 import std
.file
: thisExePath
;
142 import std
.path
: dirName
;
143 setDataPath(thisExePath
.dirName
);
149 setOpenGLContextVersion(3, 2);
151 sdwindow
= new SimpleWindow(vlEffectiveWidth
, vlEffectiveHeight
, "OpenGL 2d soft shadows", OpenGlOptions
.yes
, Resizablity
.fixedSize
);
153 sdwindow
.visibleForTheFirstTime
= delegate () {
154 sdwindow
.setAsCurrentOpenGlContext(); // make this window active
155 sdwindow
.vsync
= false;
156 //sdwindow.useGLFinish = false;
158 sdwindow
.redrawOpenGlScene();
161 sdwindow
.redrawOpenGlScene
= delegate () {
162 // clear background (so we can see lights and shadows ;-)
164 glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
165 glClear(GL_COLOR_BUFFER_BIT
);
168 //glColor(1.0f, 1.0f, 1.0f, 0.0f);
169 //drawAtXY(texMain, 0, 0);
173 glBlendFunc(GL_SRC_ALPHA
, GL_ONE
);
176 glActiveTexture(GL_TEXTURE0+1);
177 glBindTexture(GL_TEXTURE_2D, texMain.tid);
178 glActiveTexture(GL_TEXTURE0+0);
181 renderLight(lightX
, lightY
);
183 //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
188 shadScanlines
["scanlines"] = scanlines
;
189 glColor3f(1.0f, 1.0f, 1.0f);
191 // overlay normal scene
193 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
195 orthoCamera(vlWidth
, vlHeight
);
198 //drawAtXY(texMain, 0, 0);
200 // shadow casters FBO
201 //drawAtXY(fboOccluders.tex, lightX-LightSize/2, lightY-LightSize/2);
202 drawAtXY(fboOccluders
.tex
, vlWidth
-fboOccluders
.tex
.width
, vlHeight
-fboOccluders
.tex
.height
);
203 //drawAtXY(fboOccluders.tid, 0, 0, vlWidth, vlHeight);
206 //drawAtXY(fboOccluders.tex, lightX-LightSize/2, lightY-LightSize/2);
207 drawAtXY(fboShadowMap
.tex
, vlWidth
-fboShadowMap
.tex
.width
, vlHeight
-LightSize
-4);
208 //drawAtXY(fboOccluders.tid, 0, 0, vlWidth, vlHeight);
211 drawAtXYC(lightDot
, lightX
-LightSize
/2, lightY
-LightSize
/2);
212 drawAtXYC(lightDot
, lightX
+LightSize
/2, lightY
-LightSize
/2);
213 drawAtXYC(lightDot
, lightX
, lightY
);
214 drawAtXYC(lightDot
, lightX
-LightSize
/2, lightY
+LightSize
/2);
215 drawAtXYC(lightDot
, lightX
+LightSize
/2, lightY
+LightSize
/2);
219 enum MSecsPerFrame
= 1000/30; /* 30 is FPS */
221 uint[8] frameTimes
= 1000;
223 sdwindow
.eventLoop(MSecsPerFrame
,
225 if (sdwindow
.closed
) return;
226 sdwindow
.redrawOpenGlSceneNow();
228 delegate (KeyEvent event
) {
229 if (sdwindow
.closed
) return;
230 if (event
.pressed
&& event
.key
== Key
.Escape
) {
235 delegate (MouseEvent event
) {
236 lightX
= event
.x
/scale
;
237 lightY
= event
.y
/scale
-1;
239 delegate (dchar ch
) {
240 if (ch
== 's') scanlines
= !scanlines
;
241 if (ch
== 'q') { flushGui(); sdwindow
.close(); }
244 if (!sdwindow
.closed
) { flushGui(); sdwindow
.close(); }