Line data Source code
1 : /* hdr.cpp: hdr, tonemapping, and bloom
2 : *
3 : * Libprimis supports a type of high dynamic range by calculating the average
4 : * brightness of the scene and slowly changing the calibration point for the
5 : * viewed image, much as human eyes do. This results in colors being washed out
6 : * bright, e.g., when stepping into the sunlight, and time being required before
7 : * a dark area can be seen after being "used to" bright light.
8 : *
9 : * Additionally, bloom, or bleed from bright light sources, is calculated in the
10 : * process of sampling the screen for HDR purposes. This allows very bright
11 : * objects to appear more overbright (and realistic) than the light entities can
12 : * project on their own.
13 : */
14 : #include "../libprimis-headers/cube.h"
15 : #include "../../shared/geomexts.h"
16 : #include "../../shared/glemu.h"
17 : #include "../../shared/glexts.h"
18 :
19 : #include "aa.h"
20 : #include "hdr.h"
21 : #include "rendergl.h"
22 : #include "renderlights.h"
23 : #include "rendertimers.h"
24 : #include "shader.h"
25 : #include "shaderparam.h"
26 : #include "texture.h"
27 :
28 : #include "interface/control.h"
29 :
30 :
31 : GLenum hdrformat = 0;
32 :
33 : int bloomw = -1,
34 : bloomh = -1;
35 :
36 : //gl buffers needed for bloom effect
37 : GLuint hdrfbo = 0,
38 : hdrtex = 0;
39 :
40 : namespace
41 : {
42 : GLuint bloompbo = 0,
43 : bloomfbo[6] = { 0, 0, 0, 0, 0, 0 },
44 : bloomtex[6] = { 0, 0, 0, 0, 0, 0 };
45 :
46 : GLenum bloomformat = 0;
47 : int lasthdraccum = 0;
48 :
49 : FVAR(bloomthreshold, 1e-3f, 0.8f, 1e3f);
50 : FVARP(bloomscale, 0, 1.0f, 1e3f); //scale factor for bloom effect
51 : VARP(bloomblur, 0, 7, 7); //blur factor for bloom effect
52 : VARP(bloomiter, 0, 0, 4); //number of interations for bloom generation
53 0 : VARFP(bloomsize, 6, 9, 11, cleanupbloom()); //size of HDR buffer: 6 -> 2^6 = 64x64 ... 11 -> 2^11 = 2048x2048
54 0 : VARFP(bloomprec, 0, 2, 3, cleanupbloom()); //HDR buffer bit depth: 3: RGB16 2: R11G11B10 1:RGB10 0: RGB8
55 :
56 : FVAR(hdraccumscale, 0, 0.98f, 1); //for hdr, exponent base for time decay of accumulation buffer (always <= 1 so decaying with time)
57 : VAR(hdraccummillis, 1, 33, 1000); //number of ms between samplings for the hdr buffer
58 : VAR(hdrreduce, 0, 2, 2); //number of powers to reduce hdr buffer size relative to g buffer (2 = 1/4, 1 = 1/2, 0 = g-buffer size)
59 : FVARR(hdrbright, 1e-4f, 1.0f, 1e4f); //brightness factor for high dynamic range rendering
60 : FVAR(hdrsaturate, 1e-3f, 0.8f, 1e3f);
61 : }
62 :
63 0 : int gethdrformat(int prec, int fallback)
64 : {
65 0 : if(prec >= 3)
66 : {
67 0 : return GL_RGB16F;
68 : }
69 0 : if(prec >= 2)
70 : {
71 0 : return GL_R11F_G11F_B10F;
72 : }
73 0 : if(prec >= 1)
74 : {
75 0 : return GL_RGB10;
76 : }
77 0 : return fallback;
78 : }
79 :
80 0 : void setupbloom(int w, int h)
81 : {
82 0 : int maxsize = ((1<<bloomsize)*5)/4;
83 0 : while(w >= maxsize || h >= maxsize)
84 : {
85 0 : w /= 2;
86 0 : h /= 2;
87 : }
88 0 : w = std::max(w, 1);
89 0 : h = std::max(h, 1);
90 0 : if(w == bloomw && h == bloomh)
91 : {
92 0 : return;
93 : }
94 0 : bloomw = w;
95 0 : bloomh = h;
96 :
97 0 : for(int i = 0; i < 5; ++i)
98 : {
99 0 : if(!bloomtex[i])
100 : {
101 0 : glGenTextures(1, &bloomtex[i]);
102 : }
103 : }
104 :
105 0 : for(int i = 0; i < 5; ++i)
106 : {
107 0 : if(!bloomfbo[i])
108 : {
109 0 : glGenFramebuffers(1, &bloomfbo[i]);
110 : }
111 : }
112 :
113 0 : bloomformat = gethdrformat(bloomprec);
114 0 : createtexture(bloomtex[0], std::max(gw/2, bloomw), std::max(gh/2, bloomh), nullptr, 3, 1, bloomformat, GL_TEXTURE_RECTANGLE);
115 0 : createtexture(bloomtex[1], std::max(gw/4, bloomw), std::max(gh/4, bloomh), nullptr, 3, 1, bloomformat, GL_TEXTURE_RECTANGLE);
116 0 : createtexture(bloomtex[2], bloomw, bloomh, nullptr, 3, 1, GL_RGB, GL_TEXTURE_RECTANGLE);
117 0 : createtexture(bloomtex[3], bloomw, bloomh, nullptr, 3, 1, GL_RGB, GL_TEXTURE_RECTANGLE);
118 0 : if(bloomformat != GL_RGB)
119 : {
120 0 : if(!bloomtex[5])
121 : {
122 0 : glGenTextures(1, &bloomtex[5]);
123 : }
124 0 : if(!bloomfbo[5])
125 : {
126 0 : glGenFramebuffers(1, &bloomfbo[5]);
127 : }
128 0 : createtexture(bloomtex[5], bloomw, bloomh, nullptr, 3, 1, bloomformat, GL_TEXTURE_RECTANGLE);
129 : }
130 : static const float grayf[12] = { 0.125f, 0.125f, 0.125f, 0.125f, 0.125f, 0.125f, 0.125f, 0.125f, 0.125f, 0.125f, 0.125f, 0.125f };
131 0 : createtexture(bloomtex[4], bloompbo ? 4 : 1, 1, reinterpret_cast<const void *>(grayf), 3, 1, GL_R16F);
132 0 : for(int i = 0; i < (5 + (bloomformat != GL_RGB ? 1 : 0)); ++i)
133 : {
134 0 : glBindFramebuffer(GL_FRAMEBUFFER, bloomfbo[i]);
135 0 : glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, i==4 ? GL_TEXTURE_2D : GL_TEXTURE_RECTANGLE, bloomtex[i], 0);
136 0 : if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
137 : {
138 0 : fatal("failed allocating bloom buffer!");
139 : }
140 : }
141 :
142 0 : glBindFramebuffer(GL_FRAMEBUFFER, 0);
143 : }
144 :
145 0 : void cleanupbloom()
146 : {
147 0 : if(bloompbo)
148 : {
149 0 : glDeleteBuffers(1, &bloompbo);
150 0 : bloompbo = 0;
151 : }
152 0 : for(int i = 0; i < 6; ++i)
153 : {
154 0 : if(bloomfbo[i])
155 : {
156 0 : glDeleteFramebuffers(1, &bloomfbo[i]);
157 0 : bloomfbo[i] = 0;
158 : }
159 : }
160 0 : for(int i = 0; i < 6; ++i)
161 : {
162 0 : if(bloomtex[i])
163 : {
164 0 : glDeleteTextures(1, &bloomtex[i]);
165 0 : bloomtex[i] = 0;
166 : }
167 : }
168 0 : bloomw = bloomh = -1;
169 0 : lasthdraccum = 0;
170 0 : }
171 :
172 0 : FVARFP(hdrgamma, 1e-3f, 2, 1e3f, initwarning("HDR setup", Init_Load, Change_Shaders));
173 0 : VARFP(hdrprec, 0, 2, 3, gbuf.cleanupgbuffer()); //precision of hdr buffer
174 :
175 0 : void copyhdr(int sw, int sh, GLuint fbo, int dw, int dh, bool flipx, bool flipy, bool swapxy)
176 : {
177 0 : if(!dw)
178 : {
179 0 : dw = sw;
180 : }
181 0 : if(!dh)
182 : {
183 0 : dh = sh;
184 : }
185 :
186 0 : if(msaalight)
187 : {
188 0 : gbuf.resolvemsaacolor(sw, sh);
189 : }
190 0 : glerror();
191 :
192 0 : glBindFramebuffer(GL_FRAMEBUFFER, fbo);
193 0 : glViewport(0, 0, dw, dh);
194 :
195 0 : SETSHADER(reorient);
196 0 : vec reorientx(flipx ? -0.5f : 0.5f, 0, 0.5f),
197 0 : reorienty(0, flipy ? -0.5f : 0.5f, 0.5f);
198 0 : if(swapxy)
199 : {
200 0 : std::swap(reorientx, reorienty);
201 : }
202 0 : reorientx.mul(sw);
203 0 : reorienty.mul(sh);
204 0 : LOCALPARAM(reorientx, reorientx);
205 0 : LOCALPARAM(reorienty, reorienty);
206 :
207 0 : glBindTexture(GL_TEXTURE_RECTANGLE, hdrtex);
208 0 : screenquad();
209 0 : glerror();
210 :
211 0 : hdrclear = 3;
212 0 : }
213 :
214 0 : void loadhdrshaders(int aa)
215 : {
216 0 : switch(aa)
217 : {
218 0 : case AA_Luma:
219 : {
220 0 : useshaderbyname("hdrtonemapluma");
221 0 : useshaderbyname("hdrnopluma");
222 0 : if(msaalight > 1 && msaatonemap)
223 : {
224 0 : useshaderbyname("msaatonemapluma");
225 : }
226 0 : break;
227 : }
228 0 : case AA_Masked:
229 : {
230 0 : if(!msaasamples && ghasstencil)
231 : {
232 0 : useshaderbyname("hdrtonemapstencil");
233 : }
234 : else
235 : {
236 0 : useshaderbyname("hdrtonemapmasked");
237 0 : useshaderbyname("hdrnopmasked");
238 0 : if(msaalight > 1 && msaatonemap)
239 : {
240 0 : useshaderbyname("msaatonemapmasked");
241 : }
242 : }
243 0 : break;
244 : }
245 0 : case AA_Split:
246 : {
247 0 : useshaderbyname("msaatonemapsplit");
248 0 : break;
249 : }
250 0 : case AA_SplitLuma:
251 : {
252 0 : useshaderbyname("msaatonemapsplitluma");
253 0 : break;
254 : }
255 0 : case AA_SplitMasked:
256 : {
257 0 : useshaderbyname("msaatonemapsplitmasked");
258 0 : break;
259 : }
260 0 : default:
261 : {
262 0 : break;
263 : }
264 : }
265 0 : }
266 :
267 0 : void GBuffer::processhdr(GLuint outfbo, int aa)
268 : {
269 0 : timer *hdrtimer = begintimer("hdr processing");
270 :
271 0 : GLOBALPARAMF(hdrparams, hdrbright, hdrsaturate, bloomthreshold, bloomscale);
272 :
273 0 : GLuint b0fbo = bloomfbo[1],
274 0 : b0tex = bloomtex[1],
275 0 : b1fbo = bloomfbo[0],
276 0 : b1tex = bloomtex[0],
277 0 : ptex = hdrtex;
278 0 : int b0w = std::max(vieww/4, bloomw),
279 0 : b0h = std::max(viewh/4, bloomh),
280 0 : b1w = std::max(vieww/2, bloomw),
281 0 : b1h = std::max(viewh/2, bloomh),
282 0 : pw = vieww,
283 0 : ph = viewh;
284 0 : if(msaalight)
285 : {
286 0 : if(aa < AA_Split && (msaalight <= 1 || !msaatonemap)) //only bind relevant framebuffers
287 : {
288 0 : glBindFramebuffer(GL_READ_FRAMEBUFFER, mshdrfbo);
289 0 : glBindFramebuffer(GL_DRAW_FRAMEBUFFER, hdrfbo);
290 0 : glBlitFramebuffer(0, 0, vieww, viewh, 0, 0, vieww, viewh, GL_COLOR_BUFFER_BIT, GL_NEAREST);
291 : }
292 0 : else if(hasFBMSBS && (vieww > bloomw || viewh > bloomh))
293 : {
294 0 : int cw = std::max(vieww/2, bloomw),
295 0 : ch = std::max(viewh/2, bloomh);
296 0 : glBindFramebuffer(GL_READ_FRAMEBUFFER, mshdrfbo);
297 0 : glBindFramebuffer(GL_DRAW_FRAMEBUFFER, hdrfbo);
298 0 : glBlitFramebuffer(0, 0, vieww, viewh, 0, 0, cw, ch, GL_COLOR_BUFFER_BIT, GL_SCALED_RESOLVE_FASTEST_EXT);
299 0 : pw = cw;
300 0 : ph = ch;
301 0 : }
302 : else
303 : {
304 0 : glBindFramebuffer(GL_FRAMEBUFFER, hdrfbo);
305 0 : if(vieww/2 >= bloomw)
306 : {
307 0 : pw = vieww/2;
308 0 : if(viewh/2 >= bloomh)
309 : {
310 0 : ph = viewh/2;
311 0 : glViewport(0, 0, pw, ph);
312 0 : SETSHADER(msaareduce);
313 : }
314 : else
315 : {
316 0 : glViewport(0, 0, pw, viewh);
317 0 : SETSHADER(msaareducew);
318 : }
319 : }
320 : else
321 : {
322 0 : glViewport(0, 0, vieww, viewh);
323 0 : SETSHADER(msaaresolve);
324 : }
325 0 : glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mshdrtex);
326 0 : screenquad(vieww, viewh);
327 : }
328 : }
329 0 : if(hdrreduce)
330 : {
331 0 : while(pw > bloomw || ph > bloomh)
332 : {
333 0 : GLuint cfbo = b1fbo,
334 0 : ctex = b1tex;
335 0 : int cw = std::max(pw/2, bloomw),
336 0 : ch = std::max(ph/2, bloomh);
337 :
338 0 : if(hdrreduce > 1 && cw/2 >= bloomw)
339 : {
340 0 : cw /= 2;
341 0 : if(ch/2 >= bloomh)
342 : {
343 0 : ch /= 2;
344 0 : SETSHADER(hdrreduce2);
345 : }
346 0 : else SETSHADER(hdrreduce2w);
347 0 : }
348 : else
349 : {
350 0 : SETSHADER(hdrreduce);
351 : }
352 0 : if(cw == bloomw && ch == bloomh)
353 : {
354 0 : if(bloomfbo[5])
355 : {
356 0 : cfbo = bloomfbo[5];
357 0 : ctex = bloomtex[5];
358 : }
359 : else
360 : {
361 0 : cfbo = bloomfbo[2];
362 0 : ctex = bloomtex[2];
363 : }
364 : }
365 0 : glBindFramebuffer(GL_FRAMEBUFFER, cfbo);
366 0 : glViewport(0, 0, cw, ch);
367 0 : glBindTexture(GL_TEXTURE_RECTANGLE, ptex);
368 0 : screenquad(pw, ph);
369 :
370 0 : ptex = ctex;
371 0 : pw = cw;
372 0 : ph = ch;
373 0 : std::swap(b0fbo, b1fbo);
374 0 : std::swap(b0tex, b1tex);
375 0 : std::swap(b0w, b1w);
376 0 : std::swap(b0h, b1h);
377 : }
378 : }
379 0 : if(!lasthdraccum || lastmillis - lasthdraccum >= hdraccummillis)
380 : {
381 0 : GLuint ltex = ptex;
382 0 : int lw = pw,
383 0 : lh = ph;
384 0 : for(int i = 0; lw > 2 || lh > 2; i++)
385 : {
386 0 : int cw = std::max(lw/2, 2),
387 0 : ch = std::max(lh/2, 2);
388 :
389 0 : if(hdrreduce > 1 && cw/2 >= 2)
390 : {
391 0 : cw /= 2;
392 0 : if(ch/2 >= 2)
393 : {
394 0 : ch /= 2;
395 0 : if(i)
396 : {
397 0 : SETSHADER(hdrreduce2);
398 : }
399 : else
400 : {
401 0 : SETSHADER(hdrluminance2);
402 : }
403 : }
404 0 : else if(i)
405 : {
406 0 : SETSHADER(hdrreduce2w);
407 : }
408 : else
409 : {
410 0 : SETSHADER(hdrluminance2w);
411 : }
412 0 : }
413 0 : else if(i)
414 : {
415 0 : SETSHADER(hdrreduce);
416 : }
417 : else
418 : {
419 0 : SETSHADER(hdrluminance);
420 : }
421 0 : glBindFramebuffer(GL_FRAMEBUFFER, b1fbo);
422 0 : glViewport(0, 0, cw, ch);
423 0 : glBindTexture(GL_TEXTURE_RECTANGLE, ltex);
424 0 : screenquad(lw, lh);
425 :
426 0 : ltex = b1tex;
427 0 : lw = cw;
428 0 : lh = ch;
429 0 : std::swap(b0fbo, b1fbo);
430 0 : std::swap(b0tex, b1tex);
431 0 : std::swap(b0w, b1w);
432 0 : std::swap(b0h, b1h);
433 : }
434 :
435 0 : glBindFramebuffer(GL_FRAMEBUFFER, bloomfbo[4]);
436 0 : glViewport(0, 0, bloompbo ? 4 : 1, 1);
437 0 : glEnable(GL_BLEND);
438 0 : glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
439 0 : SETSHADER(hdraccum);
440 0 : glBindTexture(GL_TEXTURE_RECTANGLE, b0tex);
441 0 : LOCALPARAMF(accumscale, lasthdraccum ? std::pow(hdraccumscale, static_cast<float>(lastmillis - lasthdraccum)/hdraccummillis) : 0);
442 0 : screenquad(2, 2);
443 0 : glDisable(GL_BLEND);
444 :
445 0 : if(bloompbo)
446 : {
447 0 : glBindBuffer(GL_PIXEL_PACK_BUFFER, bloompbo);
448 0 : glPixelStorei(GL_PACK_ALIGNMENT, 1);
449 0 : glReadPixels(0, 0, 4, 1, GL_RED, GL_FLOAT, nullptr);
450 0 : glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
451 : }
452 :
453 0 : lasthdraccum = lastmillis;
454 : }
455 :
456 0 : if(bloompbo)
457 : {
458 0 : gle::bindvbo(bloompbo);
459 0 : gle::enablecolor();
460 0 : gle::colorpointer(sizeof(GLfloat), nullptr, GL_FLOAT, 1);
461 0 : gle::clearvbo();
462 : }
463 :
464 0 : b0fbo = bloomfbo[3];
465 0 : b0tex = bloomtex[3];
466 0 : b1fbo = bloomfbo[2];
467 0 : b1tex = bloomtex[2];
468 0 : b0w = b1w = bloomw;
469 0 : b0h = b1h = bloomh;
470 :
471 0 : glActiveTexture(GL_TEXTURE2);
472 0 : glBindTexture(GL_TEXTURE_2D, bloomtex[4]);
473 0 : glActiveTexture(GL_TEXTURE0);
474 :
475 0 : glBindFramebuffer(GL_FRAMEBUFFER, b0fbo);
476 0 : glViewport(0, 0, b0w, b0h);
477 0 : SETSHADER(hdrbloom);
478 0 : glBindTexture(GL_TEXTURE_RECTANGLE, ptex);
479 0 : screenquad(pw, ph);
480 :
481 0 : if(bloomblur)
482 : {
483 : std::array<float, maxblurradius+1> blurweights,
484 : bluroffsets;
485 0 : setupblurkernel(bloomblur, blurweights.data(), bluroffsets.data());
486 0 : for(int i = 0; i < (2 + 2*bloomiter); ++i)
487 : {
488 0 : glBindFramebuffer(GL_FRAMEBUFFER, b1fbo);
489 0 : glViewport(0, 0, b1w, b1h);
490 0 : setblurshader(i%2, 1, bloomblur, blurweights.data(), bluroffsets.data(), GL_TEXTURE_RECTANGLE);
491 0 : glBindTexture(GL_TEXTURE_RECTANGLE, b0tex);
492 0 : screenquad(b0w, b0h);
493 0 : std::swap(b0w, b1w);
494 0 : std::swap(b0h, b1h);
495 0 : std::swap(b0tex, b1tex);
496 0 : std::swap(b0fbo, b1fbo);
497 : }
498 : }
499 :
500 0 : if(aa >= AA_Split)
501 : {
502 0 : glBindFramebuffer(GL_FRAMEBUFFER, outfbo);
503 0 : glViewport(0, 0, vieww, viewh);
504 0 : glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mshdrtex);
505 0 : glActiveTexture(GL_TEXTURE1);
506 0 : glBindTexture(GL_TEXTURE_RECTANGLE, b0tex);
507 0 : glActiveTexture(GL_TEXTURE0);
508 0 : switch(aa)
509 : {
510 0 : case AA_SplitLuma:
511 : {
512 0 : SETSHADER(msaatonemapsplitluma);
513 0 : break;
514 : }
515 0 : case AA_SplitMasked:
516 : {
517 0 : SETSHADER(msaatonemapsplitmasked);
518 0 : setaavelocityparams(GL_TEXTURE3);
519 0 : break;
520 : }
521 0 : default:
522 : {
523 0 : SETSHADER(msaatonemapsplit);
524 0 : break;
525 : }
526 : }
527 0 : screenquad(vieww, viewh, b0w, b0h);
528 : }
529 0 : else if(msaalight <= 1 || !msaatonemap)
530 : {
531 0 : glBindFramebuffer(GL_FRAMEBUFFER, outfbo);
532 0 : glViewport(0, 0, vieww, viewh);
533 0 : glBindTexture(GL_TEXTURE_RECTANGLE, hdrtex);
534 0 : glActiveTexture(GL_TEXTURE1);
535 0 : glBindTexture(GL_TEXTURE_RECTANGLE, b0tex);
536 0 : glActiveTexture(GL_TEXTURE0);
537 0 : switch(aa)
538 : {
539 0 : case AA_Luma:
540 : {
541 0 : SETSHADER(hdrtonemapluma);
542 0 : break;
543 : }
544 0 : case AA_Masked:
545 : {
546 0 : if(!msaasamples && ghasstencil)
547 : {
548 0 : glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
549 0 : glStencilFunc(GL_EQUAL, 0, 0x80);
550 0 : glEnable(GL_STENCIL_TEST);
551 0 : SETSHADER(hdrtonemap);
552 0 : screenquad(vieww, viewh, b0w, b0h);
553 :
554 0 : glStencilFunc(GL_EQUAL, 0x80, 0x80);
555 0 : SETSHADER(hdrtonemapstencil);
556 0 : screenquad(vieww, viewh, b0w, b0h);
557 0 : glDisable(GL_STENCIL_TEST);
558 0 : goto done; //see bottom of fxn
559 : }
560 0 : SETSHADER(hdrtonemapmasked);
561 0 : setaavelocityparams(GL_TEXTURE3);
562 0 : break;
563 : }
564 0 : default:
565 : {
566 0 : SETSHADER(hdrtonemap);
567 0 : break;
568 : }
569 : }
570 0 : screenquad(vieww, viewh, b0w, b0h);
571 0 : }
572 : else
573 : {
574 0 : bool blit = msaalight > 2 && msaatonemapblit && (!aa || !outfbo);
575 :
576 0 : glBindFramebuffer(GL_FRAMEBUFFER, blit ? msrefractfbo : outfbo);
577 0 : glViewport(0, 0, vieww, viewh);
578 0 : glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mshdrtex);
579 0 : glActiveTexture(GL_TEXTURE1);
580 0 : glBindTexture(GL_TEXTURE_RECTANGLE, b0tex);
581 0 : glActiveTexture(GL_TEXTURE0);
582 :
583 0 : if(blit)
584 : {
585 0 : SETSHADER(msaatonemapsample);
586 : }
587 : else
588 : {
589 0 : switch(aa)
590 : {
591 0 : case AA_Luma:
592 : {
593 0 : SETSHADER(msaatonemapluma);
594 0 : break;
595 : }
596 0 : case AA_Masked:
597 : {
598 0 : SETSHADER(msaatonemapmasked);
599 0 : setaavelocityparams(GL_TEXTURE3);
600 0 : break;
601 : }
602 0 : default:
603 : {
604 0 : SETSHADER(msaatonemap);
605 0 : break;
606 : }
607 : }
608 : }
609 0 : screenquad(vieww, viewh, b0w, b0h);
610 :
611 0 : if(blit)
612 : {
613 0 : glBindFramebuffer(GL_READ_FRAMEBUFFER, msrefractfbo);
614 0 : glBindFramebuffer(GL_DRAW_FRAMEBUFFER, aa || !outfbo ? refractfbo : outfbo);
615 0 : glBlitFramebuffer(0, 0, vieww, viewh, 0, 0, vieww, viewh, GL_COLOR_BUFFER_BIT, GL_NEAREST);
616 :
617 0 : if(!outfbo)
618 : {
619 0 : glBindFramebuffer(GL_FRAMEBUFFER, outfbo);
620 0 : glViewport(0, 0, vieww, viewh);
621 0 : if(!blit)
622 : {
623 0 : SETSHADER(hdrnop);
624 : }
625 : else
626 : {
627 0 : switch(aa)
628 : {
629 0 : case AA_Luma:
630 : {
631 0 : SETSHADER(hdrnopluma);
632 0 : break;
633 : }
634 0 : case AA_Masked:
635 : {
636 0 : SETSHADER(hdrnopmasked);
637 0 : setaavelocityparams(GL_TEXTURE3);
638 0 : break;
639 : }
640 0 : default:
641 : {
642 0 : SETSHADER(hdrnop);
643 0 : break;
644 : }
645 : }
646 : }
647 0 : glBindTexture(GL_TEXTURE_RECTANGLE, refracttex);
648 0 : screenquad(vieww, viewh);
649 : }
650 : }
651 : }
652 :
653 0 : done:
654 0 : if(bloompbo)
655 : {
656 0 : gle::disablecolor();
657 : }
658 :
659 0 : endtimer(hdrtimer);
660 0 : }
|