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 : void viewrefract();
75 : void doscale(GLuint outfbo = 0) const;
76 : void setupscale(int sw, int sh, int w, int h);
77 : GLuint shouldscale() const;
78 : void workinoq();
79 :
80 : /**
81 : * @brief Creates the geometry buffer for the scene
82 : *
83 : * Renders and copies a fbo (framebuffer object) to msfbo (multisample framebuffer object)
84 : * or gfbo (geometry buffer framebuffer object) depending on whether msaa is enabled
85 : *
86 : * @param bool depthclear toggles clearing the depth buffer
87 : * @param gamefxn pointer to a function for game-specific rendering
88 : */
89 : void rendergbuffer(bool depthclear = true, void (*gamefxn)() = dummyfxn);
90 : bool istransparentlayer() const;
91 : void rendermodelbatches();
92 : 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);
93 :
94 : /**
95 : * @brief Returns debug information about lighting.
96 : *
97 : * Types:
98 : * 0: light passes used
99 : * 1: lights visible
100 : * 2: lights occluded
101 : * 3: light batches used
102 : * 4: light batch rects used
103 : * 5: light batch stacks used
104 : *
105 : * @param type of value to query
106 : *
107 : * @return numeric value of appropriate type
108 : */
109 : int getlightdebuginfo(uint type) const;
110 : private:
111 : void bindmsdepth() const;
112 : void bindlighttexs(int msaapass, bool transparent) const; //only used in renderlights
113 : void cleanupscale();
114 : void cleanupmsbuffer();
115 : void preparegbuffer(bool depthclear = true);
116 : void rendercsmshadowmaps() const;
117 : void rendershadowmaps(int offset = 0) const;
118 : void rendersunpass(Shader *s, int stencilref, bool transparent, float bsx1, float bsy1, float bsx2, float bsy2, const uint *tilemask);
119 : void renderlightsnobatch(Shader *s, int stencilref, bool transparent, float bsx1, float bsy1, float bsx2, float bsy2);
120 : void renderlightbatches(Shader &s, int stencilref, bool transparent, float bsx1, float bsy1, float bsx2, float bsy2, const uint *tilemask);
121 : void rendergeom();
122 :
123 : void alphaparticles(float allsx1, float allsy1, float allsx2, float allsy2) const;
124 :
125 : void rendermaterialmask() const;
126 : void renderliquidmaterials() const;
127 : void packlights();
128 :
129 : struct MaterialInfo final
130 : {
131 : float matliquidsx1,
132 : matliquidsy1,
133 : matliquidsx2,
134 : matliquidsy2;
135 : float matsolidsx1,
136 : matsolidsy1,
137 : matsolidsx2,
138 : matsolidsy2;
139 : float matrefractsx1,
140 : matrefractsy1,
141 : matrefractsx2,
142 : matrefractsy2;
143 : uint matliquidtiles[lighttilemaxheight],
144 : matsolidtiles[lighttilemaxheight];
145 : int hasmats;
146 : };
147 :
148 : struct AlphaInfo final
149 : {
150 : float alphafrontsx1, alphafrontsx2,
151 : alphafrontsy1, alphafrontsy2,
152 : alphabacksx1, alphabacksx2,
153 : alphabacksy1, alphabacksy2,
154 : alpharefractsx1, alpharefractsx2,
155 : alpharefractsy1, alpharefractsy2;
156 : int hasalphavas;
157 : };
158 :
159 : MaterialInfo findmaterials() const; //materials.cpp
160 : AlphaInfo findalphavas();
161 :
162 : struct TransparentModelInfo final
163 : {
164 : float mdlsx1, mdlsy1, mdlsx2, mdlsy2;
165 : std::array<uint, lighttilemaxheight> mdltiles;
166 :
167 1 : TransparentModelInfo() : mdlsx1(-1), mdlsy1(-1), mdlsx2(1), mdlsy2(1), mdltiles()
168 : {
169 1 : }
170 : };
171 : TransparentModelInfo tmodelinfo;
172 :
173 : uint alphatiles[lighttilemaxheight];
174 :
175 : bool transparentlayer;
176 : bool inoq = false;
177 : bool gdepthinit;
178 : bool hdrfloat;
179 : bool msaadepthblit; //no way to change this outside constructor atm
180 : bool msaatonemapblit;
181 :
182 : int scalew,
183 : scaleh;
184 : //main g-buffers
185 : GLuint gfbo,
186 : gdepthtex,
187 : gcolortex,
188 : gnormaltex,
189 : gglowtex,
190 : gdepthrb,
191 : gstencilrb;
192 : //multisample antialiasing g-buffers
193 : GLuint msfbo,
194 : msdepthtex,
195 : mscolortex,
196 : msnormaltex,
197 : msglowtex,
198 : msdepthrb,
199 : msstencilrb,
200 : mshdrfbo,
201 : mshdrtex,
202 : msrefractfbo,
203 : msrefracttex;
204 : //refractive g-buffers
205 : GLuint refractfbo,
206 : refracttex;
207 : //rescaling g-buffers
208 : std::array<GLuint, 2> scalefbo,
209 : scaletex;
210 : GLenum stencilformat;
211 : matrix4 eyematrix,
212 : linearworldmatrix;
213 :
214 : int lightpassesused,
215 : lightsvisible,
216 : lightsoccluded,
217 : lightbatchesused,
218 : lightbatchrectsused,
219 : lightbatchstacksused;
220 :
221 : static float refractmargin,
222 : refractdepth;
223 : };
224 :
225 : extern GBuffer gbuf;
226 :
227 : class PackNode final
228 : {
229 : public:
230 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)) {}
231 :
232 1 : void reset()
233 : {
234 1 : discardchildren();
235 1 : available = std::min(w, h);
236 1 : }
237 :
238 1 : bool resize(int nw, int nh)
239 : {
240 1 : if(w == nw && h == nw)
241 : {
242 0 : return false;
243 : }
244 1 : discardchildren();
245 1 : w = nw;
246 1 : h = nh;
247 1 : available = std::min(w, h);
248 1 : return true;
249 : }
250 :
251 13 : ~PackNode()
252 : {
253 13 : discardchildren();
254 13 : }
255 :
256 : bool insert(ushort &tx, ushort &ty, ushort tw, ushort th);
257 : void reserve(ushort tx, ushort ty, ushort tw, ushort th);
258 :
259 3 : int availablespace() const
260 : {
261 3 : return available;
262 : }
263 :
264 2 : vec2 dimensions() const
265 : {
266 2 : return {static_cast<float>(w), static_cast<float>(h)};
267 : }
268 :
269 : //debugging printouts, not used in program logic
270 :
271 : //i: recursion depth
272 7 : void printchildren(int i = 0) const
273 : {
274 7 : print(i);
275 :
276 7 : if(child1)
277 : {
278 3 : child1->printchildren(i+1);
279 : }
280 7 : if(child2)
281 : {
282 3 : child2->printchildren(i+1);
283 : }
284 7 : }
285 :
286 : //i: depth to print out
287 7 : void print(int i) const
288 : {
289 7 : std::printf("%d: %d %d\n", i, w, h);
290 7 : }
291 :
292 : private:
293 : ushort w, h;
294 : PackNode *child1, *child2;
295 : ushort x, y;
296 : int available;
297 :
298 18 : void discardchildren()
299 : {
300 18 : if(child1)
301 : {
302 6 : delete child1;
303 6 : child1 = nullptr;
304 : }
305 18 : if(child2)
306 : {
307 6 : delete child2;
308 6 : child2 = nullptr;
309 : }
310 18 : }
311 :
312 : void forceempty()
313 : {
314 : discardchildren();
315 : available = 0;
316 : }
317 : };
318 :
319 : extern PackNode shadowatlaspacker;
320 :
321 : struct shadowcacheval;
322 :
323 : struct ShadowMapInfo final
324 : {
325 : ushort x, y, size, sidemask;
326 : int light;
327 : const shadowcacheval *cached;
328 : };
329 :
330 : extern std::vector<ShadowMapInfo> shadowmaps;
331 : extern int smfilter;
332 :
333 : extern void addshadowmap(ushort x, ushort y, int size, int &idx, int light = -1, const shadowcacheval *cached = nullptr);
334 :
335 : constexpr int shadowatlassize = 4096;
336 :
337 : extern int smborder, smborder2;
338 :
339 : extern int gdepthstencil, gstencil, glineardepth, msaalineardepth, batchsunlight, smgather, tqaaresolvegather;
340 : extern int lighttilealignw, lighttilealignh, lighttilevieww, lighttileviewh, lighttilew, lighttileh;
341 : extern int spotlights;
342 : extern int volumetriclights;
343 : extern int nospeclights;
344 : extern int debugfullscreen;
345 : extern int msaaedgedetect;
346 : extern int hdrclear;
347 : extern int msaatonemap;
348 : extern float ldrscale;
349 : extern float ldrscaleb(); //derived from ldrscale
350 :
351 : extern int vieww, viewh;
352 :
353 : enum
354 : {
355 : ShadowMap_None = 0,
356 : ShadowMap_Reflect,
357 : ShadowMap_CubeMap,
358 : ShadowMap_Cascade,
359 : ShadowMap_Spot,
360 : };
361 :
362 : extern int shadowmapping;
363 : extern int smcullside;
364 :
365 : extern matrix4 shadowmatrix;
366 :
367 : /**
368 : * @brief sets values for one of the bilateralshader[] elements
369 : *
370 : * bilateralshader[2] elements' referenced Shader objects have their radius
371 : * and depth parameters changed
372 : *
373 : * @param radius the bilateral filter radius to set
374 : * @param pass [0-1] the element of the bilateralshader() array to change
375 : * @param depth the depth of the bilateral filtering to set
376 : */
377 : extern void setbilateralshader(int radius, int pass, float depth);
378 :
379 : /**
380 : * @brief clears bilateralarray
381 : *
382 : * Makes bilateralshader[2]'s elements point to the null pointer..
383 : */
384 : void clearbilateralshaders();
385 :
386 : /**
387 : * @brief sets bilateralshader array using bilateralshader()
388 : *
389 : * Sets bilateralshader[2] elements to point to Shader objects representing the two passes
390 : */
391 : void loadbilateralshaders();
392 :
393 : extern void loaddeferredlightshaders();
394 : extern void cleardeferredlightshaders();
395 : extern void clearshadowcache();
396 :
397 : extern void cleanupvolumetric();
398 :
399 : extern void findshadowvas();
400 : extern void findshadowmms();
401 :
402 : extern int calcshadowinfo(const extentity &e, vec &origin, float &radius, vec &spotloc, int &spotangle, float &bias);
403 : extern void rendershadowmapworld();
404 : extern void batchshadowmapmodels(bool skipmesh = false);
405 : extern void renderrsmgeom(bool dyntex = false);
406 :
407 : extern int calcspheresidemask(const vec &p, float radius, float bias);
408 : extern int calcbbrsmsplits(const ivec &bbmin, const ivec &bbmax);
409 : extern int calcspherersmsplits(const vec ¢er, float radius);
410 :
411 0 : inline bool sphereinsidespot(const vec &dir, int spot, const vec ¢er, float radius)
412 : {
413 0 : const vec2 &sc = sincos360[spot];
414 0 : float cdist = dir.dot(center),
415 0 : cradius = radius + sc.y*cdist;
416 0 : return sc.x*sc.x*(center.dot(center) - cdist*cdist) <= cradius*cradius;
417 : }
418 0 : inline bool bbinsidespot(const vec &origin, const vec &dir, int spot, const ivec &bbmin, const ivec &bbmax)
419 : {
420 0 : vec radius = vec(ivec(bbmax).sub(bbmin)).mul(0.5f),
421 0 : center = vec(bbmin).add(radius);
422 0 : return sphereinsidespot(dir, spot, center.sub(origin), radius.magnitude());
423 : }
424 :
425 : extern matrix4 worldmatrix, screenmatrix;
426 :
427 : extern int gw, gh, gdepthformat, ghasstencil;
428 : extern int msaasamples, msaalight;
429 : extern std::vector<vec2> msaapositions;
430 :
431 : extern int rhinoq;
432 :
433 : extern bool shouldworkinoq();
434 : extern void initgbuffer();
435 : extern bool usepacknorm();
436 : extern void maskgbuffer(const char *mask);
437 : extern void shadegbuffer();
438 : extern void setuplights(GBuffer &buf);
439 : extern bool debuglights();
440 : extern void cleanuplights();
441 :
442 : extern int avatarmask;
443 : extern void enableavatarmask();
444 : extern void disableavatarmask();
445 :
446 : template<class T>
447 0 : inline void calctilebounds(float sx1, float sy1, float sx2, float sy2, T &bx1, T &by1, T &bx2, T &by2)
448 : {
449 0 : int tx1 = std::max(static_cast<int>(std::floor(((sx1 + 1)*0.5f*vieww)/lighttilealignw)), 0),
450 0 : ty1 = std::max(static_cast<int>(std::floor(((sy1 + 1)*0.5f*viewh)/lighttilealignh)), 0),
451 0 : tx2 = std::min(static_cast<int>(std::ceil(((sx2 + 1)*0.5f*vieww)/lighttilealignw)), lighttilevieww),
452 0 : ty2 = std::min(static_cast<int>(std::ceil(((sy2 + 1)*0.5f*viewh)/lighttilealignh)), lighttileviewh);
453 0 : bx1 = T((tx1 * lighttilew) / lighttilevieww);
454 0 : by1 = T((ty1 * lighttileh) / lighttileviewh);
455 0 : bx2 = T((tx2 * lighttilew + lighttilevieww - 1) / lighttilevieww);
456 0 : by2 = T((ty2 * lighttileh + lighttileviewh - 1) / lighttileviewh);
457 0 : }
458 :
459 : #endif
|