summary refs log tree commit diff stats
path: root/src/renderer/renderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer/renderer.cpp')
-rw-r--r--src/renderer/renderer.cpp630
1 files changed, 630 insertions, 0 deletions
diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp new file mode 100644 index 0000000..30ef787 --- /dev/null +++ b/src/renderer/renderer.cpp
@@ -0,0 +1,630 @@
1#include "renderer.h"
2#include <glm/gtc/matrix_transform.hpp>
3#include <stb_image.h>
4#include "consts.h"
5#include "game.h"
6#include "texture.h"
7
8void setFramebufferSize(GLFWwindow* w, int width, int height)
9{
10 Game& game = *static_cast<Game*>(glfwGetWindowUserPointer(w));
11 Renderer& renderer = game.getRenderer();
12
13 renderer.width_ = width;
14 renderer.height_ = height;
15
16 renderer.bloomFb_ = {};
17 renderer.bloomDepth_ = {};
18 renderer.preBloomTex_ = {};
19 renderer.bloomPassTex1_ = {};
20 renderer.bloomPassTex2_ = {};
21
22 renderer.initializeFramebuffers();
23}
24
25bool Renderer::singletonInitialized_ = false;
26
27Renderer::Window::Window()
28{
29 // Initialize GLFW
30 if (!glfwInit())
31 {
32 throw std::runtime_error("Failed to initialize GLFW");
33 }
34
35 glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
36 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want version 3.3
37 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
38 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Mac requires this
39 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
40
41 // Create a window
42 window_ = glfwCreateWindow(1024, 768, "Aromatherapy", nullptr, nullptr);
43 if (window_ == nullptr)
44 {
45 throw std::runtime_error("Failed to open GLFW window");
46 }
47
48 glfwMakeContextCurrent(window_);
49
50 glewExperimental = true; // Needed in core profile
51 if (glewInit() != GLEW_OK)
52 {
53 throw std::runtime_error("Failed to initialize GLEW");
54 }
55
56 glfwSetFramebufferSizeCallback(window_, &setFramebufferSize);
57}
58
59Renderer::Window::~Window()
60{
61 glfwTerminate();
62}
63
64Renderer::Renderer() :
65 monitor_("res/monitor-old.obj"),
66 ntscShader_("ntsc"),
67 finalShader_("final"),
68 blitShader_("blit"),
69 fillShader_("fill"),
70 bloom1Shader_("bloom1"),
71 bloom2Shader_("bloom2")
72{
73 if (singletonInitialized_)
74 {
75 throw std::logic_error("Singleton renderer already initialized");
76 }
77
78 singletonInitialized_ = true;
79
80 // Set up vertex array object
81 glBindVertexArray(vao_.getId());
82
83 // Enable depth testing
84 glEnable(GL_DEPTH_TEST);
85 glDepthFunc(GL_LESS);
86
87 // Enable blending
88 glEnable(GL_BLEND);
89 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
90
91 // Set up the rendering buffers and textures
92 glfwGetFramebufferSize(window_.getHandle(), &width_, &height_);
93
94 initializeFramebuffers();
95
96 // Load the vertices of a flat surface
97 GLfloat g_quad_vertex_buffer_data[] = {
98 -1.0f, -1.0f, 0.0f,
99 1.0f, -1.0f, 0.0f,
100 -1.0f, 1.0f, 0.0f,
101 -1.0f, 1.0f, 0.0f,
102 1.0f, -1.0f, 0.0f,
103 1.0f, 1.0f, 0.0f,
104 };
105
106 glBindBuffer(GL_ARRAY_BUFFER, quadBuffer_.getId());
107 glBufferData(
108 GL_ARRAY_BUFFER,
109 sizeof(GLfloat) * 18,
110 g_quad_vertex_buffer_data,
111 GL_STATIC_DRAW);
112
113 // Load NTSC artifacts
114 int atdw, atdh;
115 unsigned char* artifactsData =
116 stbi_load("res/artifacts.bmp", &atdw, &atdh, 0, 3);
117
118 flipImageData(artifactsData, atdw, atdh, 3);
119
120 glBindTexture(GL_TEXTURE_2D, artifactsTex_.getId());
121 glTexImage2D(
122 GL_TEXTURE_2D,
123 0,
124 GL_RGB,
125 atdw,
126 atdh,
127 0,
128 GL_RGB,
129 GL_UNSIGNED_BYTE,
130 artifactsData);
131
132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
133 glTexParameteri(
134 GL_TEXTURE_2D,
135 GL_TEXTURE_MIN_FILTER,
136 GL_NEAREST_MIPMAP_NEAREST);
137
138 glGenerateMipmap(GL_TEXTURE_2D);
139 stbi_image_free(artifactsData);
140
141 // Load NTSC scanlines
142 unsigned char* scanlinesData =
143 stbi_load("res/scanlines_333.bmp", &atdw, &atdh, 0, 3);
144
145 flipImageData(scanlinesData, atdw, atdh, 3);
146
147 glBindTexture(GL_TEXTURE_2D, scanlinesTex_.getId());
148 glTexImage2D(
149 GL_TEXTURE_2D,
150 0,
151 GL_RGB,
152 atdw,
153 atdh,
154 0,
155 GL_RGB,
156 GL_UNSIGNED_BYTE,
157 scanlinesData);
158
159 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
160 glTexParameteri(
161 GL_TEXTURE_2D,
162 GL_TEXTURE_MIN_FILTER,
163 GL_NEAREST_MIPMAP_NEAREST);
164
165 glGenerateMipmap(GL_TEXTURE_2D);
166 stbi_image_free(scanlinesData);
167}
168
169void Renderer::initializeFramebuffers()
170{
171 // Set up the framebuffer
172 glBindFramebuffer(GL_FRAMEBUFFER, genericFb_.getId());
173 GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
174 glDrawBuffers(1, DrawBuffers);
175
176 // Set up the bloom framebuffer and depthbuffer
177 glBindFramebuffer(GL_FRAMEBUFFER, bloomFb_.getId());
178 GLenum DrawBuffers2[1] = {GL_COLOR_ATTACHMENT1};
179 glDrawBuffers(1, DrawBuffers2);
180
181 glBindRenderbuffer(GL_RENDERBUFFER, bloomDepth_.getId());
182 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width_, height_);
183 glFramebufferRenderbuffer(
184 GL_FRAMEBUFFER,
185 GL_DEPTH_ATTACHMENT,
186 GL_RENDERBUFFER,
187 bloomDepth_.getId());
188
189 // Set up the NTSC rendering buffers
190 glBindTexture(GL_TEXTURE_2D, renderPages_[0].getId());
191 glTexImage2D(
192 GL_TEXTURE_2D,
193 0,
194 GL_RGB,
195 GAME_WIDTH,
196 GAME_HEIGHT,
197 0,
198 GL_RGB,
199 GL_UNSIGNED_BYTE,
200 0);
201
202 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
203 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
204 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
205 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
206
207 glBindTexture(GL_TEXTURE_2D, renderPages_[1].getId());
208 glTexImage2D(
209 GL_TEXTURE_2D,
210 0,
211 GL_RGB,
212 GAME_WIDTH,
213 GAME_HEIGHT,
214 0,
215 GL_RGB,
216 GL_UNSIGNED_BYTE,
217 0);
218
219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
222 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
223
224 // Set up bloom rendering buffers
225 glBindTexture(GL_TEXTURE_2D, preBloomTex_.getId());
226 glTexImage2D(
227 GL_TEXTURE_2D,
228 0,
229 GL_RGB,
230 width_,
231 height_,
232 0,
233 GL_RGB,
234 GL_UNSIGNED_BYTE,
235 0);
236
237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
239 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
240 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
241
242 glBindTexture(GL_TEXTURE_2D, bloomPassTex1_.getId());
243 glTexImage2D(
244 GL_TEXTURE_2D,
245 0,
246 GL_RGB,
247 width_ / 4,
248 height_ / 4,
249 0,
250 GL_RGB,
251 GL_UNSIGNED_BYTE,
252 0);
253
254 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
255 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
256 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
257 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
258
259 glBindTexture(GL_TEXTURE_2D, bloomPassTex2_.getId());
260 glTexImage2D(
261 GL_TEXTURE_2D,
262 0,
263 GL_RGB,
264 width_ / 4,
265 height_ / 4,
266 0,
267 GL_RGB,
268 GL_UNSIGNED_BYTE,
269 0);
270
271 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
275}
276
277Renderer::~Renderer()
278{
279 singletonInitialized_ = false;
280}
281
282void Renderer::fill(Texture& tex, Rectangle dstrect, int r, int g, int b)
283{
284 // Target the framebuffer
285 glBindFramebuffer(GL_FRAMEBUFFER, genericFb_.getId());
286 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex.getId(), 0);
287
288 // Set up the vertex attributes
289 int width = tex.getWidth();
290 int height = tex.getHeight();
291
292 GLfloat minx = (GLfloat) dstrect.x / width * 2.0 - 1.0;
293 GLfloat miny = -((GLfloat) dstrect.y / height * 2.0 - 1.0);
294 GLfloat maxx = (GLfloat) (dstrect.x + dstrect.w) / width * 2.0 - 1.0;
295 GLfloat maxy = -((GLfloat) (dstrect.y + dstrect.h) / height * 2.0 - 1.0);
296
297 GLfloat vertexData[] = {
298 minx, miny,
299 maxx, miny,
300 maxx, maxy,
301 minx, miny,
302 minx, maxy,
303 maxx, maxy
304 };
305
306 GLBuffer vertexBuffer;
307 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.getId());
308 glBufferData(
309 GL_ARRAY_BUFFER,
310 sizeof(GLfloat) * 12,
311 vertexData, GL_STATIC_DRAW);
312
313 glEnableVertexAttribArray(0);
314 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
315
316 glViewport(0, 0, tex.getWidth(), tex.getHeight());
317 glClear(GL_DEPTH_BUFFER_BIT);
318
319 fillShader_.use();
320 glUniform3f(
321 fillShader_.getUniformLocation("vecColor"),
322 r / 255.0,
323 g / 255.0,
324 b / 255.0);
325
326 glDrawArrays(GL_TRIANGLES, 0, 6);
327
328 glDisableVertexAttribArray(0);
329}
330
331void Renderer::blit(
332 const Texture& src,
333 Texture& dst,
334 Rectangle srcrect,
335 Rectangle dstrect,
336 double alpha)
337{
338 alpha = glm::clamp(alpha, 0.0, 1.0);
339
340 // Target the framebuffer
341 glBindFramebuffer(GL_FRAMEBUFFER, genericFb_.getId());
342 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dst.getId(), 0);
343
344 // Set up the vertex attributes
345 int width = dst.getWidth();
346 int height = dst.getHeight();
347
348 GLfloat minx = (GLfloat) dstrect.x / width * 2.0 - 1.0;
349 GLfloat miny = -((GLfloat) dstrect.y / height * 2.0 - 1.0);
350 GLfloat maxx = (GLfloat) (dstrect.x + dstrect.w) / width * 2.0 - 1.0;
351 GLfloat maxy = -((GLfloat) (dstrect.y + dstrect.h) / height * 2.0 - 1.0);
352
353 GLfloat vertexData[] = {
354 minx, miny,
355 maxx, miny,
356 minx, maxy,
357 maxx, maxy
358 };
359
360 GLBuffer vertexBuffer;
361 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.getId());
362 glBufferData(
363 GL_ARRAY_BUFFER,
364 sizeof(GLfloat) * 8,
365 vertexData,
366 GL_STATIC_DRAW);
367
368 glEnableVertexAttribArray(0);
369 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
370
371 GLfloat minu = (GLfloat) srcrect.x / src.getWidth();
372 GLfloat minv = 1 - ((GLfloat) srcrect.y / src.getHeight());
373 GLfloat maxu = (GLfloat) (srcrect.x + srcrect.w) / src.getWidth();
374 GLfloat maxv = 1 - ((GLfloat) (srcrect.y + srcrect.h) / src.getHeight());
375
376 GLfloat uvData[] = {
377 minu, minv,
378 maxu, minv,
379 minu, maxv,
380 maxu, maxv
381 };
382
383 GLBuffer uvBuffer;
384 glBindBuffer(GL_ARRAY_BUFFER, uvBuffer.getId());
385 glBufferData(
386 GL_ARRAY_BUFFER,
387 sizeof(GLfloat) * 8,
388 uvData,
389 GL_STATIC_DRAW);
390
391 glEnableVertexAttribArray(1);
392 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
393
394 // Set up the shader
395 blitShader_.use();
396 glClear(GL_DEPTH_BUFFER_BIT);
397 glViewport(0, 0, dst.getWidth(), dst.getHeight());
398
399 glActiveTexture(GL_TEXTURE0);
400 glBindTexture(GL_TEXTURE_2D, src.getId());
401 glUniform1i(blitShader_.getUniformLocation("srctex"), 0);
402 glUniform1f(blitShader_.getUniformLocation("alpha"), alpha);
403
404 // Blit!
405 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
406
407 // Unload everything
408 glDisableVertexAttribArray(1);
409 glDisableVertexAttribArray(0);
410}
411
412void Renderer::bloomPass1(
413 const GLTexture& src,
414 GLTexture& dst,
415 bool horizontal,
416 glm::vec2 srcRes,
417 glm::vec2 dstRes)
418{
419 glBindFramebuffer(GL_FRAMEBUFFER, genericFb_.getId());
420 glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dst.getId(), 0);
421 glViewport(0,0,dstRes.x,dstRes.y);
422 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
423 bloom1Shader_.use();
424
425 glActiveTexture(GL_TEXTURE0);
426 glBindTexture(GL_TEXTURE_2D, src.getId());
427 glUniform1i(bloom1Shader_.getUniformLocation("inTex"), 0);
428
429 glm::vec2 offset = glm::vec2(0.0);
430 if (horizontal)
431 {
432 offset.x = 1.2/srcRes.x;
433 } else {
434 offset.y = 1.2/srcRes.y;
435 }
436
437 glUniform2f(bloom1Shader_.getUniformLocation("offset"), offset.x, offset.y);
438
439 glEnableVertexAttribArray(0);
440 glBindBuffer(GL_ARRAY_BUFFER, quadBuffer_.getId());
441 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
442 glDrawArrays(GL_TRIANGLES, 0, 6);
443 glDisableVertexAttribArray(0);
444}
445
446void Renderer::renderScreen(const Texture& tex)
447{
448 // First we're going to composite our frame with the previous frame
449 // We start by setting up the framebuffer
450 glBindFramebuffer(GL_FRAMEBUFFER, genericFb_.getId());
451 glFramebufferTexture(
452 GL_FRAMEBUFFER,
453 GL_COLOR_ATTACHMENT0,
454 renderPages_[curBuf_].getId(),
455 0);
456
457 // Set up the shader
458 glViewport(0,0,GAME_WIDTH,GAME_HEIGHT);
459 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
460 ntscShader_.use();
461
462 // Use the current frame texture, nearest neighbor and clamped to edge
463 glActiveTexture(GL_TEXTURE0);
464 glBindTexture(GL_TEXTURE_2D, tex.getId());
465 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
466 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
467 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
468 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
469 glUniform1i(ntscShader_.getUniformLocation("curFrameSampler"), 0);
470
471 // Use the previous frame composite texture, nearest neighbor and clamped to
472 // edge
473 glActiveTexture(GL_TEXTURE1);
474 glBindTexture(GL_TEXTURE_2D, renderPages_[(curBuf_ + 1) % 2].getId());
475 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
476 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
477 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
478 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
479 glUniform1i(ntscShader_.getUniformLocation("prevFrameSampler"), 1);
480
481 // Load the NTSC artifact texture
482 glActiveTexture(GL_TEXTURE2);
483 glBindTexture(GL_TEXTURE_2D, artifactsTex_.getId());
484 glUniform1i(ntscShader_.getUniformLocation("NTSCArtifactSampler"), 2);
485 glUniform1f(ntscShader_.getUniformLocation("NTSCLerp"), curBuf_ * 1.0);
486
487 // Change the 0.0 to a 1.0 or a 10.0 for a glitchy effect!
488 glUniform1f(ntscShader_.getUniformLocation("Tuning_NTSC"), 0.0);
489
490 // Render our composition
491 glEnableVertexAttribArray(0);
492 glBindBuffer(GL_ARRAY_BUFFER, quadBuffer_.getId());
493 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
494 glDrawArrays(GL_TRIANGLES, 0, 6);
495 glDisableVertexAttribArray(0);
496
497 // We're going to render the screen now
498 glBindFramebuffer(GL_FRAMEBUFFER, bloomFb_.getId());
499 glFramebufferTexture(
500 GL_FRAMEBUFFER,
501 GL_COLOR_ATTACHMENT1,
502 preBloomTex_.getId(),
503 0);
504
505 glViewport(0,0,width_,height_);
506 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
507 finalShader_.use();
508
509 // Use the composited frame texture, linearly filtered and filling in black
510 // for the border
511 glActiveTexture(GL_TEXTURE0);
512 glBindTexture(GL_TEXTURE_2D, renderPages_[curBuf_].getId());
513 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
514 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
515 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
516 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
517
518 float borderColor[] = {0.0f, 0.0f, 0.0f, 1.0f};
519 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
520
521 glGenerateMipmap(GL_TEXTURE_2D);
522 glUniform1i(finalShader_.getUniformLocation("rendertex"), 0);
523
524 // Use the scanlines texture
525 glActiveTexture(GL_TEXTURE1);
526 glBindTexture(GL_TEXTURE_2D, scanlinesTex_.getId());
527 glUniform1i(finalShader_.getUniformLocation("scanlinestex"), 1);
528
529 // Initialize the MVP matrices
530 glm::mat4 p_matrix = glm::perspective(
531 glm::radians(25.0f),
532 static_cast<float>(width_) / static_cast<float>(height_),
533 0.1f,
534 100.0f);
535
536 glm::mat4 v_matrix = glm::lookAt(
537 glm::vec3(3.75,0,0), // Camera
538 glm::vec3(0,0,0), // Center
539 glm::vec3(0,1,0)); // Up
540
541 glm::mat4 m_matrix = glm::mat4(1.0);
542 glm::mat4 mvp_matrix = p_matrix * v_matrix * m_matrix;
543
544 glUniformMatrix4fv(
545 finalShader_.getUniformLocation("MVP"),
546 1,
547 GL_FALSE,
548 &mvp_matrix[0][0]);
549
550 glUniformMatrix4fv(
551 finalShader_.getUniformLocation("worldMat"),
552 1,
553 GL_FALSE,
554 &m_matrix[0][0]);
555
556 glUniform2f(finalShader_.getUniformLocation("resolution"), width_, height_);
557 glUniform1f(finalShader_.getUniformLocation("iGlobalTime"), glfwGetTime());
558
559 glUniform3f(
560 finalShader_.getUniformLocation("frameColor"),
561 0.76f,
562 0.78f,
563 0.81f);
564
565 glEnableVertexAttribArray(0);
566 glBindBuffer(GL_ARRAY_BUFFER, monitor_.getVertexBufferId());
567 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
568
569 glEnableVertexAttribArray(1);
570 glBindBuffer(GL_ARRAY_BUFFER, monitor_.getNormalBufferId());
571 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
572
573 glEnableVertexAttribArray(2);
574 glBindBuffer(GL_ARRAY_BUFFER, monitor_.getUvBufferId());
575 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
576
577 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, monitor_.getIndexBufferId());
578 glDrawElements(
579 GL_TRIANGLES,
580 monitor_.getIndexCount(),
581 GL_UNSIGNED_SHORT,
582 nullptr);
583
584 glDisableVertexAttribArray(2);
585 glDisableVertexAttribArray(1);
586 glDisableVertexAttribArray(0);
587
588 // First pass of bloom!
589 glm::vec2 bufferSize = glm::vec2(width_, height_);
590
591 bloomPass1(
592 preBloomTex_,
593 bloomPassTex1_,
594 true,
595 bufferSize,
596 bufferSize / 4.0f);
597
598 bloomPass1(
599 bloomPassTex1_,
600 bloomPassTex2_,
601 false,
602 bufferSize / 4.0f,
603 bufferSize / 4.0f);
604
605 // Do the second pass of bloom and render to screen
606 glBindFramebuffer(GL_FRAMEBUFFER, 0);
607 glViewport(0, 0, width_, height_);
608 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
609 bloom2Shader_.use();
610
611 glActiveTexture(GL_TEXTURE0);
612 glBindTexture(GL_TEXTURE_2D, preBloomTex_.getId());
613 glUniform1i(bloom2Shader_.getUniformLocation("clearTex"), 0);
614
615 glActiveTexture(GL_TEXTURE1);
616 glBindTexture(GL_TEXTURE_2D, bloomPassTex2_.getId());
617 glUniform1i(bloom2Shader_.getUniformLocation("blurTex"), 1);
618
619 glUniform1f(bloom2Shader_.getUniformLocation("iGlobalTime"), glfwGetTime());
620
621 glEnableVertexAttribArray(0);
622 glBindBuffer(GL_ARRAY_BUFFER, quadBuffer_.getId());
623 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
624 glDrawArrays(GL_TRIANGLES, 0, 6);
625 glDisableVertexAttribArray(0);
626
627 glfwSwapBuffers(window_.getHandle());
628
629 curBuf_ = (curBuf_ + 1) % 2;
630}