diff --git a/examples/19-oit/oit.cpp b/examples/19-oit/oit.cpp index b5f3dff44..63905a2b8 100644 --- a/examples/19-oit/oit.cpp +++ b/examples/19-oit/oit.cpp @@ -227,6 +227,12 @@ public: m_oldHeight = 0; m_oldReset = m_reset; + m_mrtSupported = true + && 2 <= caps->limits.maxFBAttachments + && bgfx::isTextureValid(0, false, 1, bgfx::TextureFormat::RGBA16F, BGFX_TEXTURE_RT) + && bgfx::isTextureValid(0, false, 1, bgfx::TextureFormat::R16F, BGFX_TEXTURE_RT) + ; + m_timeOffset = bx::getHPCounter(); } @@ -235,7 +241,11 @@ public: // Cleanup. imguiDestroy(); - bgfx::destroy(m_fbh); + if (bgfx::isValid(m_fbh) ) + { + bgfx::destroy(m_fbh); + } + bgfx::destroy(m_ibh); bgfx::destroy(m_vbh); bgfx::destroy(m_blend); @@ -257,26 +267,6 @@ public: { if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) { - if (m_oldWidth != m_width - || m_oldHeight != m_height - || m_oldReset != m_reset - || !bgfx::isValid(m_fbh) ) - { - // Recreate variable size render targets when resolution changes. - m_oldWidth = m_width; - m_oldHeight = m_height; - m_oldReset = m_reset; - - if (bgfx::isValid(m_fbh) ) - { - bgfx::destroy(m_fbh); - } - - m_fbtextures[0] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::RGBA16F, BGFX_TEXTURE_RT); - m_fbtextures[1] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::R16F, BGFX_TEXTURE_RT); - m_fbh = bgfx::createFrameBuffer(BX_COUNTOF(m_fbtextures), m_fbtextures, true); - } - imguiBeginFrame(m_mouseState.m_mx , m_mouseState.m_my , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) @@ -287,195 +277,223 @@ public: , uint16_t(m_height) ); - showExampleDialog(this); - - ImGui::SetNextWindowPos( - ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) - , ImGuiSetCond_FirstUseEver - ); - ImGui::Begin("Settings" - , NULL - , ImVec2(m_width / 5.0f, m_height / 3.0f) - , ImGuiWindowFlags_AlwaysAutoResize + showExampleDialog(this + , !m_mrtSupported + ? "MRT or frame buffer texture format are not supported." + : NULL ); - ImGui::Separator(); - - ImGui::Text("Blend mode:"); - - ImGui::RadioButton("None", &m_mode, 0); - ImGui::RadioButton("Separate", &m_mode, 1); - ImGui::RadioButton("MRT Independent", &m_mode, 2); - - ImGui::Separator(); - - ImGui::Checkbox("Front to back", &m_frontToBack); - ImGui::Checkbox("Fade in/out", &m_fadeInOut); - - ImGui::End(); - imguiEndFrame(); - - // Set view 0 default viewport. - 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) ); - - int64_t now = bx::getHPCounter(); - const double freq = double(bx::getHPFrequency() ); - float time = (float)( (now-m_timeOffset)/freq); - - // Reference: - // Weighted, Blended Order-Independent Transparency - // http://jcgt.org/published/0002/02/09/ - // http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html - - float at[3] = { 0.0f, 0.0f, 0.0f }; - float eye[3] = { 0.0f, 0.0f, -7.0f }; - - float view[16]; - float proj[16]; - - // Set view and projection matrix for view 0. - bx::mtxLookAt(view, eye, at); - mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f); - - bgfx::setViewTransform(0, view, proj); - - // Set palette color for index 0 - bgfx::setPaletteColor(0, 0.0f, 0.0f, 0.0f, 0.0f); - - // Set palette color for index 1 - bgfx::setPaletteColor(1, 1.0f, 1.0f, 1.0f, 1.0f); - - bgfx::setViewClear(0 - , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH - , 1.0f // Depth - , 0 // Stencil - , 0 // FB texture 0, color palette 0 - , 1 == m_mode ? 1 : 0 // FB texture 1, color palette 1 - ); - - bgfx::setViewClear(1 - , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH - , 1.0f // Depth - , 0 // Stencil - , 0 // Color palette 0 - ); - - bgfx::FrameBufferHandle invalid = BGFX_INVALID_HANDLE; - bgfx::setViewFrameBuffer(0, 0 == m_mode ? invalid : m_fbh); - - // Set view and projection matrix for view 1. - bx::mtxIdentity(view); - - const bgfx::Caps* caps = bgfx::getCaps(); - bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f, 0.0f, caps->homogeneousDepth); - bgfx::setViewTransform(1, view, proj); - - for (uint32_t depth = 0; depth < 3; ++depth) + if (m_mrtSupported) { - uint32_t zz = m_frontToBack ? 2-depth : depth; - - for (uint32_t yy = 0; yy < 3; ++yy) + if (m_oldWidth != m_width + || m_oldHeight != m_height + || m_oldReset != m_reset + || !bgfx::isValid(m_fbh) ) { - for (uint32_t xx = 0; xx < 3; ++xx) + // Recreate variable size render targets when resolution changes. + m_oldWidth = m_width; + m_oldHeight = m_height; + m_oldReset = m_reset; + + if (bgfx::isValid(m_fbh) ) { - float color[4] = { xx*1.0f/3.0f, zz*1.0f/3.0f, yy*1.0f/3.0f, 0.5f }; - - if (m_fadeInOut - && zz == 1) - { - color[3] = bx::fsin(time*3.0f)*0.49f+0.5f; - } - - bgfx::setUniform(u_color, color); - - BX_UNUSED(time); - float mtx[16]; - bx::mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f); - //mtxIdentity(mtx); - mtx[12] = -2.5f + float(xx)*2.5f; - mtx[13] = -2.5f + float(yy)*2.5f; - mtx[14] = -2.5f + float(zz)*2.5f; - - // Set transform for draw call. - bgfx::setTransform(mtx); - - // Set vertex and index buffer. - bgfx::setVertexBuffer(0, m_vbh); - bgfx::setIndexBuffer(m_ibh); - - const uint64_t state = 0 - | BGFX_STATE_CULL_CW - | BGFX_STATE_RGB_WRITE - | BGFX_STATE_ALPHA_WRITE - | BGFX_STATE_DEPTH_TEST_LESS - | BGFX_STATE_MSAA - ; - - const uint64_t stateNoDepth = 0 - | BGFX_STATE_CULL_CW - | BGFX_STATE_RGB_WRITE - | BGFX_STATE_ALPHA_WRITE - | BGFX_STATE_DEPTH_TEST_ALWAYS - | BGFX_STATE_MSAA - ; - - bgfx::ProgramHandle program = BGFX_INVALID_HANDLE; - switch (m_mode) - { - case 0: - // Set vertex and fragment shaders. - program = m_blend; - - // Set render states. - bgfx::setState(state - | BGFX_STATE_BLEND_ALPHA - ); - break; - - case 1: - // Set vertex and fragment shaders. - program = m_wbSeparatePass; - - // Set render states. - bgfx::setState(stateNoDepth - | BGFX_STATE_BLEND_FUNC_SEPARATE(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_INV_SRC_ALPHA) - ); - break; - - default: - // Set vertex and fragment shaders. - program = m_wbPass; - - // Set render states. - bgfx::setState(stateNoDepth - | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE) - | BGFX_STATE_BLEND_INDEPENDENT - , 0 - | BGFX_STATE_BLEND_FUNC_RT_1(BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_SRC_COLOR) - ); - break; - } - - // Submit primitive for rendering to view 0. - bgfx::submit(0, program); + bgfx::destroy(m_fbh); } + + m_fbtextures[0] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::RGBA16F, BGFX_TEXTURE_RT); + m_fbtextures[1] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::R16F, BGFX_TEXTURE_RT); + m_fbh = bgfx::createFrameBuffer(BX_COUNTOF(m_fbtextures), m_fbtextures, true); + } + + ImGui::SetNextWindowPos( + ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) + , ImGuiSetCond_FirstUseEver + ); + ImGui::Begin("Settings" + , NULL + , ImVec2(m_width / 5.0f, m_height / 3.0f) + , ImGuiWindowFlags_AlwaysAutoResize + ); + + ImGui::Separator(); + + ImGui::Text("Blend mode:"); + + ImGui::RadioButton("None", &m_mode, 0); + ImGui::RadioButton("Separate", &m_mode, 1); + ImGui::RadioButton("MRT Independent", &m_mode, 2); + + ImGui::Separator(); + + ImGui::Checkbox("Front to back", &m_frontToBack); + ImGui::Checkbox("Fade in/out", &m_fadeInOut); + + ImGui::End(); + + // Set view 0 default viewport. + 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) ); + + int64_t now = bx::getHPCounter(); + const double freq = double(bx::getHPFrequency() ); + float time = (float)( (now-m_timeOffset)/freq); + + // Reference: + // Weighted, Blended Order-Independent Transparency + // http://jcgt.org/published/0002/02/09/ + // http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html + + float at[3] = { 0.0f, 0.0f, 0.0f }; + float eye[3] = { 0.0f, 0.0f, -7.0f }; + + float view[16]; + float proj[16]; + + // Set view and projection matrix for view 0. + bx::mtxLookAt(view, eye, at); + mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f); + + bgfx::setViewTransform(0, view, proj); + + // Set palette color for index 0 + bgfx::setPaletteColor(0, 0.0f, 0.0f, 0.0f, 0.0f); + + // Set palette color for index 1 + bgfx::setPaletteColor(1, 1.0f, 1.0f, 1.0f, 1.0f); + + bgfx::setViewClear(0 + , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH + , 1.0f // Depth + , 0 // Stencil + , 0 // FB texture 0, color palette 0 + , 1 == m_mode ? 1 : 0 // FB texture 1, color palette 1 + ); + + bgfx::setViewClear(1 + , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH + , 1.0f // Depth + , 0 // Stencil + , 0 // Color palette 0 + ); + + bgfx::FrameBufferHandle invalid = BGFX_INVALID_HANDLE; + bgfx::setViewFrameBuffer(0, 0 == m_mode ? invalid : m_fbh); + + // Set view and projection matrix for view 1. + bx::mtxIdentity(view); + + const bgfx::Caps* caps = bgfx::getCaps(); + bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f, 0.0f, caps->homogeneousDepth); + bgfx::setViewTransform(1, view, proj); + + for (uint32_t depth = 0; depth < 3; ++depth) + { + uint32_t zz = m_frontToBack ? 2-depth : depth; + + for (uint32_t yy = 0; yy < 3; ++yy) + { + for (uint32_t xx = 0; xx < 3; ++xx) + { + float color[4] = { xx*1.0f/3.0f, zz*1.0f/3.0f, yy*1.0f/3.0f, 0.5f }; + + if (m_fadeInOut + && zz == 1) + { + color[3] = bx::fsin(time*3.0f)*0.49f+0.5f; + } + + bgfx::setUniform(u_color, color); + + BX_UNUSED(time); + float mtx[16]; + bx::mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f); + //mtxIdentity(mtx); + mtx[12] = -2.5f + float(xx)*2.5f; + mtx[13] = -2.5f + float(yy)*2.5f; + mtx[14] = -2.5f + float(zz)*2.5f; + + // Set transform for draw call. + bgfx::setTransform(mtx); + + // Set vertex and index buffer. + bgfx::setVertexBuffer(0, m_vbh); + bgfx::setIndexBuffer(m_ibh); + + const uint64_t state = 0 + | BGFX_STATE_CULL_CW + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_ALPHA_WRITE + | BGFX_STATE_DEPTH_TEST_LESS + | BGFX_STATE_MSAA + ; + + const uint64_t stateNoDepth = 0 + | BGFX_STATE_CULL_CW + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_ALPHA_WRITE + | BGFX_STATE_DEPTH_TEST_ALWAYS + | BGFX_STATE_MSAA + ; + + bgfx::ProgramHandle program = BGFX_INVALID_HANDLE; + switch (m_mode) + { + case 0: + // Set vertex and fragment shaders. + program = m_blend; + + // Set render states. + bgfx::setState(state + | BGFX_STATE_BLEND_ALPHA + ); + break; + + case 1: + // Set vertex and fragment shaders. + program = m_wbSeparatePass; + + // Set render states. + bgfx::setState(stateNoDepth + | BGFX_STATE_BLEND_FUNC_SEPARATE(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_INV_SRC_ALPHA) + ); + break; + + default: + // Set vertex and fragment shaders. + program = m_wbPass; + + // Set render states. + bgfx::setState(stateNoDepth + | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE) + | BGFX_STATE_BLEND_INDEPENDENT + , 0 + | BGFX_STATE_BLEND_FUNC_RT_1(BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_SRC_COLOR) + ); + break; + } + + // Submit primitive for rendering to view 0. + bgfx::submit(0, program); + } + } + } + + if (0 != m_mode) + { + bgfx::setTexture(0, s_texColor0, m_fbtextures[0]); + bgfx::setTexture(1, s_texColor1, m_fbtextures[1]); + bgfx::setState(0 + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_INV_SRC_ALPHA, BGFX_STATE_BLEND_SRC_ALPHA) + ); + screenSpaceQuad( (float)m_width, (float)m_height, s_flipV); + bgfx::submit(1 + , 1 == m_mode ? m_wbSeparateBlit : m_wbBlit + ); } } - if (0 != m_mode) - { - bgfx::setTexture(0, s_texColor0, m_fbtextures[0]); - bgfx::setTexture(1, s_texColor1, m_fbtextures[1]); - bgfx::setState(0 - | BGFX_STATE_RGB_WRITE - | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_INV_SRC_ALPHA, BGFX_STATE_BLEND_SRC_ALPHA) - ); - screenSpaceQuad( (float)m_width, (float)m_height, s_flipV); - bgfx::submit(1 - , 1 == m_mode ? m_wbSeparateBlit : m_wbBlit - ); - } + imguiEndFrame(); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. @@ -495,6 +513,7 @@ public: int32_t m_mode; bool m_frontToBack; bool m_fadeInOut; + bool m_mrtSupported; uint32_t m_oldWidth; uint32_t m_oldHeight; diff --git a/examples/24-nbody/nbody.cpp b/examples/24-nbody/nbody.cpp index 490b05f3e..4d285d817 100644 --- a/examples/24-nbody/nbody.cpp +++ b/examples/24-nbody/nbody.cpp @@ -142,12 +142,12 @@ public: ); const bgfx::Caps* caps = bgfx::getCaps(); - const bool computeSupported = !!(caps->supported & BGFX_CAPS_COMPUTE); - const bool indirectSupported = !!(caps->supported & BGFX_CAPS_DRAW_INDIRECT); + m_computeSupported = !!(caps->supported & BGFX_CAPS_COMPUTE); + m_indirectSupported = !!(caps->supported & BGFX_CAPS_DRAW_INDIRECT); imguiCreate(); - if (computeSupported) + if (m_computeSupported) { bgfx::VertexDecl quadVertexDecl; quadVertexDecl.begin() @@ -189,7 +189,7 @@ public: m_indirectProgram = BGFX_INVALID_HANDLE; m_indirectBuffer = BGFX_INVALID_HANDLE; - if (indirectSupported) + if (m_indirectSupported) { m_indirectProgram = bgfx::createProgram(loadShader("cs_indirect"), true); m_indirectBuffer = bgfx::createIndirectBuffer(2); @@ -219,22 +219,25 @@ public: cameraDestroy(); imguiDestroy(); - if (bgfx::isValid(m_indirectProgram) ) + if (m_computeSupported) { - bgfx::destroy(m_indirectProgram); - bgfx::destroy(m_indirectBuffer); - } + if (m_indirectSupported) + { + bgfx::destroy(m_indirectProgram); + bgfx::destroy(m_indirectBuffer); + } - bgfx::destroy(u_params); - bgfx::destroy(m_currPositionBuffer0); - bgfx::destroy(m_currPositionBuffer1); - bgfx::destroy(m_prevPositionBuffer0); - bgfx::destroy(m_prevPositionBuffer1); - bgfx::destroy(m_updateInstancesProgram); - bgfx::destroy(m_initInstancesProgram); - bgfx::destroy(m_ibh); - bgfx::destroy(m_vbh); - bgfx::destroy(m_particleProgram); + bgfx::destroy(u_params); + bgfx::destroy(m_currPositionBuffer0); + bgfx::destroy(m_currPositionBuffer1); + bgfx::destroy(m_prevPositionBuffer0); + bgfx::destroy(m_prevPositionBuffer1); + bgfx::destroy(m_updateInstancesProgram); + bgfx::destroy(m_initInstancesProgram); + bgfx::destroy(m_ibh); + bgfx::destroy(m_vbh); + bgfx::destroy(m_particleProgram); + } // Shutdown bgfx. bgfx::shutdown(); @@ -257,14 +260,13 @@ public: , uint16_t(m_height) ); - showExampleDialog(this); - - const bgfx::Caps* caps = bgfx::getCaps(); - const bool computeSupported = !!(caps->supported & BGFX_CAPS_COMPUTE); - const bool indirectSupported = !!(caps->supported & BGFX_CAPS_DRAW_INDIRECT); + showExampleDialog(this + , !m_computeSupported + ? "Compute is not supported." + : NULL + ); int64_t now = bx::getHPCounter(); - float time = (float)( (now - m_timeOffset)/double(bx::getHPFrequency() ) ); static int64_t last = now; const int64_t frameTime = now - last; last = now; @@ -274,7 +276,7 @@ public: // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); - if (computeSupported) + if (m_computeSupported) { ImGui::SetNextWindowPos( ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f) @@ -318,7 +320,7 @@ public: ImGui::Separator(); - if (indirectSupported) + if (m_indirectSupported) { ImGui::Checkbox("Use draw/dispatch indirect", &m_useIndirect); } @@ -430,15 +432,6 @@ public: bgfx::submit(0, m_particleProgram); } } - else - { - bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); - - bool blink = uint32_t(time*3.0f)&1; - bgfx::dbgTextPrintf(0, 0, blink ? 0x1f : 0x01, " Compute is not supported by GPU. "); - - bgfx::touch(0); - } imguiEndFrame(); @@ -459,6 +452,8 @@ public: uint32_t m_debug; uint32_t m_reset; bool m_useIndirect; + bool m_computeSupported; + bool m_indirectSupported; ParamsData m_paramsData; diff --git a/examples/26-occlusion/occlusion.cpp b/examples/26-occlusion/occlusion.cpp index 3d4a5eb1c..d2c43c903 100644 --- a/examples/26-occlusion/occlusion.cpp +++ b/examples/26-occlusion/occlusion.cpp @@ -119,9 +119,15 @@ public: // Create program from shaders. m_program = loadProgram("vs_cubes", "fs_cubes"); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_occlusionQueries); ++ii) + const bgfx::Caps* caps = bgfx::getCaps(); + m_occlusionQuerySupported = !!(caps->supported & BGFX_CAPS_OCCLUSION_QUERY); + + if (m_occlusionQuerySupported) { - m_occlusionQueries[ii] = bgfx::createOcclusionQuery(); + for (uint32_t ii = 0; ii < BX_COUNTOF(m_occlusionQueries); ++ii) + { + m_occlusionQueries[ii] = bgfx::createOcclusionQuery(); + } } cameraCreate(); @@ -142,9 +148,12 @@ public: // Cleanup. cameraDestroy(); - for (uint32_t ii = 0; ii < BX_COUNTOF(m_occlusionQueries); ++ii) + if (m_occlusionQuerySupported) { - bgfx::destroy(m_occlusionQueries[ii]); + for (uint32_t ii = 0; ii < BX_COUNTOF(m_occlusionQueries); ++ii) + { + bgfx::destroy(m_occlusionQueries[ii]); + } } bgfx::destroy(m_ibh); @@ -171,112 +180,119 @@ public: , uint16_t(m_height) ); - showExampleDialog(this); + showExampleDialog(this + , !m_occlusionQuerySupported + ? "Occlusion query is not supported." + : NULL + ); imguiEndFrame(); - 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 float time = (float)( (now-m_timeOffset)/double(bx::getHPFrequency() ) ); - const float deltaTime = float(frameTime/freq); - - // Update camera. - float view[16]; - cameraUpdate(deltaTime, m_state.m_mouse); - cameraGetViewMtx(view); - - // Set view and projection matrix for view 0. - const bgfx::HMD* hmd = bgfx::getHMD(); - if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) ) + if (m_occlusionQuerySupported) { - float viewHead[16]; - float eye[3] = {}; - bx::mtxQuatTranslationHMD(viewHead, hmd->eye[0].rotation, eye); + 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 float time = (float)( (now-m_timeOffset)/double(bx::getHPFrequency() ) ); + const float deltaTime = float(frameTime/freq); - float tmp[16]; - bx::mtxMul(tmp, view, viewHead); + // Update camera. + float view[16]; + cameraUpdate(deltaTime, m_state.m_mouse); + cameraGetViewMtx(view); - bgfx::setViewTransform(0, tmp, hmd->eye[0].projection); - bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); - - bgfx::setViewTransform(1, tmp, hmd->eye[1].projection); - bgfx::setViewRect(1, 0, 0, hmd->width, hmd->height); - } - else - { - float proj[16]; - bx::mtxProj(proj, 90.0f, float(m_width)/float(m_height), 0.1f, 10000.0f, bgfx::getCaps()->homogeneousDepth); - - bgfx::setViewTransform(0, view, proj); - bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); - - bgfx::setViewTransform(1, view, proj); - bgfx::setViewRect(1, 0, 0, uint16_t(m_width), uint16_t(m_height) ); - - float at[3] = { 0.0f, 0.0f, 0.0f }; - float eye[3] = { 17.5f, 10.0f, -17.5f }; - bx::mtxLookAt(view, eye, at); - - bgfx::setViewTransform(2, view, proj); - bgfx::setViewRect(2, 10, uint16_t(m_height - m_height/4 - 10), uint16_t(m_width/4), uint16_t(m_height/4) ); - } - - bgfx::touch(0); - bgfx::touch(2); - - uint8_t img[CUBES_DIM*CUBES_DIM*2]; - - for (uint32_t yy = 0; yy < CUBES_DIM; ++yy) - { - for (uint32_t xx = 0; xx < CUBES_DIM; ++xx) + // Set view and projection matrix for view 0. + const bgfx::HMD* hmd = bgfx::getHMD(); + if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) ) { - float mtx[16]; - bx::mtxRotateXY(mtx, time + xx*0.21f, time + yy*0.37f); - mtx[12] = -(CUBES_DIM-1) * 3.0f / 2.0f + float(xx)*3.0f; - mtx[13] = 0.0f; - mtx[14] = -(CUBES_DIM-1) * 3.0f / 2.0f + float(yy)*3.0f; + float viewHead[16]; + float eye[3] = {}; + bx::mtxQuatTranslationHMD(viewHead, hmd->eye[0].rotation, eye); - bgfx::OcclusionQueryHandle occlusionQuery = m_occlusionQueries[yy*CUBES_DIM+xx]; + float tmp[16]; + bx::mtxMul(tmp, view, viewHead); - bgfx::setTransform(mtx); - bgfx::setVertexBuffer(0, m_vbh); - bgfx::setIndexBuffer(m_ibh); - bgfx::setCondition(occlusionQuery, true); - bgfx::setState(BGFX_STATE_DEFAULT); - bgfx::submit(0, m_program); + bgfx::setViewTransform(0, tmp, hmd->eye[0].projection); + bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height); - bgfx::setTransform(mtx); - bgfx::setVertexBuffer(0, m_vbh); - bgfx::setIndexBuffer(m_ibh); - bgfx::setState(0 - | BGFX_STATE_DEPTH_TEST_LEQUAL - | BGFX_STATE_CULL_CW - ); - bgfx::submit(1, m_program, occlusionQuery); - - bgfx::setTransform(mtx); - bgfx::setVertexBuffer(0, m_vbh); - bgfx::setIndexBuffer(m_ibh); - bgfx::setCondition(occlusionQuery, true); - bgfx::setState(BGFX_STATE_DEFAULT); - bgfx::submit(2, m_program); - - img[(yy*CUBES_DIM+xx)*2+0] = " \xfex"[bgfx::getResult(occlusionQuery)]; - img[(yy*CUBES_DIM+xx)*2+1] = 0xf; + bgfx::setViewTransform(1, tmp, hmd->eye[1].projection); + bgfx::setViewRect(1, 0, 0, hmd->width, hmd->height); } - } + else + { + float proj[16]; + bx::mtxProj(proj, 90.0f, float(m_width)/float(m_height), 0.1f, 10000.0f, bgfx::getCaps()->homogeneousDepth); - for (uint16_t xx = 0; xx < CUBES_DIM; ++xx) - { - bgfx::dbgTextImage(5 + xx*2, 5, 1, CUBES_DIM, img + xx*2, CUBES_DIM*2); - } + bgfx::setViewTransform(0, view, proj); + bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) ); - int32_t numPixels = 0; - bgfx::getResult(m_occlusionQueries[0], &numPixels); - bgfx::dbgTextPrintf(5, 5 + CUBES_DIM + 1, 0xf, "%d", numPixels); + bgfx::setViewTransform(1, view, proj); + bgfx::setViewRect(1, 0, 0, uint16_t(m_width), uint16_t(m_height) ); + + float at[3] = { 0.0f, 0.0f, 0.0f }; + float eye[3] = { 17.5f, 10.0f, -17.5f }; + bx::mtxLookAt(view, eye, at); + + bgfx::setViewTransform(2, view, proj); + bgfx::setViewRect(2, 10, uint16_t(m_height - m_height/4 - 10), uint16_t(m_width/4), uint16_t(m_height/4) ); + } + + bgfx::touch(0); + bgfx::touch(2); + + uint8_t img[CUBES_DIM*CUBES_DIM*2]; + + for (uint32_t yy = 0; yy < CUBES_DIM; ++yy) + { + for (uint32_t xx = 0; xx < CUBES_DIM; ++xx) + { + float mtx[16]; + bx::mtxRotateXY(mtx, time + xx*0.21f, time + yy*0.37f); + mtx[12] = -(CUBES_DIM-1) * 3.0f / 2.0f + float(xx)*3.0f; + mtx[13] = 0.0f; + mtx[14] = -(CUBES_DIM-1) * 3.0f / 2.0f + float(yy)*3.0f; + + bgfx::OcclusionQueryHandle occlusionQuery = m_occlusionQueries[yy*CUBES_DIM+xx]; + + bgfx::setTransform(mtx); + bgfx::setVertexBuffer(0, m_vbh); + bgfx::setIndexBuffer(m_ibh); + bgfx::setCondition(occlusionQuery, true); + bgfx::setState(BGFX_STATE_DEFAULT); + bgfx::submit(0, m_program); + + bgfx::setTransform(mtx); + bgfx::setVertexBuffer(0, m_vbh); + bgfx::setIndexBuffer(m_ibh); + bgfx::setState(0 + | BGFX_STATE_DEPTH_TEST_LEQUAL + | BGFX_STATE_CULL_CW + ); + bgfx::submit(1, m_program, occlusionQuery); + + bgfx::setTransform(mtx); + bgfx::setVertexBuffer(0, m_vbh); + bgfx::setIndexBuffer(m_ibh); + bgfx::setCondition(occlusionQuery, true); + bgfx::setState(BGFX_STATE_DEFAULT); + bgfx::submit(2, m_program); + + img[(yy*CUBES_DIM+xx)*2+0] = " \xfex"[bgfx::getResult(occlusionQuery)]; + img[(yy*CUBES_DIM+xx)*2+1] = 0xf; + } + } + + for (uint16_t xx = 0; xx < CUBES_DIM; ++xx) + { + bgfx::dbgTextImage(5 + xx*2, 5, 1, CUBES_DIM, img + xx*2, CUBES_DIM*2); + } + + int32_t numPixels = 0; + bgfx::getResult(m_occlusionQueries[0], &numPixels); + bgfx::dbgTextPrintf(5, 5 + CUBES_DIM + 1, 0xf, "%d", numPixels); + } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. @@ -299,6 +315,7 @@ public: bgfx::IndexBufferHandle m_ibh; bgfx::ProgramHandle m_program; int64_t m_timeOffset; + bool m_occlusionQuerySupported; bgfx::OcclusionQueryHandle m_occlusionQueries[CUBES_DIM*CUBES_DIM];