mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-23 18:59:19 +00:00
VideoCommon: add graphics mod editor control for shader assets
This commit is contained in:
parent
315da7b233
commit
a811317353
2 changed files with 538 additions and 0 deletions
|
@ -0,0 +1,503 @@
|
||||||
|
// Copyright 2023 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "VideoCommon/GraphicsModEditor/Controls/ShaderControl.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <misc/cpp/imgui_stdlib.h>
|
||||||
|
|
||||||
|
#include "Common/VariantUtil.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/Assets/ShaderAsset.h"
|
||||||
|
#include "VideoCommon/GraphicsModEditor/Controls/AssetDisplay.h"
|
||||||
|
#include "VideoCommon/GraphicsModEditor/EditorEvents.h"
|
||||||
|
|
||||||
|
namespace GraphicsModEditor::Controls
|
||||||
|
{
|
||||||
|
ShaderControl::ShaderControl(EditorState& state) : m_state(state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderControl::DrawImGui(const VideoCommon::CustomAssetLibrary::AssetID& asset_id,
|
||||||
|
VideoCommon::PixelShaderData* shader,
|
||||||
|
VideoCommon::CustomAssetLibrary::TimeType* last_data_write)
|
||||||
|
{
|
||||||
|
if (ImGui::BeginTable("ShaderForm", 2))
|
||||||
|
{
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("ID");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%s", asset_id.c_str());
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::CollapsingHeader("Properties", ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
|
{
|
||||||
|
for (auto& entry : shader->m_properties)
|
||||||
|
{
|
||||||
|
// C++20: error with capturing structured bindings for our version of clang
|
||||||
|
auto& name = entry.first;
|
||||||
|
auto& property = entry.second;
|
||||||
|
|
||||||
|
ImGui::Text("%s", name.c_str());
|
||||||
|
ImGui::SameLine();
|
||||||
|
// TODO Button for editing description
|
||||||
|
ImGui::SameLine();
|
||||||
|
std::visit(
|
||||||
|
overloaded{
|
||||||
|
[&](VideoCommon::ShaderProperty::Sampler2D& default_value) {
|
||||||
|
if (AssetDisplay(name, &m_state, &default_value.value.asset,
|
||||||
|
AssetDataType::Texture))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](VideoCommon::ShaderProperty::Sampler2DArray& default_value) {
|
||||||
|
if (AssetDisplay(name, &m_state, &default_value.value.asset,
|
||||||
|
AssetDataType::Texture))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](VideoCommon::ShaderProperty::SamplerCube& default_value) {
|
||||||
|
if (AssetDisplay(name, &m_state, &default_value.value.asset,
|
||||||
|
AssetDataType::Texture))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](s32& default_value) {
|
||||||
|
if (ImGui::InputInt(fmt::format("##{}", name).c_str(), &default_value))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<s32, 2>& default_value) {
|
||||||
|
if (ImGui::InputInt2(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<s32, 3>& default_value) {
|
||||||
|
if (ImGui::InputInt3(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<s32, 4>& default_value) {
|
||||||
|
if (ImGui::InputInt4(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](float& default_value) {
|
||||||
|
if (ImGui::InputFloat(fmt::format("##{}", name).c_str(), &default_value))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<float, 2>& default_value) {
|
||||||
|
if (ImGui::InputFloat2(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<float, 3>& default_value) {
|
||||||
|
if (ImGui::InputFloat3(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<float, 4>& default_value) {
|
||||||
|
if (ImGui::InputFloat4(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](VideoCommon::ShaderProperty::RGB& default_value) {
|
||||||
|
if (ImGui::ColorEdit3(fmt::format("##{}", name).c_str(),
|
||||||
|
default_value.value.data()))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](VideoCommon::ShaderProperty::RGBA& default_value) {
|
||||||
|
if (ImGui::ColorEdit4(fmt::format("##{}", name).c_str(),
|
||||||
|
default_value.value.data()))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](bool& default_value) {
|
||||||
|
if (ImGui::Checkbox(fmt::format("##{}", name).c_str(), &default_value))
|
||||||
|
{
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
property.m_default);
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("X"))
|
||||||
|
{
|
||||||
|
shader->m_properties.erase(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
if (ImGui::Button("Add"))
|
||||||
|
{
|
||||||
|
m_add_property_name = "";
|
||||||
|
m_add_property_chosen_type = "";
|
||||||
|
m_add_property_data = {};
|
||||||
|
ImGui::OpenPopup("AddShaderPropPopup");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginPopupModal("AddShaderPropPopup", nullptr))
|
||||||
|
{
|
||||||
|
if (ImGui::BeginTable("AddShaderPropForm", 2))
|
||||||
|
{
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Name");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::InputText("##PropName", &m_add_property_name);
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Type");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
|
if (ImGui::BeginCombo("##PropType", m_add_property_chosen_type.c_str()))
|
||||||
|
{
|
||||||
|
for (const auto& type : VideoCommon::ShaderProperty::GetValueTypeNames())
|
||||||
|
{
|
||||||
|
const bool is_selected = type == m_add_property_chosen_type;
|
||||||
|
if (ImGui::Selectable(type.data(), is_selected))
|
||||||
|
{
|
||||||
|
m_add_property_chosen_type = type;
|
||||||
|
m_add_property_data = VideoCommon::ShaderProperty::GetDefaultValueFromTypeName(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Add"))
|
||||||
|
{
|
||||||
|
VideoCommon::ShaderProperty shader_property;
|
||||||
|
shader_property.m_description = "";
|
||||||
|
shader_property.m_default = m_add_property_data;
|
||||||
|
shader->m_properties.insert_or_assign(m_add_property_name, std::move(shader_property));
|
||||||
|
*last_data_write = std::chrono::system_clock::now();
|
||||||
|
GraphicsModEditor::EditorEvents::ChangeOccurredEvent::Trigger();
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Cancel"))
|
||||||
|
{
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderControl::DrawImGui(const VideoCommon::CustomAssetLibrary::AssetID& asset_id,
|
||||||
|
VideoCommon::RasterShaderData* shader)
|
||||||
|
{
|
||||||
|
if (ImGui::BeginTable("ShaderForm", 2))
|
||||||
|
{
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("ID");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("%s", asset_id.c_str());
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto parse_properties =
|
||||||
|
[&](std::map<std::string, VideoCommon::ShaderProperty2>& properties) {
|
||||||
|
std::vector<std::string> properties_to_erase;
|
||||||
|
for (auto& entry : properties)
|
||||||
|
{
|
||||||
|
// C++20: error with capturing structured bindings for our version of clang
|
||||||
|
auto& name = entry.first;
|
||||||
|
auto& property = entry.second;
|
||||||
|
|
||||||
|
ImGui::Text("%s", name.c_str());
|
||||||
|
ImGui::SameLine();
|
||||||
|
// TODO Button for editing description
|
||||||
|
ImGui::SameLine();
|
||||||
|
std::visit(
|
||||||
|
overloaded{
|
||||||
|
[&](s32& default_value) {
|
||||||
|
if (ImGui::InputInt(fmt::format("##{}", name).c_str(), &default_value))
|
||||||
|
{
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<s32, 2>& default_value) {
|
||||||
|
if (ImGui::InputInt2(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<s32, 3>& default_value) {
|
||||||
|
if (ImGui::InputInt3(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<s32, 4>& default_value) {
|
||||||
|
if (ImGui::InputInt4(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](float& default_value) {
|
||||||
|
if (ImGui::InputFloat(fmt::format("##{}", name).c_str(), &default_value))
|
||||||
|
{
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<float, 2>& default_value) {
|
||||||
|
if (ImGui::InputFloat2(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<float, 3>& default_value) {
|
||||||
|
if (ImGui::InputFloat3(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](std::array<float, 4>& default_value) {
|
||||||
|
if (ImGui::InputFloat4(fmt::format("##{}", name).c_str(), default_value.data()))
|
||||||
|
{
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](VideoCommon::ShaderProperty2::RGB& default_value) {
|
||||||
|
if (ImGui::ColorEdit3(fmt::format("##{}", name).c_str(),
|
||||||
|
default_value.value.data()))
|
||||||
|
{
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](VideoCommon::ShaderProperty2::RGBA& default_value) {
|
||||||
|
if (ImGui::ColorEdit4(fmt::format("##{}", name).c_str(),
|
||||||
|
default_value.value.data()))
|
||||||
|
{
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[&](bool& default_value) {
|
||||||
|
if (ImGui::Checkbox(fmt::format("##{}", name).c_str(), &default_value))
|
||||||
|
{
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
property.m_default);
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("X"))
|
||||||
|
{
|
||||||
|
properties_to_erase.push_back(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& name : properties_to_erase)
|
||||||
|
{
|
||||||
|
properties.erase(name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ImGui::CollapsingHeader("Vertex Properties", ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
|
{
|
||||||
|
parse_properties(shader->m_vertex_properties);
|
||||||
|
ImGui::Separator();
|
||||||
|
AddShaderProperty(shader, &shader->m_vertex_properties, "vertex");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::CollapsingHeader("Pixel Properties", ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
|
{
|
||||||
|
parse_properties(shader->m_pixel_properties);
|
||||||
|
ImGui::Separator();
|
||||||
|
AddShaderProperty(shader, &shader->m_pixel_properties, "pixel");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::CollapsingHeader("Pixel Textures", ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
|
{
|
||||||
|
ImGui::PushID("Sampler");
|
||||||
|
std::vector<VideoCommon::RasterShaderData::SamplerData*> sampler_to_erase;
|
||||||
|
for (std::size_t i = 0; i < shader->m_pixel_samplers.size(); i++)
|
||||||
|
{
|
||||||
|
ImGui::PushID(static_cast<int>(i));
|
||||||
|
auto& sampler = shader->m_pixel_samplers[i];
|
||||||
|
ImGui::InputText("Name", &sampler.name, ImGuiInputTextFlags_CharsNoBlank);
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
if (ImGui::BeginCombo("##TextureType", fmt::to_string(sampler.type).c_str()))
|
||||||
|
{
|
||||||
|
static constexpr std::array<AbstractTextureType, 3> all_texture_types = {
|
||||||
|
AbstractTextureType::Texture_2D, AbstractTextureType::Texture_2DArray,
|
||||||
|
AbstractTextureType::Texture_CubeMap};
|
||||||
|
|
||||||
|
for (const auto& texture_type : all_texture_types)
|
||||||
|
{
|
||||||
|
const bool is_selected = texture_type == sampler.type;
|
||||||
|
const auto texture_type_str = fmt::to_string(texture_type);
|
||||||
|
if (ImGui::Selectable(fmt::format("{}##", texture_type_str).c_str(), is_selected))
|
||||||
|
{
|
||||||
|
sampler.type = texture_type;
|
||||||
|
GraphicsModEditor::EditorEvents::AssetReloadEvent::Trigger(asset_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("X"))
|
||||||
|
{
|
||||||
|
sampler_to_erase.push_back(&sampler);
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto sampler : sampler_to_erase)
|
||||||
|
{
|
||||||
|
std::erase(shader->m_pixel_samplers, *sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Add"))
|
||||||
|
{
|
||||||
|
VideoCommon::RasterShaderData::SamplerData sampler_data;
|
||||||
|
sampler_data.name = "";
|
||||||
|
sampler_data.type = AbstractTextureType::Texture_2D;
|
||||||
|
shader->m_pixel_samplers.push_back(std::move(sampler_data));
|
||||||
|
GraphicsModEditor::EditorEvents::ChangeOccurredEvent::Trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::CollapsingHeader("Pixel Output Target", ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
|
{
|
||||||
|
ImGui::PushID("Output Target");
|
||||||
|
std::vector<VideoCommon::RasterShaderData::OutputTargetData*> output_targets_to_erase;
|
||||||
|
for (std::size_t i = 0; i < shader->m_output_targets.size(); i++)
|
||||||
|
{
|
||||||
|
ImGui::PushID(static_cast<int>(i));
|
||||||
|
auto& output_target = shader->m_output_targets[i];
|
||||||
|
ImGui::InputText("Name", &output_target.name, ImGuiInputTextFlags_CharsNoBlank);
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("X"))
|
||||||
|
{
|
||||||
|
output_targets_to_erase.push_back(&output_target);
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto output_target : output_targets_to_erase)
|
||||||
|
{
|
||||||
|
std::erase(shader->m_output_targets, *output_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Add"))
|
||||||
|
{
|
||||||
|
VideoCommon::RasterShaderData::OutputTargetData output_target;
|
||||||
|
output_target.name = "";
|
||||||
|
shader->m_output_targets.push_back(std::move(output_target));
|
||||||
|
GraphicsModEditor::EditorEvents::ChangeOccurredEvent::Trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderControl::AddShaderProperty(
|
||||||
|
VideoCommon::RasterShaderData* shader,
|
||||||
|
std::map<std::string, VideoCommon::ShaderProperty2>* properties, std::string_view type)
|
||||||
|
{
|
||||||
|
if (ImGui::Button(fmt::format("Add {} property", type).c_str()))
|
||||||
|
{
|
||||||
|
m_add_property_name = "";
|
||||||
|
m_add_property_chosen_type = "";
|
||||||
|
m_add_property2_data = {};
|
||||||
|
ImGui::OpenPopup(fmt::format("AddShader{}PropPopup", type).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginPopupModal(fmt::format("AddShader{}PropPopup", type).c_str(), nullptr))
|
||||||
|
{
|
||||||
|
if (ImGui::BeginTable(fmt::format("AddShader{}PropForm", type).c_str(), 2))
|
||||||
|
{
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Name");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::InputText(fmt::format("##PropName{}", type).c_str(), &m_add_property_name);
|
||||||
|
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::Text("Type");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
|
if (ImGui::BeginCombo(fmt::format("##PropType{}", type).c_str(),
|
||||||
|
m_add_property_chosen_type.c_str()))
|
||||||
|
{
|
||||||
|
for (const auto& type_name : VideoCommon::ShaderProperty2::GetValueTypeNames())
|
||||||
|
{
|
||||||
|
const bool is_selected = type_name == m_add_property_chosen_type;
|
||||||
|
if (ImGui::Selectable(type.data(), is_selected))
|
||||||
|
{
|
||||||
|
m_add_property_chosen_type = type_name;
|
||||||
|
m_add_property2_data = VideoCommon::ShaderProperty2::GetDefaultValueFromTypeName(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Add"))
|
||||||
|
{
|
||||||
|
VideoCommon::ShaderProperty2 shader_property;
|
||||||
|
shader_property.m_description = "";
|
||||||
|
shader_property.m_default = m_add_property2_data;
|
||||||
|
shader->m_pixel_properties.insert_or_assign(m_add_property_name, std::move(shader_property));
|
||||||
|
GraphicsModEditor::EditorEvents::ChangeOccurredEvent::Trigger();
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Cancel"))
|
||||||
|
{
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace GraphicsModEditor::Controls
|
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2023 Dolphin Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
#include "VideoCommon/Assets/CustomAsset.h"
|
||||||
|
#include "VideoCommon/Assets/ShaderAsset.h"
|
||||||
|
#include "VideoCommon/GraphicsModEditor/EditorState.h"
|
||||||
|
|
||||||
|
namespace GraphicsModEditor::Controls
|
||||||
|
{
|
||||||
|
class ShaderControl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ShaderControl(EditorState& state);
|
||||||
|
void DrawImGui(const VideoCommon::CustomAssetLibrary::AssetID& asset_id,
|
||||||
|
VideoCommon::PixelShaderData* shader,
|
||||||
|
VideoCommon::CustomAssetLibrary::TimeType* last_data_write);
|
||||||
|
void DrawImGui(const VideoCommon::CustomAssetLibrary::AssetID& asset_id,
|
||||||
|
VideoCommon::RasterShaderData* shader);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void AddShaderProperty(VideoCommon::RasterShaderData* shader,
|
||||||
|
std::map<std::string, VideoCommon::ShaderProperty2>* properties,
|
||||||
|
std::string_view type);
|
||||||
|
std::string m_add_property_name;
|
||||||
|
std::string m_add_property_chosen_type;
|
||||||
|
VideoCommon::ShaderProperty::Value m_add_property_data;
|
||||||
|
VideoCommon::ShaderProperty2::Value m_add_property2_data;
|
||||||
|
EditorState& m_state;
|
||||||
|
};
|
||||||
|
} // namespace GraphicsModEditor::Controls
|
Loading…
Add table
Add a link
Reference in a new issue