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);
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 // //////////////////////////////////////////////////////////////////// //
118 shadBlur
["shadowDoBloor"] = true;
119 shadBlur
["scanlines"] = scanlines
;
120 shadBlur
["lightTexSize"] = SVec2F(LightSize
, LightSize
);
122 glBlendFunc(GL_SRC_ALPHA
, GL_ONE
);
124 glColor3f(1.0f, 1.0f, 0.0f);
125 //orthoCameraTr(vlWidth, vlHeight, cast(float)lightX-cast(float)LightSize/2.0f, cast(float)lightY-cast(float)LightSize/2.0f);
126 //drawFullViewTextureSS(fboShadowMap.tid, LightSize, LightSize);
127 orthoCamera(vlWidth
, vlHeight
);
128 drawAtXY(fboShadowMap
.tex
.tid
, lightX
-LightSize
/2, lightY
-LightSize
/2, LightSize
, LightSize
, mirrorY
:true);
133 // ////////////////////////////////////////////////////////////////////////// //
134 __gshared
int lightX
= vlWidth
/2, lightY
= vlHeight
/2;
137 public void main () {
138 static void setDP () {
142 import std
.file
: thisExePath
;
143 import std
.path
: dirName
;
144 setDataPath(thisExePath
.dirName
);
150 setOpenGLContextVersion(3, 2);
152 sdwindow
= new SimpleWindow(vlEffectiveWidth
, vlEffectiveHeight
, "OpenGL 2d soft shadows", OpenGlOptions
.yes
, Resizablity
.fixedSize
);
154 sdwindow
.visibleForTheFirstTime
= delegate () {
155 sdwindow
.setAsCurrentOpenGlContext(); // make this window active
156 sdwindow
.vsync
= false;
157 //sdwindow.useGLFinish = false;
159 sdwindow
.redrawOpenGlScene();
162 sdwindow
.redrawOpenGlScene
= delegate () {
163 // clear background (so we can see lights and shadows ;-)
165 glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
166 glClear(GL_COLOR_BUFFER_BIT
);
170 glBlendFunc(GL_SRC_ALPHA
, GL_ONE
);
172 renderLight(lightX
, lightY
);
174 //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
179 shadScanlines
["scanlines"] = scanlines
;
181 // overlay normal scene
183 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
185 orthoCamera(vlWidth
, vlHeight
);
188 //drawFullViewTexture(texMain);
189 drawAtXY(texMain
, 0, 0);
191 // shadow casters FBO
192 //drawAtXY(fboOccluders.tex, lightX-LightSize/2, lightY-LightSize/2);
193 drawAtXY(fboOccluders
.tex
, vlWidth
-fboOccluders
.tex
.width
, 0);
194 //drawAtXY(fboOccluders.tid, 0, 0, vlWidth, vlHeight);
197 //drawAtXY(fboOccluders.tex, lightX-LightSize/2, lightY-LightSize/2);
198 drawAtXY(fboShadowMap
.tex
, vlWidth
-fboShadowMap
.tex
.width
, LightSize
);
199 //drawAtXY(fboOccluders.tid, 0, 0, vlWidth, vlHeight);
202 drawAtXYC(lightDot
, lightX
-LightSize
/2, lightY
-LightSize
/2);
203 drawAtXYC(lightDot
, lightX
+LightSize
/2, lightY
-LightSize
/2);
204 drawAtXYC(lightDot
, lightX
, lightY
);
205 drawAtXYC(lightDot
, lightX
-LightSize
/2, lightY
+LightSize
/2);
206 drawAtXYC(lightDot
, lightX
+LightSize
/2, lightY
+LightSize
/2);
210 enum MSecsPerFrame
= 1000/30; /* 30 is FPS */
212 uint[8] frameTimes
= 1000;
214 sdwindow
.eventLoop(MSecsPerFrame
,
216 if (sdwindow
.closed
) return;
217 sdwindow
.redrawOpenGlSceneNow();
219 delegate (KeyEvent event
) {
220 if (sdwindow
.closed
) return;
221 if (event
.pressed
&& event
.key
== Key
.Escape
) {
226 delegate (MouseEvent event
) {
227 lightX
= event
.x
/scale
;
228 lightY
= vlHeight
-event
.y
/scale
-1;
230 delegate (dchar ch
) {
231 if (ch
== 's') scanlines
= !scanlines
;
232 if (ch
== 'q') { flushGui(); sdwindow
.close(); }
235 if (!sdwindow
.closed
) { flushGui(); sdwindow
.close(); }