diff --git a/examples/18-ibl/ibl.cpp b/examples/18-ibl/ibl.cpp index 27f2b7221..c09a92430 100644 --- a/examples/18-ibl/ibl.cpp +++ b/examples/18-ibl/ibl.cpp @@ -420,422 +420,457 @@ struct Mouse int32_t m_scrollPrev; }; -int _main_(int _argc, char** _argv) +struct Settings { - Args args(_argc, _argv); + 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_radianceSlider; + float m_bgType; + float m_reflectivity; + float m_rgbDiff[3]; + float m_rgbSpec[3]; + 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; +}; - uint32_t width = 1280; - uint32_t height = 720; - uint32_t debug = BGFX_DEBUG_TEXT; - uint32_t reset = 0 + +class ExampleIbl : public entry::AppI +{ + void init(int _argc, char** _argv) BX_OVERRIDE + { + Args args(_argc, _argv); + + m_width = 1280; + m_height = 720; + m_debug = BGFX_DEBUG_TEXT; + m_reset = 0 | BGFX_RESET_VSYNC | BGFX_RESET_MSAA_X16 ; - - bgfx::init(args.m_type, args.m_pciId); - bgfx::reset(width, height, reset); - - // Enable debug text. - bgfx::setDebug(debug); - - // Set views clear state. - bgfx::setViewClear(0 - , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH - , 0x303030ff - , 1.0f - , 0 - ); - - // Imgui. - imguiCreate(); - - // Uniforms. - Uniforms uniforms; - uniforms.init(); - - // Vertex declarations. - PosColorTexCoord0Vertex::init(); - - LightProbe lightProbes[LightProbe::Count]; - 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); - bgfx::UniformHandle u_flags = bgfx::createUniform("u_flags", bgfx::UniformType::Vec4); - bgfx::UniformHandle u_camPos = bgfx::createUniform("u_camPos", bgfx::UniformType::Vec4); - bgfx::UniformHandle s_texCube = bgfx::createUniform("s_texCube", bgfx::UniformType::Int1); - bgfx::UniformHandle s_texCubeIrr = bgfx::createUniform("s_texCubeIrr", bgfx::UniformType::Int1); - - bgfx::ProgramHandle programMesh = loadProgram("vs_ibl_mesh", "fs_ibl_mesh"); - bgfx::ProgramHandle programSky = loadProgram("vs_ibl_skybox", "fs_ibl_skybox"); - - Mesh* meshBunny; - meshBunny = meshLoad("meshes/bunny.bin"); - - Mesh* meshOrb; - meshOrb = meshLoad("meshes/orb.bin"); - - Camera camera; - Mouse mouse; - - struct Settings + + bgfx::init(args.m_type, args.m_pciId); + bgfx::reset(m_width, m_height, m_reset); + + // Enable debug text. + bgfx::setDebug(m_debug); + + // Set views clear state. + bgfx::setViewClear(0 + , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH + , 0x303030ff + , 1.0f + , 0 + ); + + // Imgui. + imguiCreate(); + + // Uniforms. + m_uniforms.init(); + + // Vertex declarations. + PosColorTexCoord0Vertex::init(); + + m_lightProbes[LightProbe::Bolonga].load("bolonga"); + m_lightProbes[LightProbe::Kyoto ].load("kyoto"); + m_currentLightProbe = LightProbe::Bolonga; + + 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); + s_texCube = bgfx::createUniform("s_texCube", bgfx::UniformType::Int1); + s_texCubeIrr = bgfx::createUniform("s_texCubeIrr", bgfx::UniformType::Int1); + + m_programMesh = loadProgram("vs_ibl_mesh", "fs_ibl_mesh"); + m_programSky = loadProgram("vs_ibl_skybox", "fs_ibl_skybox"); + + m_meshBunny = meshLoad("meshes/bunny.bin"); + m_meshOrb = meshLoad("meshes/orb.bin"); + + m_leftScrollArea = 0; + } + + virtual int shutdown() BX_OVERRIDE { - Settings() + meshUnload(m_meshBunny); + meshUnload(m_meshOrb); + + // Cleanup. + bgfx::destroyProgram(m_programMesh); + bgfx::destroyProgram(m_programSky); + + bgfx::destroyUniform(u_camPos); + bgfx::destroyUniform(u_flags); + bgfx::destroyUniform(u_params); + bgfx::destroyUniform(u_mtx); + + bgfx::destroyUniform(s_texCube); + bgfx::destroyUniform(s_texCubeIrr); + + for (uint8_t ii = 0; ii < LightProbe::Count; ++ii) { - 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; + m_lightProbes[ii].destroy(); } + + m_uniforms.destroy(); + + imguiDestroy(); + + // Shutdown bgfx. + bgfx::shutdown(); + + return 0; + } - float m_envRotCurr; - float m_envRotDest; - float m_lightDir[3]; - float m_lightCol[3]; - float m_glossiness; - float m_exposure; - float m_radianceSlider; - float m_bgType; - float m_reflectivity; - float m_rgbDiff[3]; - float m_rgbSpec[3]; - 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; - - int32_t leftScrollArea = 0; - - entry::MouseState mouseState; - while (!entry::processEvents(width, height, debug, reset, &mouseState) ) + bool update() BX_OVERRIDE { - imguiBeginFrame(mouseState.m_mx - , mouseState.m_my - , (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) - | (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) - | (mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) - , mouseState.m_mz - , uint16_t(width) - , uint16_t(height) - ); - - static int32_t rightScrollArea = 0; - 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( - uint8_t(currentLightProbe) - , true - , ImguiAlign::LeftIndented - , 16 - , 2 - , 2 - , "Bolonga" - , "Kyoto" - ) ); - if (imguiCube(lightProbes[currentLightProbe].m_tex, settings.m_lod, settings.m_crossCubemapPreview, true) ) + if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) { - settings.m_crossCubemapPreview = ImguiCubemap::Enum( (settings.m_crossCubemapPreview+1) % ImguiCubemap::Count); - } - 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(); - { - int32_t selection; - if (0.0f == settings.m_bgType) { selection = UINT8_C(0); } - else if (7.0f == settings.m_bgType) { selection = UINT8_C(2); } - else { selection = UINT8_C(1); } - - selection = imguiTabs( - uint8_t(selection) - , true - , ImguiAlign::LeftIndented - , 16 - , 2 - , 3 - , "Skybox" - , "Radiance" - , "Irradiance" + imguiBeginFrame(m_mouseState.m_mx + , m_mouseState.m_my + , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) + | (m_mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0) + | (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0) + , m_mouseState.m_mz + , uint16_t(m_width) + , uint16_t(m_height) ); - 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(); - - imguiSeparator(8); - imguiLabel("Post processing:"); - imguiIndent(); - imguiSlider("Exposure", settings.m_exposure, -4.0f, 4.0f, 0.1f); - imguiUnindent(); - - imguiSeparator(); - - imguiEndScrollArea(); - - imguiBeginScrollArea("", 10, 70, 256, 636, &leftScrollArea); - - imguiLabel("Mesh:"); - imguiIndent(); - settings.m_meshSelection = uint8_t(imguiChoose(settings.m_meshSelection, "Bunny", "Orbs") ); - imguiUnindent(); - - const bool isBunny = (0 == settings.m_meshSelection); - if (!isBunny) - { - 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(); - - 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); - bx::memCopy(uniforms.m_rgbDiff, settings.m_rgbDiff, 3*sizeof(float) ); - bx::memCopy(uniforms.m_rgbSpec, settings.m_rgbSpec, 3*sizeof(float) ); - bx::memCopy(uniforms.m_lightDir, settings.m_lightDir, 3*sizeof(float) ); - bx::memCopy(uniforms.m_lightCol, settings.m_lightCol, 3*sizeof(float) ); - - int64_t now = bx::getHPCounter(); - static int64_t last = now; - const int64_t frameTime = now - last; - last = now; - const double freq = double(bx::getHPFrequency() ); - const double toMs = 1000.0/freq; - const float deltaTimeSec = float(double(frameTime)/freq); - - // Use debug font to print information about this example. - bgfx::dbgTextClear(); - bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/18-ibl"); - bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Image-based lighting."); - bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); - - // 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]) + + static int32_t rightScrollArea = 0; + imguiBeginScrollArea("", m_width - 256 - 10, 10, 256, 700, &rightScrollArea); + + imguiLabel("Environment light:"); + imguiIndent(); + imguiBool("IBL Diffuse", m_settings.m_doDiffuseIbl); + imguiBool("IBL Specular", m_settings.m_doSpecularIbl); + m_currentLightProbe = LightProbe::Enum(imguiTabs( + uint8_t(m_currentLightProbe) + , true + , ImguiAlign::LeftIndented + , 16 + , 2 + , 2 + , "Bolonga" + , "Kyoto" + ) ); + if (imguiCube(m_lightProbes[m_currentLightProbe].m_tex, m_settings.m_lod, m_settings.m_crossCubemapPreview, true) ) { - camera.orbit(mouse.m_dx, mouse.m_dy); + m_settings.m_crossCubemapPreview = ImguiCubemap::Enum( (m_settings.m_crossCubemapPreview+1) % ImguiCubemap::Count); } - else if (mouseState.m_buttons[entry::MouseButton::Right]) + imguiSlider("Texture LOD", m_settings.m_lod, 0.0f, 10.1f, 0.1f); + imguiUnindent(); + + imguiSeparator(8); + imguiLabel("Directional light:"); + imguiIndent(); + imguiBool("Diffuse", m_settings.m_doDiffuse); + imguiBool("Specular", m_settings.m_doSpecular); + const bool doDirectLighting = m_settings.m_doDiffuse || m_settings.m_doSpecular; + imguiSlider("Light direction X", m_settings.m_lightDir[0], -1.0f, 1.0f, 0.1f, doDirectLighting); + imguiSlider("Light direction Y", m_settings.m_lightDir[1], -1.0f, 1.0f, 0.1f, doDirectLighting); + imguiSlider("Light direction Z", m_settings.m_lightDir[2], -1.0f, 1.0f, 0.1f, doDirectLighting); + imguiColorWheel("Color:", m_settings.m_lightCol, m_settings.m_showLightColorWheel, 0.6f, doDirectLighting); + imguiUnindent(); + + imguiSeparator(8); + imguiLabel("Background:"); + imguiIndent(); { - camera.dolly(mouse.m_dx + mouse.m_dy); + int32_t selection; + if (0.0f == m_settings.m_bgType) { selection = UINT8_C(0); } + else if (7.0f == m_settings.m_bgType) { selection = UINT8_C(2); } + else { selection = UINT8_C(1); } + + selection = imguiTabs( + uint8_t(selection) + , true + , ImguiAlign::LeftIndented + , 16 + , 2 + , 3 + , "Skybox" + , "Radiance" + , "Irradiance" + ); + if (0 == selection) { m_settings.m_bgType = 0.0f; } + else if (2 == selection) { m_settings.m_bgType = 7.0f; } + else { m_settings.m_bgType = m_settings.m_radianceSlider; } + const bool isRadiance = (selection == 1); + imguiSlider("Mip level", m_settings.m_radianceSlider, 1.0f, 6.0f, 0.1f, isRadiance); } - else if (mouseState.m_buttons[entry::MouseButton::Middle]) + imguiUnindent(); + + imguiSeparator(8); + imguiLabel("Post processing:"); + imguiIndent(); + imguiSlider("Exposure", m_settings.m_exposure, -4.0f, 4.0f, 0.1f); + imguiUnindent(); + + imguiSeparator(); + + imguiEndScrollArea(); + + imguiBeginScrollArea("", 10, 70, 256, 636, &m_leftScrollArea); + + imguiLabel("Mesh:"); + imguiIndent(); + m_settings.m_meshSelection = uint8_t(imguiChoose(m_settings.m_meshSelection, "Bunny", "Orbs") ); + imguiUnindent(); + + const bool isBunny = (0 == m_settings.m_meshSelection); + if (!isBunny) { - settings.m_envRotDest += mouse.m_dx*2.0f; + m_settings.m_metalOrSpec = 0; } - else if (0 != mouse.m_scroll) + + imguiSeparator(4); + imguiLabel("Workflow:"); + imguiIndent(); + if (imguiCheck("Metalness", 0 == m_settings.m_metalOrSpec, isBunny) ) { m_settings.m_metalOrSpec = 0; } + if (imguiCheck("Specular", 1 == m_settings.m_metalOrSpec, isBunny) ) { m_settings.m_metalOrSpec = 1; } + imguiUnindent(); + + imguiSeparator(4); + imguiLabel("Material:"); + imguiIndent(); + imguiSlider("Glossiness", m_settings.m_glossiness, 0.0f, 1.0f, 0.01f, isBunny); + imguiSlider(0 == m_settings.m_metalOrSpec ? "Metalness" : "Diffuse - Specular", m_settings.m_reflectivity, 0.0f, 1.0f, 0.01f, isBunny); + imguiUnindent(); + + imguiColorWheel("Diffuse:", &m_settings.m_rgbDiff[0], m_settings.m_showDiffColorWheel, 0.7f); + imguiSeparator(); + imguiColorWheel("Specular:", &m_settings.m_rgbSpec[0], m_settings.m_showSpecColorWheel, 0.7f, (1 == m_settings.m_metalOrSpec) && isBunny); + + imguiEndScrollArea(); + + imguiEndFrame(); + + m_uniforms.m_glossiness = m_settings.m_glossiness; + m_uniforms.m_reflectivity = m_settings.m_reflectivity; + m_uniforms.m_exposure = m_settings.m_exposure; + m_uniforms.m_bgType = m_settings.m_bgType; + m_uniforms.m_metalOrSpec = float(m_settings.m_metalOrSpec); + m_uniforms.m_doDiffuse = float(m_settings.m_doDiffuse); + m_uniforms.m_doSpecular = float(m_settings.m_doSpecular); + m_uniforms.m_doDiffuseIbl = float(m_settings.m_doDiffuseIbl); + m_uniforms.m_doSpecularIbl = float(m_settings.m_doSpecularIbl); + bx::memCopy(m_uniforms.m_rgbDiff, m_settings.m_rgbDiff, 3*sizeof(float) ); + bx::memCopy(m_uniforms.m_rgbSpec, m_settings.m_rgbSpec, 3*sizeof(float) ); + bx::memCopy(m_uniforms.m_lightDir, m_settings.m_lightDir, 3*sizeof(float) ); + bx::memCopy(m_uniforms.m_lightCol, m_settings.m_lightCol, 3*sizeof(float) ); + + int64_t now = bx::getHPCounter(); + static int64_t last = now; + const int64_t frameTime = now - last; + last = now; + const double freq = double(bx::getHPFrequency() ); + const double toMs = 1000.0/freq; + const float deltaTimeSec = float(double(frameTime)/freq); + + // Use debug font to print information about this example. + bgfx::dbgTextClear(); + bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/18-ibl"); + bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Image-based lighting."); + bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); + + // Camera. + const bool mouseOverGui = imguiMouseOverArea(); + m_mouse.update(float(m_mouseState.m_mx), float(m_mouseState.m_my), m_mouseState.m_mz, m_width, m_height); + if (!mouseOverGui) { - camera.dolly(float(mouse.m_scroll)*0.05f); - } - } - camera.update(deltaTimeSec); - bx::memCopy(uniforms.m_cameraPos, camera.m_pos.curr, 3*sizeof(float) ); - - // View Transform 0. - float view[16]; - bx::mtxIdentity(view); - - const bgfx::Caps* caps = bgfx::getCaps(); - - float proj[16]; - bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f, 0.0, caps->homogeneousDepth); - bgfx::setViewTransform(0, view, proj); - - // View Transform 1. - camera.mtxLookAt(view); - bx::mtxProj(proj, 45.0f, float(width)/float(height), 0.1f, 100.0f, caps->homogeneousDepth); - bgfx::setViewTransform(1, view, proj); - - // View rect. - bgfx::setViewRect(0, 0, 0, uint16_t(width), uint16_t(height) ); - bgfx::setViewRect(1, 0, 0, uint16_t(width), uint16_t(height) ); - - // 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); // Used for Skybox. - - // 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); - uniforms.submit(); - bgfx::submit(0, programSky); - - // Submit view 1. - bx::memCopy(uniforms.m_mtx, mtxEnvRot, 16*sizeof(float)); // Used for IBL. - if (0 == settings.m_meshSelection) - { - // Submit bunny. - float mtx[16]; - bx::mtxSRT(mtx, 1.0f, 1.0f, 1.0f, 0.0f, bx::kPi, 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); - uniforms.submit(); - 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) + if (m_mouseState.m_buttons[entry::MouseButton::Left]) { - 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); + m_camera.orbit(m_mouse.m_dx, m_mouse.m_dy); + } + else if (m_mouseState.m_buttons[entry::MouseButton::Right]) + { + m_camera.dolly(m_mouse.m_dx + m_mouse.m_dy); + } + else if (m_mouseState.m_buttons[entry::MouseButton::Middle]) + { + m_settings.m_envRotDest += m_mouse.m_dx*2.0f; + } + else if (0 != m_mouse.m_scroll) + { + m_camera.dolly(float(m_mouse.m_scroll)*0.05f); } } + m_camera.update(deltaTimeSec); + bx::memCopy(m_uniforms.m_cameraPos, m_camera.m_pos.curr, 3*sizeof(float) ); + + // View Transform 0. + float view[16]; + bx::mtxIdentity(view); + + const bgfx::Caps* caps = bgfx::getCaps(); + + float proj[16]; + bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f, 0.0, caps->homogeneousDepth); + bgfx::setViewTransform(0, view, proj); + + // View Transform 1. + m_camera.mtxLookAt(view); + bx::mtxProj(proj, 45.0f, float(m_width)/float(m_height), 0.1f, 100.0f, caps->homogeneousDepth); + bgfx::setViewTransform(1, view, proj); + + // View rect. + bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); + bgfx::setViewRect(1, 0, 0, uint16_t(m_width), uint16_t(m_height) ); + + // Env rotation. + const float amount = bx::fmin(deltaTimeSec/0.12f, 1.0f); + m_settings.m_envRotCurr = bx::flerp(m_settings.m_envRotCurr, m_settings.m_envRotDest, amount); + + // Env mtx. + float mtxEnvView[16]; + m_camera.envViewMtx(mtxEnvView); + float mtxEnvRot[16]; + bx::mtxRotateY(mtxEnvRot, m_settings.m_envRotCurr); + bx::mtxMul(m_uniforms.m_mtx, mtxEnvView, mtxEnvRot); // Used for Skybox. + + // Submit view 0. + bgfx::setTexture(0, s_texCube, m_lightProbes[m_currentLightProbe].m_tex); + bgfx::setTexture(1, s_texCubeIrr, m_lightProbes[m_currentLightProbe].m_texIrr); + bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); + screenSpaceQuad( (float)m_width, (float)m_height, true); + m_uniforms.submit(); + bgfx::submit(0, m_programSky); + + // Submit view 1. + bx::memCopy(m_uniforms.m_mtx, mtxEnvRot, 16*sizeof(float)); // Used for IBL. + if (0 == m_settings.m_meshSelection) + { + // Submit bunny. + float mtx[16]; + bx::mtxSRT(mtx, 1.0f, 1.0f, 1.0f, 0.0f, bx::kPi, 0.0f, 0.0f, -0.80f, 0.0f); + bgfx::setTexture(0, s_texCube, m_lightProbes[m_currentLightProbe].m_tex); + bgfx::setTexture(1, s_texCubeIrr, m_lightProbes[m_currentLightProbe].m_texIrr); + m_uniforms.submit(); + meshSubmit(m_meshBunny, 1, m_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 + ); + + m_uniforms.m_glossiness = xx*(1.0f/xend); + m_uniforms.m_reflectivity = (yend-yy)*(1.0f/yend); + m_uniforms.m_metalOrSpec = 0.0f; + m_uniforms.submit(); + + bgfx::setTexture(0, s_texCube, m_lightProbes[m_currentLightProbe].m_tex); + bgfx::setTexture(1, s_texCubeIrr, m_lightProbes[m_currentLightProbe].m_texIrr); + meshSubmit(m_meshOrb, 1, m_programMesh, mtx); + } + } + } + + // Advance to next frame. Rendering thread will be kicked to + // process submitted rendering primitives. + bgfx::frame(); + + return true; } - - // Advance to next frame. Rendering thread will be kicked to - // process submitted rendering primitives. - bgfx::frame(); + + return false; } + + uint32_t m_width; + uint32_t m_height; + uint32_t m_debug; + uint32_t m_reset; + entry::MouseState m_mouseState; + + Uniforms m_uniforms; + + LightProbe m_lightProbes[LightProbe::Count]; + LightProbe::Enum m_currentLightProbe; + + bgfx::UniformHandle u_mtx; + bgfx::UniformHandle u_params; + bgfx::UniformHandle u_flags; + bgfx::UniformHandle u_camPos; + bgfx::UniformHandle s_texCube; + bgfx::UniformHandle s_texCubeIrr; + + bgfx::ProgramHandle m_programMesh; + bgfx::ProgramHandle m_programSky; + + Mesh* m_meshBunny; + Mesh* m_meshOrb; + Camera m_camera; + Mouse m_mouse; + + Settings m_settings; + + int32_t m_leftScrollArea; +}; - meshUnload(meshBunny); - meshUnload(meshOrb); - - // Cleanup. - bgfx::destroyProgram(programMesh); - bgfx::destroyProgram(programSky); - - bgfx::destroyUniform(u_camPos); - bgfx::destroyUniform(u_flags); - bgfx::destroyUniform(u_params); - bgfx::destroyUniform(u_mtx); - - bgfx::destroyUniform(s_texCube); - bgfx::destroyUniform(s_texCubeIrr); - - for (uint8_t ii = 0; ii < LightProbe::Count; ++ii) - { - lightProbes[ii].destroy(); - } - - uniforms.destroy(); - - imguiDestroy(); - - // Shutdown bgfx. - bgfx::shutdown(); - - return 0; -} +ENTRY_IMPLEMENT_MAIN(ExampleIbl);