editor setup
This commit is contained in:
27
editor/include/control_layer.hpp
Normal file
27
editor/include/control_layer.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef LAYER_SWITCHER_HPP
|
||||
#define LAYER_SWITCHER_HPP
|
||||
|
||||
#include <open_engine.hpp>
|
||||
|
||||
class ControlLayer : public OpenEngine::Layer
|
||||
{
|
||||
public:
|
||||
ControlLayer(OpenEngine::Ref<OpenEngine::Layer> layer);
|
||||
ControlLayer();
|
||||
~ControlLayer() = default;
|
||||
|
||||
void OnUpdate() override;
|
||||
void OnEvent(OpenEngine::Event& event) override;
|
||||
void OnImGuiRender() override;
|
||||
void OnAttach() override;
|
||||
void OnDetach() override;
|
||||
|
||||
private:
|
||||
bool SwitchLayer(OpenEngine::KeyPressedEvent& event);
|
||||
bool SwitchExistingLayer(OpenEngine::KeyPressedEvent& event);
|
||||
bool StopRunning(OpenEngine::KeyPressedEvent& event);
|
||||
|
||||
OpenEngine::Ref<OpenEngine::Layer> active_layer;
|
||||
};
|
||||
|
||||
#endif // LAYER_SWITCHER_HPP
|
||||
169
editor/include/editor.hpp
Executable file
169
editor/include/editor.hpp
Executable file
@@ -0,0 +1,169 @@
|
||||
#ifndef EDITOR_HPP
|
||||
#define EDITOR_HPP
|
||||
|
||||
#include "open_engine/renderer/renderer2d.hpp"
|
||||
#include <open_engine.hpp>
|
||||
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/fwd.hpp>
|
||||
#include <imgui.h>
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
class EditorLayer : public OpenEngine::Layer
|
||||
{
|
||||
public:
|
||||
EditorLayer()
|
||||
: OpenEngine::Layer("editor_layer"),
|
||||
camera(1280.0f / 720.0f, 1.0f)
|
||||
{
|
||||
}
|
||||
~EditorLayer() {};
|
||||
|
||||
void OnAttach() override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
{
|
||||
OE_PROFILE_SCOPE("Texture2D Creation");
|
||||
face = OpenEngine::Texture2D::Create("assets/textures/awesomeface.png");
|
||||
}
|
||||
|
||||
OpenEngine::FramebufferSpecification specs;
|
||||
specs.width = 1280;
|
||||
specs.height = 720;
|
||||
|
||||
framebuffer = OpenEngine::FrameBuffer::Create(specs);
|
||||
}
|
||||
|
||||
void OnDetach() override
|
||||
{
|
||||
}
|
||||
|
||||
void OnUpdate() override
|
||||
{
|
||||
|
||||
OpenEngine::Renderer2D::ResetStats();
|
||||
OE_PROFILE_FUNCTION()
|
||||
{
|
||||
camera.OnUpdate();
|
||||
framebuffer->Bind();
|
||||
|
||||
OE_PROFILE_SCOPE("Setting up Rendering");
|
||||
|
||||
OpenEngine::RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f});
|
||||
OpenEngine::RenderCommand::Clear();
|
||||
OpenEngine::Renderer2D::BeginScene(camera.GetCamera());
|
||||
}
|
||||
{
|
||||
OE_PROFILE_SCOPE("Drawing Quads");
|
||||
OpenEngine::Transform tr1 = {glm::vec3(0.0f, 0.0f, -0.1f), glm::vec3(1.0f, 1.0f, 0.0f), angle};
|
||||
OpenEngine::Transform tr3 = {glm::vec3(-0.5f, -0.5f, 0.0f), glm::vec3(1.0f, 0.5f, 0.0f), angle * 0.5f};
|
||||
OpenEngine::Renderer2D::DrawQuad(tr1, face);
|
||||
OpenEngine::Renderer2D::DrawQuad(tr3, rectangle_color);
|
||||
}
|
||||
|
||||
OpenEngine::Renderer2D::EndScene();
|
||||
|
||||
OpenEngine::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};
|
||||
OpenEngine::Renderer2D::DrawQuad({{x, y, 0.0f}, glm::vec3(0.45f, 0.45f, 0.0f)}, gradient_color);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
OpenEngine::Renderer2D::EndScene();
|
||||
|
||||
framebuffer->Unbind();
|
||||
}
|
||||
|
||||
void OnEvent(OpenEngine::Event& event) override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
{
|
||||
OE_PROFILE_SCOPE("Camera OnEvent");
|
||||
camera.OnEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void OnImGuiRender() override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
ImGui::DockSpaceOverViewport();
|
||||
|
||||
ImGui::Begin("Square settings");
|
||||
|
||||
ImGui::SliderFloat("Angle", &angle, -360, 360);
|
||||
ImGui::ColorPicker4("Rectangle color", &rectangle_color[0]);
|
||||
|
||||
for (auto& result : profiling_results)
|
||||
{
|
||||
char label[50];
|
||||
strcpy(label, "%.3fms ");
|
||||
strcat(label, result.name);
|
||||
ImGui::Text(label, result.duration);
|
||||
}
|
||||
|
||||
profiling_results.clear();
|
||||
|
||||
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 };
|
||||
|
||||
camera.OnResize(viewport_panel_size.x, viewport_panel_size.y);
|
||||
}
|
||||
uint32_t texture_id = framebuffer->GetColorAttachmentRendererID();
|
||||
ImGui::Image((void*)texture_id, ImVec2{ viewport_size.x, viewport_size.y }, ImVec2{ 0, 1 }, ImVec2{ 1, 0 });
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
auto stats = OpenEngine::Renderer2D::GetStats();
|
||||
static float time = 0;
|
||||
|
||||
time += OpenEngine::Time::DeltaTime();
|
||||
|
||||
if (time >= 1) {
|
||||
time = 0;
|
||||
}
|
||||
|
||||
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::End();
|
||||
}
|
||||
|
||||
private:
|
||||
float angle = 0.0f;
|
||||
OpenEngine::Ref<OpenEngine::Texture2D> face;
|
||||
|
||||
OpenEngine::OrthographicCameraController camera;
|
||||
|
||||
std::vector<OpenEngine::Time::ProfilingResult> profiling_results;
|
||||
|
||||
glm::vec2 viewport_size = { 0.0f, 0.0f };
|
||||
OpenEngine::Ref<OpenEngine::FrameBuffer> framebuffer;
|
||||
glm::vec4 rectangle_color = {0.8f, 0.2f, 0.7f, 1.0f};
|
||||
};
|
||||
|
||||
class EditorApp : public OpenEngine::Application
|
||||
{
|
||||
public:
|
||||
EditorApp();
|
||||
~EditorApp();
|
||||
};
|
||||
|
||||
#endif // EDITOR_HPP
|
||||
152
editor/include/modding.hpp
Normal file
152
editor/include/modding.hpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#ifndef MODDING_HPP
|
||||
#define MODDING_HPP
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <open_engine.hpp>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.arch-x64/10.0.0/runtimes/arch-x64/native/nethost.h"
|
||||
#include "/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.arch-x64/10.0.0/runtimes/arch-x64/native/hostfxr.h"
|
||||
#include "/usr/share/dotnet/packs/Microsoft.NETCore.App.Host.arch-x64/10.0.0/runtimes/arch-x64/native/coreclr_delegates.h"
|
||||
|
||||
class Modding : public OpenEngine::Layer
|
||||
{
|
||||
public:
|
||||
Modding()
|
||||
: OpenEngine::Layer("modding")
|
||||
{
|
||||
};
|
||||
~Modding()
|
||||
{
|
||||
};
|
||||
|
||||
void* get_export(void* sample_lib, const char* name) {
|
||||
// dlsym is the Linux version of GetProcAddress
|
||||
void* f = dlsym(sample_lib, name);
|
||||
if (!f) {
|
||||
OE_ERROR("Failed to find symbol: {} Error: {}", name, dlerror());
|
||||
}
|
||||
return f;
|
||||
};
|
||||
|
||||
// Using the nethost library, discover the location of hostfxr and get exports
|
||||
bool load_hostfxr()
|
||||
{
|
||||
// Pre-allocate a large buffer for the path to hostfxr
|
||||
char_t buffer[250];
|
||||
size_t buffer_size = sizeof(buffer) / sizeof(char_t);
|
||||
int rc = get_hostfxr_path(buffer, &buffer_size, nullptr);
|
||||
if (rc != 0)
|
||||
return false;
|
||||
|
||||
// Load hostfxr and get desired exports
|
||||
auto* lib = dlopen(buffer, RTLD_NOW);
|
||||
init_fptr = (hostfxr_initialize_for_runtime_config_fn)get_export(lib, "hostfxr_initialize_for_runtime_config");
|
||||
get_delegate_fptr = (hostfxr_get_runtime_delegate_fn)get_export(lib, "hostfxr_get_runtime_delegate");
|
||||
close_fptr = (hostfxr_close_fn)get_export(lib, "hostfxr_close");
|
||||
|
||||
return (init_fptr && get_delegate_fptr && close_fptr);
|
||||
};
|
||||
|
||||
load_assembly_and_get_function_pointer_fn get_dotnet_load_assembly(const char_t *config_path)
|
||||
{
|
||||
// Load .NET Core
|
||||
void *load_assembly_and_get_function_pointer = nullptr;
|
||||
hostfxr_handle cxt = nullptr;
|
||||
int rc = init_fptr(config_path, nullptr, &cxt);
|
||||
if (rc != 0 || cxt == nullptr)
|
||||
{
|
||||
OE_ERROR("Init failed");
|
||||
close_fptr(cxt);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Get the load assembly function pointer
|
||||
rc = get_delegate_fptr(
|
||||
cxt,
|
||||
hdt_load_assembly_and_get_function_pointer,
|
||||
&load_assembly_and_get_function_pointer);
|
||||
if (rc != 0 || load_assembly_and_get_function_pointer == nullptr)
|
||||
OE_ERROR("Get delegate failed");
|
||||
|
||||
close_fptr(cxt);
|
||||
return (load_assembly_and_get_function_pointer_fn)load_assembly_and_get_function_pointer;
|
||||
}
|
||||
|
||||
component_entry_point_fn LoadMethod(const char* method)
|
||||
{
|
||||
component_entry_point_fn method_ptr;
|
||||
|
||||
int rc = load_assembly_and_get_function_pointer(
|
||||
dotnet_lib_path,
|
||||
dotnet_type,
|
||||
method,
|
||||
UNMANAGEDCALLERSONLY_METHOD /*delegate_type_name*/,
|
||||
nullptr,
|
||||
(void**)&method_ptr);
|
||||
|
||||
if (rc != 0) {
|
||||
OE_ERROR("Failed to load method {}", method);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return method_ptr;
|
||||
}
|
||||
|
||||
void OnAttach() override
|
||||
{
|
||||
load_hostfxr();
|
||||
|
||||
load_assembly_and_get_function_pointer = get_dotnet_load_assembly("assets/scripts/mod_loader.runtimeconfig.json");
|
||||
component_entry_point_fn init = LoadMethod("Init");
|
||||
|
||||
init(nullptr, 0);
|
||||
|
||||
hello = LoadMethod("Hello");
|
||||
|
||||
load_mod = LoadMethod("LoadMod");
|
||||
load_mod(nullptr, 0);
|
||||
}
|
||||
|
||||
void OnDetach() override
|
||||
{
|
||||
}
|
||||
|
||||
void OnUpdate() override
|
||||
{
|
||||
static float time = 0;
|
||||
|
||||
time += OpenEngine::Time::DeltaTime();
|
||||
|
||||
if (time >= 1) {
|
||||
hello(nullptr, 0);
|
||||
time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void OnEvent(OpenEngine::Event& event) override
|
||||
{
|
||||
//OpenEngine::EventDispatcher dispatcher(event);
|
||||
|
||||
//dispatcher.Dispatch<OpenEngine::KeyPressedEvent>(BIND_EVENT_FN(Sandbox2DLayer::StopRunning));
|
||||
}
|
||||
|
||||
void OnImGuiRender() override
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
hostfxr_initialize_for_runtime_config_fn init_fptr;
|
||||
hostfxr_get_runtime_delegate_fn get_delegate_fptr;
|
||||
hostfxr_close_fn close_fptr;
|
||||
load_assembly_and_get_function_pointer_fn load_assembly_and_get_function_pointer;
|
||||
|
||||
component_entry_point_fn hello = nullptr;
|
||||
component_entry_point_fn load_mod = nullptr;
|
||||
|
||||
const char_t* dotnet_lib_path = "assets/scripts/mod_loader.dll";
|
||||
const char_t* dotnet_type = "OpenEngine.ModLoader, mod_loader";
|
||||
const char_t* dotnet_type_method = "Init";
|
||||
};
|
||||
|
||||
#endif // MODDING_HPP
|
||||
252
editor/include/overlay.hpp
Normal file
252
editor/include/overlay.hpp
Normal file
@@ -0,0 +1,252 @@
|
||||
#ifndef OVERLAY_HPP
|
||||
#define OVERLAY_HPP
|
||||
|
||||
/*
|
||||
"""
|
||||
Portions of this software are copyright © 2025 The FreeType
|
||||
Project (https://freetype.org). All rights reserved.
|
||||
"""
|
||||
*/
|
||||
|
||||
#include <open_engine.hpp>
|
||||
|
||||
#include "shmup.hpp"
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
#include "freetype/fttypes.h"
|
||||
#include <freetype2/ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include <glad/glad.h>
|
||||
#include <map>
|
||||
|
||||
|
||||
struct Character {
|
||||
unsigned int texture_id; // ID handle of the glyph texture
|
||||
glm::ivec2 size; // Size of glyph
|
||||
glm::ivec2 bearing; // Offset from baseline to left/top of glyph
|
||||
FT_Long advance; // Offset to advance to next glyph
|
||||
};
|
||||
|
||||
class Overlay : public OpenEngine::Layer
|
||||
{
|
||||
public:
|
||||
Overlay(OpenEngine::Ref<Shmup>& shmup)
|
||||
: game_layer(shmup)
|
||||
{};
|
||||
|
||||
~Overlay() {};
|
||||
|
||||
void RenderText(std::string text, float x, float y, float scale, glm::vec3 color)
|
||||
{
|
||||
// activate corresponding render state
|
||||
text_shader->Bind();
|
||||
text_shader->SetVec3("textColor", glm::vec3(color.x, color.y, color.z));
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
// iterate through all characters
|
||||
std::string::const_iterator c;
|
||||
for (c = text.begin(); c != text.end(); c++)
|
||||
{
|
||||
Character ch = characters[*c];
|
||||
|
||||
float xpos = x + ch.bearing.x * scale;
|
||||
float ypos = y - (ch.size.y - ch.bearing.y) * scale;
|
||||
|
||||
float w = ch.size.x * scale;
|
||||
float h = ch.size.y * scale;
|
||||
// update VBO for each character
|
||||
float vertices[6][4] = {
|
||||
{ xpos, ypos + h, 0.0f, 0.0f },
|
||||
{ xpos, ypos, 0.0f, 1.0f },
|
||||
{ xpos + w, ypos, 1.0f, 1.0f },
|
||||
|
||||
{ xpos, ypos + h, 0.0f, 0.0f },
|
||||
{ xpos + w, ypos, 1.0f, 1.0f },
|
||||
{ xpos + w, ypos + h, 1.0f, 0.0f }
|
||||
};
|
||||
// render glyph texture over quad
|
||||
glBindTexture(GL_TEXTURE_2D, ch.texture_id);
|
||||
// update content of VBO memory
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
// render quad
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
// now advance cursors for next glyph (note that advance is number of 1/64 pixels)
|
||||
x += (ch.advance >> 6) * scale; // bitshift by 6 to get value in pixels (2^6 = 64)
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
glm::vec2 GetTextSize(const std::string& text, float scale)
|
||||
{
|
||||
float width = 0.0f;
|
||||
float height = 0.0f;
|
||||
|
||||
for (char c : text)
|
||||
{
|
||||
Character ch = characters[c];
|
||||
width += (ch.advance >> 6) * scale; // Accumulate total width
|
||||
|
||||
// Track the maximum height
|
||||
float char_height = ch.size.y * scale;
|
||||
if (char_height > height)
|
||||
height = char_height;
|
||||
}
|
||||
|
||||
return glm::vec2(width, height);
|
||||
}
|
||||
|
||||
void RenderTextCentered(std::string text, float center_x, float center_y, float scale, glm::vec3 color)
|
||||
{
|
||||
glm::vec2 text_size = GetTextSize(text, scale);
|
||||
|
||||
// Calculate top-left position to make text centered
|
||||
float x = center_x - (text_size.x / 2.0f);
|
||||
float y = center_y - (text_size.y / 2.0f);
|
||||
|
||||
RenderText(text, x, y, scale, color);
|
||||
}
|
||||
|
||||
private:
|
||||
void OnAttach() override
|
||||
{
|
||||
OE_INFO("Loading Freetype...");
|
||||
|
||||
int error;
|
||||
|
||||
FT_Library ft;
|
||||
error = FT_Init_FreeType(&ft);
|
||||
if (error != 0) {
|
||||
OE_ERROR("FREETYPE: Could not init FreeType Library");
|
||||
return;
|
||||
}
|
||||
|
||||
FT_Face face;
|
||||
error = FT_New_Face(ft, "/usr/share/fonts/TTF/JetBrainsMono-Regular.ttf", 0, &face);
|
||||
if (error != 0) {
|
||||
OE_ERROR("FREETYPE: Failed to load font");
|
||||
return;
|
||||
}
|
||||
|
||||
FT_Set_Pixel_Sizes(face, 0, 48);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
for (unsigned char c = 0; c < 128; c++)
|
||||
{
|
||||
// load character glyph
|
||||
if (FT_Load_Char(face, c, FT_LOAD_RENDER))
|
||||
{
|
||||
OE_ERROR("FREETYTPE: Failed to load Glyph: {}", c);
|
||||
continue;
|
||||
}
|
||||
|
||||
// generate texture
|
||||
unsigned int texture;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RED,
|
||||
face->glyph->bitmap.width,
|
||||
face->glyph->bitmap.rows,
|
||||
0,
|
||||
GL_RED,
|
||||
GL_UNSIGNED_BYTE,
|
||||
face->glyph->bitmap.buffer
|
||||
);
|
||||
// set texture options
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
// now store character for later use
|
||||
Character character = {
|
||||
texture,
|
||||
glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
|
||||
glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
|
||||
face->glyph->advance.x
|
||||
};
|
||||
characters.insert(std::pair<char, Character>(c, character));
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
FT_Done_Face(face);
|
||||
FT_Done_FreeType(ft);
|
||||
|
||||
text_shader = OpenEngine::Shader::Create("assets/shaders/text.glsl");
|
||||
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
};
|
||||
|
||||
void OnUpdate() override
|
||||
{
|
||||
text_shader->Bind();
|
||||
int width = OpenEngine::Application::Get().GetWindow().GetWidth();
|
||||
int height = OpenEngine::Application::Get().GetWindow().GetHeight();
|
||||
|
||||
projection = glm::ortho(0.0f, static_cast<float>(width),
|
||||
0.0f, static_cast<float>(height));
|
||||
|
||||
text_shader->SetMat4("u_ViewProjection", projection);
|
||||
|
||||
float x = height - 40;
|
||||
float y = 0;
|
||||
|
||||
switch (game_layer->GetGameState()) {
|
||||
case GameState::GameOver:
|
||||
{
|
||||
auto& window = OpenEngine::Application::Get().GetWindow();
|
||||
int width = window.GetWidth();
|
||||
int height = window.GetHeight();
|
||||
|
||||
float x = width / 2.0f;
|
||||
float y = height / 2.0f;
|
||||
RenderTextCentered("Game Over!", x, y, 1.0f, glm::vec3(0.8f, 0.2f, 0.3f));
|
||||
break;
|
||||
}
|
||||
case GameState::Paused:
|
||||
RenderTextCentered("Paused", x, y, 1.0f, glm::vec3(0.8f, 0.2f, 0.3f));
|
||||
break;
|
||||
case GameState::Playing:
|
||||
break;
|
||||
}
|
||||
|
||||
std::string s_score = "Score: " + std::to_string(game_layer->GetScore());
|
||||
std::string s_lives = std::to_string(game_layer->GetLives()) + " lives";
|
||||
RenderText(s_score, 10, OpenEngine::Application::Get().GetWindow().GetHeight() - 50, 1.0f, {0.8f, 0.2f, 0.3f});
|
||||
RenderText(
|
||||
s_lives,
|
||||
OpenEngine::Application::Get().GetWindow().GetWidth() - 220,
|
||||
OpenEngine::Application::Get().GetWindow().GetHeight() - 50,
|
||||
1.0f,
|
||||
{0.8f, 0.2f, 0.3f});
|
||||
|
||||
};
|
||||
|
||||
void OnEvent(OpenEngine::Event& event) override
|
||||
{
|
||||
};
|
||||
|
||||
private:
|
||||
std::map<char, Character> characters;
|
||||
OpenEngine::Ref<OpenEngine::Shader> text_shader;
|
||||
glm::mat4 projection;
|
||||
OpenEngine::Ref<Shmup> game_layer;
|
||||
|
||||
unsigned int VAO, VBO;
|
||||
};
|
||||
|
||||
#endif // OVERLAY_HPP
|
||||
130
editor/include/sandbox2d.hpp
Executable file
130
editor/include/sandbox2d.hpp
Executable file
@@ -0,0 +1,130 @@
|
||||
#ifndef SANDBOX2D_HPP
|
||||
#define SANDBOX2D_HPP
|
||||
|
||||
#include <open_engine.hpp>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include "imgui.h"
|
||||
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class Sandbox2DLayer : public OpenEngine::Layer
|
||||
{
|
||||
public:
|
||||
Sandbox2DLayer()
|
||||
: OpenEngine::Layer("sandbox_2d"),
|
||||
camera((float)OpenEngine::Application::Get().GetWindow().GetWidth() /
|
||||
OpenEngine::Application::Get().GetWindow().GetHeight(), 1.0f)
|
||||
{
|
||||
}
|
||||
~Sandbox2DLayer() {};
|
||||
|
||||
void OnAttach() override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
bindings = {
|
||||
{"fwd/bckwd", 1},
|
||||
{"right/left", 0},
|
||||
{"yaw", 2}
|
||||
};
|
||||
|
||||
{
|
||||
OE_PROFILE_SCOPE("Texture2D Creation");
|
||||
face = OpenEngine::Texture2D::Create("assets/textures/awesomeface.png");
|
||||
}
|
||||
}
|
||||
|
||||
void OnDetach() override
|
||||
{
|
||||
}
|
||||
|
||||
void OnUpdate() override
|
||||
{
|
||||
OE_PROFILE_FUNCTION()
|
||||
{
|
||||
OE_PROFILE_SCOPE("Setting up Rendering");
|
||||
OpenEngine::RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f});
|
||||
OpenEngine::RenderCommand::Clear();
|
||||
OpenEngine::Renderer2D::BeginScene(camera.GetCamera());
|
||||
}
|
||||
static float angle = 0.0f;
|
||||
float ts = OpenEngine::Time::DeltaTime();
|
||||
|
||||
if (angle >= 360)
|
||||
angle = 0;
|
||||
|
||||
angle += (ts * 500.0f);
|
||||
{
|
||||
OE_PROFILE_SCOPE("Drawing Quads");
|
||||
OpenEngine::Transform tr1 = {glm::vec3(0.5f, 0.5f, 0.2f), glm::vec3(0.3f), 20.0f};
|
||||
OpenEngine::Transform tr2 = {glm::vec3(-0.2f, -0.2f, 0.1f), glm::vec3(0.5f, 0.2f, 1.0f), angle};
|
||||
OpenEngine::Transform tr3 = {glm::vec3(0.0f, 0.0f, -0.1f), glm::vec3(1.0f, 1.0f, 1.0f), 45.0f};
|
||||
|
||||
OpenEngine::Renderer2D::DrawQuad({glm::vec3(0.5f, 0.5f, 0.0f), glm::vec3(0.3f), 20.0f}, glm::vec4(color[0], color[1], color[2], color[3]));
|
||||
OpenEngine::Renderer2D::DrawQuad(tr2, {0.5f, 0.3f, 0.8f, 1.0f});
|
||||
OpenEngine::Renderer2D::DrawQuad(tr3, face);
|
||||
}
|
||||
|
||||
OpenEngine::Renderer2D::EndScene();
|
||||
}
|
||||
|
||||
bool StopRunning(OpenEngine::KeyPressedEvent& event)
|
||||
{
|
||||
if (event.GetKeyCode() == OE_KEY_ESCAPE) {
|
||||
OpenEngine::Application::Get().StopRunning();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnEvent(OpenEngine::Event& event) override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
OpenEngine::EventDispatcher dispatcher(event);
|
||||
|
||||
//dispatcher.Dispatch<OpenEngine::KeyPressedEvent>(BIND_EVENT_FN(Sandbox2DLayer::StopRunning));
|
||||
{
|
||||
OE_PROFILE_SCOPE("Camera OnEvent");
|
||||
camera.OnEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void OnImGuiRender() override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
ImGui::Begin("Square settings");
|
||||
|
||||
ImGui::ColorEdit4("Square color", color);
|
||||
|
||||
for (auto& result : profiling_results)
|
||||
{
|
||||
char label[50];
|
||||
strcpy(label, "%.3fms ");
|
||||
strcat(label, result.name);
|
||||
ImGui::Text(label, result.duration);
|
||||
}
|
||||
|
||||
profiling_results.clear();
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
private:
|
||||
//OpenEngine::ShaderLibrary shader_library;
|
||||
glm::vec3 square_pos = glm::vec3(0.0f);
|
||||
glm::vec4 square_color = glm::vec4(1.0f);
|
||||
|
||||
float color[4] = {0.5f, 0.3f, 0.4f, 1.0f};
|
||||
OpenEngine::Ref<OpenEngine::Texture2D> face;
|
||||
|
||||
std::unordered_map<std::string, unsigned int> bindings;
|
||||
OpenEngine::OrthographicCameraController camera;
|
||||
|
||||
std::vector<OpenEngine::Time::ProfilingResult> profiling_results;
|
||||
};
|
||||
|
||||
#endif // SANDBOX2D_HPP
|
||||
386
editor/include/shmup.hpp
Executable file
386
editor/include/shmup.hpp
Executable file
@@ -0,0 +1,386 @@
|
||||
#ifndef SHMUP_HPP
|
||||
#define SHMUP_HPP
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <open_engine.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <dlfcn.h>
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
enum class GameState
|
||||
{
|
||||
Playing,
|
||||
Paused,
|
||||
GameOver
|
||||
};
|
||||
|
||||
class Shmup : public OpenEngine::Layer
|
||||
{
|
||||
public:
|
||||
Shmup()
|
||||
: camera((float)OpenEngine::Application::Get().GetWindow().GetWidth() /
|
||||
OpenEngine::Application::Get().GetWindow().GetHeight(), 1.0f)
|
||||
{
|
||||
}
|
||||
~Shmup() {};
|
||||
|
||||
void OnAttach() override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
{
|
||||
OE_PROFILE_SCOPE("Texture2D Creation");
|
||||
ship = OpenEngine::Texture2D::Create("assets/textures/shmup/ship.png");
|
||||
enemy_ship = OpenEngine::Texture2D::Create("assets/textures/shmup/enemy_ship.png");
|
||||
bullet_tx = OpenEngine::Texture2D::Create("assets/textures/shmup/bullet.png");
|
||||
}
|
||||
|
||||
LoadMap();
|
||||
}
|
||||
|
||||
void OnDetach() override
|
||||
{
|
||||
}
|
||||
|
||||
struct Bounds {
|
||||
glm::vec2 min; // Bottom-Left
|
||||
glm::vec2 max; // Top-Right
|
||||
};
|
||||
|
||||
Bounds GetBounds(glm::vec2 position, glm::vec2 scale) {
|
||||
Bounds b;
|
||||
// Because the original vertices are -0.5 to 0.5,
|
||||
// the distance from center to edge is exactly scale * 0.5
|
||||
glm::vec2 halfScale = scale * 0.5f;
|
||||
|
||||
b.min = position - halfScale;
|
||||
b.max = position + halfScale;
|
||||
return b;
|
||||
}
|
||||
|
||||
bool CheckCollision(const Bounds& a, const Bounds& b) {
|
||||
bool overlapX = a.max.x >= b.min.x && b.max.x >= a.min.x;
|
||||
bool overlapY = a.max.y >= b.min.y && b.max.y >= a.min.y;
|
||||
|
||||
return overlapX && overlapY;
|
||||
}
|
||||
|
||||
void MovePlayerShip()
|
||||
{
|
||||
double delta = OpenEngine::Time::DeltaTime();
|
||||
if (OpenEngine::Input::IsKeyPressed(OpenEngine::KeyCode::Up)) {
|
||||
tr1.position.y += 1 * delta;
|
||||
}
|
||||
if (OpenEngine::Input::IsKeyPressed(OpenEngine::KeyCode::Down)) {
|
||||
tr1.position.y -= 1 * delta;
|
||||
}
|
||||
if (OpenEngine::Input::IsKeyPressed(OpenEngine::KeyCode::Right)) {
|
||||
tr1.position.x += 1 * delta;
|
||||
}
|
||||
if (OpenEngine::Input::IsKeyPressed(OpenEngine::KeyCode::Left)) {
|
||||
tr1.position.x -= 1 * delta;
|
||||
}
|
||||
|
||||
if (tr1.position.y <= -0.9)
|
||||
tr1.position.y = -0.9;
|
||||
if (tr1.position.y >= -0.3)
|
||||
tr1.position.y = -0.3;
|
||||
if (tr1.position.x <= -0.8)
|
||||
tr1.position.x = -0.8;
|
||||
if (tr1.position.x >= 0.8)
|
||||
tr1.position.x = 0.8;
|
||||
}
|
||||
|
||||
bool MovePlayerShipDiscrete(OpenEngine::KeyPressedEvent& event)
|
||||
{
|
||||
if (state == GameState::Playing) {
|
||||
double delta = OpenEngine::Time::DeltaTime();
|
||||
if (event.GetKeyCode() == OpenEngine::KeyCode::Right) {
|
||||
tr1.position.x += 0.1f;
|
||||
return true;
|
||||
}
|
||||
if (event.GetKeyCode() == OpenEngine::KeyCode::Left) {
|
||||
tr1.position.x -= 0.1f;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tr1.position.y <= -0.9)
|
||||
tr1.position.y = -0.9;
|
||||
if (tr1.position.y >= -0.3)
|
||||
tr1.position.y = -0.3;
|
||||
if (tr1.position.x <= -0.8)
|
||||
tr1.position.x = -0.8;
|
||||
if (tr1.position.x >= 0.8)
|
||||
tr1.position.x = 0.8;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MoveEntities(double time_step) {
|
||||
double delta = time_step;
|
||||
|
||||
// Updating enemy positions
|
||||
for (auto& enemy : enemies) {
|
||||
enemy.position.y -= 0.3 * delta;
|
||||
if (state == GameState::Playing && (enemy.position.y <= -1.1 || CheckCollision(
|
||||
GetBounds(enemy.position, enemy.size),
|
||||
GetBounds(tr1.position, tr1.size))))
|
||||
lives--;
|
||||
}
|
||||
|
||||
// Updating friendly bullets positions
|
||||
for (auto& bullet : bullets) {
|
||||
bullet.position.y += 1.1 * delta;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateEntity()
|
||||
{
|
||||
double delta = OpenEngine::Time::DeltaTime();
|
||||
|
||||
MoveEntities(delta);
|
||||
|
||||
// Deletes enemies offscreen
|
||||
std::erase_if(enemies, [](const auto& enemy) {
|
||||
return enemy.position.y <= -1.1f;
|
||||
});
|
||||
// Deletes bullets offscreen
|
||||
std::erase_if(bullets, [](const auto& bullet) {
|
||||
return bullet.position.y >= 1.2f;
|
||||
});
|
||||
|
||||
// Lowers lives upon collision between player and enemy
|
||||
for (auto& enemy : enemies) {
|
||||
if (state == GameState::Playing) {
|
||||
if (enemy.position.y <= -1.1)
|
||||
lives--;
|
||||
|
||||
if (CheckCollision(
|
||||
GetBounds(enemy.position, enemy.size),
|
||||
GetBounds(tr1.position, tr1.size)))
|
||||
lives = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Deletes enemy and bullet and increases score after collision
|
||||
for (auto& bullet : bullets) {
|
||||
for (auto& enemy : enemies) {
|
||||
Bounds bullet_bounds = GetBounds(bullet.position, bullet.size);
|
||||
Bounds enemy_bounds = GetBounds(enemy.position, enemy.size);
|
||||
|
||||
if (CheckCollision(bullet_bounds, enemy_bounds)) {
|
||||
std::erase_if(bullets, [&](const OpenEngine::Transform& _bullet) {
|
||||
return _bullet.position == bullet.position;
|
||||
});
|
||||
std::erase_if(enemies, [&](const auto& _enemy) {
|
||||
return _enemy.position == enemy.position;
|
||||
});
|
||||
score++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Render()
|
||||
{
|
||||
OE_PROFILE_FUNCTION()
|
||||
{
|
||||
OE_PROFILE_SCOPE("Setting up Rendering");
|
||||
OpenEngine::RenderCommand::SetClearColor({0.11f, 0.11f, 0.15f, 1.0f});
|
||||
//OpenEngine::RenderCommand::SetClearColor({1.0f, 0.11f, 0.15f, 1.0f});
|
||||
OpenEngine::RenderCommand::Clear();
|
||||
OpenEngine::Renderer2D::BeginScene(camera.GetCamera());
|
||||
}
|
||||
{
|
||||
OE_PROFILE_SCOPE("Drawing Quads");
|
||||
OpenEngine::Renderer2D::DrawQuad(tr1, ship);
|
||||
|
||||
for (auto& enemy : enemies)
|
||||
OpenEngine::Renderer2D::DrawQuad(enemy, enemy_ship);
|
||||
for (auto& bullet : bullets)
|
||||
OpenEngine::Renderer2D::DrawQuad(bullet, bullet_tx);
|
||||
}
|
||||
|
||||
OpenEngine::Renderer2D::EndScene();
|
||||
|
||||
}
|
||||
|
||||
void OnUpdate() override
|
||||
{
|
||||
float delta = OpenEngine::Time::DeltaTime();
|
||||
|
||||
Render();
|
||||
|
||||
UpdateEntity();
|
||||
|
||||
if (state == GameState::Playing) {
|
||||
if (spawn_cooldown >= spawn_min_time) {
|
||||
//SpawnEnemyRandom();
|
||||
ReadMap();
|
||||
spawn_cooldown = 0;
|
||||
if (spawn_min_time > 0.5)
|
||||
spawn_min_time -= 0.01;
|
||||
}
|
||||
|
||||
//MovePlayerShip();
|
||||
|
||||
if (shooting)
|
||||
SpawnBullet();
|
||||
|
||||
shot_cooldown += delta;
|
||||
spawn_cooldown += delta;
|
||||
}
|
||||
|
||||
if (lives <= 0)
|
||||
state = GameState::GameOver;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
tr1 = {glm::vec3(0.0f, -0.9f, -0.1f), glm::vec3(0.1f), 0.0f};
|
||||
|
||||
score = 0;
|
||||
lives = 5;
|
||||
|
||||
bullets.clear();
|
||||
enemies.clear();
|
||||
|
||||
state = GameState::Playing;
|
||||
}
|
||||
|
||||
void SpawnEnemyRandom()
|
||||
{
|
||||
static std::uniform_int_distribution<int> dist{-8, 8};
|
||||
|
||||
SpawnEnemy(dist(rd));
|
||||
};
|
||||
|
||||
void SpawnEnemy(int x)
|
||||
{
|
||||
OpenEngine::Transform enemy_tr({{x/10.0f, 1.2f, 0.1f}, glm::vec3(0.1f), 180.0f});
|
||||
enemies.emplace_back(enemy_tr);
|
||||
};
|
||||
|
||||
void LoadMap(const char* path = "assets/maps/lvl1.txt")
|
||||
{
|
||||
std::string buffer;
|
||||
|
||||
std::ifstream map_file(path);
|
||||
|
||||
while (std::getline(map_file, buffer)) {
|
||||
map.emplace_back(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
void ReadMap()
|
||||
{
|
||||
static int line_n = 0;
|
||||
if (line_n >= map.size())
|
||||
return;
|
||||
|
||||
auto line = map[line_n];
|
||||
|
||||
int position = -8;
|
||||
for (int i = 0; i < line.length(); i++) {
|
||||
if (line[i] == '#')
|
||||
SpawnEnemy(position);
|
||||
position++;
|
||||
}
|
||||
|
||||
line_n++;
|
||||
};
|
||||
|
||||
void SpawnBullet()
|
||||
{
|
||||
if (shot_cooldown >= 0.2) {
|
||||
OpenEngine::Transform bullet_tr;
|
||||
bullet_tr.size = glm::vec3(0.03f);
|
||||
bullet_tr.position.x = tr1.position.x;
|
||||
bullet_tr.position.y = tr1.position.y + 0.1;
|
||||
|
||||
bullets.emplace_back(bullet_tr);
|
||||
|
||||
shot_cooldown = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProcessKeyPressedEvents(OpenEngine::KeyPressedEvent& event)
|
||||
{
|
||||
if (event.GetKeyCode() == OpenEngine::KeyCode::Space) {
|
||||
shooting = true;
|
||||
return true;
|
||||
}
|
||||
if (state == GameState::GameOver && event.GetKeyCode() == OpenEngine::KeyCode::Enter) {
|
||||
Reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
bool ProcessKeyReleased(OpenEngine::KeyReleasedEvent& event)
|
||||
{
|
||||
if (event.GetKeyCode() == OpenEngine::KeyCode::Space)
|
||||
shooting = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnEvent(OpenEngine::Event& event) override
|
||||
{
|
||||
OE_PROFILE_FUNCTION();
|
||||
|
||||
OpenEngine::EventDispatcher dispatcher(event);
|
||||
|
||||
dispatcher.Dispatch<OpenEngine::KeyPressedEvent>(BIND_EVENT_FN(Shmup::MovePlayerShipDiscrete));
|
||||
dispatcher.Dispatch<OpenEngine::KeyPressedEvent>(BIND_EVENT_FN(Shmup::ProcessKeyPressedEvents));
|
||||
dispatcher.Dispatch<OpenEngine::KeyReleasedEvent>(BIND_EVENT_FN(Shmup::ProcessKeyReleased));
|
||||
{
|
||||
OE_PROFILE_SCOPE("Camera OnEvent");
|
||||
camera.OnEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
//void OnImGuiRender() override
|
||||
//{
|
||||
// ImGuiIO io = ImGui::GetIO();
|
||||
// static auto m_Font = io.Fonts->AddFontFromFileTTF("/usr/share/fonts/TTF/JetBrainsMono-Regular.ttf", 120.0f);
|
||||
|
||||
// ImGui::GetForegroundDrawList()->AddText(m_Font, 48.0f, {5.0f, 5.0f}, 0xffffffff, "test");
|
||||
//}
|
||||
|
||||
GameState GetGameState() { return state; };
|
||||
int GetScore() { return score; };
|
||||
int GetLives() { return lives; };
|
||||
|
||||
private:
|
||||
OpenEngine::Ref<OpenEngine::Texture2D> ship;
|
||||
OpenEngine::Ref<OpenEngine::Texture2D> enemy_ship;
|
||||
OpenEngine::Ref<OpenEngine::Texture2D> bullet_tx;
|
||||
OpenEngine::Transform tr1 = {glm::vec3(0.0f, -0.9f, -0.1f), glm::vec3(0.1f), 0.0f};
|
||||
std::vector<OpenEngine::Transform> enemies, bullets;
|
||||
int score = 0;
|
||||
int lives = 5;
|
||||
|
||||
bool shooting = false;
|
||||
float spawn_cooldown = 0, shot_cooldown = 0;
|
||||
float spawn_min_time = 1.0f;
|
||||
std::vector<std::string> map;
|
||||
|
||||
std::random_device rd;
|
||||
std::mt19937 e{rd()}; // or std::default_random_engine e{rd()};
|
||||
|
||||
OpenEngine::OrthographicCameraController camera;
|
||||
GameState state = GameState::Playing;
|
||||
|
||||
//OpenEngine::Ref<Overlay> overlay;
|
||||
};
|
||||
|
||||
#endif // SHMUP_HPP
|
||||
44
editor/src/control_layer.cpp
Normal file
44
editor/src/control_layer.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <open_engine/core.hpp>
|
||||
#include <control_layer.hpp>
|
||||
#include <sandbox2d.hpp>
|
||||
#include <editor.hpp>
|
||||
|
||||
ControlLayer::ControlLayer(OpenEngine::Ref<OpenEngine::Layer> layer)
|
||||
: active_layer(layer), OpenEngine::Layer("control_layer")
|
||||
{
|
||||
}
|
||||
|
||||
void ControlLayer::OnUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
bool ControlLayer::StopRunning(OpenEngine::KeyPressedEvent& event)
|
||||
{
|
||||
if (event.GetKeyCode() == OE_KEY_ESCAPE) {
|
||||
OpenEngine::Application::Get().StopRunning();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ControlLayer::OnEvent(OpenEngine::Event& event)
|
||||
{
|
||||
OpenEngine::EventDispatcher dispatcher(event);
|
||||
|
||||
dispatcher.Dispatch<OpenEngine::KeyPressedEvent>(BIND_EVENT_FN(ControlLayer::StopRunning));
|
||||
}
|
||||
|
||||
void ControlLayer::OnImGuiRender()
|
||||
{
|
||||
}
|
||||
|
||||
void ControlLayer::OnAttach()
|
||||
{
|
||||
}
|
||||
|
||||
void ControlLayer::OnDetach()
|
||||
{
|
||||
}
|
||||
31
editor/src/editor.cpp
Normal file
31
editor/src/editor.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include <open_engine/entry_point.hpp>
|
||||
|
||||
#include <open_engine.hpp>
|
||||
#include <editor.hpp>
|
||||
|
||||
#include <control_layer.hpp>
|
||||
#include <overlay.hpp>
|
||||
#include <modding.hpp>
|
||||
|
||||
#include <editor.hpp>
|
||||
|
||||
EditorApp::EditorApp()
|
||||
{
|
||||
OpenEngine::Ref<OpenEngine::Layer> initial_layer = std::make_shared<EditorLayer>();
|
||||
OpenEngine::Ref<OpenEngine::Layer> control_layer = std::make_shared<ControlLayer>(initial_layer);
|
||||
OpenEngine::Ref<OpenEngine::Layer> modding_layer = std::make_shared<Modding>();
|
||||
|
||||
QueueLayerPush(initial_layer);
|
||||
QueueLayerPush(control_layer);
|
||||
QueueLayerPush(modding_layer);
|
||||
}
|
||||
|
||||
EditorApp::~EditorApp()
|
||||
{
|
||||
}
|
||||
|
||||
OpenEngine::Application* OpenEngine::CreateApplication()
|
||||
{
|
||||
OE_INFO("Editor Starting...");
|
||||
return new EditorApp();
|
||||
}
|
||||
Reference in New Issue
Block a user