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 : /* gbuffer: a singleton object used to store the graphics buffers
8 : * (as OpenGL uints) and the functions which act upon the g-buffers.
9 : */
10 : class GBuffer
11 : {
12 : public:
13 1 : GBuffer()
14 1 : {
15 : //set all of the textures to 0/null
16 1 : scalew = 0;
17 1 : scaleh = 0;
18 1 : gfbo = 0;
19 1 : gdepthtex = 0;
20 1 : gcolortex = 0;
21 1 : gnormaltex = 0;
22 1 : gglowtex = 0;
23 1 : gdepthrb = 0;
24 1 : gstencilrb = 0;
25 1 : msfbo = 0;
26 1 : msdepthtex = 0;
27 1 : mscolortex = 0;
28 1 : msnormaltex = 0;
29 1 : msglowtex = 0;
30 1 : msdepthrb = 0;
31 1 : msstencilrb = 0;
32 1 : mshdrfbo = 0;
33 1 : mshdrtex = 0;
34 1 : msrefractfbo = 0;
35 1 : msrefracttex = 0;
36 1 : refractfbo = 0;
37 1 : refracttex = 0;
38 1 : stencilformat= 0;
39 1 : scalefbo.fill(0);
40 1 : scaletex.fill(0);
41 1 : gdepthinit = false;
42 1 : hdrfloat = false;
43 1 : msaadepthblit= false;
44 1 : msaatonemapblit = false;
45 1 : inoq = false;
46 1 : transparentlayer = 0;
47 :
48 1 : }
49 : static void dummyfxn();
50 : //main g-buffers
51 : void cleanupgbuffer();
52 : void renderao() const; //ao.cpp
53 : void renderradiancehints() const; //radiancehints.cpp
54 : void rendertransparent(); //renderalpha.cpp
55 : void resolvemsaadepth(int w, int h) const;
56 : void setupgbuffer();
57 : void bindgdepth() const;
58 : void renderparticles(int layer = 0) const; //renderparticles.cpp
59 : void rendervolumetric();
60 : void renderwaterfog(int mat, float surface); //water.cpp
61 : void setaavelocityparams(GLenum tmu = GL_TEXTURE0); //aa.cpp
62 : void shademodelpreview(int x, int y, int w, int h, bool background = true, bool scissor = false);
63 : void viewdepth() const;
64 : void rendershadowatlas();
65 : //multisample antialiasing specific buffers
66 : void setupmsbuffer(int w, int h);
67 : void resolvemsaacolor(int w, int h);
68 : void shademinimap(const vec &color = vec(-1, -1, -1));
69 : void shadesky() const;
70 : //refractive
71 : void processhdr(GLuint outfbo, int aa);
72 : void viewrefract();
73 : void doscale(GLuint outfbo = 0) const;
74 : void setupscale(int sw, int sh, int w, int h);
75 : GLuint shouldscale() const;
76 : void workinoq();
77 : void rendergbuffer(bool depthclear = true, void (*gamefxn)() = dummyfxn);
78 : bool istransparentlayer() const;
79 : void rendermodelbatches();
80 : 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);
81 :
82 : /**
83 : * @brief Returns debug information about lighting.
84 : * 0: light passes used
85 : * 1: lights visible
86 : * 2: lights occluded
87 : * 3: light batches used
88 : * 4: light batch rects used
89 : * 5: light batch stacks used
90 : */
91 : int getlightdebuginfo(uint type) const;
92 : private:
93 : void bindmsdepth() const;
94 : void bindlighttexs(int msaapass, bool transparent) const; //only used in renderlights
95 : void cleanupscale();
96 : void cleanupmsbuffer();
97 : void preparegbuffer(bool depthclear = true);
98 : void rendercsmshadowmaps() const;
99 : void rendershadowmaps(int offset = 0) const;
100 : void rendersunpass(Shader *s, int stencilref, bool transparent, float bsx1, float bsy1, float bsx2, float bsy2, const uint *tilemask);
101 : void renderlightsnobatch(Shader *s, int stencilref, bool transparent, float bsx1, float bsy1, float bsx2, float bsy2);
102 : void renderlightbatches(Shader &s, int stencilref, bool transparent, float bsx1, float bsy1, float bsx2, float bsy2, const uint *tilemask);
103 : void rendergeom();
104 :
105 : void alphaparticles(float allsx1, float allsy1, float allsx2, float allsy2) const;
106 :
107 : void rendermaterialmask() const;
108 : void renderliquidmaterials() const;
109 : void packlights();
110 :
111 : struct MaterialInfo
112 : {
113 : float matliquidsx1,
114 : matliquidsy1,
115 : matliquidsx2,
116 : matliquidsy2;
117 : float matsolidsx1,
118 : matsolidsy1,
119 : matsolidsx2,
120 : matsolidsy2;
121 : float matrefractsx1,
122 : matrefractsy1,
123 : matrefractsx2,
124 : matrefractsy2;
125 : uint matliquidtiles[lighttilemaxheight],
126 : matsolidtiles[lighttilemaxheight];
127 : int hasmats;
128 : };
129 :
130 : struct AlphaInfo
131 : {
132 : float alphafrontsx1, alphafrontsx2,
133 : alphafrontsy1, alphafrontsy2,
134 : alphabacksx1, alphabacksx2,
135 : alphabacksy1, alphabacksy2,
136 : alpharefractsx1, alpharefractsx2,
137 : alpharefractsy1, alpharefractsy2;
138 : int hasalphavas;
139 : };
140 :
141 : MaterialInfo findmaterials() const; //materials.cpp
142 : AlphaInfo findalphavas();
143 :
144 : struct transparentmodelinfo
145 : {
146 : float mdlsx1, mdlsy1, mdlsx2, mdlsy2;
147 : std::array<uint, lighttilemaxheight> mdltiles;
148 :
149 1 : transparentmodelinfo() : mdlsx1(-1), mdlsy1(-1), mdlsx2(1), mdlsy2(1), mdltiles()
150 : {
151 1 : }
152 : };
153 : transparentmodelinfo tmodelinfo;
154 :
155 : uint alphatiles[lighttilemaxheight];
156 :
157 : bool transparentlayer;
158 : bool inoq = false;
159 : bool gdepthinit;
160 : bool hdrfloat;
161 : bool msaadepthblit; //no way to change this outside constructor atm
162 : bool msaatonemapblit;
163 :
164 : int scalew,
165 : scaleh;
166 : //main g-buffers
167 : GLuint gfbo,
168 : gdepthtex,
169 : gcolortex,
170 : gnormaltex,
171 : gglowtex,
172 : gdepthrb,
173 : gstencilrb;
174 : //multisample antialiasing g-buffers
175 : GLuint msfbo,
176 : msdepthtex,
177 : mscolortex,
178 : msnormaltex,
179 : msglowtex,
180 : msdepthrb,
181 : msstencilrb,
182 : mshdrfbo,
183 : mshdrtex,
184 : msrefractfbo,
185 : msrefracttex;
186 : //refractive g-buffers
187 : GLuint refractfbo,
188 : refracttex;
189 : //rescaling g-buffers
190 : std::array<GLuint, 2> scalefbo,
191 : scaletex;
192 : GLenum stencilformat;
193 : matrix4 eyematrix,
194 : linearworldmatrix;
195 :
196 : int lightpassesused,
197 : lightsvisible,
198 : lightsoccluded,
199 : lightbatchesused,
200 : lightbatchrectsused,
201 : lightbatchstacksused;
202 : };
203 :
204 : extern GBuffer gbuf;
205 :
206 : class PackNode
207 : {
208 : public:
209 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)) {}
210 :
211 1 : void reset()
212 : {
213 1 : discardchildren();
214 1 : available = std::min(w, h);
215 1 : }
216 :
217 1 : bool resize(int nw, int nh)
218 : {
219 1 : if(w == nw && h == nw)
220 : {
221 0 : return false;
222 : }
223 1 : discardchildren();
224 1 : w = nw;
225 1 : h = nh;
226 1 : available = std::min(w, h);
227 1 : return true;
228 : }
229 :
230 13 : ~PackNode()
231 : {
232 13 : discardchildren();
233 13 : }
234 :
235 : bool insert(ushort &tx, ushort &ty, ushort tw, ushort th);
236 : void reserve(ushort tx, ushort ty, ushort tw, ushort th);
237 :
238 3 : int availablespace() const
239 : {
240 3 : return available;
241 : }
242 :
243 2 : vec2 dimensions() const
244 : {
245 2 : return {static_cast<float>(w), static_cast<float>(h)};
246 : }
247 :
248 : //debugging printouts, not used in program logic
249 :
250 : //i: recursion depth
251 7 : void printchildren(int i = 0) const
252 : {
253 7 : print(i);
254 :
255 7 : if(child1)
256 : {
257 3 : child1->printchildren(i+1);
258 : }
259 7 : if(child2)
260 : {
261 3 : child2->printchildren(i+1);
262 : }
263 7 : }
264 :
265 : //i: depth to print out
266 7 : void print(int i) const
267 : {
268 7 : std::printf("%d: %d %d\n", i, w, h);
269 7 : }
270 :
271 : private:
272 : ushort w, h;
273 : PackNode *child1, *child2;
274 : ushort x, y;
275 : int available;
276 :
277 18 : void discardchildren()
278 : {
279 18 : if(child1)
280 : {
281 6 : delete child1;
282 6 : child1 = nullptr;
283 : }
284 18 : if(child2)
285 : {
286 6 : delete child2;
287 6 : child2 = nullptr;
288 : }
289 18 : }
290 :
291 : void forceempty()
292 : {
293 : discardchildren();
294 : available = 0;
295 : }
296 : };
297 :
298 : extern PackNode shadowatlaspacker;
299 :
300 : struct shadowcacheval;
301 :
302 : struct shadowmapinfo
303 : {
304 : ushort x, y, size, sidemask;
305 : int light;
306 : const shadowcacheval *cached;
307 : };
308 :
309 : extern std::vector<shadowmapinfo> shadowmaps;
310 : extern int smfilter;
311 :
312 : extern void addshadowmap(ushort x, ushort y, int size, int &idx, int light = -1, const shadowcacheval *cached = nullptr);
313 :
314 : constexpr int shadowatlassize = 4096;
315 :
316 : extern int smborder, smborder2;
317 :
318 : extern int gdepthstencil, gstencil, glineardepth, msaalineardepth, batchsunlight, smgather, tqaaresolvegather;
319 : extern int lighttilealignw, lighttilealignh, lighttilevieww, lighttileviewh, lighttilew, lighttileh;
320 : extern int spotlights;
321 : extern int volumetriclights;
322 : extern int nospeclights;
323 : extern int debugfullscreen;
324 : extern int msaaedgedetect;
325 : extern int hdrclear;
326 : extern int msaatonemap;
327 : extern float ldrscale;
328 : extern float ldrscaleb(); //derived from ldrscale
329 :
330 : extern int vieww, viewh;
331 :
332 : enum
333 : {
334 : ShadowMap_None = 0,
335 : ShadowMap_Reflect,
336 : ShadowMap_CubeMap,
337 : ShadowMap_Cascade,
338 : ShadowMap_Spot,
339 : };
340 :
341 : extern int shadowmapping;
342 : extern int smcullside;
343 :
344 : extern matrix4 shadowmatrix;
345 :
346 : extern void setbilateralshader(int radius, int pass, float depth);
347 : void clearbilateralshaders();
348 : void loadbilateralshaders();
349 :
350 : extern void loaddeferredlightshaders();
351 : extern void cleardeferredlightshaders();
352 : extern void clearshadowcache();
353 :
354 : extern void cleanupvolumetric();
355 :
356 : extern void findshadowvas();
357 : extern void findshadowmms();
358 :
359 : extern int calcshadowinfo(const extentity &e, vec &origin, float &radius, vec &spotloc, int &spotangle, float &bias);
360 : extern void rendershadowmapworld();
361 : extern void batchshadowmapmodels(bool skipmesh = false);
362 : extern void renderrsmgeom(bool dyntex = false);
363 :
364 : extern int calcspheresidemask(const vec &p, float radius, float bias);
365 : extern int calcbbrsmsplits(const ivec &bbmin, const ivec &bbmax);
366 : extern int calcspherersmsplits(const vec ¢er, float radius);
367 :
368 0 : inline bool sphereinsidespot(const vec &dir, int spot, const vec ¢er, float radius)
369 : {
370 0 : const vec2 &sc = sincos360[spot];
371 0 : float cdist = dir.dot(center),
372 0 : cradius = radius + sc.y*cdist;
373 0 : return sc.x*sc.x*(center.dot(center) - cdist*cdist) <= cradius*cradius;
374 : }
375 0 : inline bool bbinsidespot(const vec &origin, const vec &dir, int spot, const ivec &bbmin, const ivec &bbmax)
376 : {
377 0 : vec radius = vec(ivec(bbmax).sub(bbmin)).mul(0.5f),
378 0 : center = vec(bbmin).add(radius);
379 0 : return sphereinsidespot(dir, spot, center.sub(origin), radius.magnitude());
380 : }
381 :
382 : extern matrix4 worldmatrix, screenmatrix;
383 :
384 : extern int gw, gh, gdepthformat, ghasstencil;
385 : extern int msaasamples, msaalight;
386 : extern std::vector<vec2> msaapositions;
387 :
388 : extern int rhinoq;
389 : extern int rsmcull;
390 : extern GLuint rhfbo;
391 :
392 : extern bool shouldworkinoq();
393 : extern void initgbuffer();
394 : extern bool usepacknorm();
395 : extern void maskgbuffer(const char *mask);
396 : extern void shadegbuffer();
397 : extern void setuplights(GBuffer &buf);
398 : extern bool debuglights();
399 : extern void cleanuplights();
400 :
401 : extern int avatarmask;
402 : extern bool useavatarmask();
403 : extern void enableavatarmask();
404 : extern void disableavatarmask();
405 :
406 : template<class T>
407 0 : inline void calctilebounds(float sx1, float sy1, float sx2, float sy2, T &bx1, T &by1, T &bx2, T &by2)
408 : {
409 0 : int tx1 = std::max(static_cast<int>(std::floor(((sx1 + 1)*0.5f*vieww)/lighttilealignw)), 0),
410 0 : ty1 = std::max(static_cast<int>(std::floor(((sy1 + 1)*0.5f*viewh)/lighttilealignh)), 0),
411 0 : tx2 = std::min(static_cast<int>(std::ceil(((sx2 + 1)*0.5f*vieww)/lighttilealignw)), lighttilevieww),
412 0 : ty2 = std::min(static_cast<int>(std::ceil(((sy2 + 1)*0.5f*viewh)/lighttilealignh)), lighttileviewh);
413 0 : bx1 = T((tx1 * lighttilew) / lighttilevieww);
414 0 : by1 = T((ty1 * lighttileh) / lighttileviewh);
415 0 : bx2 = T((tx2 * lighttilew + lighttilevieww - 1) / lighttilevieww);
416 0 : by2 = T((ty2 * lighttileh + lighttileviewh - 1) / lighttileviewh);
417 0 : }
418 :
419 : #endif
|