stencil.cpp 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402
  1. /*
  2. * Copyright 2013-2014 Dario Manesku. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  4. */
  5. #include <string>
  6. #include <vector>
  7. #include "common.h"
  8. #include "bgfx_utils.h"
  9. #include <bx/crtimpl.h>
  10. #include "camera.h"
  11. #include "imgui/imgui.h"
  12. #define RENDER_VIEWID_RANGE1_PASS_0 1
  13. #define RENDER_VIEWID_RANGE1_PASS_1 2
  14. #define RENDER_VIEWID_RANGE1_PASS_2 3
  15. #define RENDER_VIEWID_RANGE1_PASS_3 4
  16. #define RENDER_VIEWID_RANGE1_PASS_4 5
  17. #define RENDER_VIEWID_RANGE1_PASS_5 6
  18. #define RENDER_VIEWID_RANGE5_PASS_6 7
  19. #define RENDER_VIEWID_RANGE1_PASS_7 13
  20. #define MAX_NUM_LIGHTS 5
  21. uint32_t packUint32(uint8_t _x, uint8_t _y, uint8_t _z, uint8_t _w)
  22. {
  23. union
  24. {
  25. uint32_t ui32;
  26. uint8_t arr[4];
  27. } un;
  28. un.arr[0] = _x;
  29. un.arr[1] = _y;
  30. un.arr[2] = _z;
  31. un.arr[3] = _w;
  32. return un.ui32;
  33. }
  34. uint32_t packF4u(float _x, float _y = 0.0f, float _z = 0.0f, float _w = 0.0f)
  35. {
  36. const uint8_t xx = uint8_t(_x*127.0f + 128.0f);
  37. const uint8_t yy = uint8_t(_y*127.0f + 128.0f);
  38. const uint8_t zz = uint8_t(_z*127.0f + 128.0f);
  39. const uint8_t ww = uint8_t(_w*127.0f + 128.0f);
  40. return packUint32(xx, yy, zz, ww);
  41. }
  42. struct PosNormalTexcoordVertex
  43. {
  44. float m_x;
  45. float m_y;
  46. float m_z;
  47. uint32_t m_normal;
  48. float m_u;
  49. float m_v;
  50. static void init()
  51. {
  52. ms_decl
  53. .begin()
  54. .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
  55. .add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true)
  56. .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
  57. .end();
  58. }
  59. static bgfx::VertexDecl ms_decl;
  60. };
  61. bgfx::VertexDecl PosNormalTexcoordVertex::ms_decl;
  62. static const float s_texcoord = 5.0f;
  63. static PosNormalTexcoordVertex s_hplaneVertices[] =
  64. {
  65. { -1.0f, 0.0f, 1.0f, packF4u(0.0f, 1.0f, 0.0f), s_texcoord, s_texcoord },
  66. { 1.0f, 0.0f, 1.0f, packF4u(0.0f, 1.0f, 0.0f), s_texcoord, 0.0f },
  67. { -1.0f, 0.0f, -1.0f, packF4u(0.0f, 1.0f, 0.0f), 0.0f, s_texcoord },
  68. { 1.0f, 0.0f, -1.0f, packF4u(0.0f, 1.0f, 0.0f), 0.0f, 0.0f },
  69. };
  70. static PosNormalTexcoordVertex s_vplaneVertices[] =
  71. {
  72. { -1.0f, 1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 1.0f, 1.0f },
  73. { 1.0f, 1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 1.0f, 0.0f },
  74. { -1.0f, -1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 0.0f, 1.0f },
  75. { 1.0f, -1.0f, 0.0f, packF4u(0.0f, 0.0f, -1.0f), 0.0f, 0.0f },
  76. };
  77. static const PosNormalTexcoordVertex s_cubeVertices[] =
  78. {
  79. { -1.0f, 1.0f, 1.0f, packF4u( 0.0f, 1.0f, 0.0f), 1.0f, 1.0f },
  80. { 1.0f, 1.0f, 1.0f, packF4u( 0.0f, 1.0f, 0.0f), 0.0f, 1.0f },
  81. { -1.0f, 1.0f, -1.0f, packF4u( 0.0f, 1.0f, 0.0f), 1.0f, 0.0f },
  82. { 1.0f, 1.0f, -1.0f, packF4u( 0.0f, 1.0f, 0.0f), 0.0f, 0.0f },
  83. { -1.0f, -1.0f, 1.0f, packF4u( 0.0f, -1.0f, 0.0f), 1.0f, 1.0f },
  84. { 1.0f, -1.0f, 1.0f, packF4u( 0.0f, -1.0f, 0.0f), 0.0f, 1.0f },
  85. { -1.0f, -1.0f, -1.0f, packF4u( 0.0f, -1.0f, 0.0f), 1.0f, 0.0f },
  86. { 1.0f, -1.0f, -1.0f, packF4u( 0.0f, -1.0f, 0.0f), 0.0f, 0.0f },
  87. { 1.0f, -1.0f, 1.0f, packF4u( 0.0f, 0.0f, 1.0f), 0.0f, 0.0f },
  88. { 1.0f, 1.0f, 1.0f, packF4u( 0.0f, 0.0f, 1.0f), 0.0f, 1.0f },
  89. { -1.0f, -1.0f, 1.0f, packF4u( 0.0f, 0.0f, 1.0f), 1.0f, 0.0f },
  90. { -1.0f, 1.0f, 1.0f, packF4u( 0.0f, 0.0f, 1.0f), 1.0f, 1.0f },
  91. { 1.0f, -1.0f, -1.0f, packF4u( 0.0f, 0.0f, -1.0f), 0.0f, 0.0f },
  92. { 1.0f, 1.0f, -1.0f, packF4u( 0.0f, 0.0f, -1.0f), 0.0f, 1.0f },
  93. { -1.0f, -1.0f, -1.0f, packF4u( 0.0f, 0.0f, -1.0f), 1.0f, 0.0f },
  94. { -1.0f, 1.0f, -1.0f, packF4u( 0.0f, 0.0f, -1.0f), 1.0f, 1.0f },
  95. { 1.0f, 1.0f, -1.0f, packF4u( 1.0f, 0.0f, 0.0f), 1.0f, 1.0f },
  96. { 1.0f, 1.0f, 1.0f, packF4u( 1.0f, 0.0f, 0.0f), 0.0f, 1.0f },
  97. { 1.0f, -1.0f, -1.0f, packF4u( 1.0f, 0.0f, 0.0f), 1.0f, 0.0f },
  98. { 1.0f, -1.0f, 1.0f, packF4u( 1.0f, 0.0f, 0.0f), 0.0f, 0.0f },
  99. { -1.0f, 1.0f, -1.0f, packF4u(-1.0f, 0.0f, 0.0f), 1.0f, 1.0f },
  100. { -1.0f, 1.0f, 1.0f, packF4u(-1.0f, 0.0f, 0.0f), 0.0f, 1.0f },
  101. { -1.0f, -1.0f, -1.0f, packF4u(-1.0f, 0.0f, 0.0f), 1.0f, 0.0f },
  102. { -1.0f, -1.0f, 1.0f, packF4u(-1.0f, 0.0f, 0.0f), 0.0f, 0.0f },
  103. };
  104. static const uint16_t s_cubeIndices[] =
  105. {
  106. 0, 1, 2,
  107. 1, 3, 2,
  108. 4, 6, 5,
  109. 5, 6, 7,
  110. 8, 9, 10,
  111. 9, 11, 10,
  112. 12, 14, 13,
  113. 13, 14, 15,
  114. 16, 17, 18,
  115. 17, 19, 18,
  116. 20, 22, 21,
  117. 21, 22, 23,
  118. };
  119. static const uint16_t s_planeIndices[] =
  120. {
  121. 0, 1, 2,
  122. 1, 3, 2,
  123. };
  124. static bool s_flipV = false;
  125. static uint32_t s_viewMask = 0;
  126. static uint32_t s_clearMask = 0;
  127. static bgfx::UniformHandle s_texColor;
  128. inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far)
  129. {
  130. bx::mtxProj(_result, _fovy, _aspect, _near, _far, s_flipV);
  131. }
  132. void setViewClearMask(uint32_t _viewMask, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
  133. {
  134. for (uint32_t view = 0, viewMask = _viewMask, ntz = bx::uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, view += 1, ntz = bx::uint32_cnttz(viewMask) )
  135. {
  136. viewMask >>= ntz;
  137. view += ntz;
  138. bgfx::setViewClear( (uint8_t)view, _flags, _rgba, _depth, _stencil);
  139. }
  140. }
  141. void setViewTransformMask(uint32_t _viewMask, const void* _view, const void* _proj)
  142. {
  143. for (uint32_t view = 0, viewMask = _viewMask, ntz = bx::uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, view += 1, ntz = bx::uint32_cnttz(viewMask) )
  144. {
  145. viewMask >>= ntz;
  146. view += ntz;
  147. bgfx::setViewTransform( (uint8_t)view, _view, _proj);
  148. }
  149. }
  150. void setViewRectMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height)
  151. {
  152. for (uint32_t view = 0, viewMask = _viewMask, ntz = bx::uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, view += 1, ntz = bx::uint32_cnttz(viewMask) )
  153. {
  154. viewMask >>= ntz;
  155. view += ntz;
  156. bgfx::setViewRect( (uint8_t)view, _x, _y, _width, _height);
  157. }
  158. }
  159. void mtxReflected(float*__restrict _result
  160. , const float* __restrict _p /* plane */
  161. , const float* __restrict _n /* normal */
  162. )
  163. {
  164. float dot = bx::vec3Dot(_p, _n);
  165. _result[ 0] = 1.0f - 2.0f * _n[0] * _n[0]; //1-2Nx^2
  166. _result[ 1] = -2.0f * _n[0] * _n[1]; //-2*Nx*Ny
  167. _result[ 2] = -2.0f * _n[0] * _n[2]; //-2*NxNz
  168. _result[ 3] = 0.0f; //0
  169. _result[ 4] = -2.0f * _n[0] * _n[1]; //-2*NxNy
  170. _result[ 5] = 1.0f - 2.0f * _n[1] * _n[1]; //1-2*Ny^2
  171. _result[ 6] = -2.0f * _n[1] * _n[2]; //-2*NyNz
  172. _result[ 7] = 0.0f; //0
  173. _result[ 8] = -2.0f * _n[0] * _n[2]; //-2*NxNz
  174. _result[ 9] = -2.0f * _n[1] * _n[2]; //-2NyNz
  175. _result[10] = 1.0f - 2.0f * _n[2] * _n[2]; //1-2*Nz^2
  176. _result[11] = 0.0f; //0
  177. _result[12] = 2.0f * dot * _n[0]; //2*dot*Nx
  178. _result[13] = 2.0f * dot * _n[1]; //2*dot*Ny
  179. _result[14] = 2.0f * dot * _n[2]; //2*dot*Nz
  180. _result[15] = 1.0f; //1
  181. }
  182. void mtxShadow(float* __restrict _result
  183. , const float* __restrict _ground
  184. , const float* __restrict _light
  185. )
  186. {
  187. float dot = _ground[0] * _light[0]
  188. + _ground[1] * _light[1]
  189. + _ground[2] * _light[2]
  190. + _ground[3] * _light[3]
  191. ;
  192. _result[ 0] = dot - _light[0] * _ground[0];
  193. _result[ 1] = 0.0f - _light[1] * _ground[0];
  194. _result[ 2] = 0.0f - _light[2] * _ground[0];
  195. _result[ 3] = 0.0f - _light[3] * _ground[0];
  196. _result[ 4] = 0.0f - _light[0] * _ground[1];
  197. _result[ 5] = dot - _light[1] * _ground[1];
  198. _result[ 6] = 0.0f - _light[2] * _ground[1];
  199. _result[ 7] = 0.0f - _light[3] * _ground[1];
  200. _result[ 8] = 0.0f - _light[0] * _ground[2];
  201. _result[ 9] = 0.0f - _light[1] * _ground[2];
  202. _result[10] = dot - _light[2] * _ground[2];
  203. _result[11] = 0.0f - _light[3] * _ground[2];
  204. _result[12] = 0.0f - _light[0] * _ground[3];
  205. _result[13] = 0.0f - _light[1] * _ground[3];
  206. _result[14] = 0.0f - _light[2] * _ground[3];
  207. _result[15] = dot - _light[3] * _ground[3];
  208. }
  209. void mtxBillboard(float* __restrict _result
  210. , const float* __restrict _view
  211. , const float* __restrict _pos
  212. , const float* __restrict _scale)
  213. {
  214. _result[ 0] = _view[0] * _scale[0];
  215. _result[ 1] = _view[4] * _scale[0];
  216. _result[ 2] = _view[8] * _scale[0];
  217. _result[ 3] = 0.0f;
  218. _result[ 4] = _view[1] * _scale[1];
  219. _result[ 5] = _view[5] * _scale[1];
  220. _result[ 6] = _view[9] * _scale[1];
  221. _result[ 7] = 0.0f;
  222. _result[ 8] = _view[2] * _scale[2];
  223. _result[ 9] = _view[6] * _scale[2];
  224. _result[10] = _view[10] * _scale[2];
  225. _result[11] = 0.0f;
  226. _result[12] = _pos[0];
  227. _result[13] = _pos[1];
  228. _result[14] = _pos[2];
  229. _result[15] = 1.0f;
  230. }
  231. struct Uniforms
  232. {
  233. void init()
  234. {
  235. m_params.m_ambientPass = 1.0f;
  236. m_params.m_lightingPass = 1.0f;
  237. m_params.m_lightCount = 4.0f;
  238. m_params.m_lightIndex = 4.0f;
  239. m_ambient[0] = 0.02f;
  240. m_ambient[1] = 0.02f;
  241. m_ambient[2] = 0.02f;
  242. m_ambient[3] = 0.0f; //unused
  243. m_diffuse[0] = 0.2f;
  244. m_diffuse[1] = 0.2f;
  245. m_diffuse[2] = 0.2f;
  246. m_diffuse[3] = 0.0f; //unused
  247. m_specular_shininess[0] = 1.0f;
  248. m_specular_shininess[1] = 1.0f;
  249. m_specular_shininess[2] = 1.0f;
  250. m_specular_shininess[3] = 10.0f; //shininess
  251. m_color[0] = 1.0f;
  252. m_color[1] = 1.0f;
  253. m_color[2] = 1.0f;
  254. m_color[3] = 1.0f;
  255. m_time = 0.0f;
  256. for (uint8_t ii = 0; ii < MAX_NUM_LIGHTS; ++ii)
  257. {
  258. m_lightPosRadius[ii][0] = 0.0f;
  259. m_lightPosRadius[ii][1] = 0.0f;
  260. m_lightPosRadius[ii][2] = 0.0f;
  261. m_lightPosRadius[ii][3] = 1.0f;
  262. m_lightRgbInnerR[ii][0] = 1.0f;
  263. m_lightRgbInnerR[ii][1] = 1.0f;
  264. m_lightRgbInnerR[ii][2] = 1.0f;
  265. m_lightRgbInnerR[ii][3] = 1.0f;
  266. }
  267. u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4);
  268. u_ambient = bgfx::createUniform("u_ambient", bgfx::UniformType::Vec4);
  269. u_diffuse = bgfx::createUniform("u_diffuse", bgfx::UniformType::Vec4);
  270. u_specular_shininess = bgfx::createUniform("u_specular_shininess", bgfx::UniformType::Vec4);
  271. u_color = bgfx::createUniform("u_color", bgfx::UniformType::Vec4);
  272. u_lightPosRadius = bgfx::createUniform("u_lightPosRadius", bgfx::UniformType::Vec4, MAX_NUM_LIGHTS);
  273. u_lightRgbInnerR = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Vec4, MAX_NUM_LIGHTS);
  274. }
  275. //call this once at initialization
  276. void submitConstUniforms()
  277. {
  278. bgfx::setUniform(u_ambient, &m_ambient);
  279. bgfx::setUniform(u_diffuse, &m_diffuse);
  280. bgfx::setUniform(u_specular_shininess, &m_specular_shininess);
  281. }
  282. //call this before each draw call
  283. void submitPerDrawUniforms()
  284. {
  285. bgfx::setUniform(u_params, &m_params);
  286. bgfx::setUniform(u_color, &m_color);
  287. bgfx::setUniform(u_lightPosRadius, &m_lightPosRadius, MAX_NUM_LIGHTS);
  288. bgfx::setUniform(u_lightRgbInnerR, &m_lightRgbInnerR, MAX_NUM_LIGHTS);
  289. }
  290. void destroy()
  291. {
  292. bgfx::destroyUniform(u_params);
  293. bgfx::destroyUniform(u_ambient);
  294. bgfx::destroyUniform(u_diffuse);
  295. bgfx::destroyUniform(u_specular_shininess);
  296. bgfx::destroyUniform(u_color);
  297. bgfx::destroyUniform(u_lightPosRadius);
  298. bgfx::destroyUniform(u_lightRgbInnerR);
  299. }
  300. struct Params
  301. {
  302. float m_ambientPass;
  303. float m_lightingPass;
  304. float m_lightCount;
  305. float m_lightIndex;
  306. };
  307. struct SvParams
  308. {
  309. float m_useStencilTex;
  310. float m_dfail;
  311. float m_unused0;
  312. float m_unused1;
  313. };
  314. Params m_params;
  315. SvParams m_svparams;
  316. float m_ambient[4];
  317. float m_diffuse[4];
  318. float m_specular_shininess[4];
  319. float m_color[4];
  320. float m_time;
  321. float m_lightPosRadius[MAX_NUM_LIGHTS][4];
  322. float m_lightRgbInnerR[MAX_NUM_LIGHTS][4];
  323. /**
  324. * u_params.x - u_ambientPass
  325. * u_params.y - u_lightingPass
  326. * u_params.z - u_lightCount
  327. * u_params.w - u_lightIndex
  328. */
  329. bgfx::UniformHandle u_params;
  330. bgfx::UniformHandle u_ambient;
  331. bgfx::UniformHandle u_diffuse;
  332. bgfx::UniformHandle u_specular_shininess;
  333. bgfx::UniformHandle u_color;
  334. bgfx::UniformHandle u_lightPosRadius;
  335. bgfx::UniformHandle u_lightRgbInnerR;
  336. };
  337. static Uniforms s_uniforms;
  338. //-------------------------------------------------
  339. // Render state
  340. //-------------------------------------------------
  341. struct RenderState
  342. {
  343. enum Enum
  344. {
  345. StencilReflection_CraftStencil = 0,
  346. StencilReflection_DrawReflected,
  347. StencilReflection_BlendPlane,
  348. StencilReflection_DrawScene,
  349. ProjectionShadows_DrawAmbient,
  350. ProjectionShadows_CraftStencil,
  351. ProjectionShadows_DrawDiffuse,
  352. Custom_BlendLightTexture,
  353. Custom_DrawPlaneBottom,
  354. Count
  355. };
  356. uint64_t m_state;
  357. uint32_t m_blendFactorRgba;
  358. uint32_t m_fstencil;
  359. uint32_t m_bstencil;
  360. };
  361. static RenderState s_renderStates[RenderState::Count] =
  362. {
  363. { // StencilReflection_CraftStencil
  364. BGFX_STATE_RGB_WRITE
  365. | BGFX_STATE_DEPTH_WRITE
  366. | BGFX_STATE_DEPTH_TEST_LESS
  367. | BGFX_STATE_MSAA
  368. , UINT32_MAX
  369. , BGFX_STENCIL_TEST_ALWAYS // pass always
  370. | BGFX_STENCIL_FUNC_REF(1) // value = 1
  371. | BGFX_STENCIL_FUNC_RMASK(0xff)
  372. | BGFX_STENCIL_OP_FAIL_S_REPLACE
  373. | BGFX_STENCIL_OP_FAIL_Z_REPLACE
  374. | BGFX_STENCIL_OP_PASS_Z_REPLACE // store the value
  375. , BGFX_STENCIL_NONE
  376. },
  377. { // StencilReflection_DrawReflected
  378. BGFX_STATE_RGB_WRITE
  379. | BGFX_STATE_ALPHA_WRITE
  380. | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
  381. | BGFX_STATE_DEPTH_WRITE
  382. | BGFX_STATE_DEPTH_TEST_LESS
  383. | BGFX_STATE_CULL_CW //reflection matrix has inverted normals. using CCW instead of CW.
  384. | BGFX_STATE_MSAA
  385. , UINT32_MAX
  386. , BGFX_STENCIL_TEST_EQUAL
  387. | BGFX_STENCIL_FUNC_REF(1)
  388. | BGFX_STENCIL_FUNC_RMASK(1)
  389. | BGFX_STENCIL_OP_FAIL_S_KEEP
  390. | BGFX_STENCIL_OP_FAIL_Z_KEEP
  391. | BGFX_STENCIL_OP_PASS_Z_KEEP
  392. , BGFX_STENCIL_NONE
  393. },
  394. { // StencilReflection_BlendPlane
  395. BGFX_STATE_RGB_WRITE
  396. | BGFX_STATE_DEPTH_WRITE
  397. | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_SRC_COLOR)
  398. | BGFX_STATE_DEPTH_TEST_LESS
  399. | BGFX_STATE_CULL_CCW
  400. | BGFX_STATE_MSAA
  401. , UINT32_MAX
  402. , BGFX_STENCIL_NONE
  403. , BGFX_STENCIL_NONE
  404. },
  405. { // StencilReflection_DrawScene
  406. BGFX_STATE_RGB_WRITE
  407. | BGFX_STATE_DEPTH_WRITE
  408. | BGFX_STATE_DEPTH_TEST_LESS
  409. | BGFX_STATE_CULL_CCW
  410. | BGFX_STATE_MSAA
  411. , UINT32_MAX
  412. , BGFX_STENCIL_NONE
  413. , BGFX_STENCIL_NONE
  414. },
  415. { // ProjectionShadows_DrawAmbient
  416. BGFX_STATE_RGB_WRITE
  417. | BGFX_STATE_DEPTH_WRITE // write depth !
  418. | BGFX_STATE_DEPTH_TEST_LESS
  419. | BGFX_STATE_CULL_CCW
  420. | BGFX_STATE_MSAA
  421. , UINT32_MAX
  422. , BGFX_STENCIL_NONE
  423. , BGFX_STENCIL_NONE
  424. },
  425. { // ProjectionShadows_CraftStencil
  426. BGFX_STATE_DEPTH_TEST_LESS
  427. | BGFX_STATE_MSAA
  428. , UINT32_MAX
  429. , BGFX_STENCIL_TEST_ALWAYS // pass always
  430. | BGFX_STENCIL_FUNC_REF(1) // value = 1
  431. | BGFX_STENCIL_FUNC_RMASK(0xff)
  432. | BGFX_STENCIL_OP_FAIL_S_KEEP
  433. | BGFX_STENCIL_OP_FAIL_Z_KEEP
  434. | BGFX_STENCIL_OP_PASS_Z_REPLACE // store the value
  435. , BGFX_STENCIL_NONE
  436. },
  437. { // ProjectionShadows_DrawDiffuse
  438. BGFX_STATE_RGB_WRITE
  439. | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE)
  440. | BGFX_STATE_DEPTH_TEST_EQUAL
  441. | BGFX_STATE_CULL_CCW
  442. | BGFX_STATE_MSAA
  443. , UINT32_MAX
  444. , BGFX_STENCIL_TEST_NOTEQUAL
  445. | BGFX_STENCIL_FUNC_REF(1)
  446. | BGFX_STENCIL_FUNC_RMASK(1)
  447. | BGFX_STENCIL_OP_FAIL_S_KEEP
  448. | BGFX_STENCIL_OP_FAIL_Z_KEEP
  449. | BGFX_STENCIL_OP_PASS_Z_KEEP
  450. , BGFX_STENCIL_NONE
  451. },
  452. { // Custom_BlendLightTexture
  453. BGFX_STATE_RGB_WRITE
  454. | BGFX_STATE_ALPHA_WRITE
  455. | BGFX_STATE_DEPTH_WRITE
  456. | BGFX_STATE_DEPTH_TEST_LESS
  457. | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_COLOR, BGFX_STATE_BLEND_INV_SRC_COLOR)
  458. | BGFX_STATE_CULL_CCW
  459. | BGFX_STATE_MSAA
  460. , UINT32_MAX
  461. , BGFX_STENCIL_NONE
  462. , BGFX_STENCIL_NONE
  463. },
  464. { // Custom_DrawPlaneBottom
  465. BGFX_STATE_RGB_WRITE
  466. | BGFX_STATE_CULL_CW
  467. | BGFX_STATE_MSAA
  468. , UINT32_MAX
  469. , BGFX_STENCIL_NONE
  470. , BGFX_STENCIL_NONE
  471. },
  472. };
  473. struct ViewState
  474. {
  475. ViewState(uint32_t _width = 1280, uint32_t _height = 720)
  476. : m_width(_width)
  477. , m_height(_height)
  478. {
  479. }
  480. uint32_t m_width;
  481. uint32_t m_height;
  482. float m_view[16];
  483. float m_proj[16];
  484. };
  485. struct ClearValues
  486. {
  487. ClearValues(uint32_t _clearRgba = 0x30303000
  488. , float _clearDepth = 1.0f
  489. , uint8_t _clearStencil = 0
  490. )
  491. : m_clearRgba(_clearRgba)
  492. , m_clearDepth(_clearDepth)
  493. , m_clearStencil(_clearStencil)
  494. { }
  495. uint32_t m_clearRgba;
  496. float m_clearDepth;
  497. uint8_t m_clearStencil;
  498. };
  499. void clearView(uint8_t _id, uint8_t _flags, const ClearValues& _clearValues)
  500. {
  501. bgfx::setViewClear(_id
  502. , _flags
  503. , _clearValues.m_clearRgba
  504. , _clearValues.m_clearDepth
  505. , _clearValues.m_clearStencil
  506. );
  507. // Keep track of cleared views
  508. s_clearMask |= 1 << _id;
  509. }
  510. void clearViewMask(uint32_t _viewMask, uint8_t _flags, const ClearValues& _clearValues)
  511. {
  512. setViewClearMask(_viewMask
  513. , _flags
  514. , _clearValues.m_clearRgba
  515. , _clearValues.m_clearDepth
  516. , _clearValues.m_clearStencil
  517. );
  518. // Keep track of cleared views
  519. s_clearMask |= _viewMask;
  520. }
  521. struct Aabb
  522. {
  523. float m_min[3];
  524. float m_max[3];
  525. };
  526. struct Obb
  527. {
  528. float m_mtx[16];
  529. };
  530. struct Sphere
  531. {
  532. float m_center[3];
  533. float m_radius;
  534. };
  535. struct Primitive
  536. {
  537. uint32_t m_startIndex;
  538. uint32_t m_numIndices;
  539. uint32_t m_startVertex;
  540. uint32_t m_numVertices;
  541. Sphere m_sphere;
  542. Aabb m_aabb;
  543. Obb m_obb;
  544. };
  545. typedef std::vector<Primitive> PrimitiveArray;
  546. struct Group
  547. {
  548. Group()
  549. {
  550. reset();
  551. }
  552. void reset()
  553. {
  554. m_vbh.idx = bgfx::invalidHandle;
  555. m_ibh.idx = bgfx::invalidHandle;
  556. m_prims.clear();
  557. }
  558. bgfx::VertexBufferHandle m_vbh;
  559. bgfx::IndexBufferHandle m_ibh;
  560. Sphere m_sphere;
  561. Aabb m_aabb;
  562. Obb m_obb;
  563. PrimitiveArray m_prims;
  564. };
  565. namespace bgfx
  566. {
  567. int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL);
  568. }
  569. struct Mesh
  570. {
  571. void load(const void* _vertices, uint32_t _numVertices, const bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices)
  572. {
  573. Group group;
  574. const bgfx::Memory* mem;
  575. uint32_t size;
  576. size = _numVertices*_decl.getStride();
  577. mem = bgfx::makeRef(_vertices, size);
  578. group.m_vbh = bgfx::createVertexBuffer(mem, _decl);
  579. size = _numIndices*2;
  580. mem = bgfx::makeRef(_indices, size);
  581. group.m_ibh = bgfx::createIndexBuffer(mem);
  582. m_groups.push_back(group);
  583. }
  584. void load(const char* _filePath)
  585. {
  586. #define BGFX_CHUNK_MAGIC_VB BX_MAKEFOURCC('V', 'B', ' ', 0x1)
  587. #define BGFX_CHUNK_MAGIC_IB BX_MAKEFOURCC('I', 'B', ' ', 0x0)
  588. #define BGFX_CHUNK_MAGIC_PRI BX_MAKEFOURCC('P', 'R', 'I', 0x0)
  589. bx::FileReaderI* reader = entry::getFileReader();
  590. bx::open(reader, _filePath);
  591. Group group;
  592. uint32_t chunk;
  593. while (4 == bx::read(reader, chunk) )
  594. {
  595. switch (chunk)
  596. {
  597. case BGFX_CHUNK_MAGIC_VB:
  598. {
  599. bx::read(reader, group.m_sphere);
  600. bx::read(reader, group.m_aabb);
  601. bx::read(reader, group.m_obb);
  602. bgfx::read(reader, m_decl);
  603. uint16_t stride = m_decl.getStride();
  604. uint16_t numVertices;
  605. bx::read(reader, numVertices);
  606. const bgfx::Memory* mem = bgfx::alloc(numVertices*stride);
  607. bx::read(reader, mem->data, mem->size);
  608. group.m_vbh = bgfx::createVertexBuffer(mem, m_decl);
  609. }
  610. break;
  611. case BGFX_CHUNK_MAGIC_IB:
  612. {
  613. uint32_t numIndices;
  614. bx::read(reader, numIndices);
  615. const bgfx::Memory* mem = bgfx::alloc(numIndices*2);
  616. bx::read(reader, mem->data, mem->size);
  617. group.m_ibh = bgfx::createIndexBuffer(mem);
  618. }
  619. break;
  620. case BGFX_CHUNK_MAGIC_PRI:
  621. {
  622. uint16_t len;
  623. bx::read(reader, len);
  624. std::string material;
  625. material.resize(len);
  626. bx::read(reader, const_cast<char*>(material.c_str() ), len);
  627. uint16_t num;
  628. bx::read(reader, num);
  629. for (uint32_t ii = 0; ii < num; ++ii)
  630. {
  631. bx::read(reader, len);
  632. std::string name;
  633. name.resize(len);
  634. bx::read(reader, const_cast<char*>(name.c_str() ), len);
  635. Primitive prim;
  636. bx::read(reader, prim.m_startIndex);
  637. bx::read(reader, prim.m_numIndices);
  638. bx::read(reader, prim.m_startVertex);
  639. bx::read(reader, prim.m_numVertices);
  640. bx::read(reader, prim.m_sphere);
  641. bx::read(reader, prim.m_aabb);
  642. bx::read(reader, prim.m_obb);
  643. group.m_prims.push_back(prim);
  644. }
  645. m_groups.push_back(group);
  646. group.reset();
  647. }
  648. break;
  649. default:
  650. DBG("%08x at %d", chunk, bx::seek(reader) );
  651. abort();
  652. break;
  653. }
  654. }
  655. bx::close(reader);
  656. }
  657. void unload()
  658. {
  659. for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it)
  660. {
  661. const Group& group = *it;
  662. bgfx::destroyVertexBuffer(group.m_vbh);
  663. if (bgfx::invalidHandle != group.m_ibh.idx)
  664. {
  665. bgfx::destroyIndexBuffer(group.m_ibh);
  666. }
  667. }
  668. m_groups.clear();
  669. }
  670. void submit(uint8_t _viewId, float* _mtx, bgfx::ProgramHandle _program, const RenderState& _renderState)
  671. {
  672. bgfx::TextureHandle texture = BGFX_INVALID_HANDLE;
  673. submit(_viewId, _mtx, _program, _renderState, texture);
  674. }
  675. void submit(uint8_t _viewId, float* _mtx, bgfx::ProgramHandle _program, const RenderState& _renderState, bgfx::TextureHandle _texture)
  676. {
  677. for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it)
  678. {
  679. const Group& group = *it;
  680. // Set uniforms
  681. s_uniforms.submitPerDrawUniforms();
  682. // Set model matrix for rendering.
  683. bgfx::setTransform(_mtx);
  684. bgfx::setIndexBuffer(group.m_ibh);
  685. bgfx::setVertexBuffer(group.m_vbh);
  686. // Set texture
  687. if (bgfx::invalidHandle != _texture.idx)
  688. {
  689. bgfx::setTexture(0, s_texColor, _texture);
  690. }
  691. // Apply render state
  692. bgfx::setStencil(_renderState.m_fstencil, _renderState.m_bstencil);
  693. bgfx::setState(_renderState.m_state, _renderState.m_blendFactorRgba);
  694. // Submit
  695. bgfx::submit(_viewId, _program);
  696. // Keep track of submited view ids
  697. s_viewMask |= 1 << _viewId;
  698. }
  699. }
  700. bgfx::VertexDecl m_decl;
  701. typedef std::vector<Group> GroupArray;
  702. GroupArray m_groups;
  703. };
  704. int _main_(int _argc, char** _argv)
  705. {
  706. Args args(_argc, _argv);
  707. ViewState viewState(1280, 720);
  708. ClearValues clearValues(0x30303000, 1.0f, 0);
  709. uint32_t debug = BGFX_DEBUG_TEXT;
  710. uint32_t reset = BGFX_RESET_VSYNC;
  711. bgfx::init(args.m_type, args.m_pciId);
  712. bgfx::reset(viewState.m_width, viewState.m_height, reset);
  713. // Enable debug text.
  714. bgfx::setDebug(debug);
  715. // Setup root path for binary shaders. Shader binaries are different
  716. // for each renderer.
  717. switch (bgfx::getRendererType() )
  718. {
  719. case bgfx::RendererType::OpenGL:
  720. case bgfx::RendererType::OpenGLES:
  721. s_flipV = true;
  722. break;
  723. default:
  724. break;
  725. }
  726. // Imgui.
  727. imguiCreate();
  728. PosNormalTexcoordVertex::init();
  729. s_uniforms.init();
  730. s_uniforms.submitConstUniforms();
  731. s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1);
  732. bgfx::ProgramHandle programTextureLighting = loadProgram("vs_stencil_texture_lighting", "fs_stencil_texture_lighting");
  733. bgfx::ProgramHandle programColorLighting = loadProgram("vs_stencil_color_lighting", "fs_stencil_color_lighting" );
  734. bgfx::ProgramHandle programColorTexture = loadProgram("vs_stencil_color_texture", "fs_stencil_color_texture" );
  735. bgfx::ProgramHandle programColorBlack = loadProgram("vs_stencil_color", "fs_stencil_color_black" );
  736. bgfx::ProgramHandle programTexture = loadProgram("vs_stencil_texture", "fs_stencil_texture" );
  737. Mesh bunnyMesh;
  738. Mesh columnMesh;
  739. Mesh cubeMesh;
  740. Mesh hplaneMesh;
  741. Mesh vplaneMesh;
  742. bunnyMesh.load("meshes/bunny.bin");
  743. columnMesh.load("meshes/column.bin");
  744. cubeMesh.load(s_cubeVertices, BX_COUNTOF(s_cubeVertices), PosNormalTexcoordVertex::ms_decl, s_cubeIndices, BX_COUNTOF(s_cubeIndices) );
  745. hplaneMesh.load(s_hplaneVertices, BX_COUNTOF(s_hplaneVertices), PosNormalTexcoordVertex::ms_decl, s_planeIndices, BX_COUNTOF(s_planeIndices) );
  746. vplaneMesh.load(s_vplaneVertices, BX_COUNTOF(s_vplaneVertices), PosNormalTexcoordVertex::ms_decl, s_planeIndices, BX_COUNTOF(s_planeIndices) );
  747. bgfx::TextureHandle figureTex = loadTexture("textures/figure-rgba.dds");
  748. bgfx::TextureHandle flareTex = loadTexture("textures/flare.dds");
  749. bgfx::TextureHandle fieldstoneTex = loadTexture("textures/fieldstone-rgba.dds");
  750. // Setup lights.
  751. const float rgbInnerR[][4] =
  752. {
  753. { 1.0f, 0.7f, 0.2f, 0.0f }, //yellow
  754. { 0.7f, 0.2f, 1.0f, 0.0f }, //purple
  755. { 0.2f, 1.0f, 0.7f, 0.0f }, //cyan
  756. { 1.0f, 0.4f, 0.2f, 0.0f }, //orange
  757. { 0.7f, 0.7f, 0.7f, 0.0f }, //white
  758. };
  759. float lightRgbInnerR[MAX_NUM_LIGHTS][4];
  760. for (uint8_t ii = 0, jj = 0; ii < MAX_NUM_LIGHTS; ++ii, ++jj)
  761. {
  762. const uint8_t index = jj%BX_COUNTOF(rgbInnerR);
  763. lightRgbInnerR[ii][0] = rgbInnerR[index][0];
  764. lightRgbInnerR[ii][1] = rgbInnerR[index][1];
  765. lightRgbInnerR[ii][2] = rgbInnerR[index][2];
  766. lightRgbInnerR[ii][3] = rgbInnerR[index][3];
  767. }
  768. bx::memCopy(s_uniforms.m_lightRgbInnerR, lightRgbInnerR, MAX_NUM_LIGHTS * 4*sizeof(float) );
  769. // Set view and projection matrices.
  770. const float aspect = float(viewState.m_width)/float(viewState.m_height);
  771. mtxProj(viewState.m_proj, 60.0f, aspect, 0.1f, 100.0f);
  772. float initialPos[3] = { 0.0f, 18.0f, -40.0f };
  773. cameraCreate();
  774. cameraSetPosition(initialPos);
  775. cameraSetVerticalAngle(-0.35f);
  776. cameraGetViewMtx(viewState.m_view);
  777. int64_t timeOffset = bx::getHPCounter();
  778. enum Scene
  779. {
  780. StencilReflectionScene = 0,
  781. ProjectionShadowsScene,
  782. };
  783. Scene scene = StencilReflectionScene;
  784. float settings_numLights = 4.0f;
  785. float settings_reflectionValue = 0.8f;
  786. bool settings_updateLights = true;
  787. bool settings_updateScene = true;
  788. static const char* titles[3] =
  789. {
  790. "Stencil Reflection Scene",
  791. "Projection Shadows Scene",
  792. };
  793. entry::MouseState mouseState;
  794. while (!entry::processEvents(viewState.m_width, viewState.m_height, debug, reset, &mouseState) )
  795. {
  796. imguiBeginFrame(mouseState.m_mx
  797. , mouseState.m_my
  798. , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0)
  799. | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0)
  800. | (mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
  801. , mouseState.m_mz
  802. , viewState.m_width
  803. , viewState.m_height
  804. );
  805. static int32_t scrollArea = 0;
  806. imguiBeginScrollArea("Settings", viewState.m_width - 256 - 10, 10, 256, 215, &scrollArea);
  807. if (imguiCheck(titles[StencilReflectionScene], StencilReflectionScene == scene) )
  808. {
  809. scene = StencilReflectionScene;
  810. settings_numLights = 4.0f;
  811. }
  812. if (imguiCheck(titles[ProjectionShadowsScene], ProjectionShadowsScene == scene) )
  813. {
  814. scene = ProjectionShadowsScene;
  815. settings_numLights = 1.0f;
  816. }
  817. imguiSeparatorLine();
  818. imguiSlider("Lights", settings_numLights, 1.0f, float(MAX_NUM_LIGHTS), 1.0f);
  819. if (scene == StencilReflectionScene)
  820. {
  821. imguiSlider("Reflection value", settings_reflectionValue, 0.0f, 1.0f, 0.01f);
  822. }
  823. if (imguiCheck("Update lights", settings_updateLights) )
  824. {
  825. settings_updateLights = !settings_updateLights;
  826. }
  827. if (imguiCheck("Update scene", settings_updateScene) )
  828. {
  829. settings_updateScene = !settings_updateScene;
  830. }
  831. imguiEndScrollArea();
  832. imguiEndFrame();
  833. // Update settings.
  834. uint8_t numLights = (uint8_t)settings_numLights;
  835. s_uniforms.m_params.m_ambientPass = 1.0f;
  836. s_uniforms.m_params.m_lightingPass = 1.0f;
  837. s_uniforms.m_params.m_lightCount = settings_numLights;
  838. s_uniforms.m_params.m_lightIndex = 0.0f;
  839. s_uniforms.m_color[3] = settings_reflectionValue;
  840. // Time.
  841. int64_t now = bx::getHPCounter();
  842. static int64_t last = now;
  843. const int64_t frameTime = now - last;
  844. last = now;
  845. const double freq = double(bx::getHPFrequency() );
  846. const double toMs = 1000.0/freq;
  847. const float time = (float)( (now - timeOffset)/double(bx::getHPFrequency() ) );
  848. const float deltaTime = float(frameTime/freq);
  849. s_uniforms.m_time = time;
  850. // Use debug font to print information about this example.
  851. bgfx::dbgTextClear();
  852. bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/13-stencil");
  853. bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Stencil reflections and shadows.");
  854. bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
  855. // Update camera.
  856. cameraUpdate(deltaTime, mouseState);
  857. cameraGetViewMtx(viewState.m_view);
  858. static float lightTimeAccumulator = 0.0f;
  859. if (settings_updateLights)
  860. {
  861. lightTimeAccumulator += deltaTime;
  862. }
  863. static float sceneTimeAccumulator = 0.0f;
  864. if (settings_updateScene)
  865. {
  866. sceneTimeAccumulator += deltaTime;
  867. }
  868. float lightPosRadius[MAX_NUM_LIGHTS][4];
  869. const float radius = (scene == StencilReflectionScene) ? 15.0f : 25.0f;
  870. for (uint8_t ii = 0; ii < numLights; ++ii)
  871. {
  872. lightPosRadius[ii][0] = sinf( (lightTimeAccumulator*1.1f + ii*0.03f + ii*bx::piHalf*1.07f ) )*20.0f;
  873. lightPosRadius[ii][1] = 8.0f + (1.0f - cosf( (lightTimeAccumulator*1.5f + ii*0.29f + bx::piHalf*1.49f ) ) )*4.0f;
  874. lightPosRadius[ii][2] = cosf( (lightTimeAccumulator*1.3f + ii*0.13f + ii*bx::piHalf*1.79f ) )*20.0f;
  875. lightPosRadius[ii][3] = radius;
  876. }
  877. bx::memCopy(s_uniforms.m_lightPosRadius, lightPosRadius, numLights * 4*sizeof(float) );
  878. // Floor position.
  879. float floorMtx[16];
  880. bx::mtxSRT(floorMtx
  881. , 20.0f //scaleX
  882. , 20.0f //scaleY
  883. , 20.0f //scaleZ
  884. , 0.0f //rotX
  885. , 0.0f //rotY
  886. , 0.0f //rotZ
  887. , 0.0f //translateX
  888. , 0.0f //translateY
  889. , 0.0f //translateZ
  890. );
  891. // Bunny position.
  892. float bunnyMtx[16];
  893. bx::mtxSRT(bunnyMtx
  894. , 5.0f
  895. , 5.0f
  896. , 5.0f
  897. , 0.0f
  898. , 1.56f - sceneTimeAccumulator
  899. , 0.0f
  900. , 0.0f
  901. , 2.0f
  902. , 0.0f
  903. );
  904. // Columns position.
  905. const float dist = 14.0f;
  906. const float columnPositions[4][3] =
  907. {
  908. { dist, 0.0f, dist },
  909. { -dist, 0.0f, dist },
  910. { dist, 0.0f, -dist },
  911. { -dist, 0.0f, -dist },
  912. };
  913. float columnMtx[4][16];
  914. for (uint8_t ii = 0; ii < 4; ++ii)
  915. {
  916. bx::mtxSRT(columnMtx[ii]
  917. , 1.0f
  918. , 1.0f
  919. , 1.0f
  920. , 0.0f
  921. , 0.0f
  922. , 0.0f
  923. , columnPositions[ii][0]
  924. , columnPositions[ii][1]
  925. , columnPositions[ii][2]
  926. );
  927. }
  928. const uint8_t numCubes = 9;
  929. float cubeMtx[numCubes][16];
  930. for (uint16_t ii = 0; ii < numCubes; ++ii)
  931. {
  932. bx::mtxSRT(cubeMtx[ii]
  933. , 1.0f
  934. , 1.0f
  935. , 1.0f
  936. , 0.0f
  937. , 0.0f
  938. , 0.0f
  939. , sinf(ii * 2.0f + 13.0f - sceneTimeAccumulator) * 13.0f
  940. , 4.0f
  941. , cosf(ii * 2.0f + 13.0f - sceneTimeAccumulator) * 13.0f
  942. );
  943. }
  944. // Make sure at the beginning everything gets cleared.
  945. clearView(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL, clearValues);
  946. bgfx::touch(0);
  947. s_viewMask |= 1;
  948. // Bunny and columns color.
  949. s_uniforms.m_color[0] = 0.70f;
  950. s_uniforms.m_color[1] = 0.65f;
  951. s_uniforms.m_color[2] = 0.60f;
  952. switch (scene)
  953. {
  954. case StencilReflectionScene:
  955. {
  956. // First pass - Draw plane.
  957. // Setup params for this scene.
  958. s_uniforms.m_params.m_ambientPass = 1.0f;
  959. s_uniforms.m_params.m_lightingPass = 1.0f;
  960. // Floor.
  961. hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
  962. , floorMtx
  963. , programColorBlack
  964. , s_renderStates[RenderState::StencilReflection_CraftStencil]
  965. );
  966. // Second pass - Draw reflected objects.
  967. // Clear depth from previous pass.
  968. clearView(RENDER_VIEWID_RANGE1_PASS_1, BGFX_CLEAR_DEPTH, clearValues);
  969. // Compute reflected matrix.
  970. float reflectMtx[16];
  971. float plane_pos[3] = { 0.0f, 0.01f, 0.0f };
  972. float normal[3] = { 0.0f, 1.0f, 0.0f };
  973. mtxReflected(reflectMtx, plane_pos, normal);
  974. // Reflect lights.
  975. float reflectedLights[MAX_NUM_LIGHTS][4];
  976. for (uint8_t ii = 0; ii < numLights; ++ii)
  977. {
  978. bx::vec3MulMtx(reflectedLights[ii], lightPosRadius[ii], reflectMtx);
  979. reflectedLights[ii][3] = lightPosRadius[ii][3];
  980. }
  981. bx::memCopy(s_uniforms.m_lightPosRadius, reflectedLights, numLights * 4*sizeof(float) );
  982. // Reflect and submit bunny.
  983. float mtxReflectedBunny[16];
  984. bx::mtxMul(mtxReflectedBunny, bunnyMtx, reflectMtx);
  985. bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_1
  986. , mtxReflectedBunny
  987. , programColorLighting
  988. , s_renderStates[RenderState::StencilReflection_DrawReflected]
  989. );
  990. // Reflect and submit columns.
  991. float mtxReflectedColumn[16];
  992. for (uint8_t ii = 0; ii < 4; ++ii)
  993. {
  994. bx::mtxMul(mtxReflectedColumn, columnMtx[ii], reflectMtx);
  995. columnMesh.submit(RENDER_VIEWID_RANGE1_PASS_1
  996. , mtxReflectedColumn
  997. , programColorLighting
  998. , s_renderStates[RenderState::StencilReflection_DrawReflected]
  999. );
  1000. }
  1001. // Set lights back.
  1002. bx::memCopy(s_uniforms.m_lightPosRadius, lightPosRadius, numLights * 4*sizeof(float) );
  1003. // Third pass - Blend plane.
  1004. // Floor.
  1005. hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_2
  1006. , floorMtx
  1007. , programTextureLighting
  1008. , s_renderStates[RenderState::StencilReflection_BlendPlane]
  1009. , fieldstoneTex
  1010. );
  1011. // Fourth pass - Draw everything else but the plane.
  1012. // Bunny.
  1013. bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_3
  1014. , bunnyMtx
  1015. , programColorLighting
  1016. , s_renderStates[RenderState::StencilReflection_DrawScene]
  1017. );
  1018. // Columns.
  1019. for (uint8_t ii = 0; ii < 4; ++ii)
  1020. {
  1021. columnMesh.submit(RENDER_VIEWID_RANGE1_PASS_3
  1022. , columnMtx[ii]
  1023. , programColorLighting
  1024. , s_renderStates[RenderState::StencilReflection_DrawScene]
  1025. );
  1026. }
  1027. }
  1028. break;
  1029. case ProjectionShadowsScene:
  1030. {
  1031. // First pass - Draw entire scene. (ambient only).
  1032. s_uniforms.m_params.m_ambientPass = 1.0f;
  1033. s_uniforms.m_params.m_lightingPass = 0.0f;
  1034. // Bunny.
  1035. bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
  1036. , bunnyMtx
  1037. , programColorLighting
  1038. , s_renderStates[RenderState::ProjectionShadows_DrawAmbient]
  1039. );
  1040. // Floor.
  1041. hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
  1042. , floorMtx
  1043. , programTextureLighting
  1044. , s_renderStates[RenderState::ProjectionShadows_DrawAmbient]
  1045. , fieldstoneTex
  1046. );
  1047. // Cubes.
  1048. for (uint8_t ii = 0; ii < numCubes; ++ii)
  1049. {
  1050. cubeMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
  1051. , cubeMtx[ii]
  1052. , programTextureLighting
  1053. , s_renderStates[RenderState::ProjectionShadows_DrawAmbient]
  1054. , figureTex
  1055. );
  1056. }
  1057. // Ground plane.
  1058. float ground[4];
  1059. float plane_pos[3] = { 0.0f, 0.0f, 0.0f };
  1060. float normal[3] = { 0.0f, 1.0f, 0.0f };
  1061. bx::memCopy(ground, normal, sizeof(float) * 3);
  1062. ground[3] = -bx::vec3Dot(plane_pos, normal) - 0.01f; // - 0.01 against z-fighting
  1063. for (uint8_t ii = 0, viewId = RENDER_VIEWID_RANGE5_PASS_6; ii < numLights; ++ii, ++viewId)
  1064. {
  1065. // Clear stencil for this light source.
  1066. clearView(viewId, BGFX_CLEAR_STENCIL, clearValues);
  1067. // Draw shadow projection of scene objects.
  1068. // Get homogeneous light pos.
  1069. float* lightPos = lightPosRadius[ii];
  1070. float pos[4];
  1071. bx::memCopy(pos, lightPos, sizeof(float) * 3);
  1072. pos[3] = 1.0f;
  1073. // Calculate shadow mtx for current light.
  1074. float shadowMtx[16];
  1075. mtxShadow(shadowMtx, ground, pos);
  1076. // Submit bunny's shadow.
  1077. float mtxShadowedBunny[16];
  1078. bx::mtxMul(mtxShadowedBunny, bunnyMtx, shadowMtx);
  1079. bunnyMesh.submit(viewId
  1080. , mtxShadowedBunny
  1081. , programColorBlack
  1082. , s_renderStates[RenderState::ProjectionShadows_CraftStencil]
  1083. );
  1084. // Submit cube shadows.
  1085. float mtxShadowedCube[16];
  1086. for (uint8_t jj = 0; jj < numCubes; ++jj)
  1087. {
  1088. bx::mtxMul(mtxShadowedCube, cubeMtx[jj], shadowMtx);
  1089. cubeMesh.submit(viewId
  1090. , mtxShadowedCube
  1091. , programColorBlack
  1092. , s_renderStates[RenderState::ProjectionShadows_CraftStencil]
  1093. );
  1094. }
  1095. // Draw entire scene. (lighting pass only. blending is on)
  1096. s_uniforms.m_params.m_ambientPass = 0.0f;
  1097. s_uniforms.m_params.m_lightingPass = 1.0f;
  1098. s_uniforms.m_params.m_lightCount = 1.0f;
  1099. s_uniforms.m_params.m_lightIndex = float(ii);
  1100. // Bunny.
  1101. bunnyMesh.submit(viewId
  1102. , bunnyMtx
  1103. , programColorLighting
  1104. , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse]
  1105. );
  1106. // Floor.
  1107. hplaneMesh.submit(viewId
  1108. , floorMtx
  1109. , programTextureLighting
  1110. , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse]
  1111. , fieldstoneTex
  1112. );
  1113. // Cubes.
  1114. for (uint8_t jj = 0; jj < numCubes; ++jj)
  1115. {
  1116. cubeMesh.submit(viewId
  1117. , cubeMtx[jj]
  1118. , programTextureLighting
  1119. , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse]
  1120. , figureTex
  1121. );
  1122. }
  1123. }
  1124. // Reset these to default..
  1125. s_uniforms.m_params.m_ambientPass = 1.0f;
  1126. s_uniforms.m_params.m_lightingPass = 1.0f;
  1127. }
  1128. break;
  1129. };
  1130. //lights
  1131. const float lightScale[3] = { 1.5f, 1.5f, 1.5f };
  1132. float lightMtx[16];
  1133. for (uint8_t ii = 0; ii < numLights; ++ii)
  1134. {
  1135. s_uniforms.m_color[0] = lightRgbInnerR[ii][0];
  1136. s_uniforms.m_color[1] = lightRgbInnerR[ii][1];
  1137. s_uniforms.m_color[2] = lightRgbInnerR[ii][2];
  1138. mtxBillboard(lightMtx, viewState.m_view, lightPosRadius[ii], lightScale);
  1139. vplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_7
  1140. , lightMtx
  1141. , programColorTexture
  1142. , s_renderStates[RenderState::Custom_BlendLightTexture]
  1143. , flareTex
  1144. );
  1145. }
  1146. // Draw floor bottom.
  1147. float floorBottomMtx[16];
  1148. bx::mtxSRT(floorBottomMtx
  1149. , 20.0f //scaleX
  1150. , 20.0f //scaleY
  1151. , 20.0f //scaleZ
  1152. , 0.0f //rotX
  1153. , 0.0f //rotY
  1154. , 0.0f //rotZ
  1155. , 0.0f //translateX
  1156. , -0.1f //translateY
  1157. , 0.0f //translateZ
  1158. );
  1159. hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_7
  1160. , floorBottomMtx
  1161. , programTexture
  1162. , s_renderStates[RenderState::Custom_DrawPlaneBottom]
  1163. , figureTex
  1164. );
  1165. // Setup view rect and transform for all used views.
  1166. setViewRectMask(s_viewMask, 0, 0, viewState.m_width, viewState.m_height);
  1167. setViewTransformMask(s_viewMask, viewState.m_view, viewState.m_proj);
  1168. s_viewMask = 0;
  1169. // Advance to next frame. Rendering thread will be kicked to
  1170. // process submitted rendering primitives.
  1171. bgfx::frame();
  1172. //reset clear values on used views
  1173. clearViewMask(s_clearMask, BGFX_CLEAR_NONE, clearValues);
  1174. s_clearMask = 0;
  1175. }
  1176. // Cleanup.
  1177. bunnyMesh.unload();
  1178. columnMesh.unload();
  1179. cubeMesh.unload();
  1180. hplaneMesh.unload();
  1181. vplaneMesh.unload();
  1182. bgfx::destroyTexture(figureTex);
  1183. bgfx::destroyTexture(fieldstoneTex);
  1184. bgfx::destroyTexture(flareTex);
  1185. bgfx::destroyProgram(programTextureLighting);
  1186. bgfx::destroyProgram(programColorLighting);
  1187. bgfx::destroyProgram(programColorTexture);
  1188. bgfx::destroyProgram(programColorBlack);
  1189. bgfx::destroyProgram(programTexture);
  1190. bgfx::destroyUniform(s_texColor);
  1191. s_uniforms.destroy();
  1192. cameraDestroy();
  1193. imguiDestroy();
  1194. // Shutdown bgfx.
  1195. bgfx::shutdown();
  1196. return 0;
  1197. }