glow.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /**************************************************************************/
  2. /* glow.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /**************************************************************************/
  30. #ifdef GLES3_ENABLED
  31. #include "glow.h"
  32. #include "../storage/texture_storage.h"
  33. using namespace GLES3;
  34. Glow *Glow::singleton = nullptr;
  35. Glow *Glow::get_singleton() {
  36. return singleton;
  37. }
  38. Glow::Glow() {
  39. singleton = this;
  40. glow.shader.initialize();
  41. glow.shader_version = glow.shader.version_create();
  42. { // Screen Triangle.
  43. glGenBuffers(1, &screen_triangle);
  44. glBindBuffer(GL_ARRAY_BUFFER, screen_triangle);
  45. const float qv[6] = {
  46. -1.0f,
  47. -1.0f,
  48. 3.0f,
  49. -1.0f,
  50. -1.0f,
  51. 3.0f,
  52. };
  53. glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6, qv, GL_STATIC_DRAW);
  54. glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
  55. glGenVertexArrays(1, &screen_triangle_array);
  56. glBindVertexArray(screen_triangle_array);
  57. glBindBuffer(GL_ARRAY_BUFFER, screen_triangle);
  58. glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);
  59. glEnableVertexAttribArray(RS::ARRAY_VERTEX);
  60. glBindVertexArray(0);
  61. glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
  62. }
  63. }
  64. Glow::~Glow() {
  65. glDeleteBuffers(1, &screen_triangle);
  66. glDeleteVertexArrays(1, &screen_triangle_array);
  67. glow.shader.version_free(glow.shader_version);
  68. singleton = nullptr;
  69. }
  70. void Glow::_draw_screen_triangle() {
  71. glBindVertexArray(screen_triangle_array);
  72. glDrawArrays(GL_TRIANGLES, 0, 3);
  73. glBindVertexArray(0);
  74. }
  75. void Glow::process_glow(GLuint p_source_color, Size2i p_size, const Glow::GLOWLEVEL *p_glow_buffers, uint32_t p_view, bool p_use_multiview) {
  76. ERR_FAIL_COND(p_source_color == 0);
  77. ERR_FAIL_COND(p_glow_buffers[3].color == 0);
  78. // Reset some OpenGL state...
  79. glDisable(GL_BLEND);
  80. glDisable(GL_DEPTH_TEST);
  81. glDepthMask(GL_FALSE);
  82. // Start with our filter pass
  83. {
  84. glBindFramebuffer(GL_FRAMEBUFFER, p_glow_buffers[0].fbo);
  85. glViewport(0, 0, p_glow_buffers[0].size.x, p_glow_buffers[0].size.y);
  86. glActiveTexture(GL_TEXTURE0);
  87. glBindTexture(p_use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D, p_source_color);
  88. uint64_t specialization = p_use_multiview ? GlowShaderGLES3::USE_MULTIVIEW : 0;
  89. bool success = glow.shader.version_bind_shader(glow.shader_version, GlowShaderGLES3::MODE_FILTER, specialization);
  90. if (!success) {
  91. return;
  92. }
  93. glow.shader.version_set_uniform(GlowShaderGLES3::PIXEL_SIZE, 1.0 / p_glow_buffers[0].size.x, 1.0 / p_glow_buffers[0].size.y, glow.shader_version, GlowShaderGLES3::MODE_FILTER, specialization);
  94. glow.shader.version_set_uniform(GlowShaderGLES3::VIEW, float(p_view), glow.shader_version, GlowShaderGLES3::MODE_FILTER, specialization);
  95. glow.shader.version_set_uniform(GlowShaderGLES3::LUMINANCE_MULTIPLIER, luminance_multiplier, glow.shader_version, GlowShaderGLES3::MODE_FILTER, specialization);
  96. glow.shader.version_set_uniform(GlowShaderGLES3::GLOW_BLOOM, glow_bloom, glow.shader_version, GlowShaderGLES3::MODE_FILTER, specialization);
  97. glow.shader.version_set_uniform(GlowShaderGLES3::GLOW_HDR_THRESHOLD, glow_hdr_bleed_threshold, glow.shader_version, GlowShaderGLES3::MODE_FILTER, specialization);
  98. glow.shader.version_set_uniform(GlowShaderGLES3::GLOW_HDR_SCALE, glow_hdr_bleed_scale, glow.shader_version, GlowShaderGLES3::MODE_FILTER, specialization);
  99. glow.shader.version_set_uniform(GlowShaderGLES3::GLOW_LUMINANCE_CAP, glow_hdr_luminance_cap, glow.shader_version, GlowShaderGLES3::MODE_FILTER, specialization);
  100. _draw_screen_triangle();
  101. }
  102. // Continue with downsampling
  103. {
  104. bool success = glow.shader.version_bind_shader(glow.shader_version, GlowShaderGLES3::MODE_DOWNSAMPLE, 0);
  105. if (!success) {
  106. return;
  107. }
  108. for (int i = 1; i < 4; i++) {
  109. glBindFramebuffer(GL_FRAMEBUFFER, p_glow_buffers[i].fbo);
  110. glViewport(0, 0, p_glow_buffers[i].size.x, p_glow_buffers[i].size.y);
  111. glActiveTexture(GL_TEXTURE0);
  112. glBindTexture(GL_TEXTURE_2D, p_glow_buffers[i - 1].color);
  113. glow.shader.version_set_uniform(GlowShaderGLES3::PIXEL_SIZE, 1.0 / p_glow_buffers[i].size.x, 1.0 / p_glow_buffers[i].size.y, glow.shader_version, GlowShaderGLES3::MODE_DOWNSAMPLE);
  114. _draw_screen_triangle();
  115. }
  116. }
  117. // Now upsample
  118. {
  119. bool success = glow.shader.version_bind_shader(glow.shader_version, GlowShaderGLES3::MODE_UPSAMPLE, 0);
  120. if (!success) {
  121. return;
  122. }
  123. for (int i = 2; i >= 0; i--) {
  124. glBindFramebuffer(GL_FRAMEBUFFER, p_glow_buffers[i].fbo);
  125. glViewport(0, 0, p_glow_buffers[i].size.x, p_glow_buffers[i].size.y);
  126. glActiveTexture(GL_TEXTURE0);
  127. glBindTexture(GL_TEXTURE_2D, p_glow_buffers[i + 1].color);
  128. glow.shader.version_set_uniform(GlowShaderGLES3::PIXEL_SIZE, 1.0 / p_glow_buffers[i].size.x, 1.0 / p_glow_buffers[i].size.y, glow.shader_version, GlowShaderGLES3::MODE_UPSAMPLE);
  129. _draw_screen_triangle();
  130. }
  131. }
  132. glDisable(GL_BLEND);
  133. glEnable(GL_DEPTH_TEST);
  134. glDepthMask(GL_TRUE);
  135. glUseProgram(0);
  136. glBindTexture(GL_TEXTURE_2D, 0);
  137. glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
  138. }
  139. #endif // GLES3_ENABLED