stencil.cpp 37 KB

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