Line data Source code
1 : #ifndef RENDERLIGHTS_H_
2 : #define RENDERLIGHTS_H_
3 :
4 : const int lighttilemaxwidth = 16;
5 : const int lighttilemaxheight = 16;
6 :
7 : /** @brief Singleton object used to store the graphics buffers
8 : *
9 : * Stores the handles for the graphics buffers nd the functions which act upon
10 : * the g-buffers.
11 : */
12 : class GBuffer final
13 : {
14 : public:
15 1 : GBuffer()
16 1 : {
17 : //set all of the textures to 0/null
18 1 : scalew = 0;
19 1 : scaleh = 0;
20 1 : gfbo = 0;
21 1 : gdepthtex = 0;
22 1 : gcolortex = 0;
23 1 : gnormaltex = 0;
24 1 : gglowtex = 0;
25 1 : gdepthrb = 0;
26 1 : gstencilrb = 0;
27 1 : msfbo = 0;
28 1 : msdepthtex = 0;
29 1 : mscolortex = 0;
30 1 : msnormaltex = 0;
31 1 : msglowtex = 0;
32 1 : msdepthrb = 0;
33 1 : msstencilrb = 0;
34 1 : mshdrfbo = 0;
35 1 : mshdrtex = 0;
36 1 : msrefractfbo = 0;
37 1 : msrefracttex = 0;
38 1 : refractfbo = 0;
39 1 : refracttex = 0;
40 1 : stencilformat= 0;
41 1 : scalefbo.fill(0);
42 1 : scaletex.fill(0);
43 1 : gdepthinit = false;
44 1 : hdrfloat = false;
45 1 : msaadepthblit= false;
46 1 : msaatonemapblit = false;
47 1 : inoq = false;
48 1 : transparentlayer = 0;
49 :
50 1 : }
51 : static void dummyfxn();
52 : //main g-buffers
53 : void cleanupgbuffer();
54 : void renderao() const; //ao.cpp
55 : void renderradiancehints() const; //radiancehints.cpp
56 : void rendertransparent(); //renderalpha.cpp
57 : void resolvemsaadepth(int w, int h) const;
58 : void setupgbuffer();
59 : void bindgdepth() const;
60 : void renderparticles(int layer = 0) const; //renderparticles.cpp
61 : void rendervolumetric();
62 : void renderwaterfog(int mat, float surface); //water.cpp
63 : void setaavelocityparams(GLenum tmu = GL_TEXTURE0); //aa.cpp
64 : void shademodelpreview(int x, int y, int w, int h, bool background = true, bool scissor = false);
65 : void viewdepth() const;
66 : void rendershadowatlas();
67 : //multisample antialiasing specific buffers
68 : void setupmsbuffer(int w, int h);
69 : void resolvemsaacolor(int w, int h);
70 : void shademinimap(const vec &color = vec(-1, -1, -1));
71 : void shadesky() const;
72 : //refractive
73 : void processhdr(GLuint outfbo, int aa);
74 :
75 : /**
76 : * @brief Draws the debug refraction buffer.
77 : *
78 : * Draws the buffer containing the refraction information to the screen.
79 : * The size of the debug draw is dependent on the debugfullscreen variable;
80 : * if 1, the debug buffer spans the whole screen, if not, the debug buffer
81 : * is drawn to the bottom right corner of the screen.
82 : */
83 : void viewrefract();
84 : void doscale(GLuint outfbo = 0) const;
85 : void setupscale(int sw, int sh, int w, int h);
86 : GLuint shouldscale() const;
87 : void workinoq();
88 :
89 : /**
90 : * @brief Creates the geometry buffer for the scene
91 : *
92 : * Renders and copies a fbo (framebuffer object) to msfbo (multisample framebuffer object)
93 : * or gfbo (geometry buffer framebuffer object) depending on whether msaa is enabled
94 : *
95 : * @param bool depthclear toggles clearing the depth buffer
96 : * @param gamefxn pointer to a function for game-specific rendering
97 : */
98 : void rendergbuffer(bool depthclear = true, void (*gamefxn)() = dummyfxn);
99 : bool istransparentlayer() const;
100 : void rendermodelbatches();
101 : void renderlights(float bsx1 = -1, float bsy1 = -1, float bsx2 = 1, float bsy2 = 1, const uint *tilemask = nullptr, int stencilmask = 0, int msaapass = 0, bool transparent = false);
102 :
103 : /**
104 : * @brief Returns debug information about lighting.
105 : *
106 : * Types:
107 : * 0: light passes used
108 : * 1: lights visible
109 : * 2: lights occluded
110 : * 3: light batches used
111 : * 4: light batch rects used
112 : * 5: light batch stacks used
113 : *
114 : * @param type of value to query
115 : *
116 : * @return numeric value of appropriate type
117 : */
118 : int getlightdebuginfo(uint type) const;
119 : private:
120 : void bindmsdepth() const;
121 : void bindlighttexs(int msaapass, bool transparent) const; //only used in renderlights
122 : void cleanupscale();
123 : void cleanupmsbuffer();
124 : void preparegbuffer(bool depthclear = true);
125 : void rendercsmshadowmaps() const;
126 : void rendershadowmaps(int offset = 0) const;
127 : void rendersunpass(Shader *s, int stencilref, bool transparent, float bsx1, float bsy1, float bsx2, float bsy2, const uint *tilemask);
128 : void renderlightsnobatch(Shader *s, int stencilref, bool transparent, float bsx1, float bsy1, float bsx2, float bsy2);
129 : void renderlightbatches(Shader &s, int stencilref, bool transparent, float bsx1, float bsy1, float bsx2, float bsy2, const uint *tilemask);
130 : void rendergeom();
131 :
132 : void alphaparticles(float allsx1, float allsy1, float allsx2, float allsy2) const;
133 :
134 : void rendermaterialmask() const;
135 : void renderliquidmaterials() const;
136 : void packlights();
137 :
138 : struct MaterialInfo final
139 : {
140 : float matliquidsx1,
141 : matliquidsy1,
142 : matliquidsx2,
143 : matliquidsy2;
144 : float matsolidsx1,
145 : matsolidsy1,
146 : matsolidsx2,
147 : matsolidsy2;
148 : float matrefractsx1,
149 : matrefractsy1,
150 : matrefractsx2,
151 : matrefractsy2;
152 : std::array<uint, lighttilemaxheight> matliquidtiles,
153 : matsolidtiles;
154 : int hasmats;
155 : };
156 :
157 : struct AlphaInfo final
158 : {
159 : float alphafrontsx1, alphafrontsx2,
160 : alphafrontsy1, alphafrontsy2,
161 : alphabacksx1, alphabacksx2,
162 : alphabacksy1, alphabacksy2,
163 : alpharefractsx1, alpharefractsx2,
164 : alpharefractsy1, alpharefractsy2;
165 : int hasalphavas;
166 : };
167 :
168 : MaterialInfo findmaterials() const; //materials.cpp
169 : AlphaInfo findalphavas();
170 :
171 : struct TransparentModelInfo final
172 : {
173 : float mdlsx1, mdlsy1, mdlsx2, mdlsy2;
174 : std::array<uint, lighttilemaxheight> mdltiles;
175 :
176 1 : TransparentModelInfo() : mdlsx1(-1), mdlsy1(-1), mdlsx2(1), mdlsy2(1), mdltiles()
177 : {
178 1 : }
179 : };
180 : TransparentModelInfo tmodelinfo;
181 :
182 : std::array<uint, lighttilemaxheight> alphatiles;
183 :
184 : bool transparentlayer;
185 : bool inoq = false;
186 : bool gdepthinit;
187 : bool hdrfloat;
188 : bool msaadepthblit; //no way to change this outside constructor atm
189 : bool msaatonemapblit;
190 :
191 : int scalew,
192 : scaleh;
193 : //main g-buffers
194 : GLuint gfbo,
195 : gdepthtex,
196 : gcolortex,
197 : gnormaltex,
198 : gglowtex,
199 : gdepthrb,
200 : gstencilrb;
201 : //multisample antialiasing g-buffers
202 : GLuint msfbo,
203 : msdepthtex,
204 : mscolortex,
205 : msnormaltex,
206 : msglowtex,
207 : msdepthrb,
208 : msstencilrb,
209 : mshdrfbo,
210 : mshdrtex,
211 : msrefractfbo,
212 : msrefracttex;
213 : //refractive g-buffers
214 : GLuint refractfbo,
215 : refracttex;
216 : //rescaling g-buffers
217 : std::array<GLuint, 2> scalefbo,
218 : scaletex;
219 : GLenum stencilformat;
220 : matrix4 eyematrix,
221 : linearworldmatrix;
222 :
223 : int lightpassesused,
224 : lightsvisible,
225 : lightsoccluded,
226 : lightbatchesused,
227 : lightbatchrectsused,
228 : lightbatchstacksused;
229 :
230 : static float refractmargin,
231 : refractdepth;
232 : };
233 :
234 : extern GBuffer gbuf;
235 :
236 : class PackNode final
237 : {
238 : public:
239 14 : PackNode(ushort x, ushort y, ushort w, ushort h) : w(w), h(h), child1(0), child2(0), x(x), y(y), available(std::min(w, h)) {}
240 :
241 1 : void reset()
242 : {
243 1 : discardchildren();
244 1 : available = std::min(w, h);
245 1 : }
246 :
247 1 : bool resize(int nw, int nh)
248 : {
249 1 : if(w == nw && h == nw)
250 : {
251 0 : return false;
252 : }
253 1 : discardchildren();
254 1 : w = nw;
255 1 : h = nh;
256 1 : available = std::min(w, h);
257 1 : return true;
258 : }
259 :
260 13 : ~PackNode()
261 : {
262 13 : discardchildren();
263 13 : }
264 :
265 : bool insert(ushort &tx, ushort &ty, ushort tw, ushort th);
266 : void reserve(ushort tx, ushort ty, ushort tw, ushort th);
267 :
268 3 : int availablespace() const
269 : {
270 3 : return available;
271 : }
272 :
273 2 : vec2 dimensions() const
274 : {
275 2 : return {static_cast<float>(w), static_cast<float>(h)};
276 : }
277 :
278 : //debugging printouts, not used in program logic
279 :
280 : //i: recursion depth
281 7 : void printchildren(int i = 0) const
282 : {
283 7 : print(i);
284 :
285 7 : if(child1)
286 : {
287 3 : child1->printchildren(i+1);
288 : }
289 7 : if(child2)
290 : {
291 3 : child2->printchildren(i+1);
292 : }
293 7 : }
294 :
295 : //i: depth to print out
296 7 : void print(int i) const
297 : {
298 7 : std::printf("%d: %d %d\n", i, w, h);
299 7 : }
300 :
301 : private:
302 : ushort w, h;
303 : PackNode *child1, *child2;
304 : ushort x, y;
305 : int available;
306 :
307 : /**
308 : * @brief Non-recursively discards children.
309 : *
310 : * Frees the heap allocated child1 and child2 pointers. If those packnodes
311 : * point to other children, that memory will be leaked.
312 : */
313 18 : void discardchildren()
314 : {
315 18 : if(child1)
316 : {
317 6 : delete child1;
318 6 : child1 = nullptr;
319 : }
320 18 : if(child2)
321 : {
322 6 : delete child2;
323 6 : child2 = nullptr;
324 : }
325 18 : }
326 :
327 : void forceempty()
328 : {
329 : discardchildren();
330 : available = 0;
331 : }
332 : };
333 :
334 : extern PackNode shadowatlaspacker;
335 :
336 : struct shadowcacheval;
337 :
338 : struct ShadowMapInfo final
339 : {
340 : ushort x, y, size, sidemask;
341 : int light;
342 : const shadowcacheval *cached;
343 : };
344 :
345 : extern std::vector<ShadowMapInfo> shadowmaps;
346 : extern int smfilter;
347 :
348 : extern void addshadowmap(ushort x, ushort y, int size, int &idx, int light = -1, const shadowcacheval *cached = nullptr);
349 :
350 : constexpr int shadowatlassize = 4096;
351 :
352 : extern int smborder, smborder2;
353 :
354 : extern int gdepthstencil, gstencil, glineardepth, msaalineardepth, batchsunlight, smgather, tqaaresolvegather;
355 : extern int lighttilealignw, lighttilealignh, lighttilevieww, lighttileviewh, lighttilew, lighttileh;
356 : extern int spotlights; /// the number of spotlights in the world
357 : extern int volumetriclights; /// the number of volumetric lights in the world
358 : extern int nospeclights; /// number of non specular lights in the world
359 : extern int debugfullscreen; /// boolean-like, 1 to draw debug on whole screen
360 : extern int msaaedgedetect;
361 : extern int hdrclear;
362 : extern int msaatonemap;
363 : extern float ldrscale;
364 :
365 : /**
366 : * @brief Returns ldrscale, but scaled down by 255
367 : *
368 : * @return ldrscale divided by 255
369 : */
370 : extern float ldrscaleb(); //derived from ldrscale
371 :
372 : extern int vieww, viewh;
373 :
374 : enum
375 : {
376 : ShadowMap_None = 0,
377 : ShadowMap_Reflect,
378 : ShadowMap_CubeMap,
379 : ShadowMap_Cascade,
380 : ShadowMap_Spot,
381 : };
382 :
383 : extern int shadowmapping;
384 : extern int smcullside;
385 :
386 : extern matrix4 shadowmatrix;
387 :
388 : /**
389 : * @brief sets values for one of the bilateralshader[] elements
390 : *
391 : * bilateralshader[2] elements' referenced Shader objects have their radius
392 : * and depth parameters changed
393 : *
394 : * @param radius the bilateral filter radius to set
395 : * @param pass [0-1] the element of the bilateralshader() array to change
396 : * @param depth the depth of the bilateral filtering to set
397 : */
398 : extern void setbilateralshader(int radius, int pass, float depth);
399 :
400 : /**
401 : * @brief clears bilateralarray
402 : *
403 : * Makes bilateralshader[2]'s elements point to the null pointer..
404 : */
405 : void clearbilateralshaders();
406 :
407 : /**
408 : * @brief sets bilateralshader array using bilateralshader()
409 : *
410 : * Sets bilateralshader[2] elements to point to Shader objects representing the two passes
411 : */
412 : void loadbilateralshaders();
413 :
414 : extern void loaddeferredlightshaders();
415 : extern void cleardeferredlightshaders();
416 : extern void clearshadowcache();
417 :
418 :
419 : /**
420 : * @brief Cleans up shaders and textures associated with volumetric rendering.
421 : *
422 : * Cleans up the volumetric framebuffers, the volumetric textures, and the volumetric shaders.
423 : * Sets the volw/volh variables indicating size of the buffers to -1.
424 : */
425 : extern void cleanupvolumetric();
426 :
427 : extern void findshadowvas();
428 : extern void findshadowmms();
429 :
430 : extern int calcshadowinfo(const extentity &e, vec &origin, float &radius, vec &spotloc, int &spotangle, float &bias);
431 : extern void rendershadowmapworld();
432 : extern void batchshadowmapmodels(bool skipmesh = false);
433 : extern void renderrsmgeom(bool dyntex = false);
434 :
435 : extern int calcspheresidemask(const vec &p, float radius, float bias);
436 : extern int calcbbrsmsplits(const ivec &bbmin, const ivec &bbmax);
437 : extern int calcspherersmsplits(const vec ¢er, float radius);
438 :
439 : bool sphereinsidespot(const vec &dir, int spot, const vec ¢er, float radius);
440 : bool bbinsidespot(const vec &origin, const vec &dir, int spot, const ivec &bbmin, const ivec &bbmax);
441 :
442 : extern matrix4 worldmatrix, screenmatrix;
443 :
444 : extern int gw, gh, gdepthformat, ghasstencil;
445 : extern int msaasamples, msaalight;
446 : extern std::vector<vec2> msaapositions;
447 :
448 : extern int rhinoq;
449 :
450 : extern bool shouldworkinoq();
451 : extern void initgbuffer();
452 :
453 : /**
454 : * @brief Returns whether to pack normal maps into the alpha channel
455 : *
456 : * Packing normals into alpha channel will be done if `forcepacknorm` is enabled
457 : * of if `msaasamples` is nonzero or if the avatar mask is disabled
458 : *
459 : * @return true if normals are to be packed into the alpha channel
460 : */
461 : extern bool usepacknorm();
462 : extern void maskgbuffer(const char *mask);
463 : extern void shadegbuffer();
464 : extern void setuplights(GBuffer &buf);
465 :
466 : /**
467 : * @brief Draws any enabled debug buffers.
468 : *
469 : * Draws the following debug buffers in the following order:
470 : * - ao (debugao)
471 : * - shadowatlas (debushadowatlas)
472 : * - depth (debugdepth)
473 : * - stencil (debugstencil)
474 : * - refract (debugrefract)
475 : * - light scissor (debuglightscissor)
476 : * - rsm (debugrsm)
477 : * - rh (debugrh)
478 : * - aa (subpixelaa::Debug, debugtqaa)
479 : *
480 : * Later elements on this list will draw over the top of earlier ones. The showing
481 : * of these elements are controlled by their respective variables (in parentheses).
482 : *
483 : * @return true if any debug buffer was drawn, false otherwise.
484 : */
485 : extern bool debuglights();
486 : extern void cleanuplights();
487 :
488 : extern int avatarmask;
489 : extern void enableavatarmask();
490 : extern void disableavatarmask();
491 :
492 : template<class T>
493 0 : inline void calctilebounds(float sx1, float sy1, float sx2, float sy2, T &bx1, T &by1, T &bx2, T &by2)
494 : {
495 0 : int tx1 = std::max(static_cast<int>(std::floor(((sx1 + 1)*0.5f*vieww)/lighttilealignw)), 0),
496 0 : ty1 = std::max(static_cast<int>(std::floor(((sy1 + 1)*0.5f*viewh)/lighttilealignh)), 0),
497 0 : tx2 = std::min(static_cast<int>(std::ceil(((sx2 + 1)*0.5f*vieww)/lighttilealignw)), lighttilevieww),
498 0 : ty2 = std::min(static_cast<int>(std::ceil(((sy2 + 1)*0.5f*viewh)/lighttilealignh)), lighttileviewh);
499 0 : bx1 = T((tx1 * lighttilew) / lighttilevieww);
500 0 : by1 = T((ty1 * lighttileh) / lighttileviewh);
501 0 : bx2 = T((tx2 * lighttilew + lighttilevieww - 1) / lighttilevieww);
502 0 : by2 = T((ty2 * lighttileh + lighttileviewh - 1) / lighttileviewh);
503 0 : }
504 :
505 : #endif
|