content browser and textures on entity sprites
This commit is contained in:
@@ -1,8 +1,13 @@
|
|||||||
#ifndef EDITOR_HPP
|
#ifndef EDITOR_HPP
|
||||||
#define EDITOR_HPP
|
#define EDITOR_HPP
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <open_engine.hpp>
|
#include <open_engine.hpp>
|
||||||
|
|
||||||
|
#include "open_engine/application.hpp"
|
||||||
|
#include "open_engine/scene/entity.hpp"
|
||||||
|
#include "open_engine/scene/scene_serializer.hpp"
|
||||||
|
#include "panels/content_browser.hpp"
|
||||||
#include "panels/scene_hierarchy.hpp"
|
#include "panels/scene_hierarchy.hpp"
|
||||||
|
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
@@ -71,6 +76,13 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
scene = CreateRef<Scene>();
|
scene = CreateRef<Scene>();
|
||||||
|
|
||||||
|
auto command_line_args = Application::Get().GetCommandLineArgs();
|
||||||
|
if (command_line_args.count > 1) {
|
||||||
|
auto scene_path = command_line_args[1];
|
||||||
|
SceneSerializer serializer(scene);
|
||||||
|
serializer.Deserialize(scene_path);
|
||||||
|
}
|
||||||
|
|
||||||
editor_camera = EditorCamera(30.0f, 1920.0f/1080.0f, 0.1f, 1000.0f);
|
editor_camera = EditorCamera(30.0f, 1920.0f/1080.0f, 0.1f, 1000.0f);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -255,6 +267,15 @@ namespace OpenEngine {
|
|||||||
uint32_t texture_id = framebuffer->GetColorAttachmentRendererID();
|
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::Image((void*)(uint64_t)texture_id, ImVec2{ viewport_size.x, viewport_size.y }, ImVec2{ 0, 1 }, ImVec2{ 1, 0 });
|
||||||
|
|
||||||
|
if (ImGui::BeginDragDropTarget()) {
|
||||||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("CONTENT_BROWSER_PAYLOAD")) {
|
||||||
|
std::filesystem::path path = (const char*)payload->Data;
|
||||||
|
if (path.extension() == ".oes")
|
||||||
|
OpenScene(path);
|
||||||
|
}
|
||||||
|
ImGui::EndDragDropTarget();
|
||||||
|
}
|
||||||
|
|
||||||
viewport_bounds[0] = { imgui_cursor_position.x, imgui_cursor_position.y };
|
viewport_bounds[0] = { imgui_cursor_position.x, imgui_cursor_position.y };
|
||||||
viewport_bounds[1] = { imgui_cursor_position.x + viewport_size.x,
|
viewport_bounds[1] = { imgui_cursor_position.x + viewport_size.x,
|
||||||
imgui_cursor_position.y + viewport_size.y };
|
imgui_cursor_position.y + viewport_size.y };
|
||||||
@@ -337,6 +358,18 @@ namespace OpenEngine {
|
|||||||
guizmo_operation = -1;
|
guizmo_operation = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void OpenScene(const std::string& file)
|
||||||
|
{
|
||||||
|
if (!file.empty()) {
|
||||||
|
scene = CreateRef<Scene>();
|
||||||
|
scene->OnViewportResize((uint32_t)viewport_size.x, (uint32_t)viewport_size.y);
|
||||||
|
scene_hierarchy.Init(scene);
|
||||||
|
|
||||||
|
SceneSerializer serializer(scene);
|
||||||
|
serializer.Deserialize(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OnImGuiRender() override
|
void OnImGuiRender() override
|
||||||
{
|
{
|
||||||
OE_PROFILE_FUNCTION();
|
OE_PROFILE_FUNCTION();
|
||||||
@@ -355,15 +388,8 @@ namespace OpenEngine {
|
|||||||
}
|
}
|
||||||
if (ImGui::MenuItem("Open Scene", "Ctrl+O")) {
|
if (ImGui::MenuItem("Open Scene", "Ctrl+O")) {
|
||||||
std::string file = FileDialogs::OpenFile("useless");
|
std::string file = FileDialogs::OpenFile("useless");
|
||||||
OE_DEBUG("loading filename: {}", file);
|
OE_DEBUG("loading scene: {}", file);
|
||||||
if (!file.empty()) {
|
OpenScene(file);
|
||||||
scene = CreateRef<Scene>();
|
|
||||||
scene->OnViewportResize((uint32_t)viewport_size.x, (uint32_t)viewport_size.y);
|
|
||||||
scene_hierarchy.Init(scene);
|
|
||||||
|
|
||||||
SceneSerializer serializer(scene);
|
|
||||||
serializer.Deserialize(file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (ImGui::MenuItem("New Scene", "Ctrl+N")) {
|
if (ImGui::MenuItem("New Scene", "Ctrl+N")) {
|
||||||
scene = CreateRef<Scene>();
|
scene = CreateRef<Scene>();
|
||||||
@@ -383,6 +409,7 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
DrawStats();
|
DrawStats();
|
||||||
scene_hierarchy.OnImGuiRender();
|
scene_hierarchy.OnImGuiRender();
|
||||||
|
brower.OnImGuiRender();
|
||||||
DrawViewport();
|
DrawViewport();
|
||||||
|
|
||||||
ImGui::ShowDemoWindow();
|
ImGui::ShowDemoWindow();
|
||||||
@@ -390,6 +417,7 @@ namespace OpenEngine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ContentBrowserPanel brower;
|
||||||
std::vector<Time::ProfilingResult> profiling_results;
|
std::vector<Time::ProfilingResult> profiling_results;
|
||||||
|
|
||||||
glm::vec2 world_pos_cursor = { 0.0f, 0.0f };
|
glm::vec2 world_pos_cursor = { 0.0f, 0.0f };
|
||||||
@@ -406,13 +434,15 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
Ref<Scene> scene;
|
Ref<Scene> scene;
|
||||||
Entity selected_entity;
|
Entity selected_entity;
|
||||||
|
|
||||||
|
std::vector<Entity> entities;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class EditorApp : public OpenEngine::Application
|
class EditorApp : public OpenEngine::Application
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EditorApp();
|
EditorApp(OpenEngine::ApplicationCommandLineArgs args);
|
||||||
~EditorApp();
|
~EditorApp();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
23
editor/include/panels/content_browser.hpp
Normal file
23
editor/include/panels/content_browser.hpp
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef CONTENT_BROWSER_HPP
|
||||||
|
#define CONTENT_BROWSER_HPP
|
||||||
|
|
||||||
|
#include "open_engine/renderer/texture.hpp"
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace OpenEngine {
|
||||||
|
|
||||||
|
class ContentBrowserPanel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ContentBrowserPanel();
|
||||||
|
|
||||||
|
void OnImGuiRender();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::filesystem::path current_directory;
|
||||||
|
Ref<Texture2D> folder_icon;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CONTENT_BROWSER_HPP
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "open_engine/application.hpp"
|
||||||
#include <open_engine/entry_point.hpp>
|
#include <open_engine/entry_point.hpp>
|
||||||
|
|
||||||
#include <open_engine.hpp>
|
#include <open_engine.hpp>
|
||||||
@@ -9,8 +10,8 @@
|
|||||||
#include <overlay.hpp>
|
#include <overlay.hpp>
|
||||||
#include <modding.hpp>
|
#include <modding.hpp>
|
||||||
|
|
||||||
EditorApp::EditorApp()
|
EditorApp::EditorApp(OpenEngine::ApplicationCommandLineArgs args)
|
||||||
: Application("OpenEngine Editor")
|
: Application("OpenEngine Editor", args)
|
||||||
{
|
{
|
||||||
OpenEngine::Ref<OpenEngine::Layer> modding_layer = OpenEngine::CreateRef<Modding>();
|
OpenEngine::Ref<OpenEngine::Layer> modding_layer = OpenEngine::CreateRef<Modding>();
|
||||||
OpenEngine::Ref<OpenEngine::Layer> editor_layer = OpenEngine::CreateRef<OpenEngine::EditorLayer>();
|
OpenEngine::Ref<OpenEngine::Layer> editor_layer = OpenEngine::CreateRef<OpenEngine::EditorLayer>();
|
||||||
@@ -25,8 +26,8 @@ EditorApp::~EditorApp()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenEngine::Application* OpenEngine::CreateApplication()
|
OpenEngine::Application* OpenEngine::CreateApplication(OpenEngine::ApplicationCommandLineArgs args)
|
||||||
{
|
{
|
||||||
OE_INFO("Editor Starting...");
|
OE_INFO("Editor Starting...");
|
||||||
return new EditorApp();
|
return new EditorApp(args);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "imgui.h"
|
||||||
#include <editor_component.hpp>
|
#include <editor_component.hpp>
|
||||||
#include <open_engine.hpp>
|
#include <open_engine.hpp>
|
||||||
|
|
||||||
@@ -106,6 +107,16 @@ namespace OpenEngine {
|
|||||||
{
|
{
|
||||||
auto& sprite = registry.get<SpriteRendererComponent>(entity);
|
auto& sprite = registry.get<SpriteRendererComponent>(entity);
|
||||||
ImGui::ColorEdit4("color", glm::value_ptr(sprite.color));
|
ImGui::ColorEdit4("color", glm::value_ptr(sprite.color));
|
||||||
|
ImGui::Button("Texture", { 100, 0 });
|
||||||
|
|
||||||
|
if (ImGui::BeginDragDropTarget()) {
|
||||||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("CONTENT_BROWSER_PAYLOAD"))
|
||||||
|
sprite.texture = Texture2D::Create(((const char*)payload->Data));
|
||||||
|
|
||||||
|
ImGui::EndDragDropTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::DragFloat("Tiling factor", &sprite.tiling_factor);
|
||||||
};
|
};
|
||||||
|
|
||||||
void CameraOnImGuiRender(entt::registry& registry, entt::entity entity)
|
void CameraOnImGuiRender(entt::registry& registry, entt::entity entity)
|
||||||
|
|||||||
88
editor/src/panels/content_browser.cpp
Normal file
88
editor/src/panels/content_browser.cpp
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#include "imgui_internal.h"
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <panels/content_browser.hpp>
|
||||||
|
|
||||||
|
#include <open_engine/renderer/texture.hpp>
|
||||||
|
#include <open_engine/logging.hpp>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace OpenEngine {
|
||||||
|
|
||||||
|
const std::filesystem::path assets_directory = "assets";
|
||||||
|
|
||||||
|
ContentBrowserPanel::ContentBrowserPanel()
|
||||||
|
: current_directory(assets_directory)
|
||||||
|
{
|
||||||
|
// TODO: Add file texture. Get free icons and add license
|
||||||
|
folder_icon = Texture2D::Create("resources/textures/folder.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentBrowserPanel::OnImGuiRender()
|
||||||
|
{
|
||||||
|
ImGui::Begin("Assets");
|
||||||
|
|
||||||
|
ImGui::Text("%s", current_directory.c_str());
|
||||||
|
|
||||||
|
if (current_directory != assets_directory)
|
||||||
|
if (ImGui::Button(".."))
|
||||||
|
current_directory = current_directory.parent_path();
|
||||||
|
|
||||||
|
auto directory_it = std::filesystem::directory_iterator(current_directory);
|
||||||
|
|
||||||
|
ImVec2 button_size = { 100, 100 };
|
||||||
|
auto panel_width = ImGui::GetContentRegionAvail().x;
|
||||||
|
uint32_t table_columns = (int)(panel_width / button_size.x) - 1;
|
||||||
|
|
||||||
|
if (table_columns <= 0)
|
||||||
|
table_columns = 1;
|
||||||
|
|
||||||
|
ImVec2 padding( 9, 9 );
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, padding);
|
||||||
|
|
||||||
|
if (ImGui::BeginTable("table1", table_columns, ImGuiTableFlags_SizingFixedSame))
|
||||||
|
{
|
||||||
|
for (auto& entry : directory_it) {
|
||||||
|
auto file_name = entry.path().filename().string();
|
||||||
|
|
||||||
|
ImGui::PushID(file_name.c_str());
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, { 0.0f, 0.0f, 0.0f, 0.0f });
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 0.192f, 0.196f, 0.266f, 1.0f });
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.270f, 0.278f, 0.352f, 1.0f });
|
||||||
|
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::ImageButton("##X", (ImTextureID)folder_icon->GetID(), button_size, { 0, 1 }, { 1, 0 });
|
||||||
|
if (entry.is_regular_file() && ImGui::BeginDragDropSource()) {
|
||||||
|
const char* source = entry.path().c_str();
|
||||||
|
ImGui::SetDragDropPayload("CONTENT_BROWSER_PAYLOAD", source, (strlen(source) + 1) * sizeof(char), ImGuiCond_Once);
|
||||||
|
|
||||||
|
ImGui::EndDragDropSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
float columnWidth = ImGui::GetColumnWidth();
|
||||||
|
float textWidth = ImGui::CalcTextSize(file_name.c_str()).x;
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (columnWidth - textWidth) * 0.5f);
|
||||||
|
ImGui::TextWrapped("%s", file_name.c_str());
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
if (entry.is_directory()) {
|
||||||
|
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||||
|
current_directory = entry.path().c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopStyleColor(3);
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,10 +10,25 @@
|
|||||||
int main(int argc, char **argv);
|
int main(int argc, char **argv);
|
||||||
|
|
||||||
namespace OpenEngine {
|
namespace OpenEngine {
|
||||||
|
|
||||||
|
struct ApplicationCommandLineArgs
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
char** args = nullptr;
|
||||||
|
|
||||||
|
const char* operator[](int index)
|
||||||
|
{
|
||||||
|
OE_CORE_ASSERT(index < count, "Index is higher than argument count.");
|
||||||
|
|
||||||
|
return args[index];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
class Application
|
class Application
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Application(const std::string& name = "OpenEngine Project");
|
Application(const std::string& name,
|
||||||
|
ApplicationCommandLineArgs& args);
|
||||||
~Application();
|
~Application();
|
||||||
|
|
||||||
virtual void OnEvent(Event& event);
|
virtual void OnEvent(Event& event);
|
||||||
@@ -25,6 +40,7 @@ namespace OpenEngine {
|
|||||||
ImGuiLayer* GetImGuiLayer() { return imgui_layer.get(); };
|
ImGuiLayer* GetImGuiLayer() { return imgui_layer.get(); };
|
||||||
|
|
||||||
inline static Application& Get() { return *instance; };
|
inline static Application& Get() { return *instance; };
|
||||||
|
ApplicationCommandLineArgs GetCommandLineArgs() const { return arguments; };
|
||||||
|
|
||||||
inline Window& GetWindow() { return *window; };
|
inline Window& GetWindow() { return *window; };
|
||||||
|
|
||||||
@@ -36,6 +52,7 @@ namespace OpenEngine {
|
|||||||
bool OnWindowResize(WindowResizeEvent& event);
|
bool OnWindowResize(WindowResizeEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ApplicationCommandLineArgs arguments;
|
||||||
const std::string name;
|
const std::string name;
|
||||||
std::unique_ptr<Window> window;
|
std::unique_ptr<Window> window;
|
||||||
|
|
||||||
@@ -49,7 +66,7 @@ namespace OpenEngine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Is defined by client
|
// Is defined by client
|
||||||
Application* CreateApplication();
|
Application* CreateApplication(ApplicationCommandLineArgs args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // APPLICATION_HPP
|
#endif // APPLICATION_HPP
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
#ifndef ENTRY_POINT_HPP
|
#ifndef ENTRY_POINT_HPP
|
||||||
#define ENTRY_POINT_HPP
|
#define ENTRY_POINT_HPP
|
||||||
|
|
||||||
#include "open_engine/core.hpp"
|
|
||||||
#include "open_engine/application.hpp"
|
#include "open_engine/application.hpp"
|
||||||
#include "open_engine/logging.hpp"
|
#include "open_engine/logging.hpp"
|
||||||
|
|
||||||
extern OpenEngine::Application* OpenEngine::CreateApplication();
|
extern OpenEngine::Application* OpenEngine::CreateApplication(OpenEngine::ApplicationCommandLineArgs args);
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
OE_PROFILE_BEGIN_SESSION("Startup", "open_engine-startup.json");
|
OE_PROFILE_BEGIN_SESSION("Startup", "open_engine-startup.json");
|
||||||
OpenEngine::Logger::Init();
|
OpenEngine::Logger::Init();
|
||||||
auto app = OpenEngine::CreateApplication();
|
auto app = OpenEngine::CreateApplication({ argc, argv });
|
||||||
OE_PROFILE_END_SESSION();
|
OE_PROFILE_END_SESSION();
|
||||||
|
|
||||||
OE_PROFILE_BEGIN_SESSION("Runtime", "open_engine-runtime.json");
|
OE_PROFILE_BEGIN_SESSION("Runtime", "open_engine-runtime.json");
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace OpenEngine {
|
|||||||
public:
|
public:
|
||||||
OpenGLShader(const std::string& shader_path);
|
OpenGLShader(const std::string& shader_path);
|
||||||
OpenGLShader(const std::string& name, const std::string& vertex_src, const std::string& frament_src);
|
OpenGLShader(const std::string& name, const std::string& vertex_src, const std::string& frament_src);
|
||||||
virtual ~OpenGLShader() = default;
|
virtual ~OpenGLShader();
|
||||||
|
|
||||||
virtual const std::string& GetName() const override { return name; };
|
virtual const std::string& GetName() const override { return name; };
|
||||||
|
|
||||||
@@ -44,11 +44,21 @@ namespace OpenEngine {
|
|||||||
private:
|
private:
|
||||||
std::string ReadFile(const std::string& shader_path);
|
std::string ReadFile(const std::string& shader_path);
|
||||||
std::unordered_map<GLenum, std::string> PreProcess(const std::string& shader_source);
|
std::unordered_map<GLenum, std::string> PreProcess(const std::string& shader_source);
|
||||||
void Compile(const std::unordered_map<GLenum, std::string> sources);
|
|
||||||
|
|
||||||
void CheckCompileErrors(unsigned int shader, const std::string& type);
|
void CompileOrGetVulkanBinaries(const std::unordered_map<GLenum, std::string>& shader_sources);
|
||||||
|
void CompileOrGetOpenGLBinaries();
|
||||||
|
void CreateProgram();
|
||||||
|
void Reflect(GLenum stage, const std::vector<uint32_t>& shader_data);
|
||||||
|
//void CheckCompileErrors(unsigned int shader, const std::string& type);
|
||||||
|
|
||||||
|
private:
|
||||||
std::string name;
|
std::string name;
|
||||||
|
std::string file_path;
|
||||||
|
|
||||||
|
std::unordered_map<GLenum, std::vector<uint32_t>> vulkan_spirv;
|
||||||
|
std::unordered_map<GLenum, std::vector<uint32_t>> opengl_spirv;
|
||||||
|
|
||||||
|
std::unordered_map<GLenum, std::string> m_OpenGLSourceCode;
|
||||||
|
|
||||||
u_int32_t id;
|
u_int32_t id;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef OPENGL_UNIFORM_BUFFER_HPP
|
||||||
|
#define OPENGL_UNIFORM_BUFFER_HPP
|
||||||
|
|
||||||
|
#include "open_engine/renderer/uniform_buffer.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace OpenEngine {
|
||||||
|
|
||||||
|
class OpenGLUniformBuffer : public UniformBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpenGLUniformBuffer(uint32_t size, uint32_t binding);
|
||||||
|
virtual ~OpenGLUniformBuffer();
|
||||||
|
|
||||||
|
virtual void SetData(const void* data, uint32_t size,
|
||||||
|
uint32_t offset = 0) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t id = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // OPENGL_UNIFORM_BUFFER_HPP
|
||||||
@@ -44,6 +44,9 @@ namespace OpenEngine {
|
|||||||
static void DrawQuad(const Transform& transform_data,
|
static void DrawQuad(const Transform& transform_data,
|
||||||
const Ref<Texture2D>& texture, int entity_id,
|
const Ref<Texture2D>& texture, int entity_id,
|
||||||
float tiling_factor = 1.0f);
|
float tiling_factor = 1.0f);
|
||||||
|
static void DrawQuad(const Transform& transform_data,
|
||||||
|
const Ref<Texture2D>& texture, const glm::vec4& color,
|
||||||
|
int entity_id, float tiling_factor = 1.0f);
|
||||||
static void DrawQuad(const Transform& transform_data,
|
static void DrawQuad(const Transform& transform_data,
|
||||||
const Ref<Subtexture2D>& subtexture, int entity_id,
|
const Ref<Subtexture2D>& subtexture, int entity_id,
|
||||||
float tiling_factor = 1.0f);
|
float tiling_factor = 1.0f);
|
||||||
@@ -53,6 +56,9 @@ namespace OpenEngine {
|
|||||||
static void DrawQuad(const glm::mat4& transform,
|
static void DrawQuad(const glm::mat4& transform,
|
||||||
const Ref<Texture2D>& texture, int entity_id,
|
const Ref<Texture2D>& texture, int entity_id,
|
||||||
float tiling_factor = 1.0f);
|
float tiling_factor = 1.0f);
|
||||||
|
static void DrawQuad(const glm::mat4& transform,
|
||||||
|
const Ref<Texture2D>& texture, const glm::vec4& color,
|
||||||
|
int entity_id, float tiling_factor = 1.0f);
|
||||||
static void DrawQuad(const glm::mat4& transform,
|
static void DrawQuad(const glm::mat4& transform,
|
||||||
const Ref<Subtexture2D>& subtexture, int entity_id,
|
const Ref<Subtexture2D>& subtexture, int entity_id,
|
||||||
float tiling_factor = 1.0f);
|
float tiling_factor = 1.0f);
|
||||||
|
|||||||
21
open_engine/include/open_engine/renderer/uniform_buffer.cpp
Normal file
21
open_engine/include/open_engine/renderer/uniform_buffer.cpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include <pch.hpp>
|
||||||
|
|
||||||
|
#include <renderer/uniform_buffer.hpp>
|
||||||
|
#include <opengl/opengl_uniform_buffer.hpp>
|
||||||
|
#include <renderer/renderer.hpp>
|
||||||
|
|
||||||
|
namespace OpenEngine {
|
||||||
|
|
||||||
|
Ref<UniformBuffer> UniformBuffer::Create(uint32_t size, uint32_t binding)
|
||||||
|
{
|
||||||
|
switch (Renderer::GetAPI())
|
||||||
|
{
|
||||||
|
case RendererAPI::API::None: OE_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr;
|
||||||
|
case RendererAPI::API::OpenGL: return CreateRef<OpenGLUniformBuffer>(size, binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
OE_CORE_ASSERT(false, "Unknown RendererAPI!");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
20
open_engine/include/open_engine/renderer/uniform_buffer.hpp
Normal file
20
open_engine/include/open_engine/renderer/uniform_buffer.hpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef UNIFORM_BUFFER_HPP
|
||||||
|
#define UNIFORM_BUFFER_HPP
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <glm/fwd.hpp>
|
||||||
|
namespace OpenEngine {
|
||||||
|
|
||||||
|
class UniformBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~UniformBuffer() {}
|
||||||
|
virtual void SetData(const void* data, uint32_t size,
|
||||||
|
uint32_t offset = 0) = 0;
|
||||||
|
|
||||||
|
static Ref<UniformBuffer> Create(uint32_t size, uint32_t binding);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // UNIFORM_BUFFER_HPP
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "open_engine/scene/native_scriptable_entity.hpp"
|
#include "open_engine/scene/native_scriptable_entity.hpp"
|
||||||
#include "open_engine/scene/scene_camera.hpp"
|
#include "open_engine/scene/scene_camera.hpp"
|
||||||
|
#include "open_engine/renderer/texture.hpp"
|
||||||
|
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
@@ -45,6 +46,8 @@ namespace OpenEngine {
|
|||||||
struct SpriteRendererComponent
|
struct SpriteRendererComponent
|
||||||
{
|
{
|
||||||
glm::vec4 color{ 1.0f, 1.0f, 1.0f, 1.0f };
|
glm::vec4 color{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
|
Ref<Texture2D> texture;
|
||||||
|
float tiling_factor = 1.0f;
|
||||||
|
|
||||||
SpriteRendererComponent() = default;
|
SpriteRendererComponent() = default;
|
||||||
SpriteRendererComponent(const SpriteRendererComponent&) = default;
|
SpriteRendererComponent(const SpriteRendererComponent&) = default;
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ namespace OpenEngine {
|
|||||||
T& AddComponents(Args&&... args)
|
T& AddComponents(Args&&... args)
|
||||||
{
|
{
|
||||||
OE_ASSERT(!HasComponent<T>(), "Entity already has component.");
|
OE_ASSERT(!HasComponent<T>(), "Entity already has component.");
|
||||||
return scene->registry.emplace<T>(handle, std::forward<Args>(args)...);
|
|
||||||
|
T& component = scene->registry.emplace<T>(handle, std::forward<Args>(args)...);
|
||||||
|
scene->OnComponentAdded(*this, component);
|
||||||
|
return component;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename ... Args>
|
template<typename T, typename ... Args>
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
Entity GetPrimaryCamera();
|
Entity GetPrimaryCamera();
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename T>
|
||||||
|
void OnComponentAdded(Entity entity, T& component);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
entt::registry registry;
|
entt::registry registry;
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,9 @@
|
|||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
namespace OpenEngine {
|
namespace OpenEngine {
|
||||||
Application::Application(const std::string& name)
|
Application::Application(const std::string& name,
|
||||||
: name(name)
|
ApplicationCommandLineArgs& args)
|
||||||
|
: name(name), arguments(args)
|
||||||
{
|
{
|
||||||
OE_PROFILE_FUNCTION();
|
OE_PROFILE_FUNCTION();
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,117 @@
|
|||||||
#include <pch.hpp>
|
#include <pch.hpp>
|
||||||
|
|
||||||
#include <opengl/opengl_shader.hpp>
|
|
||||||
|
|
||||||
#include <core.hpp>
|
#include <core.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <opengl/opengl_shader.hpp>
|
||||||
|
#include <instrumentor.hpp>
|
||||||
|
#include <core/time.hpp>
|
||||||
#include <logging.hpp>
|
#include <logging.hpp>
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
|
#include <shaderc/shaderc.hpp>
|
||||||
|
#include <spirv_cross/spirv_cross.hpp>
|
||||||
|
#include <spirv_cross/spirv_glsl.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <filesystem>
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <alloca.h>
|
//#include <alloca.h>
|
||||||
#include <cstddef>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
namespace OpenEngine {
|
namespace OpenEngine {
|
||||||
static GLenum ShaderTypeFromString(const std::string& type)
|
|
||||||
|
namespace Utils {
|
||||||
|
|
||||||
|
static GLenum ShaderTypeFromString(const std::string& type)
|
||||||
|
{
|
||||||
|
if (type == "vertex")
|
||||||
|
return GL_VERTEX_SHADER;
|
||||||
|
if (type == "fragment" || type == "pixel")
|
||||||
|
return GL_FRAGMENT_SHADER;
|
||||||
|
|
||||||
|
OE_CORE_ASSERT(false, "Unknown shader type!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static shaderc_shader_kind GLShaderStageToShaderC(GLenum stage)
|
||||||
|
{
|
||||||
|
switch (stage)
|
||||||
|
{
|
||||||
|
case GL_VERTEX_SHADER: return shaderc_glsl_vertex_shader;
|
||||||
|
case GL_FRAGMENT_SHADER: return shaderc_glsl_fragment_shader;
|
||||||
|
}
|
||||||
|
OE_CORE_ASSERT(false, "No");
|
||||||
|
return (shaderc_shader_kind)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* GLShaderStageToString(GLenum stage)
|
||||||
|
{
|
||||||
|
switch (stage)
|
||||||
|
{
|
||||||
|
case GL_VERTEX_SHADER: return "GL_VERTEX_SHADER";
|
||||||
|
case GL_FRAGMENT_SHADER: return "GL_FRAGMENT_SHADER";
|
||||||
|
}
|
||||||
|
OE_CORE_ASSERT(false, "No");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* GetCacheDirectory()
|
||||||
|
{
|
||||||
|
// TODO: make sure the assets directory is valid
|
||||||
|
return "assets/cache/shader/opengl";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateCacheDirectoryIfNeeded()
|
||||||
|
{
|
||||||
|
std::string cache_directory = GetCacheDirectory();
|
||||||
|
if (!std::filesystem::exists(cache_directory))
|
||||||
|
std::filesystem::create_directories(cache_directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* GLShaderStageCachedOpenGLFileExtension(uint32_t stage)
|
||||||
|
{
|
||||||
|
switch (stage)
|
||||||
|
{
|
||||||
|
case GL_VERTEX_SHADER: return ".cached_opengl.vert";
|
||||||
|
case GL_FRAGMENT_SHADER: return ".cached_opengl.frag";
|
||||||
|
}
|
||||||
|
OE_CORE_ASSERT(false, "No");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* GLShaderStageCachedVulkanFileExtension(uint32_t stage)
|
||||||
|
{
|
||||||
|
switch (stage)
|
||||||
|
{
|
||||||
|
case GL_VERTEX_SHADER: return ".cached_vulkan.vert";
|
||||||
|
case GL_FRAGMENT_SHADER: return ".cached_vulkan.frag";
|
||||||
|
}
|
||||||
|
OE_CORE_ASSERT(false, "No");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLShader::OpenGLShader(const std::string& filepath)
|
||||||
|
: file_path(filepath)
|
||||||
{
|
{
|
||||||
if (type == "vertex")
|
OE_PROFILE_FUNCTION();
|
||||||
return GL_VERTEX_SHADER;
|
|
||||||
if (type == "fragment" || type == "pixel")
|
|
||||||
return GL_FRAGMENT_SHADER;
|
|
||||||
|
|
||||||
OE_CORE_ERROR("Could not compile shader! Unkown shader type: {}", type);
|
Utils::CreateCacheDirectoryIfNeeded();
|
||||||
|
|
||||||
return 0;
|
std::string source = ReadFile(filepath);
|
||||||
|
auto shader_sources = PreProcess(source);
|
||||||
|
|
||||||
|
{
|
||||||
|
CompileOrGetVulkanBinaries(shader_sources);
|
||||||
|
CompileOrGetOpenGLBinaries();
|
||||||
|
CreateProgram();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract name from filepath
|
||||||
|
auto last_slash = filepath.find_last_of("/\\");
|
||||||
|
last_slash = last_slash == std::string::npos ? 0 : last_slash + 1;
|
||||||
|
auto lastDot = filepath.rfind('.');
|
||||||
|
auto count = lastDot == std::string::npos ? filepath.size() - last_slash : lastDot - last_slash;
|
||||||
|
name = filepath.substr(last_slash, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLShader::OpenGLShader(const std::string& name, const std::string& vertex_src, const std::string& fragment_src)
|
OpenGLShader::OpenGLShader(const std::string& name, const std::string& vertex_src, const std::string& fragment_src)
|
||||||
@@ -34,163 +123,263 @@ namespace OpenEngine {
|
|||||||
sources[GL_VERTEX_SHADER] = vertex_src;
|
sources[GL_VERTEX_SHADER] = vertex_src;
|
||||||
sources[GL_FRAGMENT_SHADER] = fragment_src;
|
sources[GL_FRAGMENT_SHADER] = fragment_src;
|
||||||
|
|
||||||
Compile(sources);
|
CompileOrGetVulkanBinaries(sources);
|
||||||
|
CompileOrGetOpenGLBinaries();
|
||||||
|
CreateProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLShader::OpenGLShader(const std::string& shader_path)
|
OpenGLShader::~OpenGLShader()
|
||||||
{
|
{
|
||||||
OE_PROFILE_FUNCTION();
|
OE_PROFILE_FUNCTION();
|
||||||
|
|
||||||
{
|
glDeleteProgram(id);
|
||||||
OE_PROFILE_SCOPE("Compiling Shader");
|
|
||||||
std::string source = ReadFile(shader_path);
|
|
||||||
auto shader_sources = PreProcess(source);
|
|
||||||
Compile(shader_sources);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Getting file name
|
|
||||||
auto last_slash = shader_path.find_last_of("/\\");
|
|
||||||
last_slash = last_slash == std::string::npos ? 0 : last_slash + 1;
|
|
||||||
auto last_dot = shader_path.rfind('.');
|
|
||||||
|
|
||||||
auto count = last_dot == std::string::npos ? shader_path.size() - last_slash : last_dot - last_slash;
|
|
||||||
name = shader_path.substr(last_slash, count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLShader::Compile(const std::unordered_map<GLenum, std::string> sources)
|
std::string OpenGLShader::ReadFile(const std::string& filepath)
|
||||||
{
|
|
||||||
OE_PROFILE_FUNCTION();
|
|
||||||
|
|
||||||
GLuint program = glCreateProgram();
|
|
||||||
GLenum *gl_shader_ids = (GLenum*)alloca(sources.size());
|
|
||||||
|
|
||||||
size_t shader_index = 0;
|
|
||||||
for (auto& kv_pair : sources)
|
|
||||||
{
|
|
||||||
GLenum type = kv_pair.first;
|
|
||||||
const std::string& source = kv_pair.second;
|
|
||||||
|
|
||||||
GLuint shader = glCreateShader(type);
|
|
||||||
|
|
||||||
const GLchar* source_cstr = source.c_str();
|
|
||||||
glShaderSource(shader, 1, &source_cstr, 0);
|
|
||||||
|
|
||||||
glCompileShader(shader);
|
|
||||||
|
|
||||||
GLint is_compiled = 0;
|
|
||||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &is_compiled);
|
|
||||||
if (is_compiled == GL_FALSE)
|
|
||||||
{
|
|
||||||
GLint max_length = 0;
|
|
||||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &max_length);
|
|
||||||
|
|
||||||
std::vector<GLchar> info_log(max_length);
|
|
||||||
glGetShaderInfoLog(shader, max_length, &max_length, &info_log[0]);
|
|
||||||
|
|
||||||
glDeleteShader(shader);
|
|
||||||
|
|
||||||
OE_CORE_ERROR("{0}", info_log.data());
|
|
||||||
OE_CORE_ERROR("Shader compilation failure!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
glAttachShader(program, shader);
|
|
||||||
gl_shader_ids[shader_index++] = shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
id = program;
|
|
||||||
|
|
||||||
glLinkProgram(program);
|
|
||||||
|
|
||||||
GLint is_linked = 0;
|
|
||||||
glGetProgramiv(program, GL_LINK_STATUS, (int*)&is_linked);
|
|
||||||
if (is_linked == GL_FALSE)
|
|
||||||
{
|
|
||||||
GLint max_length = 0;
|
|
||||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &max_length);
|
|
||||||
|
|
||||||
// The maxLength includes the NULL character
|
|
||||||
std::vector<GLchar> infoLog(max_length);
|
|
||||||
glGetProgramInfoLog(program, max_length, &max_length, &infoLog[0]);
|
|
||||||
|
|
||||||
// We don't need the program anymore.
|
|
||||||
glDeleteProgram(program);
|
|
||||||
|
|
||||||
for (int i = 0; i < sources.size(); i++)
|
|
||||||
glDeleteShader(gl_shader_ids[i]);
|
|
||||||
|
|
||||||
OE_CORE_ERROR("{0}", infoLog.data());
|
|
||||||
OE_CORE_ERROR("Shader link failure!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < sources.size(); i++) {
|
|
||||||
glDetachShader(program, gl_shader_ids[i]);
|
|
||||||
glDeleteShader(gl_shader_ids[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unordered_map<GLenum, std::string> OpenGLShader::PreProcess(const std::string& shader_source)
|
|
||||||
{
|
|
||||||
OE_PROFILE_FUNCTION();
|
|
||||||
|
|
||||||
// TODO: Perhaps consider using getline to get the position of errors. or even regexes
|
|
||||||
std::unordered_map<GLenum, std::string> sources;
|
|
||||||
const char* type_token = "#type";
|
|
||||||
|
|
||||||
size_t type_token_lenght = strlen(type_token);
|
|
||||||
size_t pos = shader_source.find(type_token, 0);
|
|
||||||
while (pos != std::string::npos) {
|
|
||||||
size_t eol = shader_source.find("\n", pos);
|
|
||||||
if (eol == std::string::npos)
|
|
||||||
OE_CORE_ERROR("Syntax error.");
|
|
||||||
size_t begin = pos + type_token_lenght + 1;
|
|
||||||
std::string type = shader_source.substr(begin, eol - begin);
|
|
||||||
if (type != "vertex" && type != "fragment" && type != "pixel")
|
|
||||||
OE_CORE_ERROR("Invalid shader type.");
|
|
||||||
|
|
||||||
size_t next_line_pos = shader_source.find_first_not_of("\n", eol);
|
|
||||||
pos = shader_source.find(type_token, next_line_pos);
|
|
||||||
sources[ShaderTypeFromString(type)] =
|
|
||||||
shader_source.substr(next_line_pos, pos - (next_line_pos == std::string::npos ? shader_source.size() - 1 : next_line_pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
return sources;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string OpenGLShader::ReadFile(const std::string& shader_path)
|
|
||||||
{
|
{
|
||||||
OE_PROFILE_FUNCTION();
|
OE_PROFILE_FUNCTION();
|
||||||
|
|
||||||
std::string result;
|
std::string result;
|
||||||
|
std::ifstream in(filepath, std::ios::in | std::ios::binary); // ifstream closes itself due to RAII
|
||||||
std::ifstream input(shader_path);
|
if (in)
|
||||||
if (input) {
|
{
|
||||||
input.seekg(0, std::ios::end);
|
in.seekg(0, std::ios::end);
|
||||||
|
size_t size = in.tellg();
|
||||||
size_t size = input.tellg();
|
if (size != -1)
|
||||||
if (size != -1) {
|
{
|
||||||
result.resize(size);
|
result.resize(size);
|
||||||
input.seekg(0, std::ios::beg);
|
in.seekg(0, std::ios::beg);
|
||||||
input.read(&result[0], result.size());
|
in.read(&result[0], size);
|
||||||
input.close();
|
|
||||||
} else {
|
|
||||||
OE_CORE_ERROR("Could not read from file {}", shader_path);
|
|
||||||
}
|
}
|
||||||
} else {
|
else
|
||||||
OE_CORE_ERROR("Shader file could not be open or does not exist: {}", shader_path);
|
{
|
||||||
|
OE_CORE_ERROR("Could not read from file '{0}'", filepath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OE_CORE_ERROR("Could not open file '{0}'", filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unordered_map<GLenum, std::string> OpenGLShader::PreProcess(const std::string& source)
|
||||||
|
{
|
||||||
|
OE_PROFILE_FUNCTION();
|
||||||
|
|
||||||
|
std::unordered_map<GLenum, std::string> shader_sources;
|
||||||
|
|
||||||
|
const char* type_token = "#type";
|
||||||
|
size_t type_token_length = strlen(type_token);
|
||||||
|
size_t pos = source.find(type_token, 0); //Start of shader type declaration line
|
||||||
|
while (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
size_t eol = source.find_first_of("\r\n", pos); //End of shader type declaration line
|
||||||
|
OE_CORE_ASSERT(eol != std::string::npos, "Syntax error");
|
||||||
|
size_t begin = pos + type_token_length + 1; //Start of shader type name (after "#type " keyword)
|
||||||
|
std::string type = source.substr(begin, eol - begin);
|
||||||
|
OE_CORE_ASSERT(Utils::ShaderTypeFromString(type), "Invalid shader type specified");
|
||||||
|
|
||||||
|
size_t next_line_pos = source.find_first_not_of("\r\n", eol); //Start of shader code after shader type declaration line
|
||||||
|
OE_CORE_ASSERT(next_line_pos != std::string::npos, "Syntax error");
|
||||||
|
pos = source.find(type_token, next_line_pos); //Start of next shader type declaration line
|
||||||
|
|
||||||
|
shader_sources[Utils::ShaderTypeFromString(type)] = (pos == std::string::npos) ? source.substr(next_line_pos) : source.substr(next_line_pos, pos - next_line_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader_sources;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLShader::CompileOrGetVulkanBinaries(const std::unordered_map<GLenum, std::string>& shaderSources)
|
||||||
|
{
|
||||||
|
GLuint program = glCreateProgram();
|
||||||
|
|
||||||
|
shaderc::Compiler compiler;
|
||||||
|
shaderc::CompileOptions options;
|
||||||
|
options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_2);
|
||||||
|
const bool optimize = true;
|
||||||
|
if (optimize)
|
||||||
|
options.SetOptimizationLevel(shaderc_optimization_level_performance);
|
||||||
|
|
||||||
|
std::filesystem::path cache_directory = Utils::GetCacheDirectory();
|
||||||
|
|
||||||
|
auto& shader_data = vulkan_spirv;
|
||||||
|
shader_data.clear();
|
||||||
|
for (auto&& [stage, source] : shaderSources)
|
||||||
|
{
|
||||||
|
std::filesystem::path shader_file_path = file_path;
|
||||||
|
std::filesystem::path cached_path = cache_directory / (shader_file_path.filename().string() + Utils::GLShaderStageCachedVulkanFileExtension(stage));
|
||||||
|
|
||||||
|
std::ifstream in(cached_path, std::ios::in | std::ios::binary);
|
||||||
|
if (in.is_open())
|
||||||
|
{
|
||||||
|
in.seekg(0, std::ios::end);
|
||||||
|
auto size = in.tellg();
|
||||||
|
in.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
|
auto& data = shader_data[stage];
|
||||||
|
data.resize(size / sizeof(uint32_t));
|
||||||
|
in.read((char*)data.data(), size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(source, Utils::GLShaderStageToShaderC(stage), file_path.c_str(), options);
|
||||||
|
if (module.GetCompilationStatus() != shaderc_compilation_status_success)
|
||||||
|
{
|
||||||
|
OE_CORE_ERROR(module.GetErrorMessage());
|
||||||
|
OE_CORE_ASSERT(false, "No");
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_data[stage] = std::vector<uint32_t>(module.cbegin(), module.cend());
|
||||||
|
|
||||||
|
std::ofstream out(cached_path, std::ios::out | std::ios::binary);
|
||||||
|
if (out.is_open())
|
||||||
|
{
|
||||||
|
auto& data = shader_data[stage];
|
||||||
|
out.write((char*)data.data(), data.size() * sizeof(uint32_t));
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto&& [stage, data]: shader_data)
|
||||||
|
Reflect(stage, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLShader::CompileOrGetOpenGLBinaries()
|
||||||
|
{
|
||||||
|
auto& shader_data = opengl_spirv;
|
||||||
|
|
||||||
|
shaderc::Compiler compiler;
|
||||||
|
shaderc::CompileOptions options;
|
||||||
|
options.SetTargetEnvironment(shaderc_target_env_opengl, shaderc_env_version_opengl_4_5);
|
||||||
|
const bool optimize = false;
|
||||||
|
if (optimize)
|
||||||
|
options.SetOptimizationLevel(shaderc_optimization_level_performance);
|
||||||
|
|
||||||
|
std::filesystem::path cache_directory = Utils::GetCacheDirectory();
|
||||||
|
|
||||||
|
shader_data.clear();
|
||||||
|
m_OpenGLSourceCode.clear();
|
||||||
|
for (auto&& [stage, spirv] : vulkan_spirv)
|
||||||
|
{
|
||||||
|
std::filesystem::path shader_file_path = file_path;
|
||||||
|
std::filesystem::path cached_path = cache_directory / (shader_file_path.filename().string() + Utils::GLShaderStageCachedOpenGLFileExtension(stage));
|
||||||
|
|
||||||
|
std::ifstream in(cached_path, std::ios::in | std::ios::binary);
|
||||||
|
if (in.is_open())
|
||||||
|
{
|
||||||
|
in.seekg(0, std::ios::end);
|
||||||
|
auto size = in.tellg();
|
||||||
|
in.seekg(0, std::ios::beg);
|
||||||
|
|
||||||
|
auto& data = shader_data[stage];
|
||||||
|
data.resize(size / sizeof(uint32_t));
|
||||||
|
in.read((char*)data.data(), size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spirv_cross::CompilerGLSL glsl_compiler(spirv);
|
||||||
|
m_OpenGLSourceCode[stage] = glsl_compiler.compile();
|
||||||
|
auto& source = m_OpenGLSourceCode[stage];
|
||||||
|
|
||||||
|
shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(source, Utils::GLShaderStageToShaderC(stage), file_path.c_str());
|
||||||
|
if (module.GetCompilationStatus() != shaderc_compilation_status_success)
|
||||||
|
{
|
||||||
|
OE_CORE_ERROR(module.GetErrorMessage());
|
||||||
|
OE_CORE_ASSERT(false, "No");
|
||||||
|
}
|
||||||
|
|
||||||
|
shader_data[stage] = std::vector<uint32_t>(module.cbegin(), module.cend());
|
||||||
|
|
||||||
|
std::ofstream out(cached_path, std::ios::out | std::ios::binary);
|
||||||
|
if (out.is_open())
|
||||||
|
{
|
||||||
|
auto& data = shader_data[stage];
|
||||||
|
out.write((char*)data.data(), data.size() * sizeof(uint32_t));
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLShader::CreateProgram()
|
||||||
|
{
|
||||||
|
GLuint program = glCreateProgram();
|
||||||
|
|
||||||
|
std::vector<GLuint> shader_ids;
|
||||||
|
for (auto&& [stage, spirv] : opengl_spirv)
|
||||||
|
{
|
||||||
|
GLuint shaderID = shader_ids.emplace_back(glCreateShader(stage));
|
||||||
|
glShaderBinary(1, &shaderID, GL_SHADER_BINARY_FORMAT_SPIR_V, spirv.data(), spirv.size() * sizeof(uint32_t));
|
||||||
|
glSpecializeShader(shaderID, "main", 0, nullptr, nullptr);
|
||||||
|
glAttachShader(program, shaderID);
|
||||||
|
}
|
||||||
|
|
||||||
|
glLinkProgram(program);
|
||||||
|
|
||||||
|
GLint is_linked;
|
||||||
|
glGetProgramiv(program, GL_LINK_STATUS, &is_linked);
|
||||||
|
if (is_linked == GL_FALSE)
|
||||||
|
{
|
||||||
|
GLint max_length;
|
||||||
|
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &max_length);
|
||||||
|
|
||||||
|
std::vector<GLchar> info_log(max_length);
|
||||||
|
glGetProgramInfoLog(program, max_length, &max_length, info_log.data());
|
||||||
|
OE_CORE_ERROR("Shader linking failed ({0}):\n{1}", file_path, info_log.data());
|
||||||
|
|
||||||
|
glDeleteProgram(program);
|
||||||
|
|
||||||
|
for (auto id : shader_ids)
|
||||||
|
glDeleteShader(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto id : shader_ids)
|
||||||
|
{
|
||||||
|
glDetachShader(program, id);
|
||||||
|
glDeleteShader(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
id = program;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLShader::Reflect(GLenum stage, const std::vector<uint32_t>& shader_data)
|
||||||
|
{
|
||||||
|
spirv_cross::Compiler compiler(shader_data);
|
||||||
|
spirv_cross::ShaderResources resources = compiler.get_shader_resources();
|
||||||
|
|
||||||
|
OE_CORE_TRACE("OpenGLShader::Reflect - {0} {1}", Utils::GLShaderStageToString(stage), file_path);
|
||||||
|
OE_CORE_TRACE(" {0} uniform buffers", resources.uniform_buffers.size());
|
||||||
|
OE_CORE_TRACE(" {0} resources", resources.sampled_images.size());
|
||||||
|
|
||||||
|
OE_CORE_TRACE("Uniform buffers:");
|
||||||
|
for (const auto& resource : resources.uniform_buffers)
|
||||||
|
{
|
||||||
|
const auto& buffer_type = compiler.get_type(resource.base_type_id);
|
||||||
|
uint32_t buffer_size = compiler.get_declared_struct_size(buffer_type);
|
||||||
|
uint32_t binding = compiler.get_decoration(resource.id, spv::DecorationBinding);
|
||||||
|
int member_count = buffer_type.member_types.size();
|
||||||
|
|
||||||
|
OE_CORE_TRACE(" {0}", resource.name);
|
||||||
|
OE_CORE_TRACE(" Size = {0}", buffer_size);
|
||||||
|
OE_CORE_TRACE(" Binding = {0}", binding);
|
||||||
|
OE_CORE_TRACE(" Members = {0}", member_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLShader::Bind() const
|
void OpenGLShader::Bind() const
|
||||||
{
|
{
|
||||||
|
OE_PROFILE_FUNCTION();
|
||||||
glUseProgram(id);
|
glUseProgram(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLShader::Unbind() const
|
void OpenGLShader::Unbind() const
|
||||||
{
|
{
|
||||||
|
OE_PROFILE_FUNCTION();
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,30 +464,4 @@ namespace OpenEngine {
|
|||||||
{
|
{
|
||||||
glUniform4fv(glGetUniformLocation(id, name.c_str()), 1, glm::value_ptr(value));
|
glUniform4fv(glGetUniformLocation(id, name.c_str()), 1, glm::value_ptr(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLShader::CheckCompileErrors(unsigned int shader, const std::string& type)
|
|
||||||
{
|
|
||||||
int success = GL_FALSE;
|
|
||||||
char infoLog[1024];
|
|
||||||
if (type != "PROGRAM") {
|
|
||||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
|
||||||
if (success == GL_FALSE) {
|
|
||||||
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
|
||||||
OE_CORE_ERROR("Shader of type {}, couldn't be compiled:", type);
|
|
||||||
OE_CORE_ERROR("\t{}", infoLog);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (glGetProgramiv == nullptr) {
|
|
||||||
OE_CORE_ERROR("OpenGL functions are not loaded!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
|
||||||
if (success == GL_FALSE)
|
|
||||||
{
|
|
||||||
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
|
|
||||||
OE_CORE_ERROR("Program of type {}, couldn't be compiled:", type);
|
|
||||||
OE_CORE_ERROR("\t{}", infoLog);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
27
open_engine/src/open_engine/opengl/opengl_uniform_buffer.cpp
Normal file
27
open_engine/src/open_engine/opengl/opengl_uniform_buffer.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#include <pch.hpp>
|
||||||
|
|
||||||
|
#include <opengl/opengl_uniform_buffer.hpp>
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
namespace OpenEngine {
|
||||||
|
|
||||||
|
OpenGLUniformBuffer::OpenGLUniformBuffer(uint32_t size, uint32_t binding)
|
||||||
|
{
|
||||||
|
glCreateBuffers(1, &id);
|
||||||
|
glNamedBufferData(id, size, nullptr, GL_DYNAMIC_DRAW);
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, binding, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLUniformBuffer::~OpenGLUniformBuffer()
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, &id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OpenGLUniformBuffer::SetData(const void* data, uint32_t size, uint32_t offset)
|
||||||
|
{
|
||||||
|
glNamedBufferSubData(id, offset, size, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -63,8 +63,7 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
void EditorCamera::OnUpdate()
|
void EditorCamera::OnUpdate()
|
||||||
{
|
{
|
||||||
if (Input::IsKeyPressed(Key::LeftAlt))
|
if (Input::IsKeyPressed(Key::LeftAlt)) {
|
||||||
{
|
|
||||||
const glm::vec2& mouse{ Input::GetMouseX(), Input::GetMouseY() };
|
const glm::vec2& mouse{ Input::GetMouseX(), Input::GetMouseY() };
|
||||||
glm::vec2 delta = (mouse - initial_mouse_position) * 0.003f;
|
glm::vec2 delta = (mouse - initial_mouse_position) * 0.003f;
|
||||||
initial_mouse_position = mouse;
|
initial_mouse_position = mouse;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "renderer/editor_camera.hpp"
|
#include "renderer/editor_camera.hpp"
|
||||||
|
#include "renderer/uniform_buffer.hpp"
|
||||||
#include <pch.hpp>
|
#include <pch.hpp>
|
||||||
|
|
||||||
#include <renderer/render_command.hpp>
|
#include <renderer/render_command.hpp>
|
||||||
@@ -27,7 +28,7 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
struct Renderer2DData
|
struct Renderer2DData
|
||||||
{
|
{
|
||||||
static const uint32_t max_quads = 10000;
|
static const uint32_t max_quads = 20000;
|
||||||
static const uint32_t max_vertices = max_quads * 4;
|
static const uint32_t max_vertices = max_quads * 4;
|
||||||
static const uint32_t max_indices = max_quads * 6;
|
static const uint32_t max_indices = max_quads * 6;
|
||||||
static const uint32_t max_texture_slots = 32;
|
static const uint32_t max_texture_slots = 32;
|
||||||
@@ -47,6 +48,13 @@ namespace OpenEngine {
|
|||||||
glm::vec4 quad_vertex_positioning[4];
|
glm::vec4 quad_vertex_positioning[4];
|
||||||
|
|
||||||
Statistics stats;
|
Statistics stats;
|
||||||
|
|
||||||
|
struct CameraData
|
||||||
|
{
|
||||||
|
glm::mat4 view_projection;
|
||||||
|
};
|
||||||
|
CameraData camera_buffer;
|
||||||
|
Ref<UniformBuffer> camera_uniform_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Renderer2DData renderer_data;
|
static Renderer2DData renderer_data;
|
||||||
@@ -100,8 +108,6 @@ namespace OpenEngine {
|
|||||||
samplers[i] = i;
|
samplers[i] = i;
|
||||||
|
|
||||||
renderer_data.texture_shader = Shader::Create("assets/shaders/texture.glsl");
|
renderer_data.texture_shader = Shader::Create("assets/shaders/texture.glsl");
|
||||||
renderer_data.texture_shader->Bind();
|
|
||||||
renderer_data.texture_shader->SetIntArray("u_Texture", samplers, renderer_data.max_texture_slots);
|
|
||||||
|
|
||||||
renderer_data.texture_slots[0] = renderer_data.white_texture;
|
renderer_data.texture_slots[0] = renderer_data.white_texture;
|
||||||
|
|
||||||
@@ -109,6 +115,8 @@ namespace OpenEngine {
|
|||||||
renderer_data.quad_vertex_positioning[1] = {0.5, -0.5, 0.0f, 1.0f};
|
renderer_data.quad_vertex_positioning[1] = {0.5, -0.5, 0.0f, 1.0f};
|
||||||
renderer_data.quad_vertex_positioning[2] = {0.5, 0.5, 0.0f, 1.0f};
|
renderer_data.quad_vertex_positioning[2] = {0.5, 0.5, 0.0f, 1.0f};
|
||||||
renderer_data.quad_vertex_positioning[3] = {-0.5, 0.5, 0.0f, 1.0f};
|
renderer_data.quad_vertex_positioning[3] = {-0.5, 0.5, 0.0f, 1.0f};
|
||||||
|
|
||||||
|
renderer_data.camera_uniform_buffer = UniformBuffer::Create(sizeof(Renderer2DData), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer2D::Shutdown()
|
void Renderer2D::Shutdown()
|
||||||
@@ -130,8 +138,8 @@ namespace OpenEngine {
|
|||||||
{
|
{
|
||||||
OE_PROFILE_FUNCTION();
|
OE_PROFILE_FUNCTION();
|
||||||
|
|
||||||
renderer_data.texture_shader->Bind();
|
renderer_data.camera_buffer.view_projection = camera.GetViewProjectionMatrix();
|
||||||
renderer_data.texture_shader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
|
renderer_data.camera_uniform_buffer->SetData(&renderer_data.camera_buffer, sizeof(Renderer2DData::CameraData));
|
||||||
|
|
||||||
StartBatch();
|
StartBatch();
|
||||||
}
|
}
|
||||||
@@ -140,10 +148,8 @@ namespace OpenEngine {
|
|||||||
{
|
{
|
||||||
OE_PROFILE_FUNCTION();
|
OE_PROFILE_FUNCTION();
|
||||||
|
|
||||||
glm::mat4 view_projection = camera.GetProjection() * glm::inverse(transform);
|
renderer_data.camera_buffer.view_projection = camera.GetProjection() * glm::inverse(transform);
|
||||||
|
renderer_data.camera_uniform_buffer->SetData(&renderer_data.camera_buffer, sizeof(Renderer2DData::CameraData));
|
||||||
renderer_data.texture_shader->Bind();
|
|
||||||
renderer_data.texture_shader->SetMat4("u_ViewProjection", view_projection);
|
|
||||||
|
|
||||||
StartBatch();
|
StartBatch();
|
||||||
}
|
}
|
||||||
@@ -152,10 +158,8 @@ namespace OpenEngine {
|
|||||||
{
|
{
|
||||||
OE_PROFILE_FUNCTION();
|
OE_PROFILE_FUNCTION();
|
||||||
|
|
||||||
glm::mat4 view_projection = camera.GetViewProjection();
|
renderer_data.camera_buffer.view_projection = camera.GetViewProjection();
|
||||||
|
renderer_data.camera_uniform_buffer->SetData(&renderer_data.camera_buffer, sizeof(Renderer2DData::CameraData));
|
||||||
renderer_data.texture_shader->Bind();
|
|
||||||
renderer_data.texture_shader->SetMat4("u_ViewProjection", view_projection);
|
|
||||||
|
|
||||||
StartBatch();
|
StartBatch();
|
||||||
}
|
}
|
||||||
@@ -180,6 +184,7 @@ namespace OpenEngine {
|
|||||||
for (int i = 0; i < renderer_data.texture_slot_index; i++)
|
for (int i = 0; i < renderer_data.texture_slot_index; i++)
|
||||||
renderer_data.texture_slots[i]->Bind(i);
|
renderer_data.texture_slots[i]->Bind(i);
|
||||||
|
|
||||||
|
renderer_data.texture_shader->Bind();
|
||||||
RenderCommand::DrawIndexed(renderer_data.vertex_array, renderer_data.quad_index_count);
|
RenderCommand::DrawIndexed(renderer_data.vertex_array, renderer_data.quad_index_count);
|
||||||
|
|
||||||
renderer_data.stats.draw_calls++;
|
renderer_data.stats.draw_calls++;
|
||||||
@@ -225,6 +230,43 @@ namespace OpenEngine {
|
|||||||
DrawQuad(transform, texture, entity_id);
|
DrawQuad(transform, texture, entity_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer2D::DrawQuad(const Transform& transform_data,
|
||||||
|
const Ref<Texture2D>& texture, const glm::vec4& color,
|
||||||
|
int entity_id, 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();
|
||||||
|
|
||||||
|
glm::vec3 position = transform_data.position;
|
||||||
|
glm::vec3 size = transform_data.size;
|
||||||
|
|
||||||
|
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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::mat4 transform = glm::translate(glm::mat4(1.0f), transform_data.position)
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer2D::DrawQuad(const Transform& transform_data,
|
void Renderer2D::DrawQuad(const Transform& transform_data,
|
||||||
const Ref<Subtexture2D>& subtexture, int entity_id,
|
const Ref<Subtexture2D>& subtexture, int entity_id,
|
||||||
float tiling_factor)
|
float tiling_factor)
|
||||||
@@ -333,6 +375,49 @@ namespace OpenEngine {
|
|||||||
renderer_data.stats.quad_count++;
|
renderer_data.stats.quad_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer2D::DrawQuad(const glm::mat4& transform,
|
||||||
|
const Ref<Texture2D>& texture, const glm::vec4& color,
|
||||||
|
int entity_id, 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();
|
||||||
|
|
||||||
|
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->id = entity_id;
|
||||||
|
renderer_data.quad_vertex_ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer_data.quad_index_count += 6;
|
||||||
|
renderer_data.stats.quad_count++;
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer2D::DrawQuad(const glm::mat4& transform,
|
void Renderer2D::DrawQuad(const glm::mat4& transform,
|
||||||
const Ref<Subtexture2D>& subtexture, int entity_id,
|
const Ref<Subtexture2D>& subtexture, int entity_id,
|
||||||
float tiling_factor)
|
float tiling_factor)
|
||||||
|
|||||||
21
open_engine/src/open_engine/renderer/uniform_buffer.cpp
Normal file
21
open_engine/src/open_engine/renderer/uniform_buffer.cpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include <pch.hpp>
|
||||||
|
|
||||||
|
#include <renderer/uniform_buffer.hpp>
|
||||||
|
#include <opengl/opengl_uniform_buffer.hpp>
|
||||||
|
#include <renderer/renderer.hpp>
|
||||||
|
|
||||||
|
namespace OpenEngine {
|
||||||
|
|
||||||
|
Ref<UniformBuffer> UniformBuffer::Create(uint32_t size, uint32_t binding)
|
||||||
|
{
|
||||||
|
switch (Renderer::GetAPI())
|
||||||
|
{
|
||||||
|
case RendererAPI::API::None: OE_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr;
|
||||||
|
case RendererAPI::API::OpenGL: return CreateRef<OpenGLUniformBuffer>(size, binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
OE_CORE_ASSERT(false, "Unknown RendererAPI!");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "core.hpp"
|
||||||
#include <glm/trigonometric.hpp>
|
#include <glm/trigonometric.hpp>
|
||||||
#include <pch.hpp>
|
#include <pch.hpp>
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
void SceneCamera::SetViewportSize(uint32_t width, uint32_t height)
|
void SceneCamera::SetViewportSize(uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
|
OE_CORE_ASSERT(width > 0 && height > 0, "Viewport size invalid.");
|
||||||
aspect_ratio = (float)width / (float)height;
|
aspect_ratio = (float)width / (float)height;
|
||||||
|
|
||||||
RecalculateProjection();
|
RecalculateProjection();
|
||||||
|
|||||||
@@ -76,7 +76,12 @@ namespace OpenEngine {
|
|||||||
{
|
{
|
||||||
auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity);
|
auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity);
|
||||||
|
|
||||||
Renderer2D::DrawQuad(GetTransformFromComp(transform), sprite.color, (int)entity);
|
if (sprite.texture)
|
||||||
|
Renderer2D::DrawQuad(GetTransformFromComp(transform),
|
||||||
|
sprite.texture, sprite.color, (int)entity, sprite.tiling_factor);
|
||||||
|
else
|
||||||
|
Renderer2D::DrawQuad(GetTransformFromComp(transform),
|
||||||
|
sprite.color, (int)entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer2D::EndScene();
|
Renderer2D::EndScene();
|
||||||
@@ -107,4 +112,37 @@ namespace OpenEngine {
|
|||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void Scene::OnComponentAdded(Entity entity, T& component)
|
||||||
|
{
|
||||||
|
static_assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Scene::OnComponentAdded<TransformComponent>(Entity entity, TransformComponent& component)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Scene::OnComponentAdded<CameraComponent>(Entity entity, CameraComponent& component)
|
||||||
|
{
|
||||||
|
if (viewport_width > 0 && viewport_height > 0)
|
||||||
|
component.camera.SetViewportSize(viewport_width, viewport_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Scene::OnComponentAdded<SpriteRendererComponent>(Entity entity, SpriteRendererComponent& component)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Scene::OnComponentAdded<TagComponent>(Entity entity, TagComponent& component)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void Scene::OnComponentAdded<NativeScriptComponent>(Entity entity, NativeScriptComponent& component)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user