yay! no more excessive copypasta in scripts, i can use HOFs instead!
[dd2d.git] / xmain.d
blob74378ea658b48f494486f7904b5aa0e78924d89a
1 // main driver
2 module gfxcore;
4 private:
5 import iv.glbinds;
6 import glutils;
8 import wadarc;
11 // ////////////////////////////////////////////////////////////////////////// //
12 import arsd.color;
13 import arsd.png;
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 // ////////////////////////////////////////////////////////////////////////// //
38 enum LightSize = 256;
41 // ////////////////////////////////////////////////////////////////////////// //
42 void initOpenGL () {
43 glEnable(GL_TEXTURE_2D);
44 glDisable(GL_LIGHTING);
45 glDisable(GL_DITHER);
46 glDisable(GL_BLEND);
47 glDisable(GL_DEPTH_TEST);
49 // load textures
50 texMain = new Texture("shadow_experiment/cat4.png");
51 //lightDot = new Texture("shadow_experiment/dot.png");
52 lightDot = new Texture("shadow_experiment/light.png");
54 // create shaders
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);
65 // setup matrices
66 glMatrixMode(GL_MODELVIEW);
67 glLoadIdentity();
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
79 glUseProgram(0);
80 fboOccluders.exec({
81 glColor3f(0.0f, 0.0f, 0.0f);
82 //glEnable(GL_BLEND);
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);
91 // 512 : 256
92 // move camera
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);
97 });
99 // //////////////////////////////////////////////////////////////////// //
100 // build 1d shadow map to fboShadowMapId
101 fboShadowMap.exec({
102 shadToPolar.exec({
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 // //////////////////////////////////////////////////////////////////// //
116 shadBlur.exec({
117 shadBlur["shadowDoBloor"] = true;
118 shadBlur["scanlines"] = scanlines;
119 shadBlur["lightTexSize"] = SVec2F(LightSize, LightSize);
120 glEnable(GL_BLEND);
121 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
122 // set light color
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 () {
138 version(rdmd) {
139 setDataPath("data");
140 } else {
141 import std.file : thisExePath;
142 import std.path : dirName;
143 setDataPath(thisExePath.dirName);
147 setDP();
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;
157 initOpenGL();
158 sdwindow.redrawOpenGlScene();
161 sdwindow.redrawOpenGlScene = delegate () {
162 // clear background (so we can see lights and shadows ;-)
163 glDisable(GL_BLEND);
164 glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
165 glClear(GL_COLOR_BUFFER_BIT);
167 // main level
168 //glColor(1.0f, 1.0f, 1.0f, 0.0f);
169 //drawAtXY(texMain, 0, 0);
171 // additive lights
172 glEnable(GL_BLEND);
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);
184 //glUseProgram(0);
186 // scanlines shader
187 shadScanlines.exec({
188 shadScanlines["scanlines"] = scanlines;
189 glColor3f(1.0f, 1.0f, 1.0f);
191 // overlay normal scene
192 glEnable(GL_BLEND);
193 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
195 orthoCamera(vlWidth, vlHeight);
197 // main level
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);
205 // distance FBO
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);
210 // mark light area
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,
224 delegate () {
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) {
231 flushGui();
232 sdwindow.close();
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(); }
245 flushGui();