💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
4.9 KiB

1 year ago
1 year ago
1 year ago
1 year ago
  1. /*
  2. * Copyright (C) 2023 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <engine/render/passes/final-pass.hpp>
  20. #include <engine/resources/resource-manager.hpp>
  21. #include <engine/gl/rasterizer.hpp>
  22. #include <engine/gl/framebuffer.hpp>
  23. #include <engine/gl/shader-program.hpp>
  24. #include <engine/gl/shader-variable.hpp>
  25. #include <engine/gl/vertex-buffer.hpp>
  26. #include <engine/gl/vertex-array.hpp>
  27. #include <engine/gl/vertex-attribute.hpp>
  28. #include <engine/gl/drawing-mode.hpp>
  29. #include <engine/gl/texture-2d.hpp>
  30. #include <engine/gl/texture-wrapping.hpp>
  31. #include <engine/gl/texture-filter.hpp>
  32. #include <engine/render/vertex-attribute.hpp>
  33. #include <engine/render/context.hpp>
  34. #include <cmath>
  35. #include <cstdint>
  36. #include <glad/glad.h>
  37. #include <engine/utility/hash/fnv1a.hpp>
  38. #include <engine/debug/log.hpp>
  39. namespace render {
  40. final_pass::final_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffer, resource_manager* resource_manager):
  41. pass(rasterizer, framebuffer),
  42. color_texture(nullptr),
  43. bloom_texture(nullptr),
  44. bloom_weight(0.04f),
  45. blue_noise_texture(nullptr),
  46. blue_noise_scale(1.0f)
  47. {
  48. // Load shader template and build shader program
  49. auto shader_template = resource_manager->load<gl::shader_template>("final.glsl");
  50. shader_program = shader_template->build();
  51. if (!shader_program->linked())
  52. {
  53. debug::log::error("Failed to final pass shader program: {}", shader_program->info());
  54. debug::log::warning("{}", shader_template->configure(gl::shader_stage::vertex));
  55. }
  56. }
  57. void final_pass::render(render::context& ctx)
  58. {
  59. // Update resolution
  60. const auto viewport_size = framebuffer->get_dimensions();
  61. resolution = {static_cast<float>(std::get<0>(viewport_size)), static_cast<float>(std::get<1>(viewport_size))};
  62. // Update time
  63. time = ctx.t;
  64. // Execute render commands
  65. for (const auto& command: command_buffer)
  66. {
  67. command();
  68. }
  69. // Increment current frame
  70. ++frame;
  71. }
  72. void final_pass::set_color_texture(const gl::texture_2d* texture)
  73. {
  74. this->color_texture = texture;
  75. rebuild_command_buffer();
  76. }
  77. void final_pass::set_bloom_texture(const gl::texture_2d* texture) noexcept
  78. {
  79. this->bloom_texture = texture;
  80. rebuild_command_buffer();
  81. }
  82. void final_pass::set_bloom_weight(float weight) noexcept
  83. {
  84. this->bloom_weight = weight;
  85. }
  86. void final_pass::set_blue_noise_texture(std::shared_ptr<gl::texture_2d> texture)
  87. {
  88. this->blue_noise_texture = texture;
  89. blue_noise_scale = 1.0f / static_cast<float>(texture->get_dimensions()[0]);
  90. rebuild_command_buffer();
  91. }
  92. void final_pass::rebuild_command_buffer()
  93. {
  94. command_buffer.clear();
  95. command_buffer.emplace_back
  96. (
  97. [&]()
  98. {
  99. rasterizer->use_framebuffer(*framebuffer);
  100. rasterizer->set_viewport(0, 0, static_cast<int>(resolution.x()), static_cast<int>(resolution.y()));
  101. glDisable(GL_BLEND);
  102. glDisable(GL_DEPTH_TEST);
  103. glDepthMask(GL_FALSE);
  104. glEnable(GL_CULL_FACE);
  105. glCullFace(GL_BACK);
  106. rasterizer->use_program(*shader_program);
  107. }
  108. );
  109. if (color_texture)
  110. {
  111. if (const auto var = shader_program->variable("color_texture"))
  112. {
  113. command_buffer.emplace_back([&, var](){var->update(*color_texture);});
  114. }
  115. }
  116. if (bloom_texture)
  117. {
  118. if (const auto var = shader_program->variable("bloom_texture"))
  119. {
  120. command_buffer.emplace_back([&, var](){var->update(*bloom_texture);});
  121. }
  122. }
  123. if (blue_noise_texture)
  124. {
  125. if (const auto var = shader_program->variable("blue_noise_texture"))
  126. {
  127. command_buffer.emplace_back([&, var](){var->update(*blue_noise_texture);});
  128. }
  129. }
  130. if (const auto var = shader_program->variable("bloom_weight"))
  131. {
  132. command_buffer.emplace_back([&, var](){var->update(bloom_weight);});
  133. }
  134. if (const auto var = shader_program->variable("blue_noise_scale"))
  135. {
  136. command_buffer.emplace_back([&, var](){var->update(blue_noise_scale);});
  137. }
  138. if (const auto var = shader_program->variable("resolution"))
  139. {
  140. command_buffer.emplace_back([&, var](){var->update(resolution);});
  141. }
  142. if (const auto var = shader_program->variable("time"))
  143. {
  144. command_buffer.emplace_back([&, var](){var->update(time);});
  145. }
  146. if (const auto frame_var = shader_program->variable("frame"))
  147. {
  148. command_buffer.emplace_back([&, frame_var](){frame_var->update(frame);});
  149. }
  150. command_buffer.emplace_back
  151. (
  152. [&]()
  153. {
  154. rasterizer->draw_arrays(gl::drawing_mode::triangles, 0, 3);
  155. }
  156. );
  157. }
  158. } // namespace render