diff --git a/liblava/frame/renderer.cpp b/liblava/frame/renderer.cpp index e8fce7edf34bb8285273df8c4f2832f8ff2d8717..fcea4c64625d5613db5c881efc8c693ab5f7d16c 100644 --- a/liblava/frame/renderer.cpp +++ b/liblava/frame/renderer.cpp @@ -137,7 +137,9 @@ namespace lava { std::vector<VkSemaphore> complete_semaphores = { render_complete_semaphores[current_sync] }; for (frame_submission& submission : submissions) { - complete_semaphores.push_back(submission.semaphore); + if (submission.semaphore != VK_NULL_HANDLE) { + complete_semaphores.push_back(submission.semaphore); + } } VkPipelineStageFlags const wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; diff --git a/src/headset/openvr_headset.cpp b/src/headset/openvr_headset.cpp index 2d1b5739cb8434c0c652c42f8cf457b68720b793..bf2db060edd6adcc630d97569c51c29f9f732584 100644 --- a/src/headset/openvr_headset.cpp +++ b/src/headset/openvr_headset.cpp @@ -143,36 +143,43 @@ void OpenVRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f frame_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; frame_barrier.subresourceRange = frame_image->get_subresource_range(); - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &frame_barrier); + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &frame_barrier); } - lava::device_ptr device = this->get_application()->get_device(); - - vr::VRVulkanTextureArrayData_t texture_data; - texture_data.m_nImage = (uint64_t)frame_image->get(); - texture_data.m_pDevice = device->get(); - texture_data.m_pPhysicalDevice = device->get_physical_device()->get(); - texture_data.m_pInstance = this->get_application()->get_instance().get(); - texture_data.m_pQueue = device->get_graphics_queue().vk_queue; - texture_data.m_nQueueFamilyIndex = device->get_graphics_queue().family; - texture_data.m_nWidth = this->resolution.x; - texture_data.m_nHeight = this->resolution.y; - texture_data.m_nFormat = this->get_format(); - texture_data.m_nSampleCount = VK_SAMPLE_COUNT_1_BIT; - texture_data.m_unArrayIndex = frame_id; - texture_data.m_unArraySize = this->framebuffers.size(); - - vr::Texture_t texture; - texture.handle = &texture_data; - texture.eType = vr::TextureType_Vulkan; - texture.eColorSpace = vr::ColorSpace_Auto; - - vr::EVRCompositorError error = vr::VRCompositor()->Submit((vr::EVREye)frame_id, &texture, nullptr, vr::Submit_VulkanTextureWithArrayData); - - if (error != vr::VRCompositorError_None) + lava::frame_submission submission; + submission.semaphore = VK_NULL_HANDLE; + submission.callback = [this, frame_id, frame_image]() { - lava::log()->error("OpenVR: Can't submit image to OpenVR. Maybe due to headset standby. Error code '{}'", error); - } + lava::device_ptr device = this->get_application()->get_device(); + + vr::VRVulkanTextureArrayData_t texture_data; + texture_data.m_nImage = (uint64_t)frame_image->get(); + texture_data.m_pDevice = device->get(); + texture_data.m_pPhysicalDevice = device->get_physical_device()->get(); + texture_data.m_pInstance = this->get_application()->get_instance().get(); + texture_data.m_pQueue = device->get_graphics_queue().vk_queue; + texture_data.m_nQueueFamilyIndex = device->get_graphics_queue().family; + texture_data.m_nWidth = this->resolution.x; + texture_data.m_nHeight = this->resolution.y; + texture_data.m_nFormat = this->get_format(); + texture_data.m_nSampleCount = VK_SAMPLE_COUNT_1_BIT; + texture_data.m_unArrayIndex = frame_id; + texture_data.m_unArraySize = this->framebuffers.size(); + + vr::Texture_t texture; + texture.handle = &texture_data; + texture.eType = vr::TextureType_Vulkan; + texture.eColorSpace = vr::ColorSpace_Auto; + + vr::EVRCompositorError error = vr::VRCompositor()->Submit((vr::EVREye)frame_id, &texture, nullptr, vr::Submit_VulkanTextureWithArrayData); + + if (error != vr::VRCompositorError_None) + { + lava::log()->error("OpenVR: Can't submit image to OpenVR. Maybe due to headset standby. Error code '{}'", error); + } + }; + + this->get_application()->get_renderer().add_submission(submission); } VkFormat OpenVRHeadset::get_format() const diff --git a/src/headset/openxr_headset.cpp b/src/headset/openxr_headset.cpp index d04cf5ba19a776a23f8cc0ed4e05a686c2bf7476..a9d3038ff90b534da7818f6b072fe5157c973341 100644 --- a/src/headset/openxr_headset.cpp +++ b/src/headset/openxr_headset.cpp @@ -374,7 +374,7 @@ void OpenXRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f image_barriers.push_back(swapchain_begin_barrier); - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, image_barriers.size(), image_barriers.data()); + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, image_barriers.size(), image_barriers.data()); VkImageCopy copy_region; copy_region.srcSubresource = frame_image->get_subresource_layers(), @@ -404,16 +404,21 @@ void OpenXRHeadset::submit_frame(VkCommandBuffer command_buffer, VkImageLayout f swapchain_end_barrier.subresourceRange.baseArrayLayer = 0; swapchain_end_barrier.subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &swapchain_end_barrier); + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &swapchain_end_barrier); - this->release_image(frame_id); + lava::frame_submission submission; + submission.semaphore = VK_NULL_HANDLE; + submission.callback = [this, frame_id]() + { + this->release_image(frame_id); - this->submit_count++; + this->submit_count++; - if (this->submit_count == this->views.size()) - { - this->end_frame(); - } + if (this->submit_count == this->views.size()) + { + this->end_frame(); + } + }; } } @@ -728,68 +733,13 @@ bool OpenXRHeadset::create_actions() } } - std::vector<std::string> path_strings = - { - "/user/hand/right/input/a/click", - "/user/hand/right/input/b/click", - "/user/hand/left/input/x/click", - "/user/hand/left/input/y/click", - "/user/hand/left/input/trigger/click", - "/user/hand/right/input/trigger/click", - "/user/hand/left/input/thumbstick", - "/user/hand/right/input/thumbstick", - "/user/hand/left/input/aim/pose", - "/user/hand/right/input/aim/pose", - "/interaction_profiles/htc/vive_cosmos_controller" - }; - - std::vector<XrPath> paths; - paths.resize(path_strings.size()); - - for (uint32_t index = 0; index < path_strings.size(); index++) - { - if (xrStringToPath(this->instance, path_strings[index].c_str(), &paths[index]) != XR_SUCCESS) - { - lava::log()->error("OpenXR: Can't create path for string: " + path_strings[index]); - - return false; - } - } - - std::vector<XrAction> actions = - { - this->controller_button_actions[0], - this->controller_button_actions[1], - this->controller_button_actions[2], - this->controller_button_actions[3], - this->controller_button_actions[4], - this->controller_button_actions[5], - this->controller_thumbstick_actions[0], - this->controller_thumbstick_actions[1], - this->controller_transform_actions[0], - this->controller_transform_actions[1] - }; - - std::vector<XrActionSuggestedBinding> bindings; - bindings.resize(actions.size()); - - for (uint32_t index = 0; index < bindings.size(); index++) + if (!this->suggest_vive_controller_binding()) { - bindings[index].action = actions[index]; - bindings[index].binding = paths[index]; + return false; } - XrInteractionProfileSuggestedBinding suggested_bindings; - suggested_bindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING; - suggested_bindings.next = nullptr; - suggested_bindings.interactionProfile = paths.back(); - suggested_bindings.countSuggestedBindings = bindings.size(); - suggested_bindings.suggestedBindings = bindings.data(); - - if (xrSuggestInteractionProfileBindings(this->instance, &suggested_bindings) != XR_SUCCESS) + if (!this->suggest_vive_cosmos_controller_binding()) { - lava::log()->error("OpenXR: Can't set suggested bindings"); - return false; } @@ -1487,6 +1437,146 @@ bool OpenXRHeadset::check_swapchain_format_support(int64_t required_format) cons return false; } +bool OpenXRHeadset::suggest_vive_controller_binding() +{ + std::vector<std::string> path_strings = + { + "/user/hand/right/input/trackpad/click", + "/user/hand/right/input/squeeze/click", + "/user/hand/left/input/trackpad/click", + "/user/hand/left/input/squeeze/click", + "/user/hand/left/input/trigger/click", + "/user/hand/right/input/trigger/click", + "/user/hand/left/input/trackpad", + "/user/hand/right/input/trackpad", + "/user/hand/left/input/aim/pose", + "/user/hand/right/input/aim/pose", + "/interaction_profiles/htc/vive_controller" + }; + + std::vector<XrPath> paths; + paths.resize(path_strings.size()); + + for (uint32_t index = 0; index < path_strings.size(); index++) + { + if (xrStringToPath(this->instance, path_strings[index].c_str(), &paths[index]) != XR_SUCCESS) + { + lava::log()->error("OpenXR: Can't create path for string: " + path_strings[index]); + + return false; + } + } + + std::vector<XrAction> actions = + { + this->controller_button_actions[0], + this->controller_button_actions[1], + this->controller_button_actions[2], + this->controller_button_actions[3], + this->controller_button_actions[4], + this->controller_button_actions[5], + this->controller_thumbstick_actions[0], + this->controller_thumbstick_actions[1], + this->controller_transform_actions[0], + this->controller_transform_actions[1] + }; + + std::vector<XrActionSuggestedBinding> bindings; + bindings.resize(actions.size()); + + for (uint32_t index = 0; index < bindings.size(); index++) + { + bindings[index].action = actions[index]; + bindings[index].binding = paths[index]; + } + + XrInteractionProfileSuggestedBinding suggested_bindings; + suggested_bindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING; + suggested_bindings.next = nullptr; + suggested_bindings.interactionProfile = paths.back(); + suggested_bindings.countSuggestedBindings = bindings.size(); + suggested_bindings.suggestedBindings = bindings.data(); + + if (xrSuggestInteractionProfileBindings(this->instance, &suggested_bindings) != XR_SUCCESS) + { + lava::log()->error("OpenXR: Can't set suggested bindings for vive controller"); + + return false; + } + + return true; +} + +bool OpenXRHeadset::suggest_vive_cosmos_controller_binding() +{ + std::vector<std::string> path_strings = + { + "/user/hand/right/input/a/click", + "/user/hand/right/input/b/click", + "/user/hand/left/input/x/click", + "/user/hand/left/input/y/click", + "/user/hand/left/input/trigger/click", + "/user/hand/right/input/trigger/click", + "/user/hand/left/input/thumbstick", + "/user/hand/right/input/thumbstick", + "/user/hand/left/input/aim/pose", + "/user/hand/right/input/aim/pose", + "/interaction_profiles/htc/vive_cosmos_controller" + }; + + std::vector<XrPath> paths; + paths.resize(path_strings.size()); + + for (uint32_t index = 0; index < path_strings.size(); index++) + { + if (xrStringToPath(this->instance, path_strings[index].c_str(), &paths[index]) != XR_SUCCESS) + { + lava::log()->error("OpenXR: Can't create path for string: " + path_strings[index]); + + return false; + } + } + + std::vector<XrAction> actions = + { + this->controller_button_actions[0], + this->controller_button_actions[1], + this->controller_button_actions[2], + this->controller_button_actions[3], + this->controller_button_actions[4], + this->controller_button_actions[5], + this->controller_thumbstick_actions[0], + this->controller_thumbstick_actions[1], + this->controller_transform_actions[0], + this->controller_transform_actions[1] + }; + + std::vector<XrActionSuggestedBinding> bindings; + bindings.resize(actions.size()); + + for (uint32_t index = 0; index < bindings.size(); index++) + { + bindings[index].action = actions[index]; + bindings[index].binding = paths[index]; + } + + XrInteractionProfileSuggestedBinding suggested_bindings; + suggested_bindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING; + suggested_bindings.next = nullptr; + suggested_bindings.interactionProfile = paths.back(); + suggested_bindings.countSuggestedBindings = bindings.size(); + suggested_bindings.suggestedBindings = bindings.data(); + + if (xrSuggestInteractionProfileBindings(this->instance, &suggested_bindings) != XR_SUCCESS) + { + lava::log()->error("OpenXR: Can't set suggested bindings for vive cosmos controller"); + + return false; + } + + return true; +} + std::vector<std::string> OpenXRHeadset::split_string(std::string string, char delimiter) { std::vector<std::string> strings; diff --git a/src/headset/openxr_headset.hpp b/src/headset/openxr_headset.hpp index 745c00a3c76e38efe5a5b3f747cb89031676d760..f19394b67442b8e7fa512ee46c24b24e4c6e88bb 100644 --- a/src/headset/openxr_headset.hpp +++ b/src/headset/openxr_headset.hpp @@ -72,6 +72,9 @@ private: bool check_view_type_support(XrViewConfigurationType required_type) const; bool check_swapchain_format_support(int64_t required_format) const; + bool suggest_vive_controller_binding(); + bool suggest_vive_cosmos_controller_binding(); + static std::vector<std::string> split_string(std::string string, char delimiter = ' '); private: diff --git a/src/scene.cpp b/src/scene.cpp index c8882f3a6d7e7354a941cdc9c3af0d209ff88392..4013fd982e2f076b23b1a6a4f4e876bcf7e6b051 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -1187,14 +1187,24 @@ bool Scene::load_lights(const aiScene* scene, float scale, const std::map<std::s light_scale = glm::pow(scale, 1); //It should be a 2 instead of a 1 } + glm::vec3 color = glm::make_vec3(&light->mColorDiffuse.r); + glm::vec3 position = glm::make_vec3(&light->mPosition.x); + glm::vec3 direction = glm::make_vec3(&light->mDirection.x); + float direction_length = glm::length(direction); + + if (direction_length > 0.0f) + { + direction /= direction_length; + } + SceneLight& scene_light = this->lights.emplace_back(); scene_light.node_index = node_indices.at(light->mName.C_Str()); - scene_light.initial_position = glm::make_vec3(&light->mPosition.x) * scale; - scene_light.initial_direction = glm::normalize(glm::make_vec3(&light->mDirection.x)); + scene_light.initial_position = position * scale; + scene_light.initial_direction = direction; glsl::LightData& light_data = scene_light.data; light_data.position = scene_light.initial_position; - light_data.color = glm::make_vec3(&light->mColorDiffuse.r) * light_scale; + light_data.color = color * light_scale; light_data.outer_angle = light->mAngleOuterCone; light_data.direction = scene_light.initial_direction; light_data.inner_angle = light->mAngleInnerCone;