mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-04-20 11:35:54 +00:00
VideoCommon: add action to create a camera that is relative to the game view
This commit is contained in:
parent
4dedeed941
commit
6a21af498a
2 changed files with 208 additions and 0 deletions
|
@ -0,0 +1,181 @@
|
|||
// Copyright 2025 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "VideoCommon/GraphicsModSystem/Runtime/Actions/RelativeCameraAction.h"
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <ranges>
|
||||
#include <string_view>
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <imgui.h>
|
||||
#include <misc/cpp/imgui_stdlib.h>
|
||||
|
||||
#include "Common/JsonUtil.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "VideoCommon/AbstractTexture.h"
|
||||
#include "VideoCommon/FreeLookCamera.h"
|
||||
#include "VideoCommon/GraphicsModEditor/EditorBackend.h"
|
||||
#include "VideoCommon/GraphicsModEditor/EditorEvents.h"
|
||||
#include "VideoCommon/GraphicsModEditor/EditorMain.h"
|
||||
#include "VideoCommon/GraphicsModEditor/EditorState.h"
|
||||
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h"
|
||||
|
||||
std::unique_ptr<RelativeCameraAction>
|
||||
RelativeCameraAction::Create(const picojson::value& json_data,
|
||||
std::shared_ptr<VideoCommon::CustomAssetLibrary>)
|
||||
{
|
||||
if (!json_data.is<picojson::object>())
|
||||
return nullptr;
|
||||
|
||||
// const auto& obj = json_data.get<picojson::object>();
|
||||
|
||||
return std::make_unique<RelativeCameraAction>();
|
||||
}
|
||||
|
||||
RelativeCameraAction::RelativeCameraAction(GraphicsModSystem::Camera camera)
|
||||
: m_camera(std::move(camera))
|
||||
{
|
||||
}
|
||||
|
||||
void RelativeCameraAction::OnDrawStarted(GraphicsModActionData::DrawStarted* draw_started)
|
||||
{
|
||||
if (!draw_started) [[unlikely]]
|
||||
return;
|
||||
|
||||
if (!draw_started->camera) [[unlikely]]
|
||||
return;
|
||||
|
||||
*draw_started->camera = m_camera;
|
||||
}
|
||||
|
||||
void RelativeCameraAction::DrawImGui()
|
||||
{
|
||||
if (ImGui::CollapsingHeader("Camera Data", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
if (ImGui::BeginTable("Camera Form", 2))
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Transform");
|
||||
ImGui::TableNextColumn();
|
||||
for (std::size_t i = 0; i < 4; i++)
|
||||
{
|
||||
const std::span<float> vec4 = m_camera.transform.data | std::views::take(4);
|
||||
ImGui::InputFloat4(fmt::format("##CameraTransform{}", i).c_str(), vec4.data());
|
||||
}
|
||||
if (ImGui::Button("Set to current Freelook view"))
|
||||
{
|
||||
m_camera.transform = g_freelook_camera.GetView();
|
||||
}
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Generate new render targets");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("##GenerateRenderTargets", &m_camera.generates_render_targets);
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Resolution Multiplier");
|
||||
ImGui::TableNextColumn();
|
||||
if (!m_camera.generates_render_targets)
|
||||
ImGui::BeginDisabled();
|
||||
if (ImGui::BeginCombo("##ResolutionMultiplier",
|
||||
fmt::to_string(m_camera.resolution_multiplier).c_str()))
|
||||
{
|
||||
using ResolutionMultiplierValue = std::pair<std::string_view, float>;
|
||||
static constexpr std::array<ResolutionMultiplierValue, 4> available = {
|
||||
ResolutionMultiplierValue{"0.25", 0.25f}, ResolutionMultiplierValue{"0.5", 0.5f},
|
||||
ResolutionMultiplierValue{"1.0", 1.0f}, ResolutionMultiplierValue{"2.0", 2.0f}};
|
||||
for (const auto& option : available)
|
||||
{
|
||||
const bool is_selected = option.second == m_camera.resolution_multiplier;
|
||||
if (ImGui::Selectable(fmt::format("{}##", option.first).c_str(), is_selected))
|
||||
{
|
||||
m_camera.resolution_multiplier = option.second;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (!m_camera.generates_render_targets)
|
||||
ImGui::EndDisabled();
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Render Target Type");
|
||||
ImGui::TableNextColumn();
|
||||
if (!m_camera.generates_render_targets)
|
||||
ImGui::BeginDisabled();
|
||||
if (ImGui::BeginCombo("##RenderTargetType",
|
||||
fmt::to_string(m_camera.render_target_type).c_str()))
|
||||
{
|
||||
static constexpr std::array<AbstractTextureType, 3> all_texture_types = {
|
||||
AbstractTextureType::Texture_2D, AbstractTextureType::Texture_CubeMap};
|
||||
|
||||
for (const auto& texture_type : all_texture_types)
|
||||
{
|
||||
const bool is_selected = texture_type == m_camera.render_target_type;
|
||||
const auto texture_type_str = fmt::to_string(texture_type);
|
||||
if (ImGui::Selectable(fmt::format("{}##", texture_type_str).c_str(), is_selected))
|
||||
{
|
||||
m_camera.render_target_type = texture_type;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (!m_camera.generates_render_targets)
|
||||
ImGui::EndDisabled();
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_camera.generates_render_targets &&
|
||||
ImGui::CollapsingHeader("Render Targets", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
auto& manager = Core::System::GetInstance().GetGraphicsModManager();
|
||||
auto& backend = static_cast<GraphicsModEditor::EditorBackend&>(manager.GetBackend());
|
||||
const auto render_targets = backend.GetCameraManager().GetRenderTargets(GetDrawCall());
|
||||
for (const auto& [name, render_target_texture] : render_targets)
|
||||
{
|
||||
// TODO: this is duplicated from property panel (minus copy hash), we should move this to a
|
||||
// function
|
||||
const float column_width = ImGui::GetContentRegionAvail().x;
|
||||
float image_width = render_target_texture->GetWidth();
|
||||
float image_height = render_target_texture->GetHeight();
|
||||
const float image_aspect_ratio = image_width / image_height;
|
||||
|
||||
const float final_width = std::min(image_width * 4, column_width);
|
||||
image_width = final_width;
|
||||
image_height = final_width / image_aspect_ratio;
|
||||
|
||||
ImGui::ImageButton(name.data(), *render_target_texture, ImVec2{image_width, image_height});
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
if (ImGui::Selectable("Dump"))
|
||||
{
|
||||
VideoCommon::TextureUtils::DumpTexture(*render_target_texture, std::string{name}, 0,
|
||||
false);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::Text("%s %dx%d", name.data(), render_target_texture->GetWidth(),
|
||||
render_target_texture->GetHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RelativeCameraAction::SerializeToConfig(picojson::object* obj)
|
||||
{
|
||||
if (!obj) [[unlikely]]
|
||||
return;
|
||||
|
||||
auto& json_obj = *obj;
|
||||
json_obj["generates_render_targets"] = picojson::value{m_camera.generates_render_targets};
|
||||
json_obj["resolution_multiplier"] =
|
||||
picojson::value{static_cast<double>(m_camera.resolution_multiplier)};
|
||||
}
|
||||
|
||||
std::string RelativeCameraAction::GetFactoryName() const
|
||||
{
|
||||
return std::string{factory_name};
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2025 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <picojson.h>
|
||||
|
||||
#include "VideoCommon/GraphicsModSystem/Runtime/GraphicsModAction.h"
|
||||
|
||||
class RelativeCameraAction final : public GraphicsModAction
|
||||
{
|
||||
public:
|
||||
static constexpr std::string_view factory_name = "relative_camera";
|
||||
static std::unique_ptr<RelativeCameraAction>
|
||||
Create(const picojson::value& json_data,
|
||||
std::shared_ptr<VideoCommon::CustomAssetLibrary> library);
|
||||
explicit RelativeCameraAction(GraphicsModSystem::Camera camera);
|
||||
RelativeCameraAction() = default;
|
||||
void OnDrawStarted(GraphicsModActionData::DrawStarted*) override;
|
||||
|
||||
void DrawImGui() override;
|
||||
void SerializeToConfig(picojson::object* obj) override;
|
||||
std::string GetFactoryName() const override;
|
||||
|
||||
private:
|
||||
GraphicsModSystem::Camera m_camera;
|
||||
};
|
Loading…
Add table
Reference in a new issue