ibl.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. /*
  2. * Copyright 2014 Dario Manesku. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. #include <vector>
  6. #include <string>
  7. #include "common.h"
  8. #include "bgfx_utils.h"
  9. #include "imgui/imgui.h"
  10. #include "nanovg/nanovg.h"
  11. #include <bx/readerwriter.h>
  12. #include <bx/string.h>
  13. static float s_texelHalf = 0.0f;
  14. struct Uniforms
  15. {
  16. void init()
  17. {
  18. m_time = 0.0f;
  19. bx::mtxIdentity(m_mtx);
  20. u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f);
  21. u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv);
  22. u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv);
  23. u_flags = bgfx::createUniform("u_flags", bgfx::UniformType::Uniform4fv);
  24. u_camPos = bgfx::createUniform("u_camPos", bgfx::UniformType::Uniform3fv);
  25. u_rgbDiff = bgfx::createUniform("u_rgbDiff", bgfx::UniformType::Uniform3fv);
  26. u_rgbSpec = bgfx::createUniform("u_rgbSpec", bgfx::UniformType::Uniform3fv);
  27. }
  28. // Call this once per frame.
  29. void submitPerFrameUniforms()
  30. {
  31. bgfx::setUniform(u_time, &m_time);
  32. bgfx::setUniform(u_mtx, m_mtx);
  33. bgfx::setUniform(u_flags, m_flags);
  34. bgfx::setUniform(u_camPos, m_camPos);
  35. bgfx::setUniform(u_rgbDiff, m_rgbDiff);
  36. bgfx::setUniform(u_rgbSpec, m_rgbSpec);
  37. }
  38. // Call this before each draw call.
  39. void submitPerDrawUniforms()
  40. {
  41. bgfx::setUniform(u_params, m_params);
  42. }
  43. void destroy()
  44. {
  45. bgfx::destroyUniform(u_rgbSpec);
  46. bgfx::destroyUniform(u_rgbDiff);
  47. bgfx::destroyUniform(u_camPos);
  48. bgfx::destroyUniform(u_flags);
  49. bgfx::destroyUniform(u_params);
  50. bgfx::destroyUniform(u_mtx);
  51. bgfx::destroyUniform(u_time);
  52. }
  53. union
  54. {
  55. struct
  56. {
  57. float m_glossiness;
  58. float m_exposure;
  59. float m_diffspec;
  60. float m_unused0;
  61. };
  62. float m_params[4];
  63. };
  64. union
  65. {
  66. struct
  67. {
  68. float m_diffuse;
  69. float m_specular;
  70. float m_diffuseIbl;
  71. float m_specularIbl;
  72. };
  73. float m_flags[4];
  74. };
  75. float m_time;
  76. float m_mtx[16];
  77. float m_camPos[3];
  78. float m_rgbDiff[3];
  79. float m_rgbSpec[3];
  80. bgfx::UniformHandle u_time;
  81. bgfx::UniformHandle u_mtx;
  82. bgfx::UniformHandle u_params;
  83. bgfx::UniformHandle u_flags;
  84. bgfx::UniformHandle u_camPos;
  85. bgfx::UniformHandle u_rgbDiff;
  86. bgfx::UniformHandle u_rgbSpec;
  87. };
  88. static Uniforms s_uniforms;
  89. struct Aabb
  90. {
  91. float m_min[3];
  92. float m_max[3];
  93. };
  94. struct Obb
  95. {
  96. float m_mtx[16];
  97. };
  98. struct Sphere
  99. {
  100. float m_center[3];
  101. float m_radius;
  102. };
  103. struct Primitive
  104. {
  105. uint32_t m_startIndex;
  106. uint32_t m_numIndices;
  107. uint32_t m_startVertex;
  108. uint32_t m_numVertices;
  109. Sphere m_sphere;
  110. Aabb m_aabb;
  111. Obb m_obb;
  112. };
  113. typedef std::vector<Primitive> PrimitiveArray;
  114. struct Group
  115. {
  116. Group()
  117. {
  118. reset();
  119. }
  120. void reset()
  121. {
  122. m_vbh.idx = bgfx::invalidHandle;
  123. m_ibh.idx = bgfx::invalidHandle;
  124. m_prims.clear();
  125. }
  126. bgfx::VertexBufferHandle m_vbh;
  127. bgfx::IndexBufferHandle m_ibh;
  128. Sphere m_sphere;
  129. Aabb m_aabb;
  130. Obb m_obb;
  131. PrimitiveArray m_prims;
  132. };
  133. namespace bgfx
  134. {
  135. int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl);
  136. }
  137. struct Mesh
  138. {
  139. void load(const char* _filePath)
  140. {
  141. #define BGFX_CHUNK_MAGIC_VB BX_MAKEFOURCC('V', 'B', ' ', 0x1)
  142. #define BGFX_CHUNK_MAGIC_IB BX_MAKEFOURCC('I', 'B', ' ', 0x0)
  143. #define BGFX_CHUNK_MAGIC_PRI BX_MAKEFOURCC('P', 'R', 'I', 0x0)
  144. bx::CrtFileReader reader;
  145. reader.open(_filePath);
  146. Group group;
  147. uint32_t chunk;
  148. while (4 == bx::read(&reader, chunk) )
  149. {
  150. switch (chunk)
  151. {
  152. case BGFX_CHUNK_MAGIC_VB:
  153. {
  154. bx::read(&reader, group.m_sphere);
  155. bx::read(&reader, group.m_aabb);
  156. bx::read(&reader, group.m_obb);
  157. bgfx::read(&reader, m_decl);
  158. uint16_t stride = m_decl.getStride();
  159. uint16_t numVertices;
  160. bx::read(&reader, numVertices);
  161. const bgfx::Memory* mem = bgfx::alloc(numVertices*stride);
  162. bx::read(&reader, mem->data, mem->size);
  163. group.m_vbh = bgfx::createVertexBuffer(mem, m_decl);
  164. }
  165. break;
  166. case BGFX_CHUNK_MAGIC_IB:
  167. {
  168. uint32_t numIndices;
  169. bx::read(&reader, numIndices);
  170. const bgfx::Memory* mem = bgfx::alloc(numIndices*2);
  171. bx::read(&reader, mem->data, mem->size);
  172. group.m_ibh = bgfx::createIndexBuffer(mem);
  173. }
  174. break;
  175. case BGFX_CHUNK_MAGIC_PRI:
  176. {
  177. uint16_t len;
  178. bx::read(&reader, len);
  179. std::string material;
  180. material.resize(len);
  181. bx::read(&reader, const_cast<char*>(material.c_str() ), len);
  182. uint16_t num;
  183. bx::read(&reader, num);
  184. for (uint32_t ii = 0; ii < num; ++ii)
  185. {
  186. bx::read(&reader, len);
  187. std::string name;
  188. name.resize(len);
  189. bx::read(&reader, const_cast<char*>(name.c_str() ), len);
  190. Primitive prim;
  191. bx::read(&reader, prim.m_startIndex);
  192. bx::read(&reader, prim.m_numIndices);
  193. bx::read(&reader, prim.m_startVertex);
  194. bx::read(&reader, prim.m_numVertices);
  195. bx::read(&reader, prim.m_sphere);
  196. bx::read(&reader, prim.m_aabb);
  197. bx::read(&reader, prim.m_obb);
  198. group.m_prims.push_back(prim);
  199. }
  200. m_groups.push_back(group);
  201. group.reset();
  202. }
  203. break;
  204. default:
  205. DBG("%08x at %d", chunk, reader.seek() );
  206. break;
  207. }
  208. }
  209. reader.close();
  210. }
  211. void unload()
  212. {
  213. for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it)
  214. {
  215. const Group& group = *it;
  216. bgfx::destroyVertexBuffer(group.m_vbh);
  217. if (bgfx::isValid(group.m_ibh) )
  218. {
  219. bgfx::destroyIndexBuffer(group.m_ibh);
  220. }
  221. }
  222. m_groups.clear();
  223. }
  224. void submit(uint8_t _view, bgfx::ProgramHandle _program, float* _mtx)
  225. {
  226. for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it)
  227. {
  228. const Group& group = *it;
  229. // Set uniforms.
  230. s_uniforms.submitPerDrawUniforms();
  231. // Set model matrix for rendering.
  232. bgfx::setTransform(_mtx);
  233. bgfx::setProgram(_program);
  234. bgfx::setIndexBuffer(group.m_ibh);
  235. bgfx::setVertexBuffer(group.m_vbh);
  236. // Set render states.
  237. bgfx::setState(0
  238. | BGFX_STATE_RGB_WRITE
  239. | BGFX_STATE_ALPHA_WRITE
  240. | BGFX_STATE_DEPTH_WRITE
  241. | BGFX_STATE_DEPTH_TEST_LESS
  242. | BGFX_STATE_CULL_CCW
  243. | BGFX_STATE_MSAA
  244. );
  245. // Submit primitive for rendering to view 0.
  246. bgfx::submit(_view);
  247. }
  248. }
  249. bgfx::VertexDecl m_decl;
  250. typedef std::vector<Group> GroupArray;
  251. GroupArray m_groups;
  252. };
  253. struct PosColorTexCoord0Vertex
  254. {
  255. float m_x;
  256. float m_y;
  257. float m_z;
  258. uint32_t m_rgba;
  259. float m_u;
  260. float m_v;
  261. static void init()
  262. {
  263. ms_decl
  264. .begin()
  265. .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
  266. .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
  267. .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
  268. .end();
  269. }
  270. static bgfx::VertexDecl ms_decl;
  271. };
  272. bgfx::VertexDecl PosColorTexCoord0Vertex::ms_decl;
  273. void screenSpaceQuad(float _textureWidth, float _textureHeight, bool _originBottomLeft = false, float _width = 1.0f, float _height = 1.0f)
  274. {
  275. if (bgfx::checkAvailTransientVertexBuffer(3, PosColorTexCoord0Vertex::ms_decl) )
  276. {
  277. bgfx::TransientVertexBuffer vb;
  278. bgfx::allocTransientVertexBuffer(&vb, 3, PosColorTexCoord0Vertex::ms_decl);
  279. PosColorTexCoord0Vertex* vertex = (PosColorTexCoord0Vertex*)vb.data;
  280. const float zz = 0.0f;
  281. const float minx = -_width;
  282. const float maxx = _width;
  283. const float miny = 0.0f;
  284. const float maxy = _height*2.0f;
  285. const float texelHalfW = s_texelHalf/_textureWidth;
  286. const float texelHalfH = s_texelHalf/_textureHeight;
  287. const float minu = -1.0f + texelHalfW;
  288. const float maxu = 1.0f + texelHalfW;
  289. float minv = texelHalfH;
  290. float maxv = 2.0f + texelHalfH;
  291. if (_originBottomLeft)
  292. {
  293. std::swap(minv, maxv);
  294. minv -= 1.0f;
  295. maxv -= 1.0f;
  296. }
  297. vertex[0].m_x = minx;
  298. vertex[0].m_y = miny;
  299. vertex[0].m_z = zz;
  300. vertex[0].m_rgba = 0xffffffff;
  301. vertex[0].m_u = minu;
  302. vertex[0].m_v = minv;
  303. vertex[1].m_x = maxx;
  304. vertex[1].m_y = miny;
  305. vertex[1].m_z = zz;
  306. vertex[1].m_rgba = 0xffffffff;
  307. vertex[1].m_u = maxu;
  308. vertex[1].m_v = minv;
  309. vertex[2].m_x = maxx;
  310. vertex[2].m_y = maxy;
  311. vertex[2].m_z = zz;
  312. vertex[2].m_rgba = 0xffffffff;
  313. vertex[2].m_u = maxu;
  314. vertex[2].m_v = maxv;
  315. bgfx::setVertexBuffer(&vb);
  316. }
  317. }
  318. struct LightProbe
  319. {
  320. enum Enum
  321. {
  322. Wells,
  323. Uffizi,
  324. Pisa,
  325. Ennis,
  326. Grace,
  327. Count
  328. };
  329. void load(const char* _name)
  330. {
  331. char filePath[512];
  332. strcpy(filePath, _name);
  333. strcat(filePath, "_lod.dds");
  334. m_tex = loadTexture(filePath, BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP);
  335. strcpy(filePath, _name);
  336. strcat(filePath, "_irr.dds");
  337. m_texIrr = loadTexture(filePath, BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP);
  338. }
  339. void destroy()
  340. {
  341. bgfx::destroyTexture(m_tex);
  342. bgfx::destroyTexture(m_texIrr);
  343. }
  344. bgfx::TextureHandle m_tex;
  345. bgfx::TextureHandle m_texIrr;
  346. };
  347. int _main_(int /*_argc*/, char** /*_argv*/)
  348. {
  349. uint32_t width = 1280;
  350. uint32_t height = 720;
  351. uint32_t debug = BGFX_DEBUG_TEXT;
  352. uint32_t reset = BGFX_RESET_VSYNC;
  353. bgfx::init();
  354. bgfx::reset(width, height, reset);
  355. // Enable debug text.
  356. bgfx::setDebug(debug);
  357. // Set views clear state.
  358. bgfx::setViewClear(0
  359. , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
  360. , 0x303030ff
  361. , 1.0f
  362. , 0
  363. );
  364. // Imgui.
  365. void* data = load("font/droidsans.ttf");
  366. imguiCreate(data);
  367. free(data);
  368. // Uniforms.
  369. s_uniforms.init();
  370. // Vertex declarations.
  371. PosColorTexCoord0Vertex::init();
  372. LightProbe lightProbes[LightProbe::Count];
  373. lightProbes[LightProbe::Wells ].load("wells");
  374. lightProbes[LightProbe::Uffizi].load("uffizi");
  375. lightProbes[LightProbe::Pisa ].load("pisa");
  376. lightProbes[LightProbe::Ennis ].load("ennis");
  377. lightProbes[LightProbe::Grace ].load("grace");
  378. LightProbe::Enum currentLightProbe = LightProbe::Wells;
  379. bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f);
  380. bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv);
  381. bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv);
  382. bgfx::UniformHandle u_flags = bgfx::createUniform("u_flags", bgfx::UniformType::Uniform4fv);
  383. bgfx::UniformHandle u_camPos = bgfx::createUniform("u_camPos", bgfx::UniformType::Uniform3fv);
  384. bgfx::UniformHandle u_texCube = bgfx::createUniform("u_texCube", bgfx::UniformType::Uniform1i);
  385. bgfx::UniformHandle u_texCubeIrr = bgfx::createUniform("u_texCubeIrr", bgfx::UniformType::Uniform1i);
  386. bgfx::ProgramHandle programMesh = loadProgram("vs_ibl_mesh", "fs_ibl_mesh");
  387. bgfx::ProgramHandle programSky = loadProgram("vs_ibl_skybox", "fs_ibl_skybox");
  388. Mesh meshBunny;
  389. meshBunny.load("meshes/bunny.bin");
  390. struct Settings
  391. {
  392. float m_speed;
  393. float m_glossiness;
  394. float m_exposure;
  395. float m_diffspec;
  396. float m_rgbDiff[3];
  397. float m_rgbSpec[3];
  398. bool m_diffuse;
  399. bool m_specular;
  400. bool m_diffuseIbl;
  401. bool m_specularIbl;
  402. bool m_showDiffColorWheel;
  403. bool m_showSpecColorWheel;
  404. bool m_crossCubemapPreview;
  405. };
  406. Settings settings;
  407. settings.m_speed = 0.37f;
  408. settings.m_glossiness = 1.0f;
  409. settings.m_exposure = 0.0f;
  410. settings.m_diffspec = 0.65f;
  411. settings.m_rgbDiff[0] = 0.2f;
  412. settings.m_rgbDiff[1] = 0.2f;
  413. settings.m_rgbDiff[2] = 0.2f;
  414. settings.m_rgbSpec[0] = 1.0f;
  415. settings.m_rgbSpec[1] = 1.0f;
  416. settings.m_rgbSpec[2] = 1.0f;
  417. settings.m_diffuse = true;
  418. settings.m_specular = true;
  419. settings.m_diffuseIbl = true;
  420. settings.m_specularIbl = true;
  421. settings.m_showDiffColorWheel = false;
  422. settings.m_showSpecColorWheel = false;
  423. settings.m_crossCubemapPreview = false;
  424. float time = 0.0f;
  425. int32_t leftScrollArea = 0;
  426. entry::MouseState mouseState;
  427. while (!entry::processEvents(width, height, debug, reset, &mouseState) )
  428. {
  429. imguiBeginFrame(mouseState.m_mx
  430. , mouseState.m_my
  431. , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0)
  432. | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0)
  433. , 0
  434. , width
  435. , height
  436. );
  437. static int32_t rightScrollArea = 0;
  438. imguiBeginScrollArea("Settings", width - 256 - 10, 10, 256, 590, &rightScrollArea);
  439. imguiLabel("Shade:");
  440. imguiSeparator();
  441. imguiBool("Diffuse", settings.m_diffuse);
  442. imguiBool("Specular", settings.m_specular);
  443. imguiBool("IBL Diffuse", settings.m_diffuseIbl);
  444. imguiBool("IBL Specular", settings.m_specularIbl);
  445. imguiSeparatorLine();
  446. imguiSlider("Speed", settings.m_speed, 0.0f, 1.0f, 0.01f);
  447. imguiSeparatorLine();
  448. imguiSeparator();
  449. imguiSlider("Exposure", settings.m_exposure, -8.0f, 8.0f, 0.01f);
  450. imguiSeparator();
  451. imguiLabel("Environment:");
  452. currentLightProbe = LightProbe::Enum(imguiChoose(currentLightProbe
  453. , "Wells"
  454. , "Uffizi"
  455. , "Pisa"
  456. , "Ennis"
  457. , "Grace"
  458. ) );
  459. static float lod = 0.0f;
  460. if (imguiCube(lightProbes[currentLightProbe].m_tex, lod, settings.m_crossCubemapPreview))
  461. {
  462. settings.m_crossCubemapPreview = !settings.m_crossCubemapPreview;
  463. }
  464. imguiSlider("Texture LOD", lod, float(0.0f), 10.1f, 0.1f);
  465. imguiEndScrollArea();
  466. imguiBeginScrollArea("Settings", 10, 70, 256, 576, &leftScrollArea);
  467. imguiLabel("Material properties:");
  468. imguiSeparator();
  469. imguiSlider("Diffuse - Specular", settings.m_diffspec, 0.0f, 1.0f, 0.01f);
  470. imguiSlider("Glossiness" , settings.m_glossiness, 0.0f, 1.0f, 0.01f);
  471. imguiSeparator();
  472. imguiColorWheel("Diffuse color:", &settings.m_rgbDiff[0], settings.m_showDiffColorWheel);
  473. imguiSeparator();
  474. imguiColorWheel("Specular color:", &settings.m_rgbSpec[0], settings.m_showSpecColorWheel);
  475. imguiSeparator();
  476. imguiLabel("Predefined materials:");
  477. imguiSeparator();
  478. if (imguiButton("Gold") )
  479. {
  480. settings.m_glossiness = 0.8f;
  481. settings.m_diffspec = 1.0f;
  482. settings.m_rgbDiff[0] = 0.0f;
  483. settings.m_rgbDiff[1] = 0.0f;
  484. settings.m_rgbDiff[2] = 0.0f;
  485. settings.m_rgbSpec[0] = 1.0f;
  486. settings.m_rgbSpec[1] = 0.86f;
  487. settings.m_rgbSpec[2] = 0.58f;
  488. }
  489. if (imguiButton("Copper") )
  490. {
  491. settings.m_glossiness = 0.67f;
  492. settings.m_diffspec = 1.0f;
  493. settings.m_rgbDiff[0] = 0.0f;
  494. settings.m_rgbDiff[1] = 0.0f;
  495. settings.m_rgbDiff[2] = 0.0f;
  496. settings.m_rgbSpec[0] = 0.98f;
  497. settings.m_rgbSpec[1] = 0.82f;
  498. settings.m_rgbSpec[2] = 0.76f;
  499. }
  500. if (imguiButton("Titanium") )
  501. {
  502. settings.m_glossiness = 0.57f;
  503. settings.m_diffspec = 1.0f;
  504. settings.m_rgbDiff[0] = 0.0f;
  505. settings.m_rgbDiff[1] = 0.0f;
  506. settings.m_rgbDiff[2] = 0.0f;
  507. settings.m_rgbSpec[0] = 0.76f;
  508. settings.m_rgbSpec[1] = 0.73f;
  509. settings.m_rgbSpec[2] = 0.71f;
  510. }
  511. if (imguiButton("Steel") )
  512. {
  513. settings.m_glossiness = 0.82f;
  514. settings.m_diffspec = 1.0f;
  515. settings.m_rgbDiff[0] = 0.0f;
  516. settings.m_rgbDiff[1] = 0.0f;
  517. settings.m_rgbDiff[2] = 0.0f;
  518. settings.m_rgbSpec[0] = 0.77f;
  519. settings.m_rgbSpec[1] = 0.78f;
  520. settings.m_rgbSpec[2] = 0.77f;
  521. }
  522. imguiEndScrollArea();
  523. imguiEndFrame();
  524. s_uniforms.m_glossiness = settings.m_glossiness;
  525. s_uniforms.m_exposure = settings.m_exposure;
  526. s_uniforms.m_diffspec = settings.m_diffspec;
  527. s_uniforms.m_flags[0] = float(settings.m_diffuse);
  528. s_uniforms.m_flags[1] = float(settings.m_specular);
  529. s_uniforms.m_flags[2] = float(settings.m_diffuseIbl);
  530. s_uniforms.m_flags[3] = float(settings.m_specularIbl);
  531. memcpy(s_uniforms.m_rgbDiff, settings.m_rgbDiff, 3*sizeof(float));
  532. memcpy(s_uniforms.m_rgbSpec, settings.m_rgbSpec, 3*sizeof(float));
  533. s_uniforms.submitPerFrameUniforms();
  534. int64_t now = bx::getHPCounter();
  535. static int64_t last = now;
  536. const int64_t frameTime = now - last;
  537. last = now;
  538. const double freq = double(bx::getHPFrequency() );
  539. const double toMs = 1000.0/freq;
  540. time += (float)(frameTime*settings.m_speed/freq);
  541. s_uniforms.m_time = time;
  542. // Use debug font to print information about this example.
  543. bgfx::dbgTextClear();
  544. bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/18-ibl");
  545. bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Image based lightning.");
  546. bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
  547. float at[3] = { 0.0f, 0.0f, 0.0f };
  548. float eye[3] = { 0.0f, 0.0f, -3.0f };
  549. bx::mtxRotateXY(s_uniforms.m_mtx
  550. , 0.0f
  551. , time
  552. );
  553. float view[16];
  554. float proj[16];
  555. bx::mtxIdentity(view);
  556. bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f);
  557. bgfx::setViewTransform(0, view, proj);
  558. bx::mtxLookAt(view, eye, at);
  559. memcpy(s_uniforms.m_camPos, eye, 3*sizeof(float));
  560. bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);
  561. bgfx::setViewTransform(1, view, proj);
  562. bgfx::setViewRect(0, 0, 0, width, height);
  563. bgfx::setViewRect(1, 0, 0, width, height);
  564. // View 0.
  565. bgfx::setTexture(4, u_texCube, lightProbes[currentLightProbe].m_tex);
  566. bgfx::setProgram(programSky);
  567. bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
  568. screenSpaceQuad( (float)width, (float)height, true);
  569. s_uniforms.submitPerDrawUniforms();
  570. bgfx::submit(0);
  571. // View 1.
  572. float mtx[16];
  573. bx::mtxSRT(mtx
  574. , 1.0f
  575. , 1.0f
  576. , 1.0f
  577. , 0.0f
  578. , bx::pi+time
  579. , 0.0f
  580. , 0.0f
  581. , -1.0f
  582. , 0.0f
  583. );
  584. bgfx::setTexture(4, u_texCube, lightProbes[currentLightProbe].m_tex);
  585. bgfx::setTexture(5, u_texCubeIrr, lightProbes[currentLightProbe].m_texIrr);
  586. meshBunny.submit(1, programMesh, mtx);
  587. // Advance to next frame. Rendering thread will be kicked to
  588. // process submitted rendering primitives.
  589. bgfx::frame();
  590. }
  591. meshBunny.unload();
  592. // Cleanup.
  593. bgfx::destroyProgram(programMesh);
  594. bgfx::destroyProgram(programSky);
  595. bgfx::destroyUniform(u_camPos);
  596. bgfx::destroyUniform(u_flags);
  597. bgfx::destroyUniform(u_params);
  598. bgfx::destroyUniform(u_mtx);
  599. bgfx::destroyUniform(u_time);
  600. bgfx::destroyUniform(u_texCube);
  601. bgfx::destroyUniform(u_texCubeIrr);
  602. for (uint8_t ii = 0; ii < LightProbe::Count; ++ii)
  603. {
  604. lightProbes[ii].destroy();
  605. }
  606. s_uniforms.destroy();
  607. imguiDestroy();
  608. // Shutdown bgfx.
  609. bgfx::shutdown();
  610. return 0;
  611. }