pipeline.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Copyright (c) 2012-2023 Daniele Bartolini et al.
  3. * SPDX-License-Identifier: MIT
  4. */
  5. #include "core/strings/string_id.inl"
  6. #include "core/types.h"
  7. #include "device/pipeline.h"
  8. #include "world/shader_manager.h"
  9. #include <bx/math.h>
  10. namespace crown
  11. {
  12. /*
  13. * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
  14. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  15. */
  16. struct PosTexCoord0Vertex
  17. {
  18. float m_x;
  19. float m_y;
  20. float m_z;
  21. float m_u;
  22. float m_v;
  23. static void init()
  24. {
  25. ms_layout.begin();
  26. ms_layout.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
  27. ms_layout.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
  28. ms_layout.end();
  29. }
  30. static bgfx::VertexLayout ms_layout;
  31. };
  32. bgfx::VertexLayout PosTexCoord0Vertex::ms_layout;
  33. /*
  34. * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
  35. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  36. */
  37. void screenSpaceQuad(float _textureWidth, float _textureHeight, float _texelHalf, bool _originBottomLeft, float _width = 1.0f, float _height = 1.0f)
  38. {
  39. if (3 == bgfx::getAvailTransientVertexBuffer(3, PosTexCoord0Vertex::ms_layout)) {
  40. bgfx::TransientVertexBuffer tvb;
  41. bgfx::allocTransientVertexBuffer(&tvb, 3, PosTexCoord0Vertex::ms_layout);
  42. PosTexCoord0Vertex *vertex = (PosTexCoord0Vertex *)tvb.data;
  43. const float minx = -_width;
  44. const float maxx = _width;
  45. const float miny = _height;
  46. const float maxy = -_height;
  47. const float texelHalfW = _texelHalf/_textureWidth;
  48. const float texelHalfH = _texelHalf/_textureHeight;
  49. const float minu = -1.0f + texelHalfW;
  50. const float maxu = 1.0f + texelHalfH;
  51. const float zz = 0.0f;
  52. float minv = texelHalfH;
  53. float maxv = 2.0f + texelHalfH;
  54. if (_originBottomLeft) {
  55. float temp = minv;
  56. minv = maxv;
  57. maxv = temp;
  58. minv -= 1.0f;
  59. maxv -= 1.0f;
  60. }
  61. vertex[0].m_x = maxx;
  62. vertex[0].m_y = maxy;
  63. vertex[0].m_z = zz;
  64. vertex[0].m_u = maxu;
  65. vertex[0].m_v = maxv;
  66. vertex[1].m_x = maxx;
  67. vertex[1].m_y = miny;
  68. vertex[1].m_z = zz;
  69. vertex[1].m_u = maxu;
  70. vertex[1].m_v = minv;
  71. vertex[2].m_x = minx;
  72. vertex[2].m_y = miny;
  73. vertex[2].m_z = zz;
  74. vertex[2].m_u = minu;
  75. vertex[2].m_v = minv;
  76. bgfx::setVertexBuffer(0, &tvb);
  77. }
  78. }
  79. Pipeline::Pipeline()
  80. : _main_color_texture(BGFX_INVALID_HANDLE)
  81. , _main_depth_texture(BGFX_INVALID_HANDLE)
  82. , _main_frame_buffer(BGFX_INVALID_HANDLE)
  83. , _main_color_texture_sampler(BGFX_INVALID_HANDLE)
  84. , _main_depth_texture_sampler(BGFX_INVALID_HANDLE)
  85. , _selection_texture(BGFX_INVALID_HANDLE)
  86. , _selection_depth_texture(BGFX_INVALID_HANDLE)
  87. , _selection_frame_buffer(BGFX_INVALID_HANDLE)
  88. , _selection_texture_sampler(BGFX_INVALID_HANDLE)
  89. , _selection_depth_texture_sampler(BGFX_INVALID_HANDLE)
  90. , _outline_color_uniform(BGFX_INVALID_HANDLE)
  91. {
  92. }
  93. void Pipeline::create(uint16_t width, uint16_t height)
  94. {
  95. reset(width, height);
  96. _main_color_texture_sampler = bgfx::createUniform("s_color", bgfx::UniformType::Sampler);
  97. _main_depth_texture_sampler = bgfx::createUniform("s_main_depth", bgfx::UniformType::Sampler);
  98. _selection_texture_sampler = bgfx::createUniform("s_selection", bgfx::UniformType::Sampler);
  99. _selection_depth_texture_sampler = bgfx::createUniform("s_selection_depth", bgfx::UniformType::Sampler);
  100. _outline_color_uniform = bgfx::createUniform("u_outline_color", bgfx::UniformType::Vec4);
  101. PosTexCoord0Vertex::init();
  102. }
  103. void Pipeline::destroy()
  104. {
  105. bgfx::destroy(_outline_color_uniform);
  106. bgfx::destroy(_selection_depth_texture_sampler);
  107. bgfx::destroy(_selection_texture_sampler);
  108. bgfx::destroy(_main_depth_texture_sampler);
  109. bgfx::destroy(_main_color_texture_sampler);
  110. bgfx::destroy(_selection_frame_buffer);
  111. bgfx::destroy(_selection_depth_texture);
  112. bgfx::destroy(_selection_texture);
  113. bgfx::destroy(_main_frame_buffer);
  114. bgfx::destroy(_main_depth_texture);
  115. bgfx::destroy(_main_color_texture);
  116. }
  117. void Pipeline::reset(u16 width, u16 height)
  118. {
  119. // Create main frame buffer.
  120. if (bgfx::isValid(_main_color_texture))
  121. bgfx::destroy(_main_color_texture);
  122. _main_color_texture = bgfx::createTexture2D(width
  123. , height
  124. , false
  125. , 1
  126. , bgfx::TextureFormat::BGRA8
  127. , BGFX_TEXTURE_RT
  128. );
  129. if (bgfx::isValid(_main_depth_texture))
  130. bgfx::destroy(_main_depth_texture);
  131. _main_depth_texture = bgfx::createTexture2D(width
  132. , height
  133. , false
  134. , 1
  135. , bgfx::TextureFormat::D24S8
  136. , BGFX_TEXTURE_RT
  137. );
  138. const bgfx::TextureHandle _main_frame_buffer_attachments[] =
  139. {
  140. _main_color_texture,
  141. _main_depth_texture
  142. };
  143. if (bgfx::isValid(_main_frame_buffer))
  144. bgfx::destroy(_main_frame_buffer);
  145. _main_frame_buffer = bgfx::createFrameBuffer(countof(_main_frame_buffer_attachments), _main_frame_buffer_attachments);
  146. // Create outline frame buffer.
  147. if (bgfx::isValid(_selection_texture))
  148. bgfx::destroy(_selection_texture);
  149. _selection_texture = bgfx::createTexture2D(width
  150. , height
  151. , false
  152. , 1
  153. , bgfx::TextureFormat::R32U
  154. , BGFX_TEXTURE_RT
  155. );
  156. if (bgfx::isValid(_selection_depth_texture))
  157. bgfx::destroy(_selection_depth_texture);
  158. _selection_depth_texture = bgfx::createTexture2D(width
  159. , height
  160. , false
  161. , 1
  162. , bgfx::TextureFormat::D24
  163. , BGFX_TEXTURE_RT
  164. );
  165. const bgfx::TextureHandle _selection_frame_buffer_attachments[] =
  166. {
  167. _selection_texture,
  168. _selection_depth_texture
  169. };
  170. if (bgfx::isValid(_selection_frame_buffer))
  171. bgfx::destroy(_selection_frame_buffer);
  172. _selection_frame_buffer = bgfx::createFrameBuffer(countof(_selection_frame_buffer_attachments), _selection_frame_buffer_attachments);
  173. }
  174. void Pipeline::render(ShaderManager &sm, StringId32 program, u8 view, u16 width, u16 height)
  175. {
  176. const bgfx::Caps *caps = bgfx::getCaps();
  177. f32 ortho[16];
  178. bx::mtxOrtho(ortho, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 100.0f, 0.0f, caps->homogeneousDepth);
  179. bgfx::setViewRect(view, 0, 0, width, height);
  180. bgfx::setViewTransform(view, NULL, ortho);
  181. const u32 samplerFlags = 0
  182. | BGFX_SAMPLER_MIN_POINT
  183. | BGFX_SAMPLER_MAG_POINT
  184. | BGFX_SAMPLER_MIP_POINT
  185. | BGFX_SAMPLER_U_CLAMP
  186. | BGFX_SAMPLER_V_CLAMP
  187. ;
  188. bgfx::setTexture(0, _main_color_texture_sampler, _main_color_texture, samplerFlags);
  189. screenSpaceQuad(width, height, 0.0f, caps->originBottomLeft);
  190. sm.submit(program, view, 0, UINT64_MAX);
  191. bgfx::setTexture(0, _selection_texture_sampler, _selection_texture, samplerFlags);
  192. bgfx::setTexture(1, _selection_depth_texture_sampler, _selection_depth_texture, samplerFlags);
  193. bgfx::setTexture(2, _main_depth_texture_sampler, _main_depth_texture, samplerFlags);
  194. screenSpaceQuad(width, height, 0.0f, caps->originBottomLeft);
  195. const f32 outline_color[] = { 1.0f, 0.37f, 0.05f, 1.0f };
  196. bgfx::setUniform(_outline_color_uniform, outline_color);
  197. sm.submit(STRING_ID_32("outline", UINT32_C(0x57fddcc9)), view, 0, UINT64_MAX);
  198. }
  199. } // namespace crown