Skip to content
Snippets Groups Projects
Commit 5cc16445 authored by Thomas Müller's avatar Thomas Müller
Browse files

Add button to disconnect VR & dropdown to change environment blend mode

parent a9bb0e5e
Branches
No related tags found
No related merge requests found
......@@ -47,6 +47,21 @@
NGP_NAMESPACE_BEGIN
enum class EnvironmentBlendMode {
Opaque = XR_ENVIRONMENT_BLEND_MODE_OPAQUE,
Additive = XR_ENVIRONMENT_BLEND_MODE_ADDITIVE,
AlphaBlend = XR_ENVIRONMENT_BLEND_MODE_ALPHA_BLEND,
};
inline std::string to_string(EnvironmentBlendMode mode) {
switch (mode) {
case EnvironmentBlendMode::Opaque: return "Opaque";
case EnvironmentBlendMode::Additive: return "Additive";
case EnvironmentBlendMode::AlphaBlend: return "Blend";
default: throw std::runtime_error{"Invalid blend mode."};
}
}
class OpenXRHMD {
public:
enum class ControlFlow {
......@@ -108,6 +123,22 @@ public:
// must be called for each begin_frame
void end_frame(FrameInfoPtr frame_info, float znear, float zfar);
void set_environment_blend_mode(EnvironmentBlendMode mode) {
m_environment_blend_mode = mode;
}
EnvironmentBlendMode environment_blend_mode() const {
return m_environment_blend_mode;
}
const std::vector<EnvironmentBlendMode>& supported_environment_blend_modes() const {
return m_supported_environment_blend_modes;
}
const std::string& supported_environment_blend_modes_string() const {
return m_supported_environment_blend_modes_string;
}
// if true call begin_frame and end_frame - does not imply visibility
bool must_run_frame_loop() const {
return
......@@ -161,8 +192,9 @@ private:
XrViewConfigurationType m_view_configuration_type = {};
XrViewConfigurationProperties m_view_configuration_properties = {XR_TYPE_VIEW_CONFIGURATION_PROPERTIES};
std::vector<XrViewConfigurationView> m_view_configuration_views;
std::vector<XrEnvironmentBlendMode> m_environment_blend_modes;
XrEnvironmentBlendMode m_environment_blend_mode = {XR_ENVIRONMENT_BLEND_MODE_OPAQUE};
std::vector<EnvironmentBlendMode> m_supported_environment_blend_modes;
std::string m_supported_environment_blend_modes_string;
EnvironmentBlendMode m_environment_blend_mode = EnvironmentBlendMode::Opaque;
// actions
std::array<XrPath, 2> m_hand_paths;
......
......@@ -425,34 +425,39 @@ void OpenXRHMD::init_check_for_xr_blend_mode() {
// enumerate environment blend modes
uint32_t size;
XR_CHECK_THROW(xrEnumerateEnvironmentBlendModes(m_instance, m_system_id, m_view_configuration_type, 0, &size, nullptr));
m_environment_blend_modes.resize(size);
std::vector<XrEnvironmentBlendMode> supported_blend_modes(size);
XR_CHECK_THROW(xrEnumerateEnvironmentBlendModes(
m_instance,
m_system_id,
m_view_configuration_type,
size,
&size,
m_environment_blend_modes.data()
supported_blend_modes.data()
));
if (m_print_environment_blend_modes) {
tlog::info() << fmt::format("Environment Blend Modes ({}):", m_environment_blend_modes.size());
if (supported_blend_modes.empty()) {
throw std::runtime_error{"No OpenXR environment blend modes found"};
}
bool found = false;
for (const auto& m : m_environment_blend_modes) {
if (m_print_environment_blend_modes) {
tlog::info() << fmt::format("\t{}", XrEnumStr(m));
tlog::info() << fmt::format("Environment Blend Modes ({}):", supported_blend_modes.size());
}
if (m == m_environment_blend_mode) {
found = true;
}
m_supported_environment_blend_modes.resize(size);
m_supported_environment_blend_modes_string = "";
for (size_t i = 0; i < supported_blend_modes.size(); ++i) {
if (m_print_environment_blend_modes) {
tlog::info() << fmt::format("\t{}", XrEnumStr(supported_blend_modes[i]));
}
if (!found) {
throw std::runtime_error{fmt::format("OpenXR environment blend mode {} not found", XrEnumStr(m_environment_blend_mode))};
auto b = (EnvironmentBlendMode)supported_blend_modes[i];
m_supported_environment_blend_modes[i] = b;
m_supported_environment_blend_modes_string += to_string(b) + "\0";
}
m_supported_environment_blend_modes_string += "\0";
m_environment_blend_mode = m_supported_environment_blend_modes.front();
}
void OpenXRHMD::init_xr_actions() {
......@@ -1236,7 +1241,7 @@ void OpenXRHMD::end_frame(FrameInfoPtr frame_info, float znear, float zfar) {
XrFrameEndInfo frame_end_info{XR_TYPE_FRAME_END_INFO};
frame_end_info.displayTime = m_frame_state.predictedDisplayTime;
frame_end_info.environmentBlendMode = m_environment_blend_mode;
frame_end_info.environmentBlendMode = (XrEnvironmentBlendMode)m_environment_blend_mode;
frame_end_info.layerCount = (uint32_t)layers.size();
frame_end_info.layers = layers.data();
XR_CHECK_THROW(xrEndFrame(m_session, &frame_end_info));
......
......@@ -925,7 +925,22 @@ void Testbed::imgui() {
ImGui::OpenPopup("Error");
}
}
} else {
if (ImGui::Button("Disconnect from VR/AR headset")) {
m_hmd.reset();
m_vr_frame_info = nullptr;
m_render_transparency_as_checkerboard = false;
} else if (ImGui::TreeNodeEx("VR/AR settings", ImGuiTreeNodeFlags_DefaultOpen)) {
static int blend_mode_idx = 0;
const auto& supported_blend_modes = m_hmd->supported_environment_blend_modes();
if (supported_blend_modes.size() > 1) {
if (ImGui::Combo("Environment blend mode", &blend_mode_idx, m_hmd->supported_environment_blend_modes_string().c_str())) {
auto b = m_hmd->supported_environment_blend_modes().at(blend_mode_idx);
m_hmd->set_environment_blend_mode(b);
m_render_transparency_as_checkerboard = (b == EnvironmentBlendMode::Opaque);
}
}
if (m_devices.size() > 1 && m_testbed_mode == ETestbedMode::Nerf) {
ImGui::Checkbox("Multi-GPU rendering (one per eye)", &m_use_aux_devices);
}
......@@ -936,6 +951,7 @@ void Testbed::imgui() {
}
ImGui::TreePop();
}
}
ImGui::Checkbox("Render", &m_render);
ImGui::SameLine();
......@@ -3144,7 +3160,7 @@ bool Testbed::frame() {
ImGui::EndFrame();
}
if (m_vr_frame_info) {
if (m_hmd && m_vr_frame_info) {
// If HMD is visible to the user, splat rendered images to the HMD
if (m_hmd->is_visible()) {
size_t n_views = std::min(m_views.size(), m_vr_frame_info->views.size());
......@@ -4186,7 +4202,7 @@ void Testbed::render_frame_epilogue(
Matrix<float, 3, 4> checkerboard_transform = Matrix<float, 3, 4>::Identity();
#if NGP_GUI
if (m_vr_frame_info && !m_vr_frame_info->views.empty()) {
if (m_hmd && m_vr_frame_info && !m_vr_frame_info->views.empty()) {
checkerboard_transform = m_vr_frame_info->views[0].pose;
}
#endif
......@@ -4266,7 +4282,7 @@ void Testbed::render_frame_epilogue(
#if NGP_GUI
// If in VR, indicate the hand position and render transparent background
if (m_vr_frame_info) {
if (m_hmd && m_vr_frame_info) {
auto& hands = m_vr_frame_info->hands;
auto res = render_buffer.out_resolution();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment