stencil.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410
  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.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_mz
  810. , viewState.m_width
  811. , viewState.m_height
  812. );
  813. static int32_t scrollArea = 0;
  814. imguiBeginScrollArea("Settings", viewState.m_width - 256 - 10, 10, 256, 215, &scrollArea);
  815. if (imguiCheck(titles[StencilReflectionScene], StencilReflectionScene == scene) )
  816. {
  817. scene = StencilReflectionScene;
  818. settings_numLights = 4.0f;
  819. }
  820. if (imguiCheck(titles[ProjectionShadowsScene], ProjectionShadowsScene == scene) )
  821. {
  822. scene = ProjectionShadowsScene;
  823. settings_numLights = 1.0f;
  824. }
  825. imguiSeparatorLine();
  826. imguiSlider("Lights", settings_numLights, 1.0f, float(MAX_NUM_LIGHTS), 1.0f);
  827. if (scene == StencilReflectionScene)
  828. {
  829. imguiSlider("Reflection value", settings_reflectionValue, 0.0f, 1.0f, 0.01f);
  830. }
  831. if (imguiCheck("Update lights", settings_updateLights) )
  832. {
  833. settings_updateLights = !settings_updateLights;
  834. }
  835. if (imguiCheck("Update scene", settings_updateScene) )
  836. {
  837. settings_updateScene = !settings_updateScene;
  838. }
  839. imguiEndScrollArea();
  840. imguiEndFrame();
  841. // Update settings.
  842. uint8_t numLights = (uint8_t)settings_numLights;
  843. s_uniforms.m_params.m_ambientPass = 1.0f;
  844. s_uniforms.m_params.m_lightningPass = 1.0f;
  845. s_uniforms.m_params.m_lightCount = settings_numLights;
  846. s_uniforms.m_params.m_lightIndex = 0.0f;
  847. s_uniforms.m_color[3] = settings_reflectionValue;
  848. // Time.
  849. int64_t now = bx::getHPCounter();
  850. static int64_t last = now;
  851. const int64_t frameTime = now - last;
  852. last = now;
  853. const double freq = double(bx::getHPFrequency() );
  854. const double toMs = 1000.0/freq;
  855. float time = (float)( (now - timeOffset)/double(bx::getHPFrequency() ) );
  856. const float deltaTime = float(frameTime/freq);
  857. s_uniforms.m_time = time;
  858. // Use debug font to print information about this example.
  859. bgfx::dbgTextClear();
  860. bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/13-stencil");
  861. bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Stencil reflections and shadows.");
  862. bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
  863. // Update camera.
  864. cameraUpdate(deltaTime, mouseState);
  865. cameraGetViewMtx(viewState.m_view);
  866. static float lightTimeAccumulator = 0.0f;
  867. if (settings_updateLights)
  868. {
  869. lightTimeAccumulator += deltaTime;
  870. }
  871. static float sceneTimeAccumulator = 0.0f;
  872. if (settings_updateScene)
  873. {
  874. sceneTimeAccumulator += deltaTime;
  875. }
  876. float lightPosRadius[MAX_NUM_LIGHTS][4];
  877. const float radius = (scene == StencilReflectionScene) ? 15.0f : 25.0f;
  878. for (uint8_t ii = 0; ii < numLights; ++ii)
  879. {
  880. lightPosRadius[ii][0] = sinf( (lightTimeAccumulator*1.1f + ii*0.03f + ii*bx::piHalf*1.07f ) )*20.0f;
  881. lightPosRadius[ii][1] = 8.0f + (1.0f - cosf( (lightTimeAccumulator*1.5f + ii*0.29f + bx::piHalf*1.49f ) ) )*4.0f;
  882. lightPosRadius[ii][2] = cosf( (lightTimeAccumulator*1.3f + ii*0.13f + ii*bx::piHalf*1.79f ) )*20.0f;
  883. lightPosRadius[ii][3] = radius;
  884. }
  885. memcpy(s_uniforms.m_lightPosRadius, lightPosRadius, numLights * 4*sizeof(float) );
  886. // Floor position.
  887. float floorMtx[16];
  888. bx::mtxSRT(floorMtx
  889. , 20.0f //scaleX
  890. , 20.0f //scaleY
  891. , 20.0f //scaleZ
  892. , 0.0f //rotX
  893. , 0.0f //rotY
  894. , 0.0f //rotZ
  895. , 0.0f //translateX
  896. , 0.0f //translateY
  897. , 0.0f //translateZ
  898. );
  899. // Bunny position.
  900. float bunnyMtx[16];
  901. bx::mtxSRT(bunnyMtx
  902. , 5.0f
  903. , 5.0f
  904. , 5.0f
  905. , 0.0f
  906. , 1.56f - sceneTimeAccumulator
  907. , 0.0f
  908. , 0.0f
  909. , 2.0f
  910. , 0.0f
  911. );
  912. // Columns position.
  913. const float dist = 14.0f;
  914. const float columnPositions[4][3] =
  915. {
  916. { dist, 0.0f, dist },
  917. { -dist, 0.0f, dist },
  918. { dist, 0.0f, -dist },
  919. { -dist, 0.0f, -dist },
  920. };
  921. float columnMtx[4][16];
  922. for (uint8_t ii = 0; ii < 4; ++ii)
  923. {
  924. bx::mtxSRT(columnMtx[ii]
  925. , 1.0f
  926. , 1.0f
  927. , 1.0f
  928. , 0.0f
  929. , 0.0f
  930. , 0.0f
  931. , columnPositions[ii][0]
  932. , columnPositions[ii][1]
  933. , columnPositions[ii][2]
  934. );
  935. }
  936. const uint8_t numCubes = 9;
  937. float cubeMtx[numCubes][16];
  938. for (uint16_t ii = 0; ii < numCubes; ++ii)
  939. {
  940. bx::mtxSRT(cubeMtx[ii]
  941. , 1.0f
  942. , 1.0f
  943. , 1.0f
  944. , 0.0f
  945. , 0.0f
  946. , 0.0f
  947. , sinf(ii * 2.0f + 13.0f - sceneTimeAccumulator) * 13.0f
  948. , 4.0f
  949. , cosf(ii * 2.0f + 13.0f - sceneTimeAccumulator) * 13.0f
  950. );
  951. }
  952. // Make sure at the beginning everything gets cleared.
  953. clearView(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL, clearValues);
  954. bgfx::touch(0);
  955. s_viewMask |= 1;
  956. // Bunny and columns color.
  957. s_uniforms.m_color[0] = 0.70f;
  958. s_uniforms.m_color[1] = 0.65f;
  959. s_uniforms.m_color[2] = 0.60f;
  960. switch (scene)
  961. {
  962. case StencilReflectionScene:
  963. {
  964. // First pass - Draw plane.
  965. // Setup params for this scene.
  966. s_uniforms.m_params.m_ambientPass = 1.0f;
  967. s_uniforms.m_params.m_lightningPass = 1.0f;
  968. // Floor.
  969. hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
  970. , floorMtx
  971. , programColorBlack
  972. , s_renderStates[RenderState::StencilReflection_CraftStencil]
  973. );
  974. // Second pass - Draw reflected objects.
  975. // Clear depth from previous pass.
  976. clearView(RENDER_VIEWID_RANGE1_PASS_1, BGFX_CLEAR_DEPTH, clearValues);
  977. // Compute reflected matrix.
  978. float reflectMtx[16];
  979. float plane_pos[3] = { 0.0f, 0.01f, 0.0f };
  980. float normal[3] = { 0.0f, 1.0f, 0.0f };
  981. mtxReflected(reflectMtx, plane_pos, normal);
  982. // Reflect lights.
  983. float reflectedLights[MAX_NUM_LIGHTS][4];
  984. for (uint8_t ii = 0; ii < numLights; ++ii)
  985. {
  986. bx::vec3MulMtx(reflectedLights[ii], lightPosRadius[ii], reflectMtx);
  987. reflectedLights[ii][3] = lightPosRadius[ii][3];
  988. }
  989. memcpy(s_uniforms.m_lightPosRadius, reflectedLights, numLights * 4*sizeof(float) );
  990. // Reflect and submit bunny.
  991. float mtxReflectedBunny[16];
  992. bx::mtxMul(mtxReflectedBunny, bunnyMtx, reflectMtx);
  993. bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_1
  994. , mtxReflectedBunny
  995. , programColorLightning
  996. , s_renderStates[RenderState::StencilReflection_DrawReflected]
  997. );
  998. // Reflect and submit columns.
  999. float mtxReflectedColumn[16];
  1000. for (uint8_t ii = 0; ii < 4; ++ii)
  1001. {
  1002. bx::mtxMul(mtxReflectedColumn, columnMtx[ii], reflectMtx);
  1003. columnMesh.submit(RENDER_VIEWID_RANGE1_PASS_1
  1004. , mtxReflectedColumn
  1005. , programColorLightning
  1006. , s_renderStates[RenderState::StencilReflection_DrawReflected]
  1007. );
  1008. }
  1009. // Set lights back.
  1010. memcpy(s_uniforms.m_lightPosRadius, lightPosRadius, numLights * 4*sizeof(float) );
  1011. // Third pass - Blend plane.
  1012. // Floor.
  1013. hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_2
  1014. , floorMtx
  1015. , programTextureLightning
  1016. , s_renderStates[RenderState::StencilReflection_BlendPlane]
  1017. , fieldstoneTex
  1018. );
  1019. // Fourth pass - Draw everything else but the plane.
  1020. // Bunny.
  1021. bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_3
  1022. , bunnyMtx
  1023. , programColorLightning
  1024. , s_renderStates[RenderState::StencilReflection_DrawScene]
  1025. );
  1026. // Columns.
  1027. for (uint8_t ii = 0; ii < 4; ++ii)
  1028. {
  1029. columnMesh.submit(RENDER_VIEWID_RANGE1_PASS_3
  1030. , columnMtx[ii]
  1031. , programColorLightning
  1032. , s_renderStates[RenderState::StencilReflection_DrawScene]
  1033. );
  1034. }
  1035. }
  1036. break;
  1037. case ProjectionShadowsScene:
  1038. {
  1039. // First pass - Draw entire scene. (ambient only).
  1040. s_uniforms.m_params.m_ambientPass = 1.0f;
  1041. s_uniforms.m_params.m_lightningPass = 0.0f;
  1042. // Bunny.
  1043. bunnyMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
  1044. , bunnyMtx
  1045. , programColorLightning
  1046. , s_renderStates[RenderState::ProjectionShadows_DrawAmbient]
  1047. );
  1048. // Floor.
  1049. hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
  1050. , floorMtx
  1051. , programTextureLightning
  1052. , s_renderStates[RenderState::ProjectionShadows_DrawAmbient]
  1053. , fieldstoneTex
  1054. );
  1055. // Cubes.
  1056. for (uint8_t ii = 0; ii < numCubes; ++ii)
  1057. {
  1058. cubeMesh.submit(RENDER_VIEWID_RANGE1_PASS_0
  1059. , cubeMtx[ii]
  1060. , programTextureLightning
  1061. , s_renderStates[RenderState::ProjectionShadows_DrawAmbient]
  1062. , figureTex
  1063. );
  1064. }
  1065. // Ground plane.
  1066. float ground[4];
  1067. float plane_pos[3] = { 0.0f, 0.0f, 0.0f };
  1068. float normal[3] = { 0.0f, 1.0f, 0.0f };
  1069. memcpy(ground, normal, sizeof(float) * 3);
  1070. ground[3] = -bx::vec3Dot(plane_pos, normal) - 0.01f; // - 0.01 against z-fighting
  1071. for (uint8_t ii = 0, viewId = RENDER_VIEWID_RANGE5_PASS_6; ii < numLights; ++ii, ++viewId)
  1072. {
  1073. // Clear stencil for this light source.
  1074. clearView(viewId, BGFX_CLEAR_STENCIL, clearValues);
  1075. // Draw shadow projection of scene objects.
  1076. // Get homogeneous light pos.
  1077. float* lightPos = lightPosRadius[ii];
  1078. float pos[4];
  1079. memcpy(pos, lightPos, sizeof(float) * 3);
  1080. pos[3] = 1.0f;
  1081. // Calculate shadow mtx for current light.
  1082. float shadowMtx[16];
  1083. mtxShadow(shadowMtx, ground, pos);
  1084. // Submit bunny's shadow.
  1085. float mtxShadowedBunny[16];
  1086. bx::mtxMul(mtxShadowedBunny, bunnyMtx, shadowMtx);
  1087. bunnyMesh.submit(viewId
  1088. , mtxShadowedBunny
  1089. , programColorBlack
  1090. , s_renderStates[RenderState::ProjectionShadows_CraftStencil]
  1091. );
  1092. // Submit cube shadows.
  1093. float mtxShadowedCube[16];
  1094. for (uint8_t jj = 0; jj < numCubes; ++jj)
  1095. {
  1096. bx::mtxMul(mtxShadowedCube, cubeMtx[jj], shadowMtx);
  1097. cubeMesh.submit(viewId
  1098. , mtxShadowedCube
  1099. , programColorBlack
  1100. , s_renderStates[RenderState::ProjectionShadows_CraftStencil]
  1101. );
  1102. }
  1103. // Draw entire scene. (lightning pass only. blending is on)
  1104. s_uniforms.m_params.m_ambientPass = 0.0f;
  1105. s_uniforms.m_params.m_lightningPass = 1.0f;
  1106. s_uniforms.m_params.m_lightCount = 1.0f;
  1107. s_uniforms.m_params.m_lightIndex = float(ii);
  1108. // Bunny.
  1109. bunnyMesh.submit(viewId
  1110. , bunnyMtx
  1111. , programColorLightning
  1112. , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse]
  1113. );
  1114. // Floor.
  1115. hplaneMesh.submit(viewId
  1116. , floorMtx
  1117. , programTextureLightning
  1118. , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse]
  1119. , fieldstoneTex
  1120. );
  1121. // Cubes.
  1122. for (uint8_t jj = 0; jj < numCubes; ++jj)
  1123. {
  1124. cubeMesh.submit(viewId
  1125. , cubeMtx[jj]
  1126. , programTextureLightning
  1127. , s_renderStates[RenderState::ProjectionShadows_DrawDiffuse]
  1128. , figureTex
  1129. );
  1130. }
  1131. }
  1132. // Reset these to default..
  1133. s_uniforms.m_params.m_ambientPass = 1.0f;
  1134. s_uniforms.m_params.m_lightningPass = 1.0f;
  1135. }
  1136. break;
  1137. };
  1138. //lights
  1139. const float lightScale[3] = { 1.5f, 1.5f, 1.5f };
  1140. float lightMtx[16];
  1141. for (uint8_t ii = 0; ii < numLights; ++ii)
  1142. {
  1143. s_uniforms.m_color[0] = lightRgbInnerR[ii][0];
  1144. s_uniforms.m_color[1] = lightRgbInnerR[ii][1];
  1145. s_uniforms.m_color[2] = lightRgbInnerR[ii][2];
  1146. mtxBillboard(lightMtx, viewState.m_view, lightPosRadius[ii], lightScale);
  1147. vplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_7
  1148. , lightMtx
  1149. , programColorTexture
  1150. , s_renderStates[RenderState::Custom_BlendLightTexture]
  1151. , flareTex
  1152. );
  1153. }
  1154. // Draw floor bottom.
  1155. float floorBottomMtx[16];
  1156. bx::mtxSRT(floorBottomMtx
  1157. , 20.0f //scaleX
  1158. , 20.0f //scaleY
  1159. , 20.0f //scaleZ
  1160. , 0.0f //rotX
  1161. , 0.0f //rotY
  1162. , 0.0f //rotZ
  1163. , 0.0f //translateX
  1164. , -0.1f //translateY
  1165. , 0.0f //translateZ
  1166. );
  1167. hplaneMesh.submit(RENDER_VIEWID_RANGE1_PASS_7
  1168. , floorBottomMtx
  1169. , programTexture
  1170. , s_renderStates[RenderState::Custom_DrawPlaneBottom]
  1171. , figureTex
  1172. );
  1173. // Setup view rect and transform for all used views.
  1174. setViewRectMask(s_viewMask, 0, 0, viewState.m_width, viewState.m_height);
  1175. setViewTransformMask(s_viewMask, viewState.m_view, viewState.m_proj);
  1176. s_viewMask = 0;
  1177. // Advance to next frame. Rendering thread will be kicked to
  1178. // process submitted rendering primitives.
  1179. bgfx::frame();
  1180. //reset clear values on used views
  1181. clearViewMask(s_clearMask, BGFX_CLEAR_NONE, clearValues);
  1182. s_clearMask = 0;
  1183. }
  1184. // Cleanup.
  1185. bunnyMesh.unload();
  1186. columnMesh.unload();
  1187. cubeMesh.unload();
  1188. hplaneMesh.unload();
  1189. vplaneMesh.unload();
  1190. bgfx::destroyTexture(figureTex);
  1191. bgfx::destroyTexture(fieldstoneTex);
  1192. bgfx::destroyTexture(flareTex);
  1193. bgfx::destroyProgram(programTextureLightning);
  1194. bgfx::destroyProgram(programColorLightning);
  1195. bgfx::destroyProgram(programColorTexture);
  1196. bgfx::destroyProgram(programColorBlack);
  1197. bgfx::destroyProgram(programTexture);
  1198. bgfx::destroyUniform(s_texColor);
  1199. s_uniforms.destroy();
  1200. cameraDestroy();
  1201. imguiDestroy();
  1202. // Shutdown bgfx.
  1203. bgfx::shutdown();
  1204. return 0;
  1205. }