ECS with entt
This commit is contained in:
77
editor/imgui.ini
Normal file
77
editor/imgui.ini
Normal file
@@ -0,0 +1,77 @@
|
||||
[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=166,153
|
||||
Collapsed=0
|
||||
|
||||
[Window][Dear ImGui Demo]
|
||||
Pos=899,10
|
||||
Size=358,368
|
||||
Collapsed=0
|
||||
|
||||
[Window][Dear ImGui Style Editor]
|
||||
Pos=136,23
|
||||
Size=353,682
|
||||
Collapsed=0
|
||||
|
||||
[Window][Example: Log]
|
||||
Pos=431,613
|
||||
Size=409,223
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][My First Tool]
|
||||
Pos=181,56
|
||||
Size=388,464
|
||||
Collapsed=0
|
||||
|
||||
[Window][DockSpace Demo]
|
||||
Size=1259,688
|
||||
Collapsed=0
|
||||
|
||||
[Window][Dear ImGui Debug Log]
|
||||
Pos=1349,371
|
||||
Size=644,567
|
||||
Collapsed=0
|
||||
|
||||
[Window][Example: Console]
|
||||
Pos=0,19
|
||||
Size=519,669
|
||||
Collapsed=0
|
||||
DockId=0x00000003,0
|
||||
|
||||
[Window][Example: Assets Browser]
|
||||
Pos=842,613
|
||||
Size=326,223
|
||||
Collapsed=0
|
||||
DockId=0x00000009,0
|
||||
|
||||
[Window][Example: Property editor]
|
||||
Pos=0,19
|
||||
Size=429,817
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
[Window][Example: Property editor/##tree_37EC733C]
|
||||
IsChild=1
|
||||
Size=300,782
|
||||
|
||||
[Table][0xB6880529,2]
|
||||
RefScale=13
|
||||
Column 0 Sort=0v
|
||||
|
||||
[Table][0x2048C668,2]
|
||||
RefScale=13
|
||||
Column 0 Width=4
|
||||
Column 1 Weight=2.0000
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0xC0DFADC4 Pos=0,19 Size=1259,669 Split=X Selected=0x5E5F7166
|
||||
DockNode ID=0x00000005 Parent=0xC0DFADC4 SizeRef=429,817 Selected=0x256ED220
|
||||
DockNode ID=0x0000000A Parent=0xC0DFADC4 SizeRef=1143,817 Split=X
|
||||
DockNode ID=0x00000003 Parent=0x0000000A SizeRef=519,669 Selected=0x1BCA3180
|
||||
DockNode ID=0x00000004 Parent=0x0000000A SizeRef=751,669 Split=Y
|
||||
DockNode ID=0x00000007 Parent=0x00000004 SizeRef=860,592 CentralNode=1
|
||||
DockNode ID=0x00000008 Parent=0x00000004 SizeRef=860,223 Split=X Selected=0x38CCB771
|
||||
DockNode ID=0x00000006 Parent=0x00000008 SizeRef=649,223 Selected=0x38CCB771
|
||||
DockNode ID=0x00000009 Parent=0x00000008 SizeRef=517,223 Selected=0xD2C213DD
|
||||
|
||||
@@ -1,209 +1,292 @@
|
||||
#ifndef EDITOR_HPP
|
||||
#define EDITOR_HPP
|
||||
|
||||
#include "open_engine/input/input_system.hpp"
|
||||
#include <view_layer.hpp>
|
||||
#include "open_engine/ref_scope.hpp"
|
||||
#include "panels/scene_hierarchy.hpp"
|
||||
#include <open_engine.hpp>
|
||||
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/matrix.hpp>
|
||||
#include <glm/fwd.hpp>
|
||||
#include <imgui.h>
|
||||
#include <entt/entt.hpp>
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <cstdint>
|
||||
#include <imgui.h>
|
||||
|
||||
class EditorLayer : public OpenEngine::Layer
|
||||
{
|
||||
public:
|
||||
EditorLayer(OpenEngine::Ref<ViewLayer>& view_layer)
|
||||
: OpenEngine::Layer("editor_layer"),
|
||||
view(view_layer)
|
||||
namespace OpenEngine {
|
||||
|
||||
class CameraController : public NativeScriptableEntity
|
||||
{
|
||||
public:
|
||||
void OnCreate()
|
||||
{
|
||||
};
|
||||
|
||||
void OnUpdate()
|
||||
{
|
||||
auto delta = Time::DeltaTime();
|
||||
|
||||
auto& transform = GetComponent<TransformComponent>();
|
||||
|
||||
if (Input::IsKeyPressed(KeyCode::Up))
|
||||
transform.transform[3][1] += 5.0 * delta;
|
||||
if (Input::IsKeyPressed(KeyCode::Down))
|
||||
transform.transform[3][1] -= 5.0 * delta;
|
||||
if (Input::IsKeyPressed(KeyCode::Right))
|
||||
transform.transform[3][0] += 5.0 * delta;
|
||||
if (Input::IsKeyPressed(KeyCode::Left))
|
||||
transform.transform[3][0] -= 5.0 * delta;
|
||||
};
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
class EditorLayer : public Layer
|
||||
{
|
||||
public:
|
||||
EditorLayer()
|
||||
: Layer("editor_layer")/*,
|
||||
camera((float)Application::Get().GetWindow().GetWidth() /
|
||||
Application::Get().GetWindow().GetHeight(), 1.0f)
|
||||
*/
|
||||
{
|
||||
}
|
||||
~EditorLayer() {};
|
||||
~EditorLayer() {};
|
||||
|
||||
void OnAttach() override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
}
|
||||
entt::registry registry;
|
||||
|
||||
void OnDetach() override
|
||||
{
|
||||
}
|
||||
|
||||
void OnUpdate() override
|
||||
{
|
||||
|
||||
OpenEngine::Renderer2D::ResetStats();
|
||||
void OnAttach() override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
view->GetCamera().OnUpdate();
|
||||
FramebufferSpecification specs;
|
||||
specs.width = 1280;
|
||||
specs.height = 720;
|
||||
|
||||
framebuffer = FrameBuffer::Create(specs);
|
||||
|
||||
scene = CreateRef<Scene>();
|
||||
|
||||
sq_entity = scene->CreateEntity("square");
|
||||
|
||||
sq_entity.AddComponents<TransformComponent>();
|
||||
sq_entity.AddComponents<SpriteRendererComponent>(glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
||||
camera_bis = scene->CreateEntity("Main camera");
|
||||
camera_bis.AddComponents<TransformComponent>();
|
||||
camera_bis.AddComponents<CameraComponent>();
|
||||
camera_bis.AddComponents<NativeScriptComponent>().Bind<CameraController>();
|
||||
|
||||
scene_hierarchy.SetContext(scene);
|
||||
}
|
||||
|
||||
OpenEngine::Renderer2D::EndScene();
|
||||
}
|
||||
|
||||
void OnEvent(OpenEngine::Event& event) override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
void OnDetach() override
|
||||
{
|
||||
OE_PROFILE_SCOPE("Camera OnEvent");
|
||||
view->GetCamera().OnEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
float remap(float value, float minInput, float maxInput, float minOutput, float maxOutput) {
|
||||
// 1. Normalize the input to a 0.0 - 1.0 range
|
||||
float t = (value - minInput) / (maxInput - minInput);
|
||||
|
||||
// 2. Use glm::mix to interpolate between the output range
|
||||
return glm::mix(minOutput, maxOutput, t);
|
||||
}
|
||||
|
||||
glm::vec3 ScreenToWorld(
|
||||
float screenX,
|
||||
float screenY,
|
||||
float screenZ, // depth value (0.0 = near plane, 1.0 = far plane)
|
||||
const glm::mat4& view,
|
||||
const glm::mat4& projection,
|
||||
int viewportWidth,
|
||||
int viewportHeight)
|
||||
{
|
||||
// 1. Convert screen coordinates to normalized device coordinates (NDC)
|
||||
// Screen space: origin at top-left, Y points down
|
||||
// NDC space: origin at center, range [-1, 1] for x and y
|
||||
|
||||
float x = (2.0f * screenX) / viewportWidth - 1.0f;
|
||||
float y = 1.0f - (2.0f * screenY) / viewportHeight; // Flip Y
|
||||
float z = 2.0f * screenZ - 1.0f; // [0,1] -> [-1,1]
|
||||
|
||||
glm::vec4 clipCoords(x, y, z, 1.0f);
|
||||
|
||||
// 2. Transform from clip space to view space
|
||||
glm::mat4 invProjection = glm::inverse(projection);
|
||||
glm::vec4 viewCoords = invProjection * clipCoords;
|
||||
|
||||
// 3. Transform from view space to world space
|
||||
glm::mat4 invView = glm::inverse(view);
|
||||
glm::vec4 worldCoords = invView * viewCoords;
|
||||
|
||||
// 4. Perspective divide
|
||||
if (worldCoords.w != 0.0f) {
|
||||
worldCoords /= worldCoords.w;
|
||||
}
|
||||
|
||||
return glm::vec3(worldCoords);
|
||||
}
|
||||
|
||||
void OnImGuiRender() override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
OpenEngine::Ref<OpenEngine::FrameBuffer> framebuffer = view->GetFramebuffer();
|
||||
|
||||
ImGui::DockSpaceOverViewport();
|
||||
|
||||
ImGui::Begin("Square settings");
|
||||
|
||||
//ImGui::SliderFloat("Angle", &angle, -360, 360);
|
||||
//ImGui::ColorPicker4("Rectangle color", &rectangle_color[0]);
|
||||
|
||||
for (auto& result : profiling_results)
|
||||
void OnUpdate() override
|
||||
{
|
||||
char label[50];
|
||||
strcpy(label, "%.3fms ");
|
||||
strcat(label, result.name);
|
||||
ImGui::Text(label, result.duration);
|
||||
FramebufferSpecification spec = framebuffer->GetSpecification();
|
||||
if (viewport_size.x > 0.0f && viewport_size.y > 0.0f &&
|
||||
(spec.width != viewport_size.x || spec.height != viewport_size.y))
|
||||
{
|
||||
framebuffer->Resize((uint32_t)viewport_size.x, (uint32_t)viewport_size.y);
|
||||
//camera.OnResize(viewport_size.x, viewport_size.y);
|
||||
}
|
||||
|
||||
{
|
||||
OE_PROFILE_SCOPE("Setting up Rendering");
|
||||
//camera.OnUpdate();
|
||||
framebuffer->Bind();
|
||||
|
||||
scene->OnViewportResize((uint32_t)viewport_size.x, (uint32_t)viewport_size.y);
|
||||
}
|
||||
|
||||
Renderer2D::ResetStats();
|
||||
RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f});
|
||||
RenderCommand::Clear();
|
||||
|
||||
//Renderer2D::BeginScene(camera.GetCamera());
|
||||
|
||||
/*
|
||||
for (float y = -5.0f; y < 5.0f; y += 0.5f) {
|
||||
for (float x = -5.0f; x < 5.0f; x += 0.5f) {
|
||||
|
||||
glm::vec4 gradient_color = {(x + 5.0f) / 10.0f, 0.3f, (y + 5.0f) / 10.0f, 1.0f};
|
||||
Renderer2D::DrawQuad({{x, y, 0.0f}, glm::vec3(0.45f, 0.45f, 0.0f)}, gradient_color);
|
||||
}
|
||||
}
|
||||
|
||||
Transform tr5 = {
|
||||
glm::vec3(world_pos_cursor.x, world_pos_cursor.y, 0.9f),
|
||||
glm::vec3(0.1f, 0.1f, 0.0f), 0.0f};
|
||||
|
||||
Renderer2D::DrawQuad(tr5, {1, 1, 1, 1});
|
||||
*/
|
||||
|
||||
scene->OnUpdate();
|
||||
|
||||
//Renderer2D::EndScene();
|
||||
|
||||
framebuffer->Unbind();
|
||||
}
|
||||
|
||||
profiling_results.clear();
|
||||
void OnEvent(Event& event) override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
//camera.OnEvent(event);
|
||||
}
|
||||
|
||||
float remap(float value, float minInput, float maxInput, float minOutput, float maxOutput) {
|
||||
// 1. Normalize the input to a 0.0 - 1.0 range
|
||||
float t = (value - minInput) / (maxInput - minInput);
|
||||
|
||||
// 2. Use glm::mix to interpolate between the output range
|
||||
return glm::mix(minOutput, maxOutput, t);
|
||||
}
|
||||
|
||||
glm::vec3 ScreenToWorld(
|
||||
float screenX,
|
||||
float screenY,
|
||||
float screenZ, // depth value (0.0 = near plane, 1.0 = far plane)
|
||||
const glm::mat4& view,
|
||||
const glm::mat4& projection,
|
||||
int viewportWidth,
|
||||
int viewportHeight)
|
||||
{
|
||||
// 1. Convert screen coordinates to normalized device coordinates (NDC)
|
||||
// Screen space: origin at top-left, Y points down
|
||||
// NDC space: origin at center, range [-1, 1] for x and y
|
||||
|
||||
float x = (2.0f * screenX) / viewportWidth - 1.0f;
|
||||
float y = 1.0f - (2.0f * screenY) / viewportHeight; // Flip Y
|
||||
float z = 2.0f * screenZ - 1.0f; // [0,1] -> [-1,1]
|
||||
|
||||
glm::vec4 clipCoords(x, y, z, 1.0f);
|
||||
|
||||
// 2. Transform from clip space to view space
|
||||
glm::mat4 invProjection = glm::inverse(projection);
|
||||
glm::vec4 viewCoords = invProjection * clipCoords;
|
||||
|
||||
// 3. Transform from view space to world space
|
||||
glm::mat4 invView = glm::inverse(view);
|
||||
glm::vec4 worldCoords = invView * viewCoords;
|
||||
|
||||
// 4. Perspective divide
|
||||
if (worldCoords.w != 0.0f) {
|
||||
worldCoords /= worldCoords.w;
|
||||
}
|
||||
|
||||
return glm::vec3(worldCoords);
|
||||
};
|
||||
|
||||
void DrawViewport()
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 0, 0 });
|
||||
|
||||
ImGui::Begin("Viewport");
|
||||
bool focused = ImGui::IsWindowFocused();
|
||||
bool hovered = ImGui::IsWindowHovered();
|
||||
Application::Get().GetImGuiLayer()->SetBlockEvents(!focused || !hovered);
|
||||
|
||||
ImVec2 viewport_panel_size = ImGui::GetContentRegionAvail();
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 0, 0 });
|
||||
ImGui::Begin("Viewport");
|
||||
ImVec2 viewport_panel_size = ImGui::GetContentRegionAvail();
|
||||
if (viewport_size != *((glm::vec2*)&viewport_panel_size)) {
|
||||
framebuffer->Resize(viewport_panel_size.x, viewport_panel_size.y);
|
||||
viewport_size = { viewport_panel_size.x, viewport_panel_size.y };
|
||||
|
||||
view->GetCamera().OnResize(viewport_panel_size.x, viewport_panel_size.y);
|
||||
}
|
||||
uint32_t texture_id = framebuffer->GetColorAttachmentRendererID();
|
||||
ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None;
|
||||
if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
|
||||
ImVec2 imgui_cursor_position = ImGui::GetCursorScreenPos();
|
||||
auto pair_position = Input::GetMousePosition();
|
||||
glm::vec2 mouse_position = { pair_position.first, pair_position.second };
|
||||
|
||||
int max_x = viewport_size.x + imgui_cursor_position.x;
|
||||
int max_y = viewport_size.y + imgui_cursor_position.y;
|
||||
|
||||
if (focused || hovered) {
|
||||
float x = mouse_position.x - imgui_cursor_position.x;
|
||||
float y = mouse_position.y - imgui_cursor_position.y;
|
||||
|
||||
/*
|
||||
auto& cam = camera.GetCamera();
|
||||
world_pos_cursor = ScreenToWorld(x, y, 0.0f,
|
||||
cam.GetViewMatrix(),
|
||||
cam.GetProjectionMatrix(),
|
||||
viewport_size.x,
|
||||
viewport_size.y);
|
||||
*/
|
||||
}
|
||||
|
||||
uint32_t texture_id = framebuffer->GetColorAttachmentRendererID();
|
||||
ImGui::Image((void*)(uint64_t)texture_id, ImVec2{ viewport_size.x, viewport_size.y }, ImVec2{ 0, 1 }, ImVec2{ 1, 0 });
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
};
|
||||
|
||||
void DrawStats()
|
||||
{
|
||||
if (ImGui::BeginTabItem("Avocado"))
|
||||
{
|
||||
ImVec2 imgui_cursor_position = ImGui::GetCursorScreenPos();
|
||||
auto stats = Renderer2D::GetStats();
|
||||
static float time = 0;
|
||||
|
||||
auto pair_position = OpenEngine::Input::GetMousePosition();
|
||||
glm::vec2 mouse_position = { pair_position.first, pair_position.second };
|
||||
time += Time::DeltaTime();
|
||||
|
||||
int max_x = viewport_size.x + imgui_cursor_position.x;
|
||||
int max_y = viewport_size.y + imgui_cursor_position.y;
|
||||
|
||||
if ((mouse_position.x <= max_x && mouse_position.x >= imgui_cursor_position.x)
|
||||
&& (mouse_position.y <= max_y && mouse_position.y >= imgui_cursor_position.y)) {
|
||||
|
||||
float x = mouse_position.x - imgui_cursor_position.x;
|
||||
float y = mouse_position.y - imgui_cursor_position.y;
|
||||
|
||||
auto& camera = view->GetCamera().GetCamera();
|
||||
auto world_coords = ScreenToWorld(x, y, 0.0f,
|
||||
camera.GetViewMatrix(),
|
||||
camera.GetProjectionMatrix(),
|
||||
viewport_size.x,
|
||||
viewport_size.y);
|
||||
view->SetCursorPos({ world_coords.x, world_coords.y });
|
||||
}
|
||||
ImGui::Image((void*)texture_id, ImVec2{ viewport_size.x, viewport_size.y }, ImVec2{ 0, 1 }, ImVec2{ 1, 0 });
|
||||
ImGui::EndTabItem();
|
||||
if (time >= 1) {
|
||||
time = 0;
|
||||
}
|
||||
if (ImGui::BeginTabItem("Broccoli"))
|
||||
{
|
||||
ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah");
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("Cucumber"))
|
||||
{
|
||||
ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah");
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
auto stats = OpenEngine::Renderer2D::GetStats();
|
||||
static float time = 0;
|
||||
ImGui::Begin("Statistics");
|
||||
ImGui::Text("FPS: %0.0f", 1 / Time::DeltaTime());
|
||||
ImGui::Text("Renderer2D:");
|
||||
ImGui::Text("\t\tDraw calls: %d", stats.draw_calls);
|
||||
ImGui::Text("\t\tQuad count: %d", stats.quad_count);
|
||||
ImGui::Text("\t\tVertices count: %d", stats.GetToralVertexCount());
|
||||
ImGui::Text("\t\tIndices count: %d", stats.GetToralIndexCount());
|
||||
|
||||
time += OpenEngine::Time::DeltaTime();
|
||||
/*
|
||||
for (auto& result : profiling_results)
|
||||
{
|
||||
char label[50];
|
||||
strcpy(label, "%.3fms ");
|
||||
strcat(label, result.name);
|
||||
ImGui::Text(label, result.duration);
|
||||
}
|
||||
|
||||
if (time >= 1) {
|
||||
time = 0;
|
||||
}
|
||||
profiling_results.clear();
|
||||
*/
|
||||
|
||||
ImGui::Begin("Statistics");
|
||||
ImGui::Text("FPS: %0.0f", 1 / OpenEngine::Time::DeltaTime());
|
||||
ImGui::Text("Renderer2D:");
|
||||
ImGui::Text("\t\tDraw calls: %d", stats.draw_calls);
|
||||
ImGui::Text("\t\tQuad count: %d", stats.quad_count);
|
||||
ImGui::Text("\t\tVertices count: %d", stats.GetToralVertexCount());
|
||||
ImGui::Text("\t\tIndices count: %d", stats.GetToralIndexCount());
|
||||
ImGui::ShowDemoWindow();
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::End();
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<OpenEngine::Time::ProfilingResult> profiling_results;
|
||||
void OnImGuiRender() override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
glm::vec2 viewport_size = { 0.0f, 0.0f };
|
||||
ImGui::DockSpaceOverViewport();
|
||||
|
||||
OpenEngine::Ref<ViewLayer> view;
|
||||
};
|
||||
DrawStats();
|
||||
scene_hierarchy.OnImGuiRender();
|
||||
DrawViewport();
|
||||
|
||||
ImGui::ShowDemoWindow();
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<Time::ProfilingResult> profiling_results;
|
||||
|
||||
glm::vec2 world_pos_cursor = { 0.0f, 0.0f };
|
||||
|
||||
glm::vec2 viewport_size = { 0.0f, 0.0f };
|
||||
Ref<OpenEngine::FrameBuffer> framebuffer;
|
||||
SceneHierarchy scene_hierarchy;
|
||||
//OrthographicCameraController camera;
|
||||
|
||||
Entity camera_bis;
|
||||
|
||||
Ref<Scene> scene;
|
||||
Entity sq_entity;
|
||||
};
|
||||
}
|
||||
|
||||
class EditorApp : public OpenEngine::Application
|
||||
{
|
||||
|
||||
@@ -47,7 +47,6 @@ class LevelEditor : public ViewLayer
|
||||
}
|
||||
|
||||
auto& cursor = GetCursorPos();
|
||||
OE_TRACE("world coordinates: {} {}", cursor.x, cursor.y);
|
||||
OpenEngine::Transform tr5 = {glm::vec3(cursor.x, cursor.y, 0.9f), glm::vec3(0.1f, 0.1f, 0.0f), 0.0f};
|
||||
OpenEngine::Renderer2D::DrawQuad(tr5, {1, 1, 1, 1});
|
||||
|
||||
@@ -58,14 +57,8 @@ class LevelEditor : public ViewLayer
|
||||
|
||||
void OnEvent(OpenEngine::Event& event) override
|
||||
{
|
||||
auto& cursor = GetCursorPos();
|
||||
OE_TRACE("world coordinates: {} {}", cursor.x, cursor.y);
|
||||
OpenEngine::Transform tr5 = {glm::vec3(cursor.x, cursor.y, 0.9f), glm::vec3(1.0f, 1.0f, 0.0f), 0.0f};
|
||||
OpenEngine::Renderer2D::DrawQuad(tr5, {1, 1, 1, 1});
|
||||
|
||||
OpenEngine::Renderer2D::EndScene();
|
||||
|
||||
GetFramebuffer()->Unbind();
|
||||
OE_PROFILE_FUNCTION();
|
||||
GetCamera().OnEvent(event);
|
||||
};
|
||||
|
||||
void OnDetach() override {};
|
||||
|
||||
40
editor/include/panels/scene_hierarchy.hpp
Normal file
40
editor/include/panels/scene_hierarchy.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef SCENE_HIERARCHY_HPP
|
||||
#define SCENE_HIERARCHY_HPP
|
||||
|
||||
#include "imgui.h"
|
||||
#include <open_engine.hpp>
|
||||
|
||||
namespace OpenEngine {
|
||||
class SceneHierarchy
|
||||
{
|
||||
public:
|
||||
SceneHierarchy() = default;
|
||||
SceneHierarchy(const Ref<Scene>& scene);
|
||||
|
||||
void SetContext(const Ref<Scene>& scene);
|
||||
|
||||
void OnImGuiRender();
|
||||
|
||||
private:
|
||||
void DrawEntityNode(Entity& entity);
|
||||
void DrawComponents(Entity& entity);
|
||||
|
||||
template <typename T>
|
||||
void DrawComponentDrawer(Entity& entity, const char* header)
|
||||
{
|
||||
if (entity.HasComponent<T>())
|
||||
if (ImGui::TreeNodeEx((void*)typeid(T).hash_code(), ImGuiTreeNodeFlags_DefaultOpen, "%s", header)) {
|
||||
entity.GetComponents<T>().OnImGuiRender(entity);
|
||||
ImGui::TreePop();
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Ref<Scene> scene;
|
||||
Entity selected_context, renamed_entity;
|
||||
double last_selected_time = 10.0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SCENE_HIERARCHY_HPP
|
||||
@@ -9,18 +9,14 @@
|
||||
#include <overlay.hpp>
|
||||
#include <modding.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
EditorApp::EditorApp()
|
||||
: Application("OpenEngine Editor")
|
||||
{
|
||||
OpenEngine::Ref<OpenEngine::Layer> modding_layer = std::make_shared<Modding>();
|
||||
OpenEngine::Ref<ViewLayer> view = OpenEngine::CreateRef<LevelEditor>();
|
||||
OpenEngine::Ref<OpenEngine::Layer> initial_layer = std::make_shared<EditorLayer>(view);
|
||||
OpenEngine::Ref<OpenEngine::Layer> control_layer = std::make_shared<ControlLayer>(initial_layer);
|
||||
OpenEngine::Ref<OpenEngine::Layer> modding_layer = OpenEngine::CreateRef<Modding>();
|
||||
OpenEngine::Ref<OpenEngine::Layer> editor_layer = OpenEngine::CreateRef<OpenEngine::EditorLayer>();
|
||||
OpenEngine::Ref<OpenEngine::Layer> control_layer = OpenEngine::CreateRef<ControlLayer>(editor_layer);
|
||||
|
||||
QueueLayerPush(view);
|
||||
QueueLayerPush(initial_layer);
|
||||
QueueLayerPush(editor_layer);
|
||||
QueueLayerPush(control_layer);
|
||||
QueueLayerPush(modding_layer);
|
||||
}
|
||||
|
||||
150
editor/src/panels/scene_hierarchy.cpp
Normal file
150
editor/src/panels/scene_hierarchy.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#include "open_engine/scene/components.hpp"
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <panels/scene_hierarchy.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
namespace OpenEngine {
|
||||
SceneHierarchy::SceneHierarchy(const Ref<Scene>& scene)
|
||||
: scene(scene)
|
||||
{
|
||||
}
|
||||
|
||||
void SceneHierarchy::SetContext(const Ref<Scene>& context)
|
||||
{
|
||||
scene = context;
|
||||
}
|
||||
|
||||
void SceneHierarchy::OnImGuiRender()
|
||||
{
|
||||
ImGui::Begin("Scene");
|
||||
|
||||
for (auto entity_entt : scene->GetRegistry().view<TagComponent>()) {
|
||||
Entity entity{ entity_entt, scene.get() };
|
||||
|
||||
DrawEntityNode(entity);
|
||||
}
|
||||
|
||||
if ((ImGui::IsMouseDown(0) && ImGui::IsWindowHovered())
|
||||
|| (ImGui::IsKeyDown(ImGuiKey_Escape) && ImGui::IsWindowHovered()))
|
||||
{
|
||||
selected_context = {};
|
||||
renamed_entity = {};
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopupContextWindow(0, ImGuiPopupFlags_MouseButtonRight | ImGuiPopupFlags_NoOpenOverItems))
|
||||
{
|
||||
if (ImGui::MenuItem("Create Empty Entity"))
|
||||
{
|
||||
scene->CreateEntity("Empty entity");
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
ImGui::Begin("Properties");
|
||||
|
||||
if (selected_context) {
|
||||
DrawComponents(selected_context);
|
||||
|
||||
if (ImGui::BeginPopupContextWindow(0, ImGuiPopupFlags_MouseButtonRight | ImGuiPopupFlags_NoOpenOverItems))
|
||||
{
|
||||
if (ImGui::MenuItem("Add transform"))
|
||||
{
|
||||
selected_context.AddComponents<TransformComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Add Sprite"))
|
||||
{
|
||||
selected_context.AddComponents<SpriteRendererComponent>();
|
||||
}
|
||||
if (ImGui::MenuItem("Add camera"))
|
||||
{
|
||||
selected_context.AddComponents<CameraComponent>();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void SceneHierarchy::DrawEntityNode(Entity& entity)
|
||||
{
|
||||
auto& tag = entity.GetComponents<TagComponent>().tag;
|
||||
|
||||
if (renamed_entity == entity && selected_context == entity) {
|
||||
char buffer[255];
|
||||
std::memset(buffer, 0, sizeof(buffer));
|
||||
std::strncpy(buffer, tag.c_str(), sizeof(buffer));
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2));
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
|
||||
if (ImGui::InputText("##tagEditor", buffer, sizeof(buffer), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)
|
||||
|| (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0))) {
|
||||
tag = buffer;
|
||||
renamed_entity = {};
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Escape))
|
||||
renamed_entity = {};
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
} else {
|
||||
ImGuiTreeNodeFlags flags = ((selected_context == entity) ? ImGuiTreeNodeFlags_Selected : 0) | ImGuiTreeNodeFlags_OpenOnArrow;
|
||||
flags |= ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||
|
||||
bool opened = ImGui::TreeNodeEx((void*)(uint64_t)(uint32_t)entity, flags, "%s", tag.c_str());
|
||||
|
||||
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
// FocusViewportOnEntity(entity); // future implementation
|
||||
renamed_entity = {};
|
||||
} else if (ImGui::IsItemClicked()) {
|
||||
|
||||
double current_time = ImGui::GetTime();
|
||||
double double_click_time = ImGui::GetIO().MouseDoubleClickTime; // Usually ~0.3s
|
||||
|
||||
if (selected_context == entity) {
|
||||
renamed_entity = entity;
|
||||
if (current_time - last_selected_time > double_click_time)
|
||||
{
|
||||
renamed_entity = entity;
|
||||
}
|
||||
} else {
|
||||
// First time selecting
|
||||
selected_context = entity;
|
||||
last_selected_time = current_time;
|
||||
}
|
||||
}
|
||||
|
||||
if (opened)
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneHierarchy::DrawComponents(Entity& entity)
|
||||
{
|
||||
if (entity.HasComponent<TagComponent>())
|
||||
entity.GetComponents<TagComponent>().OnImGuiRender(entity);
|
||||
|
||||
DrawComponentDrawer<TransformComponent>(entity, "Transform");
|
||||
DrawComponentDrawer<SpriteRendererComponent>(entity, "Sprite");
|
||||
DrawComponentDrawer<CameraComponent>(entity, "Camera");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (ImGui::BeginPopupContextWindow(0, ImGuiPopupFlags_MouseButtonRight | ImGuiPopupFlags_NoOpenOverItems))
|
||||
{
|
||||
if (ImGui::MenuItem("Create Empty Entity"))
|
||||
{
|
||||
// m_Context->CreateEntity("Empty Entity");
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
*/
|
||||
59
imgui.ini
Normal file
59
imgui.ini
Normal file
@@ -0,0 +1,59 @@
|
||||
[Window][WindowOverViewport_11111111]
|
||||
Pos=0,0
|
||||
Size=1272,1386
|
||||
Collapsed=0
|
||||
|
||||
[Window][Statistics]
|
||||
Pos=0,0
|
||||
Size=404,149
|
||||
Collapsed=0
|
||||
DockId=0x00000001,0
|
||||
|
||||
[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Square settings]
|
||||
Pos=1037,307
|
||||
Size=235,1079
|
||||
Collapsed=0
|
||||
DockId=0x00000008,0
|
||||
|
||||
[Window][Viewport]
|
||||
Pos=406,0
|
||||
Size=629,1386
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Dear ImGui Demo]
|
||||
Pos=1037,0
|
||||
Size=235,1386
|
||||
Collapsed=0
|
||||
DockId=0x00000007,0
|
||||
|
||||
[Window][Scene]
|
||||
Pos=0,151
|
||||
Size=404,264
|
||||
Collapsed=0
|
||||
DockId=0x00000009,0
|
||||
|
||||
[Window][Properties]
|
||||
Pos=0,417
|
||||
Size=404,969
|
||||
Collapsed=0
|
||||
DockId=0x0000000A,0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,0 Size=1272,1386 Split=X
|
||||
DockNode ID=0x00000003 Parent=0x08BD597D SizeRef=1035,1386 Split=X
|
||||
DockNode ID=0x00000005 Parent=0x00000003 SizeRef=404,1386 Split=Y Selected=0x553E127E
|
||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=274,149 Selected=0x553E127E
|
||||
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=274,1235 Split=Y Selected=0xE601B12F
|
||||
DockNode ID=0x00000009 Parent=0x00000002 SizeRef=498,264 Selected=0xE601B12F
|
||||
DockNode ID=0x0000000A Parent=0x00000002 SizeRef=498,969 Selected=0x8C72BEA8
|
||||
DockNode ID=0x00000006 Parent=0x00000003 SizeRef=629,1386 CentralNode=1 Selected=0xC450F867
|
||||
DockNode ID=0x00000004 Parent=0x08BD597D SizeRef=235,1386 Split=Y Selected=0x5E5F7166
|
||||
DockNode ID=0x00000007 Parent=0x00000004 SizeRef=235,305 Selected=0x5E5F7166
|
||||
DockNode ID=0x00000008 Parent=0x00000004 SizeRef=235,1079 Selected=0xA5FF3A7A
|
||||
|
||||
24
licenses/entt.md
Normal file
24
licenses/entt.md
Normal file
@@ -0,0 +1,24 @@
|
||||
This software uses the EnTT library.
|
||||
The EnTT library is used under the MIT License, see bellow.
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-2026 Michele Caini, author of EnTT
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copy of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copy or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
20
licenses/fmt.md
Normal file
20
licenses/fmt.md
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -2,8 +2,10 @@
|
||||
#define OPEN_ENGINE_HPP
|
||||
|
||||
#include "open_engine/orthographic_camera_controller.hpp"
|
||||
#include "open_engine/scene/native_scriptable_entity.hpp"
|
||||
#include "open_engine/imgui/imgui_layer.hpp"
|
||||
#include "open_engine/events/key_event.hpp"
|
||||
#include "open_engine/scene/components.hpp"
|
||||
#include "open_engine/application.hpp"
|
||||
#include "open_engine/ref_scope.hpp"
|
||||
#include "open_engine/logging.hpp"
|
||||
@@ -21,7 +23,9 @@
|
||||
#include "open_engine/renderer/renderer2d.hpp"
|
||||
#include "open_engine/renderer/renderer.hpp"
|
||||
#include "open_engine/renderer/texture.hpp"
|
||||
#include "open_engine/scene/components.hpp"
|
||||
#include "open_engine/renderer/buffer.hpp"
|
||||
#include "open_engine/renderer/shader.hpp"
|
||||
|
||||
#include "open_engine/scene/entity.hpp"
|
||||
#include "open_engine/scene/scene.hpp"
|
||||
#endif // OPEN_ENGINE_HPP
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace OpenEngine {
|
||||
void QueueLayerPop(Ref<Layer> layer);
|
||||
void QueueOverlayPush(Ref<Layer> layer);
|
||||
void QueueOverlayPop(Ref<Layer> layer);
|
||||
ImGuiLayer* GetImGuiLayer() { return imgui_layer.get(); };
|
||||
|
||||
inline static Application& Get() { return *instance; };
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#define BIT(x) (1 << x)
|
||||
|
||||
#define BIND_EVENT_FN(function) std::bind(&function, this, std::placeholders::_1)
|
||||
//#define BIND_EVENT_FN(function) std::bind(&function, this, std::placeholders::_1)
|
||||
#define BIND_EVENT_FN(fn) [this](auto&&...args) -> decltype(auto) { return this->fn(std::forward<decltype(args)>(args)...); }
|
||||
|
||||
#endif // CORE_HPP
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef IMGUI_LAYER_HPP
|
||||
#define IMGUI_LAYER_HPP
|
||||
|
||||
#include "open_engine/events/key_event.hpp"
|
||||
#include "open_engine/events/event.hpp"
|
||||
#include "open_engine/layer.hpp"
|
||||
|
||||
@@ -15,11 +16,15 @@ namespace OpenEngine {
|
||||
virtual void OnDetach() override;
|
||||
virtual void OnImGuiRender() override;
|
||||
virtual void OnEvent(Event& event) override;
|
||||
bool CloseWindow(OpenEngine::KeyPressedEvent& event);
|
||||
|
||||
void SetBlockEvents(bool block) { block_events = block; };
|
||||
|
||||
void Begin();
|
||||
void End();
|
||||
|
||||
private:
|
||||
bool block_events = false;
|
||||
float previous_frame_time = 0.0f;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef CAMERA_HPP
|
||||
#define CAMERA_HPP
|
||||
#ifndef ORTHOGRAPHIC_CAMERA_HPP
|
||||
#define ORTHOGRAPHIC_CAMERA_HPP
|
||||
|
||||
#include <glm/fwd.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
@@ -33,4 +33,4 @@ namespace OpenEngine {
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CAMERA_HPP
|
||||
#endif // ORTHOGRAPHIC_CAMERA_HPP
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <array>
|
||||
|
||||
|
||||
26
open_engine/include/open_engine/renderer/camera.hpp
Normal file
26
open_engine/include/open_engine/renderer/camera.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef CAMERA_HPP
|
||||
#define CAMERA_HPP
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace OpenEngine {
|
||||
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
Camera() = default;
|
||||
~Camera() = default;
|
||||
Camera(const glm::mat4& projection)
|
||||
: projection(projection)
|
||||
{
|
||||
};
|
||||
|
||||
const glm::mat4& GetProjection() const { return projection; };
|
||||
|
||||
protected:
|
||||
glm::mat4 projection = glm::mat4(1.0f);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CAMERA_HPP
|
||||
@@ -1,9 +1,10 @@
|
||||
#ifndef RENDERER2D_HPP
|
||||
#define RENDERER2D_HPP
|
||||
|
||||
#include "open_engine/orthographic_camera.hpp"
|
||||
#include "open_engine/renderer/subtexture2d.hpp"
|
||||
#include "open_engine/orthographic_camera.hpp"
|
||||
#include "open_engine/renderer/texture.hpp"
|
||||
#include "open_engine/renderer/camera.hpp"
|
||||
#include "open_engine/ref_scope.hpp"
|
||||
|
||||
#include <glm/fwd.hpp>
|
||||
@@ -32,6 +33,7 @@ namespace OpenEngine {
|
||||
static void Shutdown();
|
||||
|
||||
static void BeginScene(const OrthographicCamera& camera);
|
||||
static void BeginScene(const Camera& camera, const glm::mat4& transform);
|
||||
static void EndScene();
|
||||
static void Flush();
|
||||
|
||||
@@ -39,6 +41,10 @@ namespace OpenEngine {
|
||||
static void DrawQuad(const Transform& transform_data, const Ref<Texture2D>& texture, float tiling_factor = 1.0f);
|
||||
static void DrawQuad(const Transform& transform_data, const Ref<Subtexture2D>& subtexture, float tiling_factor = 1.0f);
|
||||
|
||||
static void DrawQuad(const glm::mat4& transform, const glm::vec4& color);
|
||||
static void DrawQuad(const glm::mat4& transform, const Ref<Texture2D>& texture, float tiling_factor = 1.0f);
|
||||
static void DrawQuad(const glm::mat4& transform, const Ref<Subtexture2D>& subtexture, float tiling_factor = 1.0f);
|
||||
|
||||
static void ResetStats();
|
||||
static const Statistics& GetStats();
|
||||
|
||||
|
||||
151
open_engine/include/open_engine/scene/components.hpp
Normal file
151
open_engine/include/open_engine/scene/components.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#ifndef COMPONENTS_HPP
|
||||
#define COMPONENTS_HPP
|
||||
|
||||
#include "open_engine/scene/native_scriptable_entity.hpp"
|
||||
#include "open_engine/scene/scene_camera.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <imgui.h>
|
||||
#include <string>
|
||||
|
||||
namespace OpenEngine {
|
||||
|
||||
struct TagComponent
|
||||
{
|
||||
std::string tag;
|
||||
|
||||
TagComponent() = default;
|
||||
TagComponent(const TagComponent&) = default;
|
||||
TagComponent(const std::string& tag)
|
||||
: tag(tag) {}
|
||||
|
||||
void OnImGuiRender(Entity& entity)
|
||||
{
|
||||
char buffer[256];
|
||||
std::memset(buffer, 0, sizeof(buffer));
|
||||
std::strncpy(buffer, tag.c_str(), sizeof(buffer));
|
||||
|
||||
ImGui::Text("Name");
|
||||
if (ImGui::InputText("##tagEditor", buffer, sizeof(buffer), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll)
|
||||
|| (!ImGui::IsItemActive() && ImGui::IsMouseClicked(0)))
|
||||
tag = buffer;
|
||||
};
|
||||
};
|
||||
|
||||
struct TransformComponent
|
||||
{
|
||||
glm::mat4 transform{ 1.0f };
|
||||
|
||||
TransformComponent() = default;
|
||||
TransformComponent(const TransformComponent&) = default;
|
||||
TransformComponent(const glm::mat4& transform_mat)
|
||||
: transform(transform_mat) {}
|
||||
|
||||
operator glm::mat4() { return transform; };
|
||||
operator const glm::mat4() const { return transform; };
|
||||
|
||||
void OnImGuiRender(Entity& entity)
|
||||
{
|
||||
ImGui::DragFloat3("Position", glm::value_ptr(transform[3]), 0.1f);
|
||||
};
|
||||
};
|
||||
|
||||
struct SpriteRendererComponent
|
||||
{
|
||||
glm::vec4 color{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
|
||||
SpriteRendererComponent() = default;
|
||||
SpriteRendererComponent(const SpriteRendererComponent&) = default;
|
||||
SpriteRendererComponent(const glm::vec4& color)
|
||||
: color(color) {}
|
||||
|
||||
void OnImGuiRender(Entity& entity)
|
||||
{
|
||||
ImGui::ColorEdit4("color", glm::value_ptr(color));
|
||||
};
|
||||
};
|
||||
|
||||
struct CameraComponent
|
||||
{
|
||||
SceneCamera camera;
|
||||
bool primary = true;
|
||||
bool fixed_aspect_ratio = false;
|
||||
|
||||
CameraComponent() = default;
|
||||
CameraComponent(const CameraComponent&) = default;
|
||||
|
||||
void OnImGuiRender(Entity& entity)
|
||||
{
|
||||
ImGui::Checkbox("Is primary", &primary);
|
||||
const char* projection_type_strings[] = {"Perspective", "Orthographic"};
|
||||
const char* current_projection_type = projection_type_strings[(int)camera.GetProjectionType()];
|
||||
|
||||
if (ImGui::BeginCombo("Projection", current_projection_type)) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
bool is_selected = current_projection_type == projection_type_strings[i];
|
||||
if (ImGui::Selectable(projection_type_strings[i], is_selected)) {
|
||||
current_projection_type = projection_type_strings[i];
|
||||
camera.SetProjectionType((SceneCamera::ProjectionType)i);
|
||||
}
|
||||
|
||||
if (is_selected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (camera.GetProjectionType() == SceneCamera::ProjectionType::Perspective) {
|
||||
float fov = camera.GetVerticalFov();
|
||||
if (ImGui::DragFloat("Fov", &fov, 0.1f))
|
||||
camera.SetVerticalFov(fov);
|
||||
|
||||
float near_clip = camera.GetPerspectiveNearClip();
|
||||
if (ImGui::DragFloat("Near clip", &near_clip, 0.1f))
|
||||
camera.SetPerspectiveNearClip(near_clip);
|
||||
|
||||
float far_clip = camera.GetPerspectiveFarClip();
|
||||
if (ImGui::DragFloat("Far clip", &far_clip, 0.1f))
|
||||
camera.SetPerspectiveFarClip(far_clip);
|
||||
}
|
||||
else if (camera.GetProjectionType() == SceneCamera::ProjectionType::Orthographic) {
|
||||
ImGui::Checkbox("Has fixed aspect ratio", &fixed_aspect_ratio);
|
||||
float ortho_size = camera.GetOrthographicSize();
|
||||
if (ImGui::DragFloat("Orthographic size", &ortho_size, 0.1f))
|
||||
camera.SetOrthographicSize(ortho_size);
|
||||
|
||||
float near_clip = camera.GetOrthographicNearClip();
|
||||
if (ImGui::DragFloat("Near clip", &near_clip, 0.1f))
|
||||
camera.SetOrthographicNearClip(near_clip);
|
||||
|
||||
float far_clip = camera.GetOrthographicFarClip();
|
||||
if (ImGui::DragFloat("Far clip", &far_clip, 0.1f))
|
||||
camera.SetOrthographicFarClip(far_clip);
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
struct NativeScriptComponent
|
||||
{
|
||||
NativeScriptableEntity* instance = nullptr;
|
||||
|
||||
NativeScriptableEntity* (*InstanciateScript)();
|
||||
void (*DestroyInstanceScript)(NativeScriptComponent*);
|
||||
|
||||
template <typename T>
|
||||
void Bind()
|
||||
{
|
||||
InstanciateScript = []() { return static_cast<NativeScriptableEntity*>(new T()); };
|
||||
DestroyInstanceScript = [](NativeScriptComponent* nsc)
|
||||
{
|
||||
(delete nsc->instance);
|
||||
nsc->instance = nullptr;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // COMPONENTS_HPP
|
||||
64
open_engine/include/open_engine/scene/entity.hpp
Normal file
64
open_engine/include/open_engine/scene/entity.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef ENTITY_HPP
|
||||
#define ENTITY_HPP
|
||||
|
||||
#include "open_engine/core.hpp"
|
||||
|
||||
#include "open_engine/scene/scene.hpp"
|
||||
|
||||
#include <entt/entt.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace OpenEngine {
|
||||
class Entity
|
||||
{
|
||||
public:
|
||||
Entity() = default;
|
||||
Entity(entt::entity handle, Scene* scene);
|
||||
Entity(const Entity& other) = default;
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
T& AddComponents(Args&&... args)
|
||||
{
|
||||
OE_ASSERT(!HasComponent<T>(), "Entity already has component.");
|
||||
return scene->registry.emplace<T>(handle, std::forward<Args>(args)...);
|
||||
};
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
T& GetComponents(Args&&... args)
|
||||
{
|
||||
OE_ASSERT(HasComponent<T>(), "Entity doesn't have component.");
|
||||
return scene->registry.get<T>(handle);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void RemoveComponents()
|
||||
{
|
||||
OE_ASSERT(HasComponent<T>(), "Entity doesn't have component.");
|
||||
scene->registry.remove<T>(handle);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
bool HasComponent()
|
||||
{
|
||||
return scene->registry.all_of<T>(handle);
|
||||
};
|
||||
|
||||
operator bool() const { return handle != entt::null; };
|
||||
operator uint32_t() const { return (uint32_t)handle; };
|
||||
|
||||
bool operator ==(const Entity& other) const {
|
||||
return handle == other.handle && scene == other.scene;
|
||||
};
|
||||
|
||||
bool operator !=(const Entity& other) const {
|
||||
return !operator==(other);
|
||||
};
|
||||
|
||||
private:
|
||||
entt::entity handle { entt::null };
|
||||
OpenEngine::Scene* scene = nullptr;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ENTITY_HPP
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef NATIVE_SCRIPTABLE_ENTITY_HPP
|
||||
#define NATIVE_SCRIPTABLE_ENTITY_HPP
|
||||
|
||||
#include "open_engine/scene/entity.hpp"
|
||||
|
||||
namespace OpenEngine {
|
||||
|
||||
class NativeScriptableEntity
|
||||
{
|
||||
public:
|
||||
virtual ~NativeScriptableEntity() = default;
|
||||
template <typename T>
|
||||
T& GetComponent() { return entity.GetComponents<T>(); };
|
||||
|
||||
protected:
|
||||
virtual void OnCreate() {};
|
||||
virtual void OnUpdate() {};
|
||||
virtual void OnDestroy() {};
|
||||
|
||||
private:
|
||||
Entity entity;
|
||||
|
||||
friend class Scene;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NATIVE_SCRIPTABLE_ENTITY_HPP
|
||||
33
open_engine/include/open_engine/scene/scene.hpp
Normal file
33
open_engine/include/open_engine/scene/scene.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef SCENE_HPP
|
||||
#define SCENE_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
namespace OpenEngine {
|
||||
|
||||
class Entity;
|
||||
|
||||
class Scene
|
||||
{
|
||||
public:
|
||||
Scene() {};
|
||||
~Scene() = default;
|
||||
|
||||
Entity CreateEntity(const std::string& name = std::string());
|
||||
|
||||
void OnUpdate();
|
||||
void OnViewportResize(uint32_t width, uint32_t height);
|
||||
|
||||
entt::registry& GetRegistry() { return registry; };
|
||||
|
||||
private:
|
||||
entt::registry registry;
|
||||
|
||||
uint32_t viewport_width = 0, viewport_height = 0;
|
||||
|
||||
friend class Entity;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SCENE_HPP
|
||||
74
open_engine/include/open_engine/scene/scene_camera.hpp
Normal file
74
open_engine/include/open_engine/scene/scene_camera.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef SCENE_CAMERA_HPP
|
||||
#define SCENE_CAMERA_HPP
|
||||
|
||||
#include "open_engine/renderer/camera.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace OpenEngine {
|
||||
class SceneCamera : public Camera
|
||||
{
|
||||
public:
|
||||
enum class ProjectionType { Perspective = 0, Orthographic = 1 };
|
||||
public:
|
||||
SceneCamera();
|
||||
virtual ~SceneCamera() = default;
|
||||
|
||||
void SetViewportSize(uint32_t width, uint32_t height);
|
||||
|
||||
ProjectionType GetProjectionType() { return projection_type; };
|
||||
void SetProjectionType(ProjectionType type) {
|
||||
projection_type = type;
|
||||
RecalculateProjection();
|
||||
};
|
||||
|
||||
void SetOrthographic(float size, float near_clip, float far_clip);
|
||||
void SetPerspective(float fov, float near_clip, float far_clip);
|
||||
|
||||
float GetOrthographicSize() const { return orthographic_size; }
|
||||
void SetOrthographicSize(float size) {
|
||||
orthographic_size = size;
|
||||
RecalculateProjection();
|
||||
};
|
||||
float GetOrthographicNearClip() const { return orthographic_near; };
|
||||
void SetOrthographicNearClip(float near) {
|
||||
orthographic_near = near;
|
||||
RecalculateProjection();
|
||||
};
|
||||
float GetOrthographicFarClip() const { return orthographic_far; };
|
||||
void SetOrthographicFarClip(float far) {
|
||||
orthographic_far = far;
|
||||
RecalculateProjection();
|
||||
};
|
||||
|
||||
float GetVerticalFov() const { return fov; }
|
||||
void SetVerticalFov(float fov_value) {
|
||||
fov = fov_value;
|
||||
RecalculateProjection();
|
||||
};
|
||||
float GetPerspectiveNearClip() const { return perspective_near; };
|
||||
void SetPerspectiveNearClip(float near) {
|
||||
perspective_near = near;
|
||||
RecalculateProjection();
|
||||
};
|
||||
float GetPerspectiveFarClip() const { return perspective_far; };
|
||||
void SetPerspectiveFarClip(float far) {
|
||||
perspective_far = far;
|
||||
RecalculateProjection();
|
||||
};
|
||||
|
||||
private:
|
||||
void RecalculateProjection();
|
||||
|
||||
private:
|
||||
ProjectionType projection_type = ProjectionType::Orthographic;
|
||||
float orthographic_size = 10.0f;
|
||||
float orthographic_near = -1.0f, orthographic_far = 1.0f;
|
||||
|
||||
float fov = 45.0f;
|
||||
float perspective_near = 0.01f, perspective_far = 1000.0f;
|
||||
|
||||
float aspect_ratio = 0.0f;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SCENE_CAMERA_HPP
|
||||
@@ -1,14 +1,14 @@
|
||||
#include "imgui.h"
|
||||
#include "instrumentor.hpp"
|
||||
#include <pch.hpp>
|
||||
|
||||
#include <imgui/imgui_layer.hpp>
|
||||
|
||||
#include <opengl/imgui_opengl.h>
|
||||
#include <opengl/imgui_glfw.h>
|
||||
#include <instrumentor.hpp>
|
||||
#include <application.hpp>
|
||||
#include <layer.hpp>
|
||||
|
||||
#include "imgui.h"
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
@@ -340,10 +340,10 @@ namespace OpenEngine {
|
||||
|
||||
void ImGuiLayer::OnEvent(Event& event)
|
||||
{
|
||||
/*
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
event.handled |= event.IsInCategory(EventCategoryMouse) & io.WantCaptureMouse;
|
||||
event.handled |= event.IsInCategory(EventCategoryKeyboard) & io.WantCaptureKeyboard;
|
||||
*/
|
||||
if (block_events) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
event.handled |= event.IsInCategory(EventCategoryMouse) & io.WantCaptureMouse;
|
||||
event.handled |= event.IsInCategory(EventCategoryKeyboard) & io.WantCaptureKeyboard;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "logging.hpp"
|
||||
#include <pch.hpp>
|
||||
|
||||
#include <core.hpp>
|
||||
@@ -6,6 +7,7 @@
|
||||
#include <glad/glad.h>
|
||||
|
||||
namespace OpenEngine {
|
||||
static const uint32_t max_framebuffer_size = 8192;
|
||||
OpenGLFramebuffer::OpenGLFramebuffer(const FramebufferSpecification& spec)
|
||||
: specs(spec)
|
||||
{
|
||||
@@ -61,6 +63,10 @@ namespace OpenEngine {
|
||||
|
||||
void OpenGLFramebuffer::Resize(uint32_t width, uint32_t height)
|
||||
{
|
||||
if (width == 0 || height == 0 || width > max_framebuffer_size || height > max_framebuffer_size) {
|
||||
OE_CORE_WARN("Attempted to resize framebuffer to {} {}", width, height);
|
||||
return;
|
||||
}
|
||||
specs.width = width;
|
||||
specs.height = height;
|
||||
|
||||
|
||||
7
open_engine/src/open_engine/renderer/camera.cpp
Normal file
7
open_engine/src/open_engine/renderer/camera.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <pch.hpp>
|
||||
|
||||
#include <open_engine/renderer/camera.hpp>
|
||||
|
||||
namespace OpenEngine {
|
||||
|
||||
}
|
||||
@@ -7,10 +7,11 @@
|
||||
#include <renderer/buffer.hpp>
|
||||
#include <renderer/shader.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <glm/fwd.hpp>
|
||||
#include <glm/trigonometric.hpp>
|
||||
#include <glm/ext/quaternion_common.hpp>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/trigonometric.hpp>
|
||||
#include <glm/fwd.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace OpenEngine {
|
||||
struct QuadVertex
|
||||
@@ -135,6 +136,21 @@ namespace OpenEngine {
|
||||
renderer_data.texture_slot_index = 1;
|
||||
}
|
||||
|
||||
void Renderer2D::BeginScene(const Camera& camera, const glm::mat4& transform)
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
glm::mat4 view_projection = camera.GetProjection() * glm::inverse(transform);
|
||||
|
||||
renderer_data.texture_shader->Bind();
|
||||
renderer_data.texture_shader->SetMat4("u_ViewProjection", view_projection);
|
||||
|
||||
renderer_data.quad_index_count = 0;
|
||||
renderer_data.quad_vertex_ptr = renderer_data.quad_vertex_base;
|
||||
|
||||
renderer_data.texture_slot_index = 1;
|
||||
}
|
||||
|
||||
void Renderer2D::EndScene()
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
@@ -196,17 +212,7 @@ namespace OpenEngine {
|
||||
* glm::rotate(glm::mat4(1.0f), glm::radians(transform_data.rotation), { 0.0f, 0.0f, 1.0f })
|
||||
* glm::scale(glm::mat4(1.0f), transform_data.size);
|
||||
|
||||
for (size_t i = 0; i < quad_vertex_count; i++) {
|
||||
renderer_data.quad_vertex_ptr->position = transform * renderer_data.quad_vertex_positioning[i];
|
||||
renderer_data.quad_vertex_ptr->color = color;
|
||||
renderer_data.quad_vertex_ptr->tex_coord = texture_coords[i];
|
||||
renderer_data.quad_vertex_ptr->tex_index = texture_index;
|
||||
renderer_data.quad_vertex_ptr->tiling_factor = tiling_factor;
|
||||
renderer_data.quad_vertex_ptr++;
|
||||
}
|
||||
|
||||
renderer_data.quad_index_count += 6;
|
||||
renderer_data.stats.quad_count++;
|
||||
DrawQuad(transform, texture);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const Transform& transform_data, const Ref<Subtexture2D>& subtexture, float tiling_factor)
|
||||
@@ -246,17 +252,7 @@ namespace OpenEngine {
|
||||
* glm::rotate(glm::mat4(1.0f), glm::radians(transform_data.rotation), { 0.0f, 0.0f, 1.0f })
|
||||
* glm::scale(glm::mat4(1.0f), transform_data.size);
|
||||
|
||||
for (size_t i = 0; i < quad_vertex_count; i++) {
|
||||
renderer_data.quad_vertex_ptr->position = transform * renderer_data.quad_vertex_positioning[i];
|
||||
renderer_data.quad_vertex_ptr->color = color;
|
||||
renderer_data.quad_vertex_ptr->tex_coord = texture_coords[i];
|
||||
renderer_data.quad_vertex_ptr->tex_index = texture_index;
|
||||
renderer_data.quad_vertex_ptr->tiling_factor = tiling_factor;
|
||||
renderer_data.quad_vertex_ptr++;
|
||||
}
|
||||
|
||||
renderer_data.quad_index_count += 6;
|
||||
renderer_data.stats.quad_count++;
|
||||
DrawQuad(transform, subtexture);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const Transform& transform_data, const glm::vec4& color)
|
||||
@@ -277,6 +273,104 @@ namespace OpenEngine {
|
||||
* glm::scale(glm::mat4(1.0f), transform_data.size);
|
||||
|
||||
|
||||
DrawQuad(transform, color);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::mat4& transform, const Ref<Texture2D>& texture, float tiling_factor)
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
constexpr size_t quad_vertex_count = 4;
|
||||
constexpr glm::vec2 texture_coords[] = { { 0.0f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f }};
|
||||
|
||||
if (renderer_data.quad_index_count >= Renderer2DData::max_indices)
|
||||
FlushAndReset();
|
||||
|
||||
constexpr glm::vec4 color = glm::vec4(1.0f);
|
||||
|
||||
float texture_index = 0;
|
||||
for (uint32_t i = 1; i < renderer_data.texture_slot_index; i++) {
|
||||
if (*renderer_data.texture_slots[i].get() == *texture.get()) {
|
||||
texture_index = (float)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (texture_index == 0) {
|
||||
if (renderer_data.texture_slot_index >= Renderer2DData::max_texture_slots)
|
||||
FlushAndReset();
|
||||
|
||||
texture_index = (float)renderer_data.texture_slot_index;
|
||||
renderer_data.texture_slots[renderer_data.texture_slot_index] = texture;
|
||||
renderer_data.texture_slot_index++;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < quad_vertex_count; i++) {
|
||||
renderer_data.quad_vertex_ptr->position = transform * renderer_data.quad_vertex_positioning[i];
|
||||
renderer_data.quad_vertex_ptr->color = color;
|
||||
renderer_data.quad_vertex_ptr->tex_coord = texture_coords[i];
|
||||
renderer_data.quad_vertex_ptr->tex_index = texture_index;
|
||||
renderer_data.quad_vertex_ptr->tiling_factor = tiling_factor;
|
||||
renderer_data.quad_vertex_ptr++;
|
||||
}
|
||||
|
||||
renderer_data.quad_index_count += 6;
|
||||
renderer_data.stats.quad_count++;
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::mat4& transform, const Ref<Subtexture2D>& subtexture, float tiling_factor)
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
constexpr size_t quad_vertex_count = 4;
|
||||
const glm::vec2* texture_coords = subtexture->GetCoords();
|
||||
const Ref<Texture2D>& texture = subtexture->GetTexture();
|
||||
|
||||
if (renderer_data.quad_index_count >= Renderer2DData::max_indices)
|
||||
FlushAndReset();
|
||||
|
||||
constexpr glm::vec4 color = glm::vec4(1.0f);
|
||||
|
||||
float texture_index = 0;
|
||||
for (uint32_t i = 1; i < renderer_data.texture_slot_index; i++) {
|
||||
if (*renderer_data.texture_slots[i].get() == *texture.get()) {
|
||||
texture_index = (float)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (texture_index == 0) {
|
||||
if (renderer_data.texture_slot_index >= Renderer2DData::max_texture_slots)
|
||||
FlushAndReset();
|
||||
|
||||
texture_index = (float)renderer_data.texture_slot_index;
|
||||
renderer_data.texture_slots[renderer_data.texture_slot_index] = texture;
|
||||
renderer_data.texture_slot_index++;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < quad_vertex_count; i++) {
|
||||
renderer_data.quad_vertex_ptr->position = transform * renderer_data.quad_vertex_positioning[i];
|
||||
renderer_data.quad_vertex_ptr->color = color;
|
||||
renderer_data.quad_vertex_ptr->tex_coord = texture_coords[i];
|
||||
renderer_data.quad_vertex_ptr->tex_index = texture_index;
|
||||
renderer_data.quad_vertex_ptr->tiling_factor = tiling_factor;
|
||||
renderer_data.quad_vertex_ptr++;
|
||||
}
|
||||
|
||||
renderer_data.quad_index_count += 6;
|
||||
renderer_data.stats.quad_count++;
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::mat4& transform, const glm::vec4& color)
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
constexpr size_t quad_vertex_count = 4;
|
||||
constexpr glm::vec2 texture_coords[] = { { 0.0f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f }};
|
||||
|
||||
if (renderer_data.quad_index_count >= Renderer2DData::max_indices)
|
||||
FlushAndReset();
|
||||
|
||||
for (size_t i = 0; i < quad_vertex_count; i++) {
|
||||
renderer_data.quad_vertex_ptr->position = transform * renderer_data.quad_vertex_positioning[i];
|
||||
renderer_data.quad_vertex_ptr->color = color;
|
||||
@@ -290,6 +384,7 @@ namespace OpenEngine {
|
||||
renderer_data.stats.quad_count++;
|
||||
}
|
||||
|
||||
|
||||
void Renderer2D::ResetStats()
|
||||
{
|
||||
memset(&renderer_data.stats, 0, sizeof(Statistics));
|
||||
|
||||
60
open_engine/src/open_engine/scene/camera.cpp
Executable file
60
open_engine/src/open_engine/scene/camera.cpp
Executable file
@@ -0,0 +1,60 @@
|
||||
#include <glm/trigonometric.hpp>
|
||||
#include <pch.hpp>
|
||||
|
||||
#include <scene/scene_camera.hpp>
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
|
||||
namespace OpenEngine {
|
||||
SceneCamera::SceneCamera()
|
||||
{
|
||||
RecalculateProjection();
|
||||
}
|
||||
|
||||
void SceneCamera::SetOrthographic(float size, float near_clip, float far_clip)
|
||||
{
|
||||
projection_type = ProjectionType::Orthographic;
|
||||
orthographic_size = size;
|
||||
orthographic_near = near_clip;
|
||||
orthographic_far = far_clip;
|
||||
|
||||
RecalculateProjection();
|
||||
}
|
||||
|
||||
void SceneCamera::SetPerspective(float fov_value, float near_clip, float far_clip)
|
||||
{
|
||||
projection_type = ProjectionType::Perspective;
|
||||
fov = fov_value;
|
||||
perspective_near = near_clip;
|
||||
perspective_far = far_clip;
|
||||
|
||||
RecalculateProjection();
|
||||
}
|
||||
|
||||
void SceneCamera::SetViewportSize(uint32_t width, uint32_t height)
|
||||
{
|
||||
aspect_ratio = (float)width / (float)height;
|
||||
|
||||
RecalculateProjection();
|
||||
}
|
||||
|
||||
void SceneCamera::RecalculateProjection()
|
||||
{
|
||||
|
||||
if (projection_type == ProjectionType::Orthographic) {
|
||||
float ortho_left = -orthographic_size * aspect_ratio * 0.5;
|
||||
float ortho_right = orthographic_size * aspect_ratio * 0.5;
|
||||
float ortho_bottom = orthographic_size * -0.5;
|
||||
float ortho_top = orthographic_size * 0.5;
|
||||
|
||||
projection = glm::ortho(
|
||||
ortho_left, ortho_right,
|
||||
ortho_bottom, ortho_top,
|
||||
orthographic_near, orthographic_far);
|
||||
}
|
||||
else if (projection_type == ProjectionType::Perspective) {
|
||||
projection = glm::perspective(
|
||||
glm::radians(fov), aspect_ratio,
|
||||
perspective_near, perspective_far);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
open_engine/src/open_engine/scene/entity.cpp
Normal file
10
open_engine/src/open_engine/scene/entity.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <pch.hpp>
|
||||
|
||||
#include <scene/entity.hpp>
|
||||
|
||||
namespace OpenEngine {
|
||||
Entity::Entity(entt::entity handle, Scene* scene)
|
||||
: handle(handle), scene(scene)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#include <pch.hpp>
|
||||
78
open_engine/src/open_engine/scene/scene.cpp
Normal file
78
open_engine/src/open_engine/scene/scene.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include <pch.hpp>
|
||||
|
||||
#include <scene/scene.hpp>
|
||||
#include <renderer/renderer2d.hpp>
|
||||
|
||||
#include <scene/entity.hpp>
|
||||
#include <scene/components.hpp>
|
||||
|
||||
namespace OpenEngine {
|
||||
Entity Scene::CreateEntity(const std::string& name)
|
||||
{
|
||||
Entity entity = { registry.create(), this };
|
||||
|
||||
auto& tag = entity.AddComponents<TagComponent>();
|
||||
tag.tag = name.empty() ? "Entity" : name;
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
void Scene::OnUpdate()
|
||||
{
|
||||
{
|
||||
OE_PROFILE_SCOPE("Updating Sripts");
|
||||
|
||||
registry.view<NativeScriptComponent>().each([=, this](auto entity, auto& nsc)
|
||||
{
|
||||
if (!nsc.instance) {
|
||||
nsc.instance = nsc.InstanciateScript();
|
||||
nsc.instance->entity = Entity{ entity, this };
|
||||
nsc.instance->OnCreate();
|
||||
}
|
||||
|
||||
nsc.instance->OnUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
Camera* main_camera = nullptr;
|
||||
glm::mat4* main_transform = nullptr;
|
||||
{
|
||||
auto camera_view = registry.view<CameraComponent, TransformComponent>();
|
||||
for (auto entity : camera_view) {
|
||||
auto [camera_component, transform] = camera_view.get<CameraComponent, TransformComponent>(entity);
|
||||
|
||||
if (camera_component.primary) {
|
||||
main_camera = &camera_component.camera;
|
||||
main_transform = &transform.transform;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (main_camera) {
|
||||
Renderer2D::BeginScene(main_camera->GetProjection(), *main_transform);
|
||||
|
||||
auto view = registry.view<TransformComponent, SpriteRendererComponent>();
|
||||
|
||||
for (const auto& entity : view) {
|
||||
auto [transform, sprite] = view.get<TransformComponent, SpriteRendererComponent>(entity);
|
||||
Renderer2D::DrawQuad(transform.transform, sprite.color);
|
||||
}
|
||||
|
||||
Renderer2D::EndScene();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::OnViewportResize(uint32_t width, uint32_t height)
|
||||
{
|
||||
viewport_width = width;
|
||||
viewport_height = height;
|
||||
|
||||
auto view = registry.view<CameraComponent>();
|
||||
for (auto entity : view) {
|
||||
auto& camera_comp = view.get<CameraComponent>(entity);
|
||||
if (!camera_comp.fixed_aspect_ratio)
|
||||
camera_comp.camera.SetViewportSize(width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user