diff options
Diffstat (limited to '3rdparty/bgfx/examples/18-ibl/ibl.cpp')
-rw-r--r-- | 3rdparty/bgfx/examples/18-ibl/ibl.cpp | 748 |
1 files changed, 516 insertions, 232 deletions
diff --git a/3rdparty/bgfx/examples/18-ibl/ibl.cpp b/3rdparty/bgfx/examples/18-ibl/ibl.cpp index 51a194730e4..a0cf6268d9c 100644 --- a/3rdparty/bgfx/examples/18-ibl/ibl.cpp +++ b/3rdparty/bgfx/examples/18-ibl/ibl.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2014 Dario Manesku. All rights reserved. + * Copyright 2014-2016 Dario Manesku. All rights reserved. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ @@ -18,86 +18,51 @@ static float s_texelHalf = 0.0f; struct Uniforms { - void init() - { - m_time = 0.0f; - bx::mtxIdentity(m_mtx); - - u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Mat4); - u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4); - u_flags = bgfx::createUniform("u_flags", bgfx::UniformType::Vec4); - u_camPos = bgfx::createUniform("u_camPos", bgfx::UniformType::Vec4); - u_rgbDiff = bgfx::createUniform("u_rgbDiff", bgfx::UniformType::Vec4); - u_rgbSpec = bgfx::createUniform("u_rgbSpec", bgfx::UniformType::Vec4); - } + enum { NumVec4 = 12 }; - // Call this once per frame. - void submitPerFrameUniforms() + void init() { - bgfx::setUniform(u_mtx, m_mtx); - bgfx::setUniform(u_flags, m_flags); - bgfx::setUniform(u_camPos, m_camPosTime); - bgfx::setUniform(u_rgbDiff, m_rgbDiff); - bgfx::setUniform(u_rgbSpec, m_rgbSpec); + u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, NumVec4); } - // Call this before each draw call. - void submitPerDrawUniforms() + void submit() { - bgfx::setUniform(u_params, m_params); + bgfx::setUniform(u_params, m_params, NumVec4); } void destroy() { - bgfx::destroyUniform(u_rgbSpec); - bgfx::destroyUniform(u_rgbDiff); - bgfx::destroyUniform(u_camPos); - bgfx::destroyUniform(u_flags); bgfx::destroyUniform(u_params); - bgfx::destroyUniform(u_mtx); } union { struct { - float m_glossiness; - float m_exposure; - float m_diffspec; - float m_time; - }; - - float m_params[4]; - }; - - union - { - struct - { - float m_diffuse; - float m_specular; - float m_diffuseIbl; - float m_specularIbl; + union + { + float m_mtx[16]; + /* 0*/ struct { float m_mtx0[4]; }; + /* 1*/ struct { float m_mtx1[4]; }; + /* 2*/ struct { float m_mtx2[4]; }; + /* 3*/ struct { float m_mtx3[4]; }; + }; + /* 4*/ struct { float m_glossiness, m_reflectivity, m_exposure, m_bgType; }; + /* 5*/ struct { float m_metalOrSpec, m_unused5[3]; }; + /* 6*/ struct { float m_doDiffuse, m_doSpecular, m_doDiffuseIbl, m_doSpecularIbl; }; + /* 7*/ struct { float m_cameraPos[3], m_unused7[1]; }; + /* 8*/ struct { float m_rgbDiff[4]; }; + /* 9*/ struct { float m_rgbSpec[4]; }; + /*10*/ struct { float m_lightDir[3], m_unused10[1]; }; + /*11*/ struct { float m_lightCol[3], m_unused11[1]; }; }; - float m_flags[4]; + float m_params[NumVec4*4]; }; - float m_mtx[16]; - float m_camPosTime[4]; - float m_rgbDiff[4]; - float m_rgbSpec[4]; - - bgfx::UniformHandle u_mtx; bgfx::UniformHandle u_params; - bgfx::UniformHandle u_flags; - bgfx::UniformHandle u_camPos; - bgfx::UniformHandle u_rgbDiff; - bgfx::UniformHandle u_rgbSpec; }; -static Uniforms s_uniforms; - struct PosColorTexCoord0Vertex { float m_x; @@ -181,11 +146,8 @@ struct LightProbe { enum Enum { - Wells, - Uffizi, - Pisa, - Ennis, - Grace, + Bolonga, + Kyoto, Count }; @@ -213,6 +175,253 @@ struct LightProbe bgfx::TextureHandle m_texIrr; }; +struct Camera +{ + Camera() + { + reset(); + } + + void reset() + { + m_target.curr[0] = 0.0f; + m_target.curr[1] = 0.0f; + m_target.curr[2] = 0.0f; + m_target.dest[0] = 0.0f; + m_target.dest[1] = 0.0f; + m_target.dest[2] = 0.0f; + + m_pos.curr[0] = 0.0f; + m_pos.curr[1] = 0.0f; + m_pos.curr[2] = -3.0f; + m_pos.dest[0] = 0.0f; + m_pos.dest[1] = 0.0f; + m_pos.dest[2] = -3.0f; + + m_orbit[0] = 0.0f; + m_orbit[1] = 0.0f; + } + + void mtxLookAt(float* _outViewMtx) + { + bx::mtxLookAt(_outViewMtx, m_pos.curr, m_target.curr); + } + + void orbit(float _dx, float _dy) + { + m_orbit[0] += _dx; + m_orbit[1] += _dy; + } + + void dolly(float _dz) + { + const float cnear = 1.0f; + const float cfar = 10.0f; + + const float toTarget[3] = + { + m_target.dest[0] - m_pos.dest[0], + m_target.dest[1] - m_pos.dest[1], + m_target.dest[2] - m_pos.dest[2], + }; + const float toTargetLen = bx::vec3Length(toTarget); + const float invToTargetLen = 1.0f/(toTargetLen+FLT_MIN); + const float toTargetNorm[3] = + { + toTarget[0]*invToTargetLen, + toTarget[1]*invToTargetLen, + toTarget[2]*invToTargetLen, + }; + + float delta = toTargetLen*_dz; + float newLen = toTargetLen + delta; + if ( (cnear < newLen || _dz < 0.0f) + && (newLen < cfar || _dz > 0.0f) ) + { + m_pos.dest[0] += toTargetNorm[0]*delta; + m_pos.dest[1] += toTargetNorm[1]*delta; + m_pos.dest[2] += toTargetNorm[2]*delta; + } + } + + void consumeOrbit(float _amount) + { + float consume[2]; + consume[0] = m_orbit[0]*_amount; + consume[1] = m_orbit[1]*_amount; + m_orbit[0] -= consume[0]; + m_orbit[1] -= consume[1]; + + const float toPos[3] = + { + m_pos.curr[0] - m_target.curr[0], + m_pos.curr[1] - m_target.curr[1], + m_pos.curr[2] - m_target.curr[2], + }; + const float toPosLen = bx::vec3Length(toPos); + const float invToPosLen = 1.0f/(toPosLen+FLT_MIN); + const float toPosNorm[3] = + { + toPos[0]*invToPosLen, + toPos[1]*invToPosLen, + toPos[2]*invToPosLen, + }; + + float ll[2]; + latLongFromVec(ll[0], ll[1], toPosNorm); + ll[0] += consume[0]; + ll[1] -= consume[1]; + ll[1] = bx::fclamp(ll[1], 0.02f, 0.98f); + + float tmp[3]; + vecFromLatLong(tmp, ll[0], ll[1]); + + float diff[3]; + diff[0] = (tmp[0]-toPosNorm[0])*toPosLen; + diff[1] = (tmp[1]-toPosNorm[1])*toPosLen; + diff[2] = (tmp[2]-toPosNorm[2])*toPosLen; + + m_pos.curr[0] += diff[0]; + m_pos.curr[1] += diff[1]; + m_pos.curr[2] += diff[2]; + m_pos.dest[0] += diff[0]; + m_pos.dest[1] += diff[1]; + m_pos.dest[2] += diff[2]; + } + + void update(float _dt) + { + const float amount = bx::fmin(_dt/0.12f, 1.0f); + + consumeOrbit(amount); + + m_target.curr[0] = bx::flerp(m_target.curr[0], m_target.dest[0], amount); + m_target.curr[1] = bx::flerp(m_target.curr[1], m_target.dest[1], amount); + m_target.curr[2] = bx::flerp(m_target.curr[2], m_target.dest[2], amount); + m_pos.curr[0] = bx::flerp(m_pos.curr[0], m_pos.dest[0], amount); + m_pos.curr[1] = bx::flerp(m_pos.curr[1], m_pos.dest[1], amount); + m_pos.curr[2] = bx::flerp(m_pos.curr[2], m_pos.dest[2], amount); + } + + void envViewMtx(float* _mtx) + { + const float toTarget[3] = + { + m_target.curr[0] - m_pos.curr[0], + m_target.curr[1] - m_pos.curr[1], + m_target.curr[2] - m_pos.curr[2], + }; + + const float toTargetLen = bx::vec3Length(toTarget); + const float invToTargetLen = 1.0f/(toTargetLen+FLT_MIN); + const float toTargetNorm[3] = + { + toTarget[0]*invToTargetLen, + toTarget[1]*invToTargetLen, + toTarget[2]*invToTargetLen, + }; + + float tmp[3]; + const float fakeUp[3] = { 0.0f, 1.0f, 0.0f }; + + float right[3]; + bx::vec3Cross(tmp, fakeUp, toTargetNorm); + bx::vec3Norm(right, tmp); + + float up[3]; + bx::vec3Cross(tmp, toTargetNorm, right); + bx::vec3Norm(up, tmp); + + _mtx[ 0] = right[0]; + _mtx[ 1] = right[1]; + _mtx[ 2] = right[2]; + _mtx[ 3] = 0.0f; + _mtx[ 4] = up[0]; + _mtx[ 5] = up[1]; + _mtx[ 6] = up[2]; + _mtx[ 7] = 0.0f; + _mtx[ 8] = toTargetNorm[0]; + _mtx[ 9] = toTargetNorm[1]; + _mtx[10] = toTargetNorm[2]; + _mtx[11] = 0.0f; + _mtx[12] = 0.0f; + _mtx[13] = 0.0f; + _mtx[14] = 0.0f; + _mtx[15] = 1.0f; + } + + static inline void vecFromLatLong(float _vec[3], float _u, float _v) + { + const float phi = _u * 2.0f*bx::pi; + const float theta = _v * bx::pi; + + const float st = bx::fsin(theta); + const float sp = bx::fsin(phi); + const float ct = bx::fcos(theta); + const float cp = bx::fcos(phi); + + _vec[0] = -st*sp; + _vec[1] = ct; + _vec[2] = -st*cp; + } + + static inline void latLongFromVec(float& _u, float& _v, const float _vec[3]) + { + const float phi = atan2f(_vec[0], _vec[2]); + const float theta = acosf(_vec[1]); + + _u = (bx::pi + phi)*bx::invPi*0.5f; + _v = theta*bx::invPi; + } + + struct Interp3f + { + float curr[3]; + float dest[3]; + }; + + Interp3f m_target; + Interp3f m_pos; + float m_orbit[2]; +}; + +struct Mouse +{ + Mouse() + : m_dx(0.0f) + , m_dy(0.0f) + , m_prevMx(0.0f) + , m_prevMy(0.0f) + , m_scroll(0) + , m_scrollPrev(0) + { + } + + void update(float _mx, float _my, int32_t _mz, uint32_t _width, uint32_t _height) + { + const float widthf = float(int32_t(_width)); + const float heightf = float(int32_t(_height)); + + // Delta movement. + m_dx = float(_mx - m_prevMx)/widthf; + m_dy = float(_my - m_prevMy)/heightf; + + m_prevMx = _mx; + m_prevMy = _my; + + // Scroll. + m_scroll = _mz - m_scrollPrev; + m_scrollPrev = _mz; + } + + float m_dx; // Screen space. + float m_dy; + float m_prevMx; + float m_prevMy; + int32_t m_scroll; + int32_t m_scrollPrev; +}; + int _main_(int _argc, char** _argv) { Args args(_argc, _argv); @@ -220,7 +429,10 @@ int _main_(int _argc, char** _argv) uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; - uint32_t reset = BGFX_RESET_VSYNC; + uint32_t reset = 0 + | BGFX_RESET_VSYNC + | BGFX_RESET_MSAA_X16 + ; bgfx::init(args.m_type, args.m_pciId); bgfx::reset(width, height, reset); @@ -240,18 +452,16 @@ int _main_(int _argc, char** _argv) imguiCreate(); // Uniforms. - s_uniforms.init(); + Uniforms uniforms; + uniforms.init(); // Vertex declarations. PosColorTexCoord0Vertex::init(); LightProbe lightProbes[LightProbe::Count]; - lightProbes[LightProbe::Wells ].load("wells"); - lightProbes[LightProbe::Uffizi].load("uffizi"); - lightProbes[LightProbe::Pisa ].load("pisa"); - lightProbes[LightProbe::Ennis ].load("ennis"); - lightProbes[LightProbe::Grace ].load("grace"); - LightProbe::Enum currentLightProbe = LightProbe::Wells; + lightProbes[LightProbe::Bolonga].load("bolonga"); + lightProbes[LightProbe::Kyoto ].load("kyoto"); + LightProbe::Enum currentLightProbe = LightProbe::Bolonga; bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Mat4); bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4); @@ -266,43 +476,73 @@ int _main_(int _argc, char** _argv) Mesh* meshBunny; meshBunny = meshLoad("meshes/bunny.bin"); + Mesh* meshOrb; + meshOrb = meshLoad("meshes/orb.bin"); + + Camera camera; + Mouse mouse; + struct Settings { - float m_speed; + Settings() + { + m_envRotCurr = 0.0f; + m_envRotDest = 0.0f; + m_lightDir[0] = -0.8f; + m_lightDir[1] = 0.2f; + m_lightDir[2] = -0.5f; + m_lightCol[0] = 1.0f; + m_lightCol[1] = 1.0f; + m_lightCol[2] = 1.0f; + m_glossiness = 0.7f; + m_exposure = 0.0f; + m_bgType = 3.0f; + m_radianceSlider = 2.0f; + m_reflectivity = 0.85f; + m_rgbDiff[0] = 1.0f; + m_rgbDiff[1] = 1.0f; + m_rgbDiff[2] = 1.0f; + m_rgbSpec[0] = 1.0f; + m_rgbSpec[1] = 1.0f; + m_rgbSpec[2] = 1.0f; + m_lod = 0.0f; + m_doDiffuse = false; + m_doSpecular = false; + m_doDiffuseIbl = true; + m_doSpecularIbl = true; + m_showLightColorWheel = true; + m_showDiffColorWheel = true; + m_showSpecColorWheel = true; + m_metalOrSpec = 0; + m_meshSelection = 0; + m_crossCubemapPreview = ImguiCubemap::Latlong; + } + + float m_envRotCurr; + float m_envRotDest; + float m_lightDir[3]; + float m_lightCol[3]; float m_glossiness; float m_exposure; - float m_diffspec; + float m_radianceSlider; + float m_bgType; + float m_reflectivity; float m_rgbDiff[3]; float m_rgbSpec[3]; - bool m_diffuse; - bool m_specular; - bool m_diffuseIbl; - bool m_specularIbl; + float m_lod; + bool m_doDiffuse; + bool m_doSpecular; + bool m_doDiffuseIbl; + bool m_doSpecularIbl; + bool m_showLightColorWheel; bool m_showDiffColorWheel; bool m_showSpecColorWheel; + uint8_t m_metalOrSpec; + uint8_t m_meshSelection; ImguiCubemap::Enum m_crossCubemapPreview; }; Settings settings; - settings.m_speed = 0.37f; - settings.m_glossiness = 1.0f; - settings.m_exposure = 0.0f; - settings.m_diffspec = 0.65f; - settings.m_rgbDiff[0] = 0.2f; - settings.m_rgbDiff[1] = 0.2f; - settings.m_rgbDiff[2] = 0.2f; - settings.m_rgbSpec[0] = 1.0f; - settings.m_rgbSpec[1] = 1.0f; - settings.m_rgbSpec[2] = 1.0f; - settings.m_diffuse = true; - settings.m_specular = true; - settings.m_diffuseIbl = true; - settings.m_specularIbl = true; - settings.m_showDiffColorWheel = true; - settings.m_showSpecColorWheel = false; - settings.m_crossCubemapPreview = ImguiCubemap::Cross; - - float time = 0.0f; int32_t leftScrollArea = 0; @@ -320,127 +560,114 @@ int _main_(int _argc, char** _argv) ); static int32_t rightScrollArea = 0; - imguiBeginScrollArea("Settings", width - 256 - 10, 10, 256, 540, &rightScrollArea); - - imguiLabel("Shade:"); - imguiSeparator(); - imguiBool("Diffuse", settings.m_diffuse); - imguiBool("Specular", settings.m_specular); - imguiBool("IBL Diffuse", settings.m_diffuseIbl); - imguiBool("IBL Specular", settings.m_specularIbl); - - imguiSeparatorLine(); - imguiSlider("Speed", settings.m_speed, 0.0f, 1.0f, 0.01f); - imguiSeparatorLine(); - - imguiSeparator(); - imguiSlider("Exposure", settings.m_exposure, -8.0f, 8.0f, 0.01f); - imguiSeparator(); - - imguiLabel("Environment:"); - currentLightProbe = LightProbe::Enum(imguiChoose(currentLightProbe - , "Wells" - , "Uffizi" - , "Pisa" - , "Ennis" - , "Grace" + imguiBeginScrollArea("", width - 256 - 10, 10, 256, 700, &rightScrollArea); + + imguiLabel("Environment light:"); + imguiIndent(); + imguiBool("IBL Diffuse", settings.m_doDiffuseIbl); + imguiBool("IBL Specular", settings.m_doSpecularIbl); + currentLightProbe = LightProbe::Enum(imguiTabs(currentLightProbe, true, ImguiAlign::LeftIndented, 16, 2, 2 + , "Bolonga" + , "Kyoto" ) ); - static float lod = 0.0f; - if (imguiCube(lightProbes[currentLightProbe].m_tex, lod, settings.m_crossCubemapPreview, true) ) + if (imguiCube(lightProbes[currentLightProbe].m_tex, settings.m_lod, settings.m_crossCubemapPreview, true) ) { settings.m_crossCubemapPreview = ImguiCubemap::Enum( (settings.m_crossCubemapPreview+1) % ImguiCubemap::Count); } - imguiSlider("Texture LOD", lod, 0.0f, 10.1f, 0.1f); - - imguiEndScrollArea(); - - imguiBeginScrollArea("Settings", 10, 70, 256, 576, &leftScrollArea); - - imguiLabel("Material properties:"); - imguiSeparator(); - imguiSlider("Diffuse - Specular", settings.m_diffspec, 0.0f, 1.0f, 0.01f); - imguiSlider("Glossiness" , settings.m_glossiness, 0.0f, 1.0f, 0.01f); - imguiSeparator(); - - imguiColorWheel("Diffuse color:", &settings.m_rgbDiff[0], settings.m_showDiffColorWheel); - imguiSeparator(); - imguiColorWheel("Specular color:", &settings.m_rgbSpec[0], settings.m_showSpecColorWheel); - - imguiSeparator(); - imguiLabel("Predefined materials:"); - imguiSeparator(); - - if (imguiButton("Gold") ) + imguiSlider("Texture LOD", settings.m_lod, 0.0f, 10.1f, 0.1f); + imguiUnindent(); + + imguiSeparator(8); + imguiLabel("Directional light:"); + imguiIndent(); + imguiBool("Diffuse", settings.m_doDiffuse); + imguiBool("Specular", settings.m_doSpecular); + const bool doDirectLighting = settings.m_doDiffuse || settings.m_doSpecular; + imguiSlider("Light direction X", settings.m_lightDir[0], -1.0f, 1.0f, 0.1f, doDirectLighting); + imguiSlider("Light direction Y", settings.m_lightDir[1], -1.0f, 1.0f, 0.1f, doDirectLighting); + imguiSlider("Light direction Z", settings.m_lightDir[2], -1.0f, 1.0f, 0.1f, doDirectLighting); + imguiColorWheel("Color:", settings.m_lightCol, settings.m_showLightColorWheel, 0.6f, doDirectLighting); + imguiUnindent(); + + imguiSeparator(8); + imguiLabel("Background:"); + imguiIndent(); { - settings.m_glossiness = 0.8f; - settings.m_diffspec = 1.0f; - - settings.m_rgbDiff[0] = 0.0f; - settings.m_rgbDiff[1] = 0.0f; - settings.m_rgbDiff[2] = 0.0f; - - settings.m_rgbSpec[0] = 1.0f; - settings.m_rgbSpec[1] = 0.86f; - settings.m_rgbSpec[2] = 0.58f; + int32_t selection; + if (0.0f == settings.m_bgType) { selection = 0; } + else if (7.0f == settings.m_bgType) { selection = 2; } + else { selection = 1; } + selection = imguiTabs(selection, true, ImguiAlign::LeftIndented, 16, 2, 3 + , "Skybox" + , "Radiance" + , "Irradiance" + ); + if (0 == selection) { settings.m_bgType = 0.0f; } + else if (2 == selection) { settings.m_bgType = 7.0f; } + else { settings.m_bgType = settings.m_radianceSlider; } + const bool isRadiance = (selection == 1); + imguiSlider("Mip level", settings.m_radianceSlider, 1.0f, 6.0f, 0.1f, isRadiance); } + imguiUnindent(); - if (imguiButton("Copper") ) - { - settings.m_glossiness = 0.67f; - settings.m_diffspec = 1.0f; + imguiSeparator(8); + imguiLabel("Post processing:"); + imguiIndent(); + imguiSlider("Exposure", settings.m_exposure, -4.0f, 4.0f, 0.1f); + imguiUnindent(); - settings.m_rgbDiff[0] = 0.0f; - settings.m_rgbDiff[1] = 0.0f; - settings.m_rgbDiff[2] = 0.0f; - - settings.m_rgbSpec[0] = 0.98f; - settings.m_rgbSpec[1] = 0.82f; - settings.m_rgbSpec[2] = 0.76f; - } + imguiSeparator(); - if (imguiButton("Titanium") ) - { - settings.m_glossiness = 0.57f; - settings.m_diffspec = 1.0f; + imguiEndScrollArea(); - settings.m_rgbDiff[0] = 0.0f; - settings.m_rgbDiff[1] = 0.0f; - settings.m_rgbDiff[2] = 0.0f; + imguiBeginScrollArea("", 10, 70, 256, 636, &leftScrollArea); - settings.m_rgbSpec[0] = 0.76f; - settings.m_rgbSpec[1] = 0.73f; - settings.m_rgbSpec[2] = 0.71f; - } + imguiLabel("Mesh:"); + imguiIndent(); + settings.m_meshSelection = imguiChoose(settings.m_meshSelection, "Bunny", "Orbs"); + imguiUnindent(); - if (imguiButton("Steel") ) + const bool isBunny = (0 == settings.m_meshSelection); + if (!isBunny) { - settings.m_glossiness = 0.82f; - settings.m_diffspec = 1.0f; - - settings.m_rgbDiff[0] = 0.0f; - settings.m_rgbDiff[1] = 0.0f; - settings.m_rgbDiff[2] = 0.0f; - - settings.m_rgbSpec[0] = 0.77f; - settings.m_rgbSpec[1] = 0.78f; - settings.m_rgbSpec[2] = 0.77f; + settings.m_metalOrSpec = 0; } + imguiSeparator(4); + imguiLabel("Workflow:"); + imguiIndent(); + if (imguiCheck("Metalness", 0 == settings.m_metalOrSpec, isBunny) ) { settings.m_metalOrSpec = 0; } + if (imguiCheck("Specular", 1 == settings.m_metalOrSpec, isBunny) ) { settings.m_metalOrSpec = 1; } + imguiUnindent(); + + imguiSeparator(4); + imguiLabel("Material:"); + imguiIndent(); + imguiSlider("Glossiness", settings.m_glossiness, 0.0f, 1.0f, 0.01f, isBunny); + imguiSlider(0 == settings.m_metalOrSpec ? "Metalness" : "Diffuse - Specular", settings.m_reflectivity, 0.0f, 1.0f, 0.01f, isBunny); + imguiUnindent(); + + imguiColorWheel("Diffuse:", &settings.m_rgbDiff[0], settings.m_showDiffColorWheel, 0.7f); + imguiSeparator(); + imguiColorWheel("Specular:", &settings.m_rgbSpec[0], settings.m_showSpecColorWheel, 0.7f, (1 == settings.m_metalOrSpec) && isBunny); + imguiEndScrollArea(); imguiEndFrame(); - s_uniforms.m_glossiness = settings.m_glossiness; - s_uniforms.m_exposure = settings.m_exposure; - s_uniforms.m_diffspec = settings.m_diffspec; - s_uniforms.m_flags[0] = float(settings.m_diffuse); - s_uniforms.m_flags[1] = float(settings.m_specular); - s_uniforms.m_flags[2] = float(settings.m_diffuseIbl); - s_uniforms.m_flags[3] = float(settings.m_specularIbl); - memcpy(s_uniforms.m_rgbDiff, settings.m_rgbDiff, 3*sizeof(float) ); - memcpy(s_uniforms.m_rgbSpec, settings.m_rgbSpec, 3*sizeof(float) ); - - s_uniforms.submitPerFrameUniforms(); + uniforms.m_glossiness = settings.m_glossiness; + uniforms.m_reflectivity = settings.m_reflectivity; + uniforms.m_exposure = settings.m_exposure; + uniforms.m_bgType = settings.m_bgType; + uniforms.m_metalOrSpec = float(settings.m_metalOrSpec); + uniforms.m_doDiffuse = float(settings.m_doDiffuse); + uniforms.m_doSpecular = float(settings.m_doSpecular); + uniforms.m_doDiffuseIbl = float(settings.m_doDiffuseIbl); + uniforms.m_doSpecularIbl = float(settings.m_doSpecularIbl); + memcpy(uniforms.m_rgbDiff, settings.m_rgbDiff, 3*sizeof(float) ); + memcpy(uniforms.m_rgbSpec, settings.m_rgbSpec, 3*sizeof(float) ); + memcpy(uniforms.m_lightDir, settings.m_lightDir, 3*sizeof(float) ); + memcpy(uniforms.m_lightCol, settings.m_lightCol, 3*sizeof(float) ); int64_t now = bx::getHPCounter(); static int64_t last = now; @@ -448,9 +675,7 @@ int _main_(int _argc, char** _argv) last = now; const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0/freq; - - time += (float)(frameTime*settings.m_speed/freq); - s_uniforms.m_camPosTime[3] = time; + const float deltaTimeSec = float(double(frameTime)/freq); // Use debug font to print information about this example. bgfx::dbgTextClear(); @@ -458,53 +683,111 @@ int _main_(int _argc, char** _argv) bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Image-based lighting."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); - float at[3] = { 0.0f, 0.0f, 0.0f }; - float eye[3] = { 0.0f, 0.0f, -3.0f }; - - bx::mtxRotateXY(s_uniforms.m_mtx - , 0.0f - , time - ); + // Camera. + const bool mouseOverGui = imguiMouseOverArea(); + mouse.update(float(mouseState.m_mx), float(mouseState.m_my), mouseState.m_mz, width, height); + if (!mouseOverGui) + { + if (mouseState.m_buttons[entry::MouseButton::Left]) + { + camera.orbit(mouse.m_dx, mouse.m_dy); + } + else if (mouseState.m_buttons[entry::MouseButton::Right]) + { + camera.dolly(mouse.m_dx + mouse.m_dy); + } + else if (mouseState.m_buttons[entry::MouseButton::Middle]) + { + settings.m_envRotDest += mouse.m_dx*2.0f; + } + else if (0 != mouse.m_scroll) + { + camera.dolly(float(mouse.m_scroll)*0.05f); + } + } + camera.update(deltaTimeSec); + memcpy(uniforms.m_cameraPos, camera.m_pos.curr, 3*sizeof(float) ); + // View Transform 0. float view[16]; float proj[16]; - bx::mtxIdentity(view); bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); bgfx::setViewTransform(0, view, proj); - bx::mtxLookAt(view, eye, at); - memcpy(s_uniforms.m_camPosTime, eye, 3*sizeof(float) ); - bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); + // View Transform 1. + camera.mtxLookAt(view); + bx::mtxProj(proj, 45.0f, float(width)/float(height), 0.1f, 100.0f); bgfx::setViewTransform(1, view, proj); + // View rect. bgfx::setViewRect(0, 0, 0, width, height); bgfx::setViewRect(1, 0, 0, width, height); - // View 0. + // Env rotation. + const float amount = bx::fmin(deltaTimeSec/0.12f, 1.0f); + settings.m_envRotCurr = bx::flerp(settings.m_envRotCurr, settings.m_envRotDest, amount); + + // Env mtx. + float mtxEnvView[16]; + camera.envViewMtx(mtxEnvView); + float mtxEnvRot[16]; + bx::mtxRotateY(mtxEnvRot, settings.m_envRotCurr); + bx::mtxMul(uniforms.m_mtx, mtxEnvView, mtxEnvRot); + + // Submit view 0. bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex); + bgfx::setTexture(1, s_texCubeIrr, lightProbes[currentLightProbe].m_texIrr); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, true); - s_uniforms.submitPerDrawUniforms(); + uniforms.submit(); bgfx::submit(0, programSky); - // View 1. - float mtx[16]; - bx::mtxSRT(mtx - , 1.0f - , 1.0f - , 1.0f - , 0.0f - , bx::pi+time - , 0.0f - , 0.0f - , -1.0f - , 0.0f - ); - - bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex); - bgfx::setTexture(1, s_texCubeIrr, lightProbes[currentLightProbe].m_texIrr); - meshSubmit(meshBunny, 1, programMesh, mtx); + // Submit view 1. + if (0 == settings.m_meshSelection) + { + // Submit bunny. + float mtx[16]; + bx::mtxSRT(mtx, 1.0f, 1.0f, 1.0f, 0.0f, bx::pi, 0.0f, 0.0f, -0.80f, 0.0f); + bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex); + bgfx::setTexture(1, s_texCubeIrr, lightProbes[currentLightProbe].m_texIrr); + meshSubmit(meshBunny, 1, programMesh, mtx); + } + else + { + // Submit orbs. + for (float yy = 0, yend = 5.0f; yy < yend; yy+=1.0f) + { + for (float xx = 0, xend = 5.0f; xx < xend; xx+=1.0f) + { + const float scale = 1.2f; + const float spacing = 2.2f; + const float yAdj = -0.8f; + + float mtx[16]; + bx::mtxSRT(mtx + , scale/xend + , scale/xend + , scale/xend + , 0.0f + , 0.0f + , 0.0f + , 0.0f + (xx/xend)*spacing - (1.0f + (scale-1.0f)*0.5f - 1.0f/xend) + , yAdj/yend + (yy/yend)*spacing - (1.0f + (scale-1.0f)*0.5f - 1.0f/yend) + , 0.0f + ); + + uniforms.m_glossiness = xx*(1.0f/xend); + uniforms.m_reflectivity = (yend-yy)*(1.0f/yend); + uniforms.m_metalOrSpec = 0.0f; + uniforms.submit(); + + bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex); + bgfx::setTexture(1, s_texCubeIrr, lightProbes[currentLightProbe].m_texIrr); + meshSubmit(meshOrb, 1, programMesh, mtx); + } + } + } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. @@ -512,6 +795,7 @@ int _main_(int _argc, char** _argv) } meshUnload(meshBunny); + meshUnload(meshOrb); // Cleanup. bgfx::destroyProgram(programMesh); @@ -530,7 +814,7 @@ int _main_(int _argc, char** _argv) lightProbes[ii].destroy(); } - s_uniforms.destroy(); + uniforms.destroy(); imguiDestroy(); |