Completely remove the defunct UI system
This commit is contained in:
parent
648d2968d4
commit
626e314ec2
16 changed files with 4 additions and 939 deletions
|
@ -6,8 +6,6 @@ set(SRC
|
|||
include/physics.hpp
|
||||
include/scene.hpp
|
||||
include/imgui_backend.hpp
|
||||
include/uielement.hpp
|
||||
include/screen.hpp
|
||||
include/object.hpp
|
||||
include/debug.hpp
|
||||
include/components.hpp
|
||||
|
@ -19,7 +17,6 @@ set(SRC
|
|||
src/input.cpp
|
||||
src/physics.cpp
|
||||
src/imgui_backend.cpp
|
||||
src/screen.cpp
|
||||
src/scene.cpp
|
||||
src/debug.cpp
|
||||
src/console.cpp)
|
||||
|
|
|
@ -103,17 +103,6 @@ struct Camera {
|
|||
Matrix4x4 view, perspective;
|
||||
};
|
||||
|
||||
namespace ui {
|
||||
class Screen;
|
||||
}
|
||||
|
||||
struct UI {
|
||||
int width = 1920, height = 1080;
|
||||
|
||||
std::string ui_path;
|
||||
ui::Screen* screen = nullptr;
|
||||
};
|
||||
|
||||
struct EnvironmentProbe {
|
||||
bool is_sized = true;
|
||||
prism::float3 size = prism::float3(10);
|
||||
|
|
|
@ -10,11 +10,6 @@
|
|||
#include "path.hpp"
|
||||
|
||||
class GFX;
|
||||
|
||||
namespace ui {
|
||||
class Screen;
|
||||
}
|
||||
|
||||
class Scene;
|
||||
class RenderTarget;
|
||||
class Physics;
|
||||
|
@ -141,22 +136,6 @@ namespace prism {
|
|||
*/
|
||||
void save_scene(std::string_view path);
|
||||
|
||||
/** Load a UI screen from disk. This will not change the current screen.
|
||||
@param path The screen file path.
|
||||
@return Returns a instance of the screen if successful, and nullptr on failure.
|
||||
*/
|
||||
ui::Screen* load_screen(const prism::path& path);
|
||||
|
||||
/** Set the current screen.
|
||||
@param screen The screen object to set as current. Can be null.
|
||||
*/
|
||||
void set_screen(ui::Screen* screen);
|
||||
|
||||
/** Gets the current screen.
|
||||
@return The current screen. Can be null.
|
||||
*/
|
||||
[[nodiscard]] ui::Screen* get_screen() const;
|
||||
|
||||
/** Load a prefab from disk.
|
||||
@param scene The scene to add the prefab to.
|
||||
@param path The prefab file path.
|
||||
|
@ -231,31 +210,6 @@ namespace prism {
|
|||
*/
|
||||
void process_mouse_down(int button, prism::Offset offset);
|
||||
|
||||
/** Pushes a UI event for the current screen. Does nothing if there is no screen set.
|
||||
@param name The name of the event.
|
||||
@param data Data for the event. Defaulted to an empty string.
|
||||
*/
|
||||
void push_event(std::string_view name, std::string_view data = "");
|
||||
|
||||
/** Load a localization file from disk. This will change the current localization.
|
||||
@param path The localization file path.
|
||||
*/
|
||||
void load_localization(std::string_view path);
|
||||
|
||||
/** Queries whether or not the current localization loaded has a key.
|
||||
@param id The key to query.
|
||||
@return Whether or not the locale has the key specified.
|
||||
@note Having no localization loaded will always return false.
|
||||
*/
|
||||
[[nodiscard]] bool has_localization(std::string_view id) const;
|
||||
|
||||
/** Localizes a string.
|
||||
@param id The locale key to use.
|
||||
@return A localized string if the key is found, or an empty string if not found.
|
||||
@note Having no localization loaded will always return a empty string.
|
||||
*/
|
||||
std::string localize(const std::string& id);
|
||||
|
||||
/** Adds a timer to the list of timers.
|
||||
@param timer The timer to add.
|
||||
@note The timer instance is passed by reference. Use this to keep track of your timers without having to query it's state back.
|
||||
|
@ -335,8 +289,6 @@ namespace prism {
|
|||
|
||||
bool paused = false;
|
||||
|
||||
ui::Screen* current_screen = nullptr;
|
||||
|
||||
Scene* current_scene = nullptr;
|
||||
std::vector<std::unique_ptr<Scene>> scenes;
|
||||
std::map<std::string, Scene*> path_to_scene;
|
||||
|
|
|
@ -201,7 +201,7 @@ class GFXFramebuffer;
|
|||
class GFXTexture;
|
||||
|
||||
/// Represents a scene consisting of Objects with varying Components.
|
||||
class Scene : public ObjectComponents<Data, Transform, Renderable, Light, Camera, Collision, Rigidbody, UI, EnvironmentProbe> {
|
||||
class Scene : public ObjectComponents<Data, Transform, Renderable, Light, Camera, Collision, Rigidbody, EnvironmentProbe> {
|
||||
public:
|
||||
/// If loaded from disk, the path to the scene file this originated from.
|
||||
std::string path;
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
#include "uielement.hpp"
|
||||
#include "file.hpp"
|
||||
#include "common.hpp"
|
||||
|
||||
class GFXBuffer;
|
||||
|
||||
namespace ui {
|
||||
class Screen {
|
||||
public:
|
||||
Screen() {}
|
||||
Screen(const prism::path path);
|
||||
|
||||
void process_event(const std::string& type, std::string data = "");
|
||||
|
||||
void process_mouse(const int x, const int y);
|
||||
void calculate_sizes();
|
||||
|
||||
std::vector<UIElement> elements;
|
||||
|
||||
UIElement* find_element(const std::string& id);
|
||||
|
||||
using CallbackFunction = std::function<void()>;
|
||||
std::map<std::string, CallbackFunction> listeners;
|
||||
|
||||
bool blurs_background = false;
|
||||
|
||||
void add_listener(const std::string& id, std::function<void()> callback);
|
||||
|
||||
prism::Extent extent;
|
||||
bool view_changed = false;
|
||||
|
||||
GFXBuffer* glyph_buffer = nullptr;
|
||||
GFXBuffer* instance_buffer = nullptr;
|
||||
GFXBuffer* elements_buffer = nullptr;
|
||||
};
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "assetptr.hpp"
|
||||
|
||||
enum class MetricType {
|
||||
Absolute,
|
||||
Relative,
|
||||
Offset
|
||||
};
|
||||
|
||||
struct Color {
|
||||
Color() : r(1.0f), g(1.0f), b(1.0f), a(1.0f) {}
|
||||
|
||||
Color(const float v) : r(v), g(v), b(v), a(1.0f) {}
|
||||
|
||||
union {
|
||||
struct {
|
||||
float r, g, b, a;
|
||||
};
|
||||
|
||||
float v[4];
|
||||
};
|
||||
};
|
||||
|
||||
class GFXTexture;
|
||||
class Texture;
|
||||
|
||||
class UIElement {
|
||||
public:
|
||||
struct Metrics {
|
||||
struct Metric {
|
||||
MetricType type = MetricType::Absolute;
|
||||
int value = 0;
|
||||
};
|
||||
|
||||
Metric x, y, width, height;
|
||||
} metrics;
|
||||
|
||||
struct Background {
|
||||
Color color = Color(0.0f);
|
||||
std::string image;
|
||||
|
||||
AssetPtr<Texture> texture;
|
||||
} background;
|
||||
|
||||
enum class TextLocation {
|
||||
TopLeft,
|
||||
Center
|
||||
} text_location = TextLocation::TopLeft;
|
||||
|
||||
std::string id, text, parent;
|
||||
|
||||
bool wrap_text = false;
|
||||
|
||||
float absolute_x = 0.0f, absolute_y = 0.0f, absolute_width = 0.0f, absolute_height = 0.0f;
|
||||
float text_x = 0.0f, text_y = 0.0f;
|
||||
|
||||
bool visible = true;
|
||||
|
||||
std::string on_click_script;
|
||||
};
|
||||
|
||||
inline bool operator==(const UIElement& a, const UIElement& b) {
|
||||
return a.id == b.id;
|
||||
}
|
|
@ -11,7 +11,6 @@
|
|||
#include "json_conversions.hpp"
|
||||
#include "app.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "screen.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "gfx.hpp"
|
||||
#include "imgui_backend.hpp"
|
||||
|
@ -60,26 +59,12 @@ prism::app* engine::get_app() const {
|
|||
return app;
|
||||
}
|
||||
|
||||
void engine::load_localization(const std::string_view path) {
|
||||
Expects(!path.empty());
|
||||
|
||||
auto file = prism::open_file(prism::app_domain / path);
|
||||
if(file.has_value()) {
|
||||
nlohmann::json j;
|
||||
file->read_as_stream() >> j;
|
||||
|
||||
strings = j["strings"].get<std::map<std::string, std::string>>();
|
||||
}
|
||||
}
|
||||
|
||||
void engine::pause() {
|
||||
paused = true;
|
||||
push_event("engine_pause");
|
||||
}
|
||||
|
||||
void engine::unpause() {
|
||||
paused = false;
|
||||
push_event("engine_unpause");
|
||||
}
|
||||
|
||||
bool engine::is_paused() const {
|
||||
|
@ -193,25 +178,6 @@ void engine::save_scene(const std::string_view path) {
|
|||
out << j;
|
||||
}
|
||||
|
||||
ui::Screen* engine::load_screen(const prism::path& path) {
|
||||
Expects(!path.empty());
|
||||
|
||||
return new ui::Screen(path);
|
||||
}
|
||||
|
||||
void engine::set_screen(ui::Screen* screen) {
|
||||
current_screen = screen;
|
||||
|
||||
screen->extent = windows[0]->extent;
|
||||
screen->calculate_sizes();
|
||||
|
||||
get_renderer()->set_screen(screen);
|
||||
}
|
||||
|
||||
ui::Screen* engine::get_screen() const {
|
||||
return current_screen;
|
||||
}
|
||||
|
||||
AnimationChannel engine::load_animation(nlohmann::json a) {
|
||||
AnimationChannel animation;
|
||||
|
||||
|
@ -454,13 +420,6 @@ void engine::resize(const int identifier, const prism::Extent extent) {
|
|||
|
||||
gfx->recreate_view(identifier, drawable_extent.width, drawable_extent.height);
|
||||
renderer->resize_render_target(*window->render_target, drawable_extent);
|
||||
|
||||
if(identifier == 0) {
|
||||
if(current_screen != nullptr) {
|
||||
current_screen->extent = extent;
|
||||
current_screen->calculate_sizes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void engine::process_key_down(const unsigned int keyCode) {
|
||||
|
@ -479,31 +438,9 @@ void engine::process_key_up(const unsigned int keyCode) {
|
|||
}
|
||||
|
||||
void engine::process_mouse_down(const int button, const prism::Offset offset) {
|
||||
if(current_screen != nullptr && button == 0)
|
||||
current_screen->process_mouse(offset.x, offset.y);
|
||||
|
||||
imgui->process_mouse_down(button);
|
||||
}
|
||||
|
||||
void engine::push_event(const std::string_view name, const std::string_view data) {
|
||||
Expects(!name.empty());
|
||||
|
||||
if(current_screen != nullptr)
|
||||
current_screen->process_event(name.data(), data.data());
|
||||
}
|
||||
|
||||
bool engine::has_localization(const std::string_view id) const {
|
||||
Expects(!id.empty());
|
||||
|
||||
return strings.count(id.data());
|
||||
}
|
||||
|
||||
std::string engine::localize(const std::string& id) {
|
||||
Expects(!id.empty());
|
||||
|
||||
return strings[id];
|
||||
}
|
||||
|
||||
void engine::calculate_bone(Mesh& mesh, const Mesh::Part& part, Bone& bone, const Bone* parent_bone) {
|
||||
if(part.offset_matrices.empty())
|
||||
return;
|
||||
|
@ -769,11 +706,6 @@ void engine::render(const int index) {
|
|||
GFXCommandBuffer* commandbuffer = gfx->acquire_command_buffer(true);
|
||||
|
||||
if(index == 0) {
|
||||
if(current_screen != nullptr && current_screen->view_changed) {
|
||||
renderer->update_screen();
|
||||
current_screen->view_changed = false;
|
||||
}
|
||||
|
||||
imgui->render(0);
|
||||
|
||||
app->render(commandbuffer);
|
||||
|
|
|
@ -65,12 +65,6 @@ void load_rigidbody_component(nlohmann::json j, Rigidbody& rigidbody) {
|
|||
rigidbody.mass = j["mass"];
|
||||
}
|
||||
|
||||
void load_ui_component(nlohmann::json j, UI& ui) {
|
||||
ui.width = j["width"];
|
||||
ui.height = j["height"];
|
||||
ui.ui_path = j["path"];
|
||||
}
|
||||
|
||||
void load_probe_component(nlohmann::json j, EnvironmentProbe& probe) {
|
||||
if(j.contains("size"))
|
||||
probe.size = j["size"];
|
||||
|
@ -105,9 +99,6 @@ Object load_object(Scene& scene, const nlohmann::json obj) {
|
|||
if(obj.contains("rigidbody"))
|
||||
load_rigidbody_component(obj["rigidbody"], scene.add<Rigidbody>(o));
|
||||
|
||||
if(obj.contains("ui"))
|
||||
load_ui_component(obj["ui"], scene.add<UI>(o));
|
||||
|
||||
if(obj.contains("environment_probe"))
|
||||
load_probe_component(obj["environment_probe"], scene.add<EnvironmentProbe>(o));
|
||||
|
||||
|
@ -158,12 +149,6 @@ void save_rigidbody_component(nlohmann::json& j, const Rigidbody& rigidbody) {
|
|||
j["mass"] = rigidbody.mass;
|
||||
}
|
||||
|
||||
void save_ui_component(nlohmann::json& j, const UI& ui) {
|
||||
j["width"] = ui.width;
|
||||
j["height"] = ui.height;
|
||||
j["path"] = ui.ui_path;
|
||||
}
|
||||
|
||||
void save_probe_component(nlohmann::json& j, const EnvironmentProbe& probe) {
|
||||
j["size"] = probe.size;
|
||||
j["is_sized"] = probe.is_sized;
|
||||
|
@ -199,9 +184,6 @@ nlohmann::json save_object(Object obj) {
|
|||
if(scene->has<Rigidbody>(obj))
|
||||
save_rigidbody_component(j["rigidbody"], scene->get<Rigidbody>(obj));
|
||||
|
||||
if(scene->has<UI>(obj))
|
||||
save_ui_component(j["ui"], scene->get<UI>(obj));
|
||||
|
||||
if(scene->has<EnvironmentProbe>(obj))
|
||||
save_probe_component(j["environment_probe"], scene->get<EnvironmentProbe>(obj));
|
||||
|
||||
|
|
|
@ -1,191 +0,0 @@
|
|||
#include "screen.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <string_view>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "file.hpp"
|
||||
#include "font.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "string_utils.hpp"
|
||||
#include "log.hpp"
|
||||
#include "assertions.hpp"
|
||||
#include "uielement.hpp"
|
||||
|
||||
void ui::Screen::calculate_sizes() {
|
||||
unsigned int numChildren = 0;
|
||||
|
||||
int actualWidth = extent.width, actualHeight = extent.height;
|
||||
int offsetX = 0, offsetY = 0;
|
||||
|
||||
for(size_t i = 0; i < elements.size(); i++) {
|
||||
auto& element = elements[i];
|
||||
|
||||
auto id = "ui_" + element.id;
|
||||
//if(engine->has_localization(id))
|
||||
// element.text = engine->localize(id);
|
||||
|
||||
UIElement* parent = nullptr;
|
||||
if(!element.parent.empty())
|
||||
parent = find_element(element.parent);
|
||||
|
||||
const auto& fillAbsolute = [parent](const auto& metric, auto& absolute, auto base, auto offset) {
|
||||
switch(metric.type) {
|
||||
case MetricType::Absolute:
|
||||
absolute = offset + metric.value;
|
||||
break;
|
||||
case MetricType::Relative:
|
||||
absolute = offset + ((base - offset) * (metric.value / 100.0f));
|
||||
break;
|
||||
case MetricType::Offset:
|
||||
{
|
||||
if(parent == nullptr)
|
||||
absolute = base - metric.value;
|
||||
else
|
||||
absolute = parent->absolute_height - metric.value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
fillAbsolute(element.metrics.x, element.absolute_x, offsetX + actualWidth, offsetX);
|
||||
fillAbsolute(element.metrics.y, element.absolute_y, offsetY + actualHeight, offsetY);
|
||||
|
||||
fillAbsolute(element.metrics.width, element.absolute_width, actualWidth, 0);
|
||||
fillAbsolute(element.metrics.height, element.absolute_height, actualHeight, 0);
|
||||
|
||||
if(parent) {
|
||||
const float heightPerRow = actualWidth / (float)elements.size();
|
||||
|
||||
element.absolute_x = (float)numChildren * heightPerRow;
|
||||
element.absolute_y = actualHeight - 50.0f;
|
||||
element.absolute_width = (float)heightPerRow;
|
||||
element.absolute_height = (float)50.0f;
|
||||
|
||||
numChildren++;
|
||||
}
|
||||
|
||||
if(element.text_location == UIElement::TextLocation::Center) {
|
||||
if(get_string_width(element.text) < element.absolute_width)
|
||||
element.text_x = (element.absolute_width / 2.0f) - (get_string_width(element.text) / 2.0f);
|
||||
|
||||
if(get_font_height() < element.absolute_height)
|
||||
element.text_y = (element.absolute_height / 2.0f) - (get_font_height() / 2.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ui::Screen::process_mouse(const int x, const int y) {
|
||||
Expects(x >= 0);
|
||||
Expects(y >= 0);
|
||||
}
|
||||
|
||||
UIElement* ui::Screen::find_element(const std::string& id) {
|
||||
Expects(!id.empty());
|
||||
|
||||
UIElement* foundElement = nullptr;
|
||||
for(auto& element : elements) {
|
||||
if(element.id == id)
|
||||
foundElement = &element;
|
||||
}
|
||||
|
||||
Expects(foundElement != nullptr);
|
||||
|
||||
return foundElement;
|
||||
}
|
||||
|
||||
ui::Screen::Screen(const prism::path path) {
|
||||
auto file = prism::open_file(path);
|
||||
if(!file.has_value()) {
|
||||
prism::log::error(System::Core, "Failed to load UI from {}!", path);
|
||||
return;
|
||||
}
|
||||
|
||||
nlohmann::json j;
|
||||
file->read_as_stream() >> j;
|
||||
|
||||
for(auto& element : j["elements"]) {
|
||||
UIElement ue;
|
||||
ue.id = element["id"];
|
||||
|
||||
if(element.contains("on_click"))
|
||||
ue.on_click_script = element["on_click"];
|
||||
|
||||
if(element.contains("text"))
|
||||
ue.text = element["text"];
|
||||
|
||||
if(element.contains("parent"))
|
||||
ue.parent = element["parent"];
|
||||
|
||||
if(element.contains("metrics")) {
|
||||
const auto& metrics = element["metrics"];
|
||||
|
||||
const auto parseMetric = [](const std::string& str) {
|
||||
UIElement::Metrics::Metric m;
|
||||
|
||||
if(string_contains(str, "px")) {
|
||||
auto v = remove_substring(str, "px");
|
||||
|
||||
if(string_contains(str, "@")) {
|
||||
m.type = MetricType::Offset;
|
||||
m.value = std::stoi(remove_substring(v, "@"));
|
||||
} else {
|
||||
m.type = MetricType::Absolute;
|
||||
m.value = std::stoi(v);
|
||||
}
|
||||
} else if(string_contains(str, "%")) {
|
||||
m.type = MetricType::Relative;
|
||||
m.value = std::stoi(remove_substring(str, "%"));
|
||||
}
|
||||
|
||||
return m;
|
||||
};
|
||||
|
||||
if(metrics.contains("x"))
|
||||
ue.metrics.x = parseMetric(metrics["x"]);
|
||||
|
||||
if(metrics.contains("y"))
|
||||
ue.metrics.y = parseMetric(metrics["y"]);
|
||||
|
||||
if(metrics.contains("width"))
|
||||
ue.metrics.width = parseMetric(metrics["width"]);
|
||||
|
||||
if(metrics.contains("height"))
|
||||
ue.metrics.height = parseMetric(metrics["height"]);
|
||||
}
|
||||
|
||||
if(element.contains("background")) {
|
||||
if(element["background"].contains("color")) {
|
||||
auto tokens = tokenize(element["background"]["color"].get<std::string_view>(), ",");
|
||||
ue.background.color.r = std::stof(tokens[0]);
|
||||
ue.background.color.g = std::stof(tokens[1]);
|
||||
ue.background.color.b = std::stof(tokens[2]);
|
||||
ue.background.color.a = std::stof(tokens[3]);
|
||||
}
|
||||
|
||||
if(element["background"].contains("image")) {
|
||||
ue.background.image = element["background"]["image"];
|
||||
}
|
||||
}
|
||||
|
||||
if(element.contains("wrap"))
|
||||
ue.wrap_text = element["wrap"];
|
||||
|
||||
if(element.contains("textLocation")) {
|
||||
if(element["textLocation"] == "topLeft")
|
||||
ue.text_location = UIElement::TextLocation::TopLeft;
|
||||
else if(element["textLocation"] == "center")
|
||||
ue.text_location = UIElement::TextLocation::Center;
|
||||
}
|
||||
|
||||
elements.push_back(ue);
|
||||
}
|
||||
}
|
||||
|
||||
void ui::Screen::add_listener(const std::string& id, std::function<void()> callback) {
|
||||
listeners[id] = callback;
|
||||
}
|
||||
|
||||
void ui::Screen::process_event(const std::string& type, const std::string data) {
|
||||
|
||||
}
|
|
@ -55,21 +55,12 @@ namespace prism {
|
|||
|
||||
void recreate_all_render_targets();
|
||||
|
||||
void set_screen(ui::Screen* screen);
|
||||
|
||||
void init_screen(ui::Screen* screen);
|
||||
|
||||
void update_screen();
|
||||
|
||||
struct controller_continuity {
|
||||
int elementOffset = 0;
|
||||
};
|
||||
|
||||
void render(GFXCommandBuffer* command_buffer, Scene* scene, RenderTarget& target, int index);
|
||||
|
||||
void render_screen(GFXCommandBuffer* commandBuffer, ui::Screen* screen, prism::Extent extent,
|
||||
controller_continuity& continuity, render_screen_options options = render_screen_options());
|
||||
|
||||
void render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Object camera_object, Camera& camera,
|
||||
prism::Extent extent, RenderTarget& target, controller_continuity &continuity);
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include "gfx_commandbuffer.hpp"
|
||||
#include "math.hpp"
|
||||
#include "screen.hpp"
|
||||
#include "file.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "font.hpp"
|
||||
|
@ -185,48 +184,6 @@ void renderer::recreate_all_render_targets() {
|
|||
|
||||
}
|
||||
|
||||
void renderer::set_screen(ui::Screen* screen) {
|
||||
Expects(screen != nullptr);
|
||||
|
||||
current_screen = screen;
|
||||
|
||||
init_screen(screen);
|
||||
|
||||
update_screen();
|
||||
}
|
||||
|
||||
void renderer::init_screen(ui::Screen* screen) {
|
||||
Expects(screen != nullptr);
|
||||
|
||||
std::array<GylphMetric, numGlyphs> metrics = {};
|
||||
for(int i = 0; i < numGlyphs; i++) {
|
||||
GylphMetric& metric = metrics[i];
|
||||
metric.x0_y0 = utility::pack_u32(font.sizes[fontSize][i].x0, font.sizes[fontSize][i].y0);
|
||||
metric.x1_y1 = utility::pack_u32(font.sizes[fontSize][i].x1, font.sizes[fontSize][i].y1);
|
||||
metric.xoff = font.sizes[fontSize][i].xoff;
|
||||
metric.yoff = font.sizes[fontSize][i].yoff;
|
||||
metric.xoff2 = font.sizes[fontSize][i].xoff2;
|
||||
metric.yoff2 = font.sizes[fontSize][i].yoff2;
|
||||
}
|
||||
|
||||
screen->glyph_buffer = gfx->create_buffer(nullptr, instance_alignment + (sizeof(GylphMetric) * numGlyphs), false, GFXBufferUsage::Storage);
|
||||
|
||||
gfx->copy_buffer(screen->glyph_buffer, metrics.data(), instance_alignment, sizeof(GylphMetric) * numGlyphs);
|
||||
|
||||
screen->elements_buffer = gfx->create_buffer(nullptr, sizeof(ElementInstance) * 50, true, GFXBufferUsage::Storage);
|
||||
|
||||
screen->instance_buffer = gfx->create_buffer(nullptr, sizeof(StringInstance) * 50, true, GFXBufferUsage::Storage);
|
||||
}
|
||||
|
||||
void renderer::update_screen() {
|
||||
if(current_screen != nullptr) {
|
||||
for(auto& element : current_screen->elements) {
|
||||
if(!element.background.image.empty())
|
||||
element.background.texture = assetm->get<Texture>(prism::app_domain / element.background.image);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarget& target, int index) {
|
||||
const auto extent = target.extent;
|
||||
const auto render_extent = target.get_render_extent();
|
||||
|
@ -404,9 +361,6 @@ void renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
|
|||
|
||||
commandbuffer->pop_group();
|
||||
|
||||
if(current_screen != nullptr)
|
||||
render_screen(commandbuffer, current_screen, extent, continuity);
|
||||
|
||||
commandbuffer->push_group("Extra Passes");
|
||||
|
||||
for(auto& pass : passes)
|
||||
|
@ -533,18 +487,6 @@ void renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj
|
|||
}
|
||||
}
|
||||
|
||||
const auto& screens = scene.get_all<UI>();
|
||||
for(const auto& [obj, screen] : screens) {
|
||||
if(!screen.screen)
|
||||
continue;
|
||||
|
||||
render_screen_options options = {};
|
||||
options.render_world = true;
|
||||
options.mvp = camera.perspective * camera.view * scene.get<Transform>(obj).model;
|
||||
|
||||
render_screen(command_buffer, screen.screen, extent, continuity, options);
|
||||
}
|
||||
|
||||
SkyPushConstant pc;
|
||||
pc.view = matrix_from_quat(scene.get<Transform>(camera_object).rotation);
|
||||
pc.aspect = static_cast<float>(extent.width) / static_cast<float>(extent.height);
|
||||
|
@ -568,136 +510,6 @@ void renderer::render_camera(GFXCommandBuffer* command_buffer, Scene& scene, Obj
|
|||
gfx->copy_buffer(target.sceneBuffer, &sceneInfo, 0, sizeof(SceneInformation));
|
||||
}
|
||||
|
||||
void renderer::render_screen(GFXCommandBuffer *commandbuffer, ui::Screen* screen, prism::Extent extent, controller_continuity& continuity, render_screen_options options) {
|
||||
std::array<GlyphInstance, maxInstances> instances;
|
||||
std::vector<ElementInstance> elementInstances;
|
||||
std::array<StringInstance, 50> stringInstances = {};
|
||||
|
||||
int stringLen = 0;
|
||||
int numElements = 0;
|
||||
|
||||
for(auto [i, element] : utility::enumerate(screen->elements)) {
|
||||
if(!element.visible)
|
||||
continue;
|
||||
|
||||
ElementInstance instance;
|
||||
|
||||
instance.position = utility::pack_u32(utility::to_fixed(element.absolute_x), utility::to_fixed(element.absolute_y));
|
||||
instance.size = utility::pack_u32(utility::to_fixed(element.absolute_width), utility::to_fixed(element.absolute_height));
|
||||
instance.color[0] = element.background.color.r;
|
||||
instance.color[1] = element.background.color.g;
|
||||
instance.color[2] = element.background.color.b;
|
||||
instance.color[3] = element.background.color.a;
|
||||
|
||||
elementInstances.push_back(instance);
|
||||
|
||||
stringInstances[i].xy = utility::pack_u32(utility::to_fixed(element.absolute_x + element.text_x), utility::to_fixed(element.absolute_y + element.text_y));
|
||||
|
||||
float advance = 0.0f;
|
||||
float yadvance = 0.0f;
|
||||
|
||||
bool do_y_advance = false; // so we can not advance the text by a space if we're wrapping per word
|
||||
|
||||
for(size_t j = 0; j < element.text.length(); j++) {
|
||||
auto index = element.text[j] - 32;
|
||||
|
||||
if(do_y_advance) {
|
||||
advance = 0.0f;
|
||||
yadvance += font.ascentSizes[fontSize];
|
||||
do_y_advance = false;
|
||||
}
|
||||
|
||||
if(element.wrap_text) {
|
||||
if(element.text[j] == ' ') {
|
||||
std::string t;
|
||||
float temp_advance = 0.0f;
|
||||
for(size_t k = j + 1; k < element.text.length() + j; k++) {
|
||||
t += element.text[k];
|
||||
auto index = element.text[k] - 32;
|
||||
temp_advance += font.sizes[fontSize][index].xadvance;
|
||||
|
||||
if(element.text[k] == ' ')
|
||||
break;
|
||||
}
|
||||
|
||||
if((temp_advance + advance) >= element.absolute_width)
|
||||
do_y_advance = true;
|
||||
}
|
||||
}
|
||||
|
||||
GlyphInstance& instance = instances[stringLen + j];
|
||||
instance.position = utility::pack_u32(utility::to_fixed(advance), utility::to_fixed(yadvance));
|
||||
instance.index = utility::pack_u32(index, 0);
|
||||
instance.instance = i;
|
||||
|
||||
advance += font.sizes[fontSize][index].xadvance;
|
||||
|
||||
if(element.text[j] == '\n') {
|
||||
advance = 0.0f;
|
||||
yadvance += font.ascentSizes[fontSize];
|
||||
}
|
||||
}
|
||||
|
||||
stringLen += static_cast<int>(element.text.length());
|
||||
numElements++;
|
||||
}
|
||||
|
||||
gfx->copy_buffer(screen->glyph_buffer, instances.data(), 0, instance_alignment);
|
||||
gfx->copy_buffer(screen->instance_buffer, stringInstances.data(), 0, sizeof(StringInstance) * 50);
|
||||
gfx->copy_buffer(screen->elements_buffer, elementInstances.data(), sizeof(ElementInstance) * continuity.elementOffset, sizeof(ElementInstance) * elementInstances.size());
|
||||
|
||||
const prism::float2 windowSize = {static_cast<float>(extent.width), static_cast<float>(extent.height)};
|
||||
|
||||
for(auto [i, element] : utility::enumerate(screen->elements)) {
|
||||
if(!element.visible)
|
||||
continue;
|
||||
|
||||
UIPushConstant pc;
|
||||
pc.screenSize = windowSize;
|
||||
|
||||
if(options.render_world) {
|
||||
commandbuffer->set_graphics_pipeline(world_general_pipeline);
|
||||
pc.mvp = options.mvp;
|
||||
} else {
|
||||
commandbuffer->set_graphics_pipeline(general_pipeline);
|
||||
}
|
||||
|
||||
if (element.background.texture) {
|
||||
commandbuffer->bind_texture(element.background.texture->handle, 2);
|
||||
}
|
||||
else {
|
||||
commandbuffer->bind_texture(dummy_texture, 2);
|
||||
}
|
||||
|
||||
commandbuffer->set_push_constant(&pc, sizeof(UIPushConstant));
|
||||
|
||||
commandbuffer->bind_shader_buffer(screen->elements_buffer, 0, 0, sizeof(ElementInstance) * 50);
|
||||
commandbuffer->draw(0, 4, i + continuity.elementOffset, 1);
|
||||
}
|
||||
|
||||
UIPushConstant pc;
|
||||
pc.screenSize = windowSize;
|
||||
|
||||
if(options.render_world) {
|
||||
commandbuffer->set_graphics_pipeline(world_text_pipeline);
|
||||
pc.mvp = options.mvp;
|
||||
} else {
|
||||
commandbuffer->set_graphics_pipeline(text_pipeline);
|
||||
}
|
||||
|
||||
commandbuffer->set_push_constant(&pc, sizeof(UIPushConstant));
|
||||
|
||||
commandbuffer->bind_shader_buffer(screen->glyph_buffer, 0, 0, instance_alignment);
|
||||
commandbuffer->bind_shader_buffer(screen->glyph_buffer, instance_alignment, 1, sizeof(GylphMetric) * numGlyphs);
|
||||
commandbuffer->bind_shader_buffer(screen->instance_buffer, 0, 2, sizeof(StringInstance) * 50);
|
||||
commandbuffer->bind_texture(font_texture, 3);
|
||||
|
||||
if(stringLen > 0)
|
||||
commandbuffer->draw(0, 4, 0, stringLen);
|
||||
|
||||
continuity.elementOffset += numElements;
|
||||
}
|
||||
|
||||
void renderer::create_mesh_pipeline(Material& material) const {
|
||||
GFXShaderConstant materials_constant = {};
|
||||
materials_constant.type = GFXShaderConstant::Type::Integer;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "gfx.hpp"
|
||||
#include "gfx_commandbuffer.hpp"
|
||||
#include "imgui_utility.hpp"
|
||||
#include "screen.hpp"
|
||||
#include "console.hpp"
|
||||
#include "input.hpp"
|
||||
#include "scenecapture.hpp"
|
||||
|
@ -459,20 +458,6 @@ void editRigidbody(Rigidbody& rigidbody) {
|
|||
ImGui::DragInt("Mass", &rigidbody.mass);
|
||||
}
|
||||
|
||||
void editUI(UI& ui) {
|
||||
ImGui::DragInt("Width", &ui.width);
|
||||
ImGui::DragInt("Height", &ui.height);
|
||||
ImGui::InputText("Path", &ui.ui_path);
|
||||
|
||||
if(ImGui::Button("Reload")) {
|
||||
ui.screen = engine->load_screen(prism::app_domain / ui.ui_path);
|
||||
engine->get_renderer()->init_screen(ui.screen);
|
||||
ui.screen->extent.width = ui.width;
|
||||
ui.screen->extent.height = ui.height;
|
||||
ui.screen->calculate_sizes();
|
||||
}
|
||||
}
|
||||
|
||||
void editProbe(EnvironmentProbe& probe) {
|
||||
ImGui::Checkbox("Is Sized", &probe.is_sized);
|
||||
if(probe.is_sized)
|
||||
|
@ -608,11 +593,6 @@ void CommonEditor::drawPropertyEditor() {
|
|||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if(ImGui::Selectable("UI")) {
|
||||
scene->add<UI>(selected_object);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if(ImGui::Selectable("Environment Probe")) {
|
||||
scene->add<EnvironmentProbe>(selected_object);
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
@ -639,9 +619,6 @@ void CommonEditor::drawPropertyEditor() {
|
|||
if(componentHeader<Rigidbody>(*scene, selected_object, "Rigidbody"))
|
||||
editRigidbody(scene->get<Rigidbody>(selected_object));
|
||||
|
||||
if(componentHeader<UI>(*scene, selected_object, "UI"))
|
||||
editUI(scene->get<UI>(selected_object));
|
||||
|
||||
if(componentHeader<EnvironmentProbe>(*scene, selected_object, "Environment Probe"))
|
||||
editProbe(scene->get<EnvironmentProbe>(selected_object));
|
||||
}
|
||||
|
|
|
@ -2,13 +2,11 @@ set(SRC
|
|||
include/prismeditor.hpp
|
||||
include/materialeditor.hpp
|
||||
include/sceneeditor.hpp
|
||||
include/uieditor.hpp
|
||||
include/prefabeditor.hpp
|
||||
|
||||
src/prismeditor.cpp
|
||||
src/materialeditor.cpp
|
||||
src/sceneeditor.cpp
|
||||
src/uieditor.cpp
|
||||
src/prefabeditor.cpp)
|
||||
|
||||
add_platform_executable(
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "prismeditor.hpp"
|
||||
|
||||
#include "screen.hpp"
|
||||
|
||||
class UIEditor : public Editor {
|
||||
public:
|
||||
UIEditor();
|
||||
|
||||
ui::Screen* screen = nullptr;
|
||||
UIElement* current_element = nullptr;
|
||||
|
||||
bool has_menubar() const override;
|
||||
std::string get_title() const override;
|
||||
|
||||
Scene* get_scene() const override;
|
||||
|
||||
void setup_windows(ImGuiID dockspace) override;
|
||||
|
||||
void edit_metric(const char* label, UIElement::Metrics::Metric* metric);
|
||||
std::string save_metric(UIElement::Metrics::Metric metric);
|
||||
|
||||
void save(std::string path);
|
||||
|
||||
void draw(CommonEditor* editor) override;
|
||||
};
|
|
@ -11,11 +11,9 @@
|
|||
#include "json_conversions.hpp"
|
||||
#include "platform.hpp"
|
||||
#include "string_utils.hpp"
|
||||
#include "screen.hpp"
|
||||
#include "sceneeditor.hpp"
|
||||
#include "materialeditor.hpp"
|
||||
#include "prefabeditor.hpp"
|
||||
#include "uieditor.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
std::string get_filename(const std::string path) {
|
||||
|
@ -164,15 +162,6 @@ void PrismEditor::open_asset(const prism::path path) {
|
|||
|
||||
editor->scene = engine->get_scene();
|
||||
|
||||
editors.push_back(editor);
|
||||
} else if(path.extension() == ".json") {
|
||||
UIEditor* editor = new UIEditor();
|
||||
editor->path = path.string();
|
||||
setup_editor(editor);
|
||||
|
||||
editor->screen = engine->load_screen(path);
|
||||
editor->screen->calculate_sizes();
|
||||
|
||||
editors.push_back(editor);
|
||||
}
|
||||
}
|
||||
|
@ -233,14 +222,6 @@ void PrismEditor::drawUI() {
|
|||
editors.push_back(editor);
|
||||
}
|
||||
|
||||
if(ImGui::MenuItem("UI")) {
|
||||
UIEditor* editor = new UIEditor();
|
||||
editor->modified = true;
|
||||
setup_editor(editor);
|
||||
|
||||
editors.push_back(editor);
|
||||
}
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,218 +0,0 @@
|
|||
#include "uieditor.hpp"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <imgui.h>
|
||||
#include <imgui_stdlib.h>
|
||||
#include <imgui_internal.h>
|
||||
|
||||
#include "engine.hpp"
|
||||
#include "imgui_utility.hpp"
|
||||
|
||||
UIEditor::UIEditor() : Editor() {
|
||||
screen = new ui::Screen();
|
||||
screen->extent.width = 1280;
|
||||
screen->extent.height = 720;
|
||||
}
|
||||
|
||||
bool UIEditor::has_menubar() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string UIEditor::get_title() const {
|
||||
return path.empty() ? "New UI" : get_filename(path);
|
||||
}
|
||||
|
||||
Scene* UIEditor::get_scene() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UIEditor::setup_windows(ImGuiID dockspace) {
|
||||
ImGuiID dock_main_id = dockspace;
|
||||
|
||||
ImGuiID dock_id_left, dock_id_right;
|
||||
ImGui::DockBuilderSplitNode(dock_main_id, ImGuiDir_Left, 0.60f, &dock_id_left, &dock_id_right);
|
||||
|
||||
ImGui::DockBuilderDockWindow(get_window_name("Properties").c_str(), dock_id_right);
|
||||
|
||||
ImGui::DockBuilderSplitNode(dock_id_left, ImGuiDir_Left, 0.30f, &dock_id_left, &dock_id_right);
|
||||
ImGui::DockBuilderDockWindow(get_window_name("Outliner").c_str(), dock_id_left);
|
||||
ImGui::DockBuilderDockWindow(get_window_name("Preview").c_str(), dock_id_right);
|
||||
}
|
||||
|
||||
void UIEditor::edit_metric(const char* label, UIElement::Metrics::Metric* metric) {
|
||||
if(ImGui::DragInt(label, &metric->value, 1.0f, 0, 0, metric->type == MetricType::Absolute ? "%d" : "%d%%"))
|
||||
screen->calculate_sizes();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushID(label);
|
||||
|
||||
if(ImGui::ComboEnum("T", &metric->type))
|
||||
screen->calculate_sizes();
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
std::string UIEditor::save_metric(UIElement::Metrics::Metric metric) {
|
||||
return std::to_string(metric.value) + (metric.type == MetricType::Absolute ? "px" : "%");
|
||||
}
|
||||
|
||||
void UIEditor::save(std::string path) {
|
||||
nlohmann::json j;
|
||||
|
||||
for (auto& element : screen->elements) {
|
||||
nlohmann::json e;
|
||||
e["id"] = element.id;
|
||||
e["text"] = element.text;
|
||||
e["visible"] = element.visible;
|
||||
e["wrapText"] = element.wrap_text;
|
||||
|
||||
nlohmann::json m;
|
||||
m["x"] = save_metric(element.metrics.x);
|
||||
m["y"] = save_metric(element.metrics.y);
|
||||
m["width"] = save_metric(element.metrics.width);
|
||||
m["height"] = save_metric(element.metrics.height);
|
||||
|
||||
e["metrics"] = m;
|
||||
|
||||
if(element.text_location == UIElement::TextLocation::Center) {
|
||||
e["textLocation"] = "center";
|
||||
} else {
|
||||
e["textLocation"] = "topLeft";
|
||||
}
|
||||
|
||||
j["elements"].push_back(e);
|
||||
}
|
||||
|
||||
std::ofstream out(path);
|
||||
out << std::setw(4) << j;
|
||||
}
|
||||
|
||||
void UIEditor::draw(CommonEditor*) {
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
if (ImGui::BeginMenu("File")) {
|
||||
if(ImGui::MenuItem("Save", "CTRL+S")) {
|
||||
if (path.empty()) {
|
||||
platform::save_dialog([this](std::string path) {
|
||||
this->path = path;
|
||||
|
||||
save(path);
|
||||
});
|
||||
} else {
|
||||
save(path);
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Save as...", "CTRL+S")) {
|
||||
platform::save_dialog([this](std::string path) {
|
||||
this->path = path;
|
||||
|
||||
save(path);
|
||||
});
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(ImGui::MenuItem("Close"))
|
||||
wants_to_close = true;
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
if(begin("Outliner")) {
|
||||
if(ImGui::Button("Add Element")) {
|
||||
screen->elements.push_back(UIElement());
|
||||
current_element = &screen->elements.back();
|
||||
}
|
||||
|
||||
for(auto& element : screen->elements) {
|
||||
if(ImGui::Selectable(element.id.c_str()))
|
||||
current_element = &element;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if(begin("Properties")) {
|
||||
if(current_element != nullptr) {
|
||||
ImGui::InputText("ID", ¤t_element->id);
|
||||
|
||||
edit_metric("X", ¤t_element->metrics.x);
|
||||
edit_metric("Y", ¤t_element->metrics.y);
|
||||
edit_metric("Width", ¤t_element->metrics.width);
|
||||
edit_metric("Height", ¤t_element->metrics.height);
|
||||
|
||||
ImGui::InputText("Text", ¤t_element->text);
|
||||
|
||||
ImGui::ColorEdit4("Background color", current_element->background.color.v);
|
||||
|
||||
ImGui::Checkbox("Visible", ¤t_element->visible);
|
||||
ImGui::Checkbox("Wrap text", ¤t_element->wrap_text);
|
||||
|
||||
bool setCenter = current_element->text_location == UIElement::TextLocation::Center;
|
||||
ImGui::Checkbox("Center Text", &setCenter);
|
||||
|
||||
current_element->text_location = setCenter ? UIElement::TextLocation::Center : UIElement::TextLocation::TopLeft;
|
||||
|
||||
if(ImGui::Button("Delete")) {
|
||||
utility::erase(screen->elements, *current_element);
|
||||
}
|
||||
|
||||
if(ImGui::Button("Duplicate")) {
|
||||
UIElement element = *current_element;
|
||||
element.id += " (duplicate)";
|
||||
|
||||
screen->elements.push_back(element);
|
||||
current_element = &screen->elements.back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if(begin("Preview")) {
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
static int width = 1280, height = 720;
|
||||
static int scale = 3;
|
||||
|
||||
bool c = ImGui::InputInt("Width", &width);
|
||||
c |= ImGui::InputInt("Height", &height);
|
||||
c |= ImGui::InputInt("Scale", &scale);
|
||||
|
||||
if(c) {
|
||||
screen->extent.width = width;
|
||||
screen->extent.height = height;
|
||||
screen->calculate_sizes();
|
||||
}
|
||||
|
||||
const ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
|
||||
draw_list->AddRect(ImVec2(p.x, p.y), ImVec2(p.x + (width / scale), p.y + (height / scale)), IM_COL32_WHITE);
|
||||
|
||||
for(auto& element : screen->elements) {
|
||||
if(element.absolute_width > 0 && element.absolute_height > 0) {
|
||||
draw_list->AddRect(
|
||||
ImVec2(p.x + (element.absolute_x / scale), p.y + (element.absolute_y / scale)),
|
||||
ImVec2(p.x + ((element.absolute_x + element.absolute_width) / scale), p.y + ((element.absolute_y + element.absolute_height) / scale)),
|
||||
IM_COL32_WHITE
|
||||
);
|
||||
}
|
||||
|
||||
if(!element.text.empty()) {
|
||||
if(element.text_location == UIElement::TextLocation::Center) {
|
||||
auto textSize = ImGui::CalcTextSize(element.text.c_str());
|
||||
|
||||
draw_list->AddText(ImVec2(p.x + (element.absolute_x + (element.absolute_width / 2)) / scale - (textSize.x / 2), p.y + (element.absolute_y + (element.absolute_height / 2)) / scale - (textSize.y / 2)), IM_COL32_WHITE, element.text.c_str());
|
||||
} else {
|
||||
draw_list->AddText(ImVec2(p.x + (element.absolute_x / scale), p.y + (element.absolute_y / scale)), IM_COL32_WHITE, element.text.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
Reference in a new issue