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