ibl.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. /*
  2. * Copyright 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.h>
  9. #include <bx/timer.h>
  10. #include <bx/readerwriter.h>
  11. #include "entry/entry.h"
  12. #include "fpumath.h"
  13. #include "imgui/imgui.h"
  14. #include <stdio.h>
  15. #include <string.h>
  16. static const char* s_shaderPath = NULL;
  17. static bool s_flipV = false;
  18. static float s_texelHalf = 0.0f;
  19. static void shaderFilePath(char* _out, const char* _name)
  20. {
  21. strcpy(_out, s_shaderPath);
  22. strcat(_out, _name);
  23. strcat(_out, ".bin");
  24. }
  25. long int fsize(FILE* _file)
  26. {
  27. long int pos = ftell(_file);
  28. fseek(_file, 0L, SEEK_END);
  29. long int size = ftell(_file);
  30. fseek(_file, pos, SEEK_SET);
  31. return size;
  32. }
  33. static const bgfx::Memory* load(const char* _filePath)
  34. {
  35. FILE* file = fopen(_filePath, "rb");
  36. if (NULL != file)
  37. {
  38. uint32_t size = (uint32_t)fsize(file);
  39. const bgfx::Memory* mem = bgfx::alloc(size+1);
  40. size_t ignore = fread(mem->data, 1, size, file);
  41. BX_UNUSED(ignore);
  42. fclose(file);
  43. mem->data[mem->size-1] = '\0';
  44. return mem;
  45. }
  46. return NULL;
  47. }
  48. static const bgfx::Memory* loadShader(const char* _name)
  49. {
  50. char filePath[512];
  51. shaderFilePath(filePath, _name);
  52. return load(filePath);
  53. }
  54. static bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName)
  55. {
  56. const bgfx::Memory* mem;
  57. mem = loadShader(_vsName);
  58. bgfx::VertexShaderHandle vs = bgfx::createVertexShader(mem);
  59. mem = loadShader(_fsName);
  60. bgfx::FragmentShaderHandle fs = bgfx::createFragmentShader(mem);
  61. bgfx::ProgramHandle program = bgfx::createProgram(vs, fs);
  62. bgfx::destroyVertexShader(vs);
  63. bgfx::destroyFragmentShader(fs);
  64. return program;
  65. }
  66. static const bgfx::Memory* loadTexture(const char* _name)
  67. {
  68. char filePath[512];
  69. strcpy(filePath, "textures/");
  70. strcat(filePath, _name);
  71. return load(filePath);
  72. }
  73. struct Uniforms
  74. {
  75. void init()
  76. {
  77. m_time = 0.0f;
  78. mtxIdentity(m_mtx);
  79. u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f);
  80. u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv);
  81. u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv);
  82. u_flags = bgfx::createUniform("u_flags", bgfx::UniformType::Uniform4fv);
  83. u_camPos = bgfx::createUniform("u_camPos", bgfx::UniformType::Uniform3fv);
  84. u_rgbDiff = bgfx::createUniform("u_rgbDiff", bgfx::UniformType::Uniform3fv);
  85. u_rgbSpec = bgfx::createUniform("u_rgbSpec", bgfx::UniformType::Uniform3fv);
  86. }
  87. // Call this once at initialization.
  88. void submitConstUniforms()
  89. {
  90. }
  91. // Call this once per frame.
  92. void submitPerFrameUniforms()
  93. {
  94. bgfx::setUniform(u_time, &m_time);
  95. bgfx::setUniform(u_mtx, m_mtx);
  96. bgfx::setUniform(u_flags, m_flags);
  97. bgfx::setUniform(u_camPos, m_camPos);
  98. bgfx::setUniform(u_rgbDiff, m_rgbDiff);
  99. bgfx::setUniform(u_rgbSpec, m_rgbSpec);
  100. }
  101. // Call this before each draw call.
  102. void submitPerDrawUniforms()
  103. {
  104. bgfx::setUniform(u_params, m_params);
  105. }
  106. void destroy()
  107. {
  108. bgfx::destroyUniform(u_rgbSpec);
  109. bgfx::destroyUniform(u_rgbDiff);
  110. bgfx::destroyUniform(u_camPos);
  111. bgfx::destroyUniform(u_flags);
  112. bgfx::destroyUniform(u_params);
  113. bgfx::destroyUniform(u_mtx);
  114. bgfx::destroyUniform(u_time);
  115. }
  116. union
  117. {
  118. struct
  119. {
  120. float m_glossiness;
  121. float m_exposure;
  122. float m_diffspec;
  123. float m_unused0;
  124. };
  125. float m_params[4];
  126. };
  127. union
  128. {
  129. struct
  130. {
  131. float m_diffuse;
  132. float m_specular;
  133. float m_diffuseIbl;
  134. float m_specularIbl;
  135. };
  136. float m_flags[4];
  137. };
  138. float m_time;
  139. float m_mtx[16];
  140. float m_camPos[3];
  141. float m_rgbDiff[3];
  142. float m_rgbSpec[3];
  143. bgfx::UniformHandle u_time;
  144. bgfx::UniformHandle u_mtx;
  145. bgfx::UniformHandle u_params;
  146. bgfx::UniformHandle u_flags;
  147. bgfx::UniformHandle u_camPos;
  148. bgfx::UniformHandle u_rgbDiff;
  149. bgfx::UniformHandle u_rgbSpec;
  150. };
  151. static Uniforms s_uniforms;
  152. struct Aabb
  153. {
  154. float m_min[3];
  155. float m_max[3];
  156. };
  157. struct Obb
  158. {
  159. float m_mtx[16];
  160. };
  161. struct Sphere
  162. {
  163. float m_center[3];
  164. float m_radius;
  165. };
  166. struct Primitive
  167. {
  168. uint32_t m_startIndex;
  169. uint32_t m_numIndices;
  170. uint32_t m_startVertex;
  171. uint32_t m_numVertices;
  172. Sphere m_sphere;
  173. Aabb m_aabb;
  174. Obb m_obb;
  175. };
  176. typedef std::vector<Primitive> PrimitiveArray;
  177. struct Group
  178. {
  179. Group()
  180. {
  181. reset();
  182. }
  183. void reset()
  184. {
  185. m_vbh.idx = bgfx::invalidHandle;
  186. m_ibh.idx = bgfx::invalidHandle;
  187. m_prims.clear();
  188. }
  189. bgfx::VertexBufferHandle m_vbh;
  190. bgfx::IndexBufferHandle m_ibh;
  191. Sphere m_sphere;
  192. Aabb m_aabb;
  193. Obb m_obb;
  194. PrimitiveArray m_prims;
  195. };
  196. struct Mesh
  197. {
  198. void load(const char* _filePath)
  199. {
  200. #define BGFX_CHUNK_MAGIC_VB BX_MAKEFOURCC('V', 'B', ' ', 0x0)
  201. #define BGFX_CHUNK_MAGIC_IB BX_MAKEFOURCC('I', 'B', ' ', 0x0)
  202. #define BGFX_CHUNK_MAGIC_PRI BX_MAKEFOURCC('P', 'R', 'I', 0x0)
  203. bx::CrtFileReader reader;
  204. reader.open(_filePath);
  205. Group group;
  206. uint32_t chunk;
  207. while (4 == bx::read(&reader, chunk) )
  208. {
  209. switch (chunk)
  210. {
  211. case BGFX_CHUNK_MAGIC_VB:
  212. {
  213. bx::read(&reader, group.m_sphere);
  214. bx::read(&reader, group.m_aabb);
  215. bx::read(&reader, group.m_obb);
  216. bx::read(&reader, m_decl);
  217. uint16_t stride = m_decl.getStride();
  218. uint16_t numVertices;
  219. bx::read(&reader, numVertices);
  220. const bgfx::Memory* mem = bgfx::alloc(numVertices*stride);
  221. bx::read(&reader, mem->data, mem->size);
  222. group.m_vbh = bgfx::createVertexBuffer(mem, m_decl);
  223. }
  224. break;
  225. case BGFX_CHUNK_MAGIC_IB:
  226. {
  227. uint32_t numIndices;
  228. bx::read(&reader, numIndices);
  229. const bgfx::Memory* mem = bgfx::alloc(numIndices*2);
  230. bx::read(&reader, mem->data, mem->size);
  231. group.m_ibh = bgfx::createIndexBuffer(mem);
  232. }
  233. break;
  234. case BGFX_CHUNK_MAGIC_PRI:
  235. {
  236. uint16_t len;
  237. bx::read(&reader, len);
  238. std::string material;
  239. material.resize(len);
  240. bx::read(&reader, const_cast<char*>(material.c_str() ), len);
  241. uint16_t num;
  242. bx::read(&reader, num);
  243. for (uint32_t ii = 0; ii < num; ++ii)
  244. {
  245. bx::read(&reader, len);
  246. std::string name;
  247. name.resize(len);
  248. bx::read(&reader, const_cast<char*>(name.c_str() ), len);
  249. Primitive prim;
  250. bx::read(&reader, prim.m_startIndex);
  251. bx::read(&reader, prim.m_numIndices);
  252. bx::read(&reader, prim.m_startVertex);
  253. bx::read(&reader, prim.m_numVertices);
  254. bx::read(&reader, prim.m_sphere);
  255. bx::read(&reader, prim.m_aabb);
  256. bx::read(&reader, prim.m_obb);
  257. group.m_prims.push_back(prim);
  258. }
  259. m_groups.push_back(group);
  260. group.reset();
  261. }
  262. break;
  263. default:
  264. DBG("%08x at %d", chunk, reader.seek() );
  265. break;
  266. }
  267. }
  268. reader.close();
  269. }
  270. void unload()
  271. {
  272. for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it)
  273. {
  274. const Group& group = *it;
  275. bgfx::destroyVertexBuffer(group.m_vbh);
  276. if (bgfx::isValid(group.m_ibh) )
  277. {
  278. bgfx::destroyIndexBuffer(group.m_ibh);
  279. }
  280. }
  281. m_groups.clear();
  282. }
  283. void submit(uint8_t _view, bgfx::ProgramHandle _program, float* _mtx)
  284. {
  285. for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it)
  286. {
  287. const Group& group = *it;
  288. // Set uniforms.
  289. s_uniforms.submitPerDrawUniforms();
  290. // Set model matrix for rendering.
  291. bgfx::setTransform(_mtx);
  292. bgfx::setProgram(_program);
  293. bgfx::setIndexBuffer(group.m_ibh);
  294. bgfx::setVertexBuffer(group.m_vbh);
  295. // Set render states.
  296. bgfx::setState(0
  297. | BGFX_STATE_RGB_WRITE
  298. | BGFX_STATE_ALPHA_WRITE
  299. | BGFX_STATE_DEPTH_WRITE
  300. | BGFX_STATE_DEPTH_TEST_LESS
  301. | BGFX_STATE_CULL_CCW
  302. | BGFX_STATE_MSAA
  303. );
  304. // Submit primitive for rendering to view 0.
  305. bgfx::submit(_view);
  306. }
  307. }
  308. bgfx::VertexDecl m_decl;
  309. typedef std::vector<Group> GroupArray;
  310. GroupArray m_groups;
  311. };
  312. struct PosColorTexCoord0Vertex
  313. {
  314. float m_x;
  315. float m_y;
  316. float m_z;
  317. uint32_t m_rgba;
  318. float m_u;
  319. float m_v;
  320. static void init()
  321. {
  322. ms_decl.begin();
  323. ms_decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
  324. ms_decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
  325. ms_decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
  326. ms_decl.end();
  327. }
  328. static bgfx::VertexDecl ms_decl;
  329. };
  330. bgfx::VertexDecl PosColorTexCoord0Vertex::ms_decl;
  331. void screenSpaceQuad(float _textureWidth, float _textureHeight, bool _originBottomLeft = false, float _width = 1.0f, float _height = 1.0f)
  332. {
  333. if (bgfx::checkAvailTransientVertexBuffer(3, PosColorTexCoord0Vertex::ms_decl) )
  334. {
  335. bgfx::TransientVertexBuffer vb;
  336. bgfx::allocTransientVertexBuffer(&vb, 3, PosColorTexCoord0Vertex::ms_decl);
  337. PosColorTexCoord0Vertex* vertex = (PosColorTexCoord0Vertex*)vb.data;
  338. const float zz = 0.0f;
  339. const float minx = -_width;
  340. const float maxx = _width;
  341. const float miny = 0.0f;
  342. const float maxy = _height*2.0f;
  343. const float texelHalfW = s_texelHalf/_textureWidth;
  344. const float texelHalfH = s_texelHalf/_textureHeight;
  345. const float minu = -1.0f + texelHalfW;
  346. const float maxu = 1.0f + texelHalfW;
  347. float minv = texelHalfH;
  348. float maxv = 2.0f + texelHalfH;
  349. if (_originBottomLeft)
  350. {
  351. std::swap(minv, maxv);
  352. minv -= 1.0f;
  353. maxv -= 1.0f;
  354. }
  355. vertex[0].m_x = minx;
  356. vertex[0].m_y = miny;
  357. vertex[0].m_z = zz;
  358. vertex[0].m_rgba = 0xffffffff;
  359. vertex[0].m_u = minu;
  360. vertex[0].m_v = minv;
  361. vertex[1].m_x = maxx;
  362. vertex[1].m_y = miny;
  363. vertex[1].m_z = zz;
  364. vertex[1].m_rgba = 0xffffffff;
  365. vertex[1].m_u = maxu;
  366. vertex[1].m_v = minv;
  367. vertex[2].m_x = maxx;
  368. vertex[2].m_y = maxy;
  369. vertex[2].m_z = zz;
  370. vertex[2].m_rgba = 0xffffffff;
  371. vertex[2].m_u = maxu;
  372. vertex[2].m_v = maxv;
  373. bgfx::setVertexBuffer(&vb);
  374. }
  375. }
  376. void mtxScaleRotateTranslate(float* _result
  377. , const float _scaleX
  378. , const float _scaleY
  379. , const float _scaleZ
  380. , const float _rotX
  381. , const float _rotY
  382. , const float _rotZ
  383. , const float _translateX
  384. , const float _translateY
  385. , const float _translateZ
  386. )
  387. {
  388. float mtxRotateTranslate[16];
  389. float mtxScale[16];
  390. mtxRotateXYZ(mtxRotateTranslate, _rotX, _rotY, _rotZ);
  391. mtxRotateTranslate[12] = _translateX;
  392. mtxRotateTranslate[13] = _translateY;
  393. mtxRotateTranslate[14] = _translateZ;
  394. memset(mtxScale, 0, sizeof(float)*16);
  395. mtxScale[0] = _scaleX;
  396. mtxScale[5] = _scaleY;
  397. mtxScale[10] = _scaleZ;
  398. mtxScale[15] = 1.0f;
  399. mtxMul(_result, mtxScale, mtxRotateTranslate);
  400. }
  401. void imguiBool(const char* _str, bool& _flag, bool _enabled = true)
  402. {
  403. if (imguiCheck(_str, _flag, _enabled) )
  404. {
  405. _flag = !_flag;
  406. }
  407. }
  408. int _main_(int /*_argc*/, char** /*_argv*/)
  409. {
  410. uint32_t width = 1280;
  411. uint32_t height = 720;
  412. uint32_t debug = BGFX_DEBUG_TEXT;
  413. uint32_t reset = BGFX_RESET_VSYNC;
  414. bgfx::init();
  415. bgfx::reset(width, height, reset);
  416. // Enable debug text.
  417. bgfx::setDebug(debug);
  418. // Set views clear state.
  419. bgfx::setViewClear(0
  420. , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
  421. , 0x303030ff
  422. , 1.0f
  423. , 0
  424. );
  425. // Setup root path for binary shaders. Shader binaries are different
  426. // for each renderer.
  427. switch (bgfx::getRendererType() )
  428. {
  429. default:
  430. case bgfx::RendererType::Direct3D9:
  431. s_shaderPath = "shaders/dx9/";
  432. break;
  433. case bgfx::RendererType::Direct3D11:
  434. s_shaderPath = "shaders/dx11/";
  435. break;
  436. case bgfx::RendererType::OpenGL:
  437. s_shaderPath = "shaders/glsl/";
  438. s_flipV = true;
  439. break;
  440. case bgfx::RendererType::OpenGLES2:
  441. case bgfx::RendererType::OpenGLES3:
  442. s_shaderPath = "shaders/gles/";
  443. s_flipV = true;
  444. break;
  445. }
  446. // Imgui.
  447. FILE* file = fopen("font/droidsans.ttf", "rb");
  448. uint32_t size = (uint32_t)fsize(file);
  449. void* data = malloc(size);
  450. size_t ignore = fread(data, 1, size, file);
  451. BX_UNUSED(ignore);
  452. fclose(file);
  453. imguiCreate(data, size);
  454. // Uniforms.
  455. s_uniforms.init();
  456. // Vertex declarations.
  457. PosColorTexCoord0Vertex::init();
  458. struct LightProbe
  459. {
  460. void load(const char* _name)
  461. {
  462. const uint32_t texFlags = BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP;
  463. char filePath[512];
  464. strcpy(filePath, _name);
  465. strcat(filePath, "_lod.dds");
  466. m_tex = bgfx::createTexture(loadTexture(filePath), texFlags);
  467. strcpy(filePath, _name);
  468. strcat(filePath, "_irr.dds");
  469. m_texIrr = bgfx::createTexture(loadTexture(filePath), texFlags);
  470. }
  471. void destroy()
  472. {
  473. bgfx::destroyTexture(m_tex);
  474. bgfx::destroyTexture(m_texIrr);
  475. }
  476. bgfx::TextureHandle m_tex;
  477. bgfx::TextureHandle m_texIrr;
  478. };
  479. enum LightProbes
  480. {
  481. LPWells,
  482. LPUffizi,
  483. LPPisa,
  484. LPEnnis,
  485. LPGrace,
  486. LPCount
  487. };
  488. LightProbe lightProbes[LPCount];
  489. lightProbes[LPWells].load("wells");
  490. lightProbes[LPUffizi].load("uffizi");
  491. lightProbes[LPPisa].load("pisa");
  492. lightProbes[LPEnnis].load("ennis");
  493. lightProbes[LPGrace].load("grace");
  494. uint8_t currentLightProbe = LPWells;
  495. bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f);
  496. bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv);
  497. bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv);
  498. bgfx::UniformHandle u_flags = bgfx::createUniform("u_flags", bgfx::UniformType::Uniform4fv);
  499. bgfx::UniformHandle u_camPos = bgfx::createUniform("u_camPos", bgfx::UniformType::Uniform3fv);
  500. bgfx::UniformHandle u_texCube = bgfx::createUniform("u_texCube", bgfx::UniformType::Uniform1i);
  501. bgfx::UniformHandle u_texCubeIrr = bgfx::createUniform("u_texCubeIrr", bgfx::UniformType::Uniform1i);
  502. bgfx::UniformHandle u_texAlbedo = bgfx::createUniform("u_texAlbedo", bgfx::UniformType::Uniform1i);
  503. bgfx::UniformHandle u_texNormal = bgfx::createUniform("u_texNormal", bgfx::UniformType::Uniform1i);
  504. bgfx::UniformHandle u_texSpecular = bgfx::createUniform("u_texSpecular", bgfx::UniformType::Uniform1i);
  505. bgfx::UniformHandle u_texRoughness = bgfx::createUniform("u_texRoughness", bgfx::UniformType::Uniform1i);
  506. bgfx::ProgramHandle programMesh = loadProgram("vs_ibl_mesh", "fs_ibl_mesh");
  507. bgfx::ProgramHandle programSky = loadProgram("vs_ibl_skybox", "fs_ibl_skybox");
  508. Mesh meshBunny;
  509. meshBunny.load("meshes/bunny.bin");
  510. struct Settings
  511. {
  512. float m_speed;
  513. float m_glossiness;
  514. float m_exposure;
  515. float m_diffspec;
  516. float m_rgbDiff[3];
  517. float m_rgbSpec[3];
  518. bool m_diffuse;
  519. bool m_specular;
  520. bool m_diffuseIbl;
  521. bool m_specularIbl;
  522. bool m_singleSliderDiff;
  523. bool m_singleSliderSpec;
  524. };
  525. Settings settings;
  526. settings.m_speed = 0.37f;
  527. settings.m_glossiness = 1.0f;
  528. settings.m_exposure = 0.0f;
  529. settings.m_diffspec = 0.65f;
  530. settings.m_rgbDiff[0] = 0.2f;
  531. settings.m_rgbDiff[1] = 0.2f;
  532. settings.m_rgbDiff[2] = 0.2f;
  533. settings.m_rgbSpec[0] = 1.0f;
  534. settings.m_rgbSpec[1] = 1.0f;
  535. settings.m_rgbSpec[2] = 1.0f;
  536. settings.m_diffuse = true;
  537. settings.m_specular = true;
  538. settings.m_diffuseIbl = true;
  539. settings.m_specularIbl = true;
  540. settings.m_singleSliderDiff = false;
  541. settings.m_singleSliderSpec = false;
  542. float time = 0.0f;
  543. s_uniforms.submitConstUniforms();
  544. entry::MouseState mouseState;
  545. while (!entry::processEvents(width, height, debug, reset, &mouseState) )
  546. {
  547. imguiBeginFrame(mouseState.m_mx
  548. , mouseState.m_my
  549. , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0)
  550. | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0)
  551. , 0
  552. , width
  553. , height
  554. );
  555. static int32_t rightScrollArea = 0;
  556. imguiBeginScrollArea("Settings", width - 256 - 10, 10, 256, 426, &rightScrollArea);
  557. imguiLabel("Shade:");
  558. imguiSeparator();
  559. imguiBool("Diffuse", settings.m_diffuse);
  560. imguiBool("Specular", settings.m_specular);
  561. imguiBool("IBL Diffuse", settings.m_diffuseIbl);
  562. imguiBool("IBL Specular", settings.m_specularIbl);
  563. imguiSeparatorLine();
  564. imguiSlider("Speed", &settings.m_speed, 0.0f, 1.0f, 0.01f);
  565. imguiSeparatorLine();
  566. imguiLabel("Environment:");
  567. currentLightProbe = imguiChoose(currentLightProbe
  568. , "Wells"
  569. , "Uffizi"
  570. , "Pisa"
  571. , "Ennis"
  572. , "Grace"
  573. );
  574. imguiSeparator();
  575. imguiSlider("Exposure", &settings.m_exposure, -8.0f, 8.0f, 0.01f);
  576. imguiEndScrollArea();
  577. static int32_t leftScrollArea = 0;
  578. imguiBeginScrollArea("Settings", 10, 70, 256, 576, &leftScrollArea);
  579. imguiLabel("Material properties:");
  580. imguiSeparator();
  581. imguiSlider("Diffuse - Specular", &settings.m_diffspec, 0.0f, 1.0f, 0.01f);
  582. imguiSlider("Glossiness" , &settings.m_glossiness, 0.0f, 1.0f, 0.01f);
  583. imguiSeparatorLine();
  584. imguiLabel("Diffuse color:");
  585. imguiSeparator();
  586. imguiBool("Single slider", settings.m_singleSliderDiff);
  587. if (settings.m_singleSliderDiff)
  588. {
  589. imguiSlider("RGB:", &settings.m_rgbDiff[0], 0.0f, 1.0f, 0.01f);
  590. settings.m_rgbDiff[1] = settings.m_rgbDiff[0];
  591. settings.m_rgbDiff[2] = settings.m_rgbDiff[0];
  592. }
  593. else
  594. {
  595. imguiSlider("R:", &settings.m_rgbDiff[0], 0.0f, 1.0f, 0.01f);
  596. imguiSlider("G:", &settings.m_rgbDiff[1], 0.0f, 1.0f, 0.01f);
  597. imguiSlider("B:", &settings.m_rgbDiff[2], 0.0f, 1.0f, 0.01f);
  598. }
  599. imguiSeparatorLine();
  600. imguiLabel("Specular color:");
  601. imguiSeparator();
  602. imguiBool("Single slider", settings.m_singleSliderSpec);
  603. if (settings.m_singleSliderSpec)
  604. {
  605. imguiSlider("RGB:", &settings.m_rgbSpec[0], 0.0f, 1.0f, 0.01f);
  606. settings.m_rgbSpec[1] = settings.m_rgbSpec[0];
  607. settings.m_rgbSpec[2] = settings.m_rgbSpec[0];
  608. }
  609. else
  610. {
  611. imguiSlider("R:", &settings.m_rgbSpec[0], 0.0f, 1.0f, 0.01f);
  612. imguiSlider("G:", &settings.m_rgbSpec[1], 0.0f, 1.0f, 0.01f);
  613. imguiSlider("B:", &settings.m_rgbSpec[2], 0.0f, 1.0f, 0.01f);
  614. }
  615. imguiSeparatorLine();
  616. imguiLabel("Predefined materials:");
  617. imguiSeparator();
  618. if (imguiButton("Gold") )
  619. {
  620. settings.m_glossiness = 0.8f;
  621. settings.m_diffspec = 1.0f;
  622. settings.m_rgbDiff[0] = 0.0f;
  623. settings.m_rgbDiff[1] = 0.0f;
  624. settings.m_rgbDiff[2] = 0.0f;
  625. settings.m_rgbSpec[0] = 1.0f;
  626. settings.m_rgbSpec[1] = 0.86f;
  627. settings.m_rgbSpec[2] = 0.58f;
  628. settings.m_singleSliderSpec = false;
  629. }
  630. if (imguiButton("Copper") )
  631. {
  632. settings.m_glossiness = 0.67f;
  633. settings.m_diffspec = 1.0f;
  634. settings.m_rgbDiff[0] = 0.0f;
  635. settings.m_rgbDiff[1] = 0.0f;
  636. settings.m_rgbDiff[2] = 0.0f;
  637. settings.m_rgbSpec[0] = 0.98f;
  638. settings.m_rgbSpec[1] = 0.82f;
  639. settings.m_rgbSpec[2] = 0.76f;
  640. settings.m_singleSliderSpec = false;
  641. }
  642. if (imguiButton("Titanium") )
  643. {
  644. settings.m_glossiness = 0.57f;
  645. settings.m_diffspec = 1.0f;
  646. settings.m_rgbDiff[0] = 0.0f;
  647. settings.m_rgbDiff[1] = 0.0f;
  648. settings.m_rgbDiff[2] = 0.0f;
  649. settings.m_rgbSpec[0] = 0.76f;
  650. settings.m_rgbSpec[1] = 0.73f;
  651. settings.m_rgbSpec[2] = 0.71f;
  652. settings.m_singleSliderSpec = false;
  653. }
  654. if (imguiButton("Steel") )
  655. {
  656. settings.m_glossiness = 0.82f;
  657. settings.m_diffspec = 1.0f;
  658. settings.m_rgbDiff[0] = 0.0f;
  659. settings.m_rgbDiff[1] = 0.0f;
  660. settings.m_rgbDiff[2] = 0.0f;
  661. settings.m_rgbSpec[0] = 0.77f;
  662. settings.m_rgbSpec[1] = 0.78f;
  663. settings.m_rgbSpec[2] = 0.77f;
  664. settings.m_singleSliderSpec = false;
  665. }
  666. imguiEndScrollArea();
  667. imguiEndFrame();
  668. s_uniforms.m_glossiness = settings.m_glossiness;
  669. s_uniforms.m_exposure = settings.m_exposure;
  670. s_uniforms.m_diffspec = settings.m_diffspec;
  671. s_uniforms.m_flags[0] = float(settings.m_diffuse);
  672. s_uniforms.m_flags[1] = float(settings.m_specular);
  673. s_uniforms.m_flags[2] = float(settings.m_diffuseIbl);
  674. s_uniforms.m_flags[3] = float(settings.m_specularIbl);
  675. memcpy(s_uniforms.m_rgbDiff, settings.m_rgbDiff, 3*sizeof(float));
  676. memcpy(s_uniforms.m_rgbSpec, settings.m_rgbSpec, 3*sizeof(float));
  677. s_uniforms.submitPerFrameUniforms();
  678. int64_t now = bx::getHPCounter();
  679. static int64_t last = now;
  680. const int64_t frameTime = now - last;
  681. last = now;
  682. const double freq = double(bx::getHPFrequency() );
  683. const double toMs = 1000.0/freq;
  684. time += (float)(frameTime*settings.m_speed/freq);
  685. s_uniforms.m_time = time;
  686. // Use debug font to print information about this example.
  687. bgfx::dbgTextClear();
  688. bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/18-ibl");
  689. bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Image based lightning.");
  690. bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
  691. float at[3] = { 0.0f, 0.0f, 0.0f };
  692. float eye[3] = { 0.0f, 0.0f, -3.0f };
  693. mtxRotateXY(s_uniforms.m_mtx
  694. , 0.0f
  695. , time
  696. );
  697. float view[16];
  698. float proj[16];
  699. mtxIdentity(view);
  700. mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f);
  701. bgfx::setViewTransform(0, view, proj);
  702. mtxLookAt(view, eye, at);
  703. memcpy(s_uniforms.m_camPos, eye, 3*sizeof(float));
  704. mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);
  705. bgfx::setViewTransform(1, view, proj);
  706. bgfx::setViewRect(0, 0, 0, width, height);
  707. bgfx::setViewRect(1, 0, 0, width, height);
  708. // View 0.
  709. bgfx::setTexture(4, u_texCube, lightProbes[currentLightProbe].m_tex);
  710. bgfx::setProgram(programSky);
  711. bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
  712. screenSpaceQuad( (float)width, (float)height, true);
  713. bgfx::submit(0);
  714. // View 1.
  715. float mtx[16];
  716. mtxScaleRotateTranslate(mtx
  717. , 1.0f
  718. , 1.0f
  719. , 1.0f
  720. , 0.0f
  721. , (float(M_PI))+time
  722. , 0.0f
  723. , 0.0f
  724. , -1.0f
  725. , 0.0f
  726. );
  727. bgfx::setTexture(4, u_texCube, lightProbes[currentLightProbe].m_tex);
  728. bgfx::setTexture(5, u_texCubeIrr, lightProbes[currentLightProbe].m_texIrr);
  729. meshBunny.submit(1, programMesh, mtx);
  730. // Advance to next frame. Rendering thread will be kicked to
  731. // process submitted rendering primitives.
  732. bgfx::frame();
  733. }
  734. meshBunny.unload();
  735. // Cleanup.
  736. bgfx::destroyProgram(programMesh);
  737. bgfx::destroyProgram(programSky);
  738. bgfx::destroyUniform(u_camPos);
  739. bgfx::destroyUniform(u_flags);
  740. bgfx::destroyUniform(u_params);
  741. bgfx::destroyUniform(u_mtx);
  742. bgfx::destroyUniform(u_time);
  743. bgfx::destroyUniform(u_texRoughness);
  744. bgfx::destroyUniform(u_texSpecular);
  745. bgfx::destroyUniform(u_texNormal);
  746. bgfx::destroyUniform(u_texAlbedo);
  747. bgfx::destroyUniform(u_texCube);
  748. bgfx::destroyUniform(u_texCubeIrr);
  749. for (uint8_t ii = 0; ii < LPCount; ++ii)
  750. {
  751. lightProbes[ii].destroy();
  752. }
  753. s_uniforms.destroy();
  754. imguiDestroy();
  755. // Shutdown bgfx.
  756. bgfx::shutdown();
  757. return 0;
  758. }