简单添加entt实体组件系统库
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
# Directories
|
||||
.vs/
|
||||
.vscode/
|
||||
bin/
|
||||
bin-int/
|
||||
.idea/
|
||||
|
||||
@ -8,20 +8,28 @@ add_subdirectory(vendor/glm)
|
||||
|
||||
file(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||
|
||||
include_directories(vendor/stb)
|
||||
file(GLOB STB vendor/stb/stb_image.h)
|
||||
# stb_image
|
||||
set(STB_INCLUDE_DIR vendor/stb)
|
||||
include_directories(${SRB_INCLUDE_DIR}/include)
|
||||
file(GLOB_RECURSE STB ${STB_INCLUDE_DIR}/include/*)
|
||||
|
||||
# entt
|
||||
set(ENTT_INCLUDE_DIR vendor/entt)
|
||||
include_directories(${ENTT_INCLUDE_DIR}/include)
|
||||
file(GLOB_RECURSE ENTT ${ENTT_INCLUDE_DIR}/include/*)
|
||||
|
||||
include_directories(vendor/imgui)
|
||||
include_directories(vendor/imgui/backends)
|
||||
file(GLOB IMGUI vendor/imgui/**.cpp
|
||||
vendor/imgui/backends/imgui_impl_opengl3.cpp
|
||||
vendor/imgui/backends/imgui_impl_sdl3.cpp)
|
||||
# imgui
|
||||
set(IMGUI_INCLUDE_DIR vendor/imgui)
|
||||
include_directories(${IMGUI_INCLUDE_DIR} ${IMGUI_INCLUDE_DIR}/backends)
|
||||
file(GLOB IMGUI ${IMGUI_INCLUDE_DIR}/*.cpp
|
||||
${IMGUI_INCLUDE_DIR}/backends/imgui_impl_opengl3.cpp
|
||||
${IMGUI_INCLUDE_DIR}/backends/imgui_impl_sdl3.cpp)
|
||||
|
||||
add_library(Hazel SHARED
|
||||
${SOURCES}
|
||||
${IMGUI}
|
||||
${STB}
|
||||
${ENTT}
|
||||
)
|
||||
|
||||
|
||||
@ -35,8 +43,9 @@ set(SDL3_SHARED ON CACHE BOOL "Build SDL as shared library" FORCE)
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src # 暴露头文件给其他项目
|
||||
vendor/imgui
|
||||
vendor/imgui/backends
|
||||
${STB_INCLUDE_DIR}
|
||||
${IMGUI_INCLUDE_DIR}
|
||||
${ENTT_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -7,23 +7,26 @@
|
||||
#include "Hazel/Core/Application.h"
|
||||
#include "Hazel/Core/Core.h"
|
||||
#include "Hazel/Core/Log.h"
|
||||
#include "Hazel/Debug/Instrumentor.h"
|
||||
#include "Hazel/Core/Window.h"
|
||||
#include "Hazel/Debug/Instrumentor.h"
|
||||
#include "Hazel/ImGui/ImGuiLayer.h"
|
||||
|
||||
|
||||
#include "Hazel/Scene/Components.h"
|
||||
#include "Hazel/Scene/Scene.h"
|
||||
#include "Hazel/Scene/ScriptableEntity.h"
|
||||
#include "Hazel/Scene/Entity.h"
|
||||
|
||||
|
||||
// ------------------------ Renderer ----------------------------
|
||||
#include "Hazel/Renderer/Buffer.h"
|
||||
#include "Hazel/Renderer/FrameBuffer.h"
|
||||
#include "Hazel/Renderer/OrthographicCameraController.h"
|
||||
#include "Hazel/Renderer/Renderer.h"
|
||||
#include "Hazel/Renderer/Renderer2D.h"
|
||||
#include "Hazel/Renderer/RendererCommand.h"
|
||||
|
||||
#include "Hazel/Renderer/Buffer.h"
|
||||
#include "Hazel/Renderer/Shader.h"
|
||||
#include "Hazel/Renderer/Texture.h"
|
||||
#include "Hazel/Renderer/SubTexture2D.h"
|
||||
#include "Hazel/Renderer/Texture.h"
|
||||
#include "Hazel/Renderer/VertexArray.h"
|
||||
|
||||
#include "Hazel/Renderer/OrthographicCameraController.h"
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ namespace Hazel {
|
||||
Application* Application::s_Instance = nullptr;
|
||||
|
||||
|
||||
Application::Application()
|
||||
Application::Application(const std::string& name, int width, int height)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
|
||||
@ -24,7 +24,7 @@ namespace Hazel {
|
||||
}
|
||||
s_Instance = this;
|
||||
|
||||
m_Window = std::unique_ptr<Window>(Window::Create());
|
||||
m_Window = Window::Create(WindowProps(name, width, height));
|
||||
m_Window->SetEventCallback(std::bind(&Application::OnEvent, this, std::placeholders::_1));
|
||||
m_Window->SetWindowResizeEventCallback(std::bind(&Application::OnWindowResize, this, std::placeholders::_1));
|
||||
|
||||
@ -107,7 +107,7 @@ namespace Hazel {
|
||||
HZ_PROFILE_FUNCTION();
|
||||
m_Minimized = false;
|
||||
HZ_CORE_INFO("Resized window:({0}, {1})", m_Window->GetWidth(), m_Window->GetHeight());
|
||||
Renderer::OnWindowResize(m_Window->GetWidth(), m_Window->GetHeight());
|
||||
// Renderer::OnWindowResize(m_Window->GetWidth(), m_Window->GetHeight());
|
||||
}
|
||||
void Application::PushLayer(Layer* layer)
|
||||
{
|
||||
@ -122,4 +122,9 @@ namespace Hazel {
|
||||
m_layerStack.PushOverlay(layer);
|
||||
layer->OnAttach();
|
||||
}
|
||||
|
||||
void Application::Close()
|
||||
{
|
||||
m_Running = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ namespace Hazel {
|
||||
class HAZEL_API Application
|
||||
{
|
||||
public:
|
||||
Application();
|
||||
Application(const std::string& name = "Hazel App", int width = 1280, int height = 720);
|
||||
virtual ~Application();
|
||||
|
||||
void Run();
|
||||
@ -22,11 +22,16 @@ namespace Hazel {
|
||||
void OnWindowResize(SDL_Event& e);
|
||||
void PushLayer(Layer* layer);
|
||||
void PushOverlay(Layer* layer);
|
||||
inline Window& GetWindow() { return *m_Window; }
|
||||
|
||||
void Close();
|
||||
|
||||
ImGuiLayer* GetImGuiLayer() const { return m_imguiLayer; }
|
||||
|
||||
inline Window& GetWindow() const { return *m_Window; }
|
||||
inline static Application& Get() { return *s_Instance; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<Hazel::Window> m_Window;
|
||||
Scope<Window> m_Window;
|
||||
ImGuiLayer* m_imguiLayer;
|
||||
bool m_Running = true;
|
||||
|
||||
|
||||
@ -17,6 +17,13 @@ namespace Hazel
|
||||
template<typename T>
|
||||
using Scope = std::unique_ptr<T>;
|
||||
|
||||
template<typename T, typename ... Args>
|
||||
constexpr Scope<T> CreateScope(Args&&... args)
|
||||
{
|
||||
return std::make_unique<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
using Ref = std::shared_ptr<T>;
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ namespace Hazel {
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define HZ_CORE_TRACE(...) ::Hazel::Log::getCoreLogger()->trace(__VA_ARGS__)
|
||||
#define HZ_CORE_DEBUG(...) ::Hazel::Log::getCoreLogger()->debug(__VA_ARGS__)
|
||||
#define HZ_CORE_INFO(...) ::Hazel::Log::getCoreLogger()->info(__VA_ARGS__)
|
||||
|
||||
@ -15,12 +15,12 @@ namespace Hazel
|
||||
struct WindowProps
|
||||
{
|
||||
std::string title;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
WindowProps(const std::string& title = "Hazel",
|
||||
unsigned int width = 1280,
|
||||
unsigned int height = 720) : title(title), width(width), height(height) {}
|
||||
WindowProps(const std::string& title = "Hazel App",
|
||||
uint32_t width = 1280,
|
||||
uint32_t height = 720) : title(title), width(width), height(height) {}
|
||||
|
||||
};
|
||||
|
||||
@ -34,8 +34,8 @@ namespace Hazel
|
||||
|
||||
virtual void OnUpdate() = 0;
|
||||
|
||||
virtual unsigned int GetWidth() const = 0;
|
||||
virtual unsigned int GetHeight() const = 0;
|
||||
virtual uint32_t GetWidth() const = 0;
|
||||
virtual uint32_t GetHeight() const = 0;
|
||||
|
||||
// Window attributes
|
||||
virtual void SetEventCallback(const EventCallbackFn& callback) = 0;
|
||||
@ -43,7 +43,7 @@ namespace Hazel
|
||||
virtual void SetVSync(bool enabled) = 0;
|
||||
virtual bool IsVSync() const = 0;
|
||||
|
||||
static Window* Create(const WindowProps& props = WindowProps());
|
||||
static Scope<Window> Create(const WindowProps& props = WindowProps());
|
||||
|
||||
virtual Uint32 GetMainWindowID() const = 0;
|
||||
virtual void* GetNativeWindow() const = 0;
|
||||
|
||||
@ -61,7 +61,10 @@ namespace Hazel
|
||||
|
||||
void ImGuiLayer::OnEvent(SDL_Event& e)
|
||||
{
|
||||
ImGui_ImplSDL3_ProcessEvent(&e);
|
||||
// if (m_BlockEvent)
|
||||
// {
|
||||
ImGui_ImplSDL3_ProcessEvent(&e);
|
||||
// }
|
||||
}
|
||||
|
||||
void ImGuiLayer::OnImGuiRender()
|
||||
@ -81,7 +84,7 @@ namespace Hazel
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
Application& app = Application::Get();
|
||||
const Application& app = Application::Get();
|
||||
io.DisplaySize = ImVec2(static_cast<float>(app.GetWindow().GetWidth()), static_cast<float>(app.GetWindow().GetHeight()));
|
||||
|
||||
ImGui::Render();
|
||||
@ -90,7 +93,7 @@ namespace Hazel
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow();
|
||||
SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
|
||||
const SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
|
||||
|
||||
@ -22,7 +22,10 @@ namespace Hazel {
|
||||
void Begin();
|
||||
void End();
|
||||
|
||||
void BlockEvents(const bool block) {m_BlockEvent = block;}
|
||||
|
||||
private:
|
||||
bool m_BlockEvent = true;
|
||||
float m_Time = 0.0f;
|
||||
|
||||
};
|
||||
|
||||
5
Hazel/src/Hazel/Renderer/Camera.cpp
Normal file
5
Hazel/src/Hazel/Renderer/Camera.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sfd on 25-5-28.
|
||||
//
|
||||
|
||||
#include "Camera.h"
|
||||
24
Hazel/src/Hazel/Renderer/Camera.h
Normal file
24
Hazel/src/Hazel/Renderer/Camera.h
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by sfd on 25-5-28.
|
||||
//
|
||||
|
||||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
#include "glm/glm.hpp"
|
||||
#include "Hazel/Core/Core.h"
|
||||
|
||||
namespace Hazel {
|
||||
class HAZEL_API Camera{
|
||||
public:
|
||||
Camera() = default;
|
||||
Camera(const glm::mat4& projection) : m_Projection(projection) {}
|
||||
virtual ~Camera() = default;
|
||||
|
||||
const glm::mat4& GetProjection() const { return m_Projection; }
|
||||
protected:
|
||||
glm::mat4 m_Projection = glm::mat4(1.0f);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //CAMERA_H
|
||||
29
Hazel/src/Hazel/Renderer/FrameBuffer.cpp
Normal file
29
Hazel/src/Hazel/Renderer/FrameBuffer.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
//
|
||||
// Created by sfd on 25-5-25.
|
||||
//
|
||||
|
||||
#include "FrameBuffer.h"
|
||||
|
||||
#include <Platform/OpenGL/OpenGLFrameBuffer.h>
|
||||
|
||||
#include "Renderer.h"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
Ref<FrameBuffer> FrameBuffer::Create(const FrameBufferSpecification& spec)
|
||||
{
|
||||
switch (Renderer::GetAPI())
|
||||
{
|
||||
case RendererAPI::API::NONE:
|
||||
HZ_CORE_ERROR("NONE is not Support!");
|
||||
return nullptr;
|
||||
case RendererAPI::API::OPENGL:
|
||||
return CreateRef<OpenGLFrameBuffer>(spec);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
HZ_CORE_ERROR("Unknown RendererAPI!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
41
Hazel/src/Hazel/Renderer/FrameBuffer.h
Normal file
41
Hazel/src/Hazel/Renderer/FrameBuffer.h
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// Created by sfd on 25-5-25.
|
||||
//
|
||||
|
||||
#ifndef FRAMEBUFFER_H
|
||||
#define FRAMEBUFFER_H
|
||||
#include <Hazel/Core/Core.h>
|
||||
|
||||
#include "glm/vec2.hpp"
|
||||
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
struct FrameBufferSpecification
|
||||
{
|
||||
uint32_t Width, Height;
|
||||
uint32_t Samples;
|
||||
|
||||
bool SwapChainTarget = false;
|
||||
};
|
||||
|
||||
|
||||
class HAZEL_API FrameBuffer
|
||||
{
|
||||
public:
|
||||
virtual ~FrameBuffer() = default;
|
||||
// virtual FrameBufferSpecification& GetSpecification() = 0;
|
||||
virtual const FrameBufferSpecification& GetSpecification() const = 0;
|
||||
virtual uint32_t GetColorAttachmentID() const = 0;
|
||||
|
||||
virtual void Bind() = 0;
|
||||
virtual void UnBind() = 0;
|
||||
|
||||
virtual void Resize(uint32_t width, uint32_t height) = 0;
|
||||
|
||||
static Ref<FrameBuffer> Create(const FrameBufferSpecification& spec);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //FRAMEBUFFER_H
|
||||
@ -12,6 +12,7 @@ namespace Hazel
|
||||
class HAZEL_API GraphicsContext
|
||||
{
|
||||
public:
|
||||
virtual ~GraphicsContext() = default;
|
||||
virtual void Init() = 0;
|
||||
virtual void SwapBuffers() = 0;
|
||||
|
||||
|
||||
@ -10,41 +10,41 @@
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
OrthographicCameraController::OrthographicCameraController(float aspectRatio, bool isRotation) : m_AspectRatio(aspectRatio), m_isRotation(isRotation),m_Bounds(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel), m_Camera(m_Bounds.left, m_Bounds.right, m_Bounds.bottom, m_Bounds.top)
|
||||
OrthographicCameraController::OrthographicCameraController(float aspectRatio, bool isRotation)
|
||||
: m_AspectRatio(aspectRatio), m_isRotation(isRotation),
|
||||
m_Bounds(-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel),
|
||||
m_Camera(m_Bounds.left, m_Bounds.right, m_Bounds.bottom, m_Bounds.top)
|
||||
{
|
||||
}
|
||||
|
||||
void OrthographicCameraController::OnResize(const float width, const float height)
|
||||
{
|
||||
m_AspectRatio = width / height;
|
||||
CalculateView();
|
||||
}
|
||||
|
||||
void OrthographicCameraController::OnUpdate(TimeStep ts)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
const bool* state = SDL_GetKeyboardState(NULL);
|
||||
static const bool* state = SDL_GetKeyboardState(NULL);
|
||||
float time = ts;
|
||||
|
||||
if (state[SDL_SCANCODE_A])
|
||||
{
|
||||
m_CameraPosition.x -= m_CameraTranslationSpeed * time;
|
||||
}
|
||||
else if (state[SDL_SCANCODE_D])
|
||||
{
|
||||
m_CameraPosition.x += m_CameraTranslationSpeed * time;
|
||||
}
|
||||
|
||||
if (state[SDL_SCANCODE_W])
|
||||
{
|
||||
m_CameraPosition.y += m_CameraTranslationSpeed * time;
|
||||
}
|
||||
else if (state[SDL_SCANCODE_S])
|
||||
{
|
||||
m_CameraPosition.y -= m_CameraTranslationSpeed * time;
|
||||
}
|
||||
|
||||
if (m_isRotation)
|
||||
{
|
||||
if (state[SDL_SCANCODE_Q])
|
||||
{
|
||||
m_CameraRotation += m_CameraRotationSpeed * time;
|
||||
}
|
||||
else if (state[SDL_SCANCODE_E])
|
||||
{
|
||||
m_CameraRotation -= m_CameraRotationSpeed * time;
|
||||
}
|
||||
|
||||
m_Camera.SetRotation(m_CameraRotation);
|
||||
}
|
||||
@ -57,35 +57,38 @@ namespace Hazel
|
||||
|
||||
void OrthographicCameraController::OnEvent(SDL_Event& e)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
OnMouseScrolled(e);
|
||||
OnWindowResized(e);
|
||||
HZ_PROFILE_FUNCTION();
|
||||
OnMouseScrolled(e);
|
||||
OnWindowResized(e);
|
||||
}
|
||||
|
||||
void OrthographicCameraController::CalculateView()
|
||||
{
|
||||
m_Bounds = {-m_AspectRatio * m_ZoomLevel, m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel};
|
||||
m_Camera.SetProjection(m_Bounds.left, m_Bounds.right, m_Bounds.bottom, m_Bounds.top);
|
||||
}
|
||||
|
||||
bool OrthographicCameraController::OnMouseScrolled(SDL_Event& e)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
if (e.type == SDL_EVENT_MOUSE_WHEEL)
|
||||
{
|
||||
m_ZoomLevel += e.wheel.y * 0.25f;
|
||||
m_ZoomLevel = std::max(m_ZoomLevel, 0.25f);
|
||||
m_Bounds = { -m_AspectRatio * m_ZoomLevel,m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel };
|
||||
m_Camera.SetProjection(m_Bounds.left, m_Bounds.right, m_Bounds.bottom, m_Bounds.top);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
HZ_PROFILE_FUNCTION();
|
||||
if (e.type == SDL_EVENT_MOUSE_WHEEL)
|
||||
{
|
||||
m_ZoomLevel -= e.wheel.y * 0.25f;
|
||||
m_ZoomLevel = std::max(m_ZoomLevel, 0.25f);
|
||||
CalculateView();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OrthographicCameraController::OnWindowResized(SDL_Event& e)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
if (e.type == SDL_EVENT_WINDOW_RESIZED && (e.window.windowID == Application::Get().GetWindow().GetMainWindowID()))
|
||||
{
|
||||
m_AspectRatio = static_cast<float>(e.window.data1) / static_cast<float>(e.window.data2);
|
||||
m_Bounds = { -m_AspectRatio * m_ZoomLevel,m_AspectRatio * m_ZoomLevel, -m_ZoomLevel, m_ZoomLevel };
|
||||
m_Camera.SetProjection(m_Bounds.left, m_Bounds.right, m_Bounds.bottom, m_Bounds.top);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
HZ_PROFILE_FUNCTION();
|
||||
if (e.type == SDL_EVENT_WINDOW_RESIZED)
|
||||
{
|
||||
OnResize(static_cast<float>(e.window.data1), static_cast<float>(e.window.data2));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,8 +19,8 @@ namespace Hazel
|
||||
struct OrthographicCameraBounds
|
||||
{
|
||||
float left, right, bottom, top;
|
||||
float GetWidth() { return right - left; }
|
||||
float GetHeight() { return top - bottom; }
|
||||
float GetWidth() const { return right - left; }
|
||||
float GetHeight() const { return top - bottom; }
|
||||
};
|
||||
|
||||
class HAZEL_API OrthographicCameraController
|
||||
@ -29,11 +29,14 @@ namespace Hazel
|
||||
OrthographicCameraController(float aspectRatio, bool isRotation = false);
|
||||
void SetProjection(float left, float right, float bottom, float top);
|
||||
|
||||
void OnResize(const float width, const float height);
|
||||
|
||||
void OnUpdate(TimeStep ts);
|
||||
void OnEvent(SDL_Event& e);
|
||||
|
||||
void SetZoomLevel(float level) {m_ZoomLevel = level;}
|
||||
void CalculateView();
|
||||
|
||||
void SetZoomLevel(const float level) {m_ZoomLevel = level; CalculateView();}
|
||||
float GetZoomLevel() const {return m_ZoomLevel;}
|
||||
|
||||
OrthographicCamera& GetCamera() {return m_Camera;}
|
||||
|
||||
@ -127,6 +127,22 @@ namespace Hazel
|
||||
s_Data.QuadVertexPosition[3] = {-0.5f, 0.5f, 0.0f, 1.0f};
|
||||
}
|
||||
|
||||
void Renderer2D::BeginScene(const Camera& camera, const glm::mat4& tranform)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
|
||||
const glm::mat4 viewProjection = camera.GetProjection() * glm::inverse(tranform);
|
||||
|
||||
|
||||
s_Data.TextureShader->Bind();
|
||||
s_Data.TextureShader->SetMat4("u_ViewProjection", viewProjection);
|
||||
|
||||
s_Data.QuadIndexCount = 0;
|
||||
s_Data.QuadVertexBufferPtr = s_Data.QuadVertexBufferBase;
|
||||
|
||||
s_Data.TextureSlotIndex = 1;
|
||||
}
|
||||
|
||||
void Renderer2D::BeginScene(const OrthographicCamera& camera)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
@ -182,7 +198,6 @@ namespace Hazel
|
||||
s_Data.QuadVertexBufferPtr = s_Data.QuadVertexBufferBase;
|
||||
|
||||
s_Data.TextureSlotIndex = 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -198,26 +213,9 @@ namespace Hazel
|
||||
{
|
||||
FlushAndReset();
|
||||
}
|
||||
|
||||
constexpr float texIndex = 0.0f;
|
||||
constexpr float tilingFactor = 1.0f;
|
||||
glm::vec2 texCoords[] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
|
||||
|
||||
const glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPosition[i];
|
||||
s_Data.QuadVertexBufferPtr->Color = color;
|
||||
s_Data.QuadVertexBufferPtr->TexCoord = texCoords[i];
|
||||
s_Data.QuadVertexBufferPtr->TexIndex = texIndex;
|
||||
s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor;
|
||||
s_Data.QuadVertexBufferPtr++;
|
||||
}
|
||||
|
||||
s_Data.QuadIndexCount += 6;
|
||||
|
||||
s_Data.Stats.QuadCount ++;
|
||||
DrawQuad(transform, color);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture2D>& texture, const float tilingFactor, const glm::vec4& tintColor)
|
||||
@ -233,41 +231,9 @@ namespace Hazel
|
||||
FlushAndReset();
|
||||
}
|
||||
|
||||
glm::vec2 texCoords[] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
|
||||
|
||||
float textureIndex = 0.0f;
|
||||
|
||||
for (uint32_t i = 1; i < s_Data.TextureSlotIndex; i++)
|
||||
{
|
||||
if (*s_Data.TextureSlots[i].get() == *texture.get())
|
||||
{
|
||||
textureIndex = (float)i;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (textureIndex == 0.0f)
|
||||
{
|
||||
textureIndex = (float)s_Data.TextureSlotIndex;
|
||||
s_Data.TextureSlots[s_Data.TextureSlotIndex] = texture;
|
||||
s_Data.TextureSlotIndex++;
|
||||
}
|
||||
|
||||
const glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::scale(glm::mat4(1.0f), { size.x, size.y, 1.0f });
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPosition[i];
|
||||
s_Data.QuadVertexBufferPtr->Color = tintColor;
|
||||
s_Data.QuadVertexBufferPtr->TexCoord = texCoords[i];
|
||||
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
|
||||
s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor;
|
||||
s_Data.QuadVertexBufferPtr++;
|
||||
}
|
||||
s_Data.QuadIndexCount += 6;
|
||||
|
||||
s_Data.Stats.QuadCount ++;
|
||||
DrawQuad(transform, texture, tilingFactor, tintColor);
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<SubTexture2D>& subTexture, const float tilingFactor, const glm::vec4& tintColor)
|
||||
@ -321,6 +287,77 @@ namespace Hazel
|
||||
s_Data.Stats.QuadCount ++;
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::mat4& transform, const glm::vec4& Color)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
if (s_Data.QuadIndexCount >= s_Data.MaxIndices)
|
||||
{
|
||||
FlushAndReset();
|
||||
}
|
||||
|
||||
glm::vec2 texCoords[] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
|
||||
const float textureIndex = 0.0f;
|
||||
const float tilingFactor = 1.0f;
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPosition[i];
|
||||
s_Data.QuadVertexBufferPtr->Color = Color;
|
||||
s_Data.QuadVertexBufferPtr->TexCoord = texCoords[i];
|
||||
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
|
||||
s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor;
|
||||
s_Data.QuadVertexBufferPtr++;
|
||||
}
|
||||
s_Data.QuadIndexCount += 6;
|
||||
|
||||
s_Data.Stats.QuadCount ++;
|
||||
}
|
||||
|
||||
void Renderer2D::DrawQuad(const glm::mat4& transform, const Ref<Texture2D>& texture, float tilingFactor,
|
||||
const glm::vec4& tintColor)
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
if (s_Data.QuadIndexCount >= s_Data.MaxIndices)
|
||||
{
|
||||
FlushAndReset();
|
||||
}
|
||||
|
||||
glm::vec2 texCoords[] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
|
||||
|
||||
float textureIndex = 0.0f;
|
||||
|
||||
for (uint32_t i = 1; i < s_Data.TextureSlotIndex; i++)
|
||||
{
|
||||
if (*s_Data.TextureSlots[i].get() == *texture.get())
|
||||
{
|
||||
textureIndex = (float)i;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (textureIndex == 0.0f)
|
||||
{
|
||||
textureIndex = (float)s_Data.TextureSlotIndex;
|
||||
s_Data.TextureSlots[s_Data.TextureSlotIndex] = texture;
|
||||
s_Data.TextureSlotIndex++;
|
||||
}
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
s_Data.QuadVertexBufferPtr->Position = transform * s_Data.QuadVertexPosition[i];
|
||||
s_Data.QuadVertexBufferPtr->Color = tintColor;
|
||||
s_Data.QuadVertexBufferPtr->TexCoord = texCoords[i];
|
||||
s_Data.QuadVertexBufferPtr->TexIndex = textureIndex;
|
||||
s_Data.QuadVertexBufferPtr->TilingFactor = tilingFactor;
|
||||
s_Data.QuadVertexBufferPtr++;
|
||||
}
|
||||
s_Data.QuadIndexCount += 6;
|
||||
|
||||
s_Data.Stats.QuadCount ++;
|
||||
}
|
||||
|
||||
|
||||
void Renderer2D::DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, const float rotation,
|
||||
const glm::vec4& color)
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#ifndef RENDERER2D_H
|
||||
#define RENDERER2D_H
|
||||
|
||||
#include "Camera.h"
|
||||
#include "OrthographicCamera.h"
|
||||
#include "SubTexture2D.h"
|
||||
#include "Texture.h"
|
||||
@ -15,9 +16,19 @@ namespace Hazel
|
||||
{
|
||||
class HAZEL_API Renderer2D{
|
||||
public:
|
||||
|
||||
struct RenderCamera
|
||||
{
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
};
|
||||
|
||||
|
||||
static void Init();
|
||||
|
||||
static void BeginScene(const OrthographicCamera& camera);
|
||||
static void BeginScene(const Camera& camera, const glm::mat4& tranform);
|
||||
static void BeginScene(const OrthographicCamera& camera); // TODO: remove this
|
||||
|
||||
static void EndScene();
|
||||
static void Flush();
|
||||
|
||||
@ -28,6 +39,9 @@ namespace Hazel
|
||||
static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<SubTexture2D>& subTexture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
|
||||
static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<SubTexture2D>& subTexture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
|
||||
|
||||
static void DrawQuad(const glm::mat4& transform, const glm::vec4& Color);
|
||||
static void DrawQuad(const glm::mat4& transform, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
|
||||
|
||||
static void DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color);
|
||||
static void DrawRotateQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color);
|
||||
static void DrawRotateQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const Ref<Texture2D>& texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
|
||||
|
||||
@ -23,12 +23,13 @@ namespace Hazel
|
||||
};
|
||||
|
||||
public:
|
||||
virtual ~RendererAPI() = default;
|
||||
virtual void Init() = 0;
|
||||
virtual void SetClearColor(const glm::vec4& color) = 0;
|
||||
virtual void SetViewPort(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0;
|
||||
virtual void Clear() = 0;
|
||||
|
||||
virtual void DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray, uint32_t indexCount = 0) = 0;
|
||||
virtual void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray, uint32_t indexCount = 0) = 0;
|
||||
|
||||
inline static API GetAPI() {return s_API; }
|
||||
|
||||
|
||||
61
Hazel/src/Hazel/Renderer/ScenceCamera.cpp
Normal file
61
Hazel/src/Hazel/Renderer/ScenceCamera.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
//
|
||||
// Created by sfd on 25-5-28.
|
||||
//
|
||||
|
||||
#include "ScenceCamera.h"
|
||||
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
ScenceCamera::ScenceCamera()
|
||||
{
|
||||
RecalculateProjection();
|
||||
}
|
||||
|
||||
void ScenceCamera::SetOrthographic(const float size, const float nearClip, const float farClip)
|
||||
{
|
||||
m_ProjectionType = ProjectionType::Orthographic;
|
||||
m_OrthographicSize = size;
|
||||
m_OrthographicNear = nearClip;
|
||||
m_OrthographicFar = farClip;
|
||||
|
||||
RecalculateProjection();
|
||||
}
|
||||
|
||||
void ScenceCamera::SetPerspective(const float verticalFOV, const float nearClip, const float farClip)
|
||||
{
|
||||
m_ProjectionType = ProjectionType::Perspective;
|
||||
m_PerspectiveFOV = verticalFOV;
|
||||
m_PerspectiveNear = nearClip;
|
||||
m_PerspectiveFar = farClip;
|
||||
|
||||
RecalculateProjection();
|
||||
}
|
||||
|
||||
void ScenceCamera::SetViewPortSize(uint32_t width, uint32_t height)
|
||||
{
|
||||
m_AspectRatio = (float)width / (float)height;
|
||||
|
||||
RecalculateProjection();
|
||||
}
|
||||
|
||||
void ScenceCamera::RecalculateProjection()
|
||||
{
|
||||
if (m_ProjectionType == ProjectionType::Perspective)
|
||||
{
|
||||
m_Projection = glm::perspective(m_PerspectiveFOV, m_AspectRatio, m_PerspectiveNear, m_PerspectiveFar);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float orthoLeft = -m_OrthographicSize * m_AspectRatio * 0.5f;
|
||||
const float orthoRight = m_OrthographicSize * m_AspectRatio * 0.5f;
|
||||
const float orthoBottom = -m_OrthographicSize * 0.5f;
|
||||
const float orthoTop = m_OrthographicSize * 0.5f;
|
||||
|
||||
|
||||
m_Projection = glm::ortho(orthoLeft, orthoRight, orthoBottom, orthoTop, m_OrthographicNear,
|
||||
m_OrthographicFar);
|
||||
}
|
||||
}
|
||||
}
|
||||
64
Hazel/src/Hazel/Renderer/ScenceCamera.h
Normal file
64
Hazel/src/Hazel/Renderer/ScenceCamera.h
Normal file
@ -0,0 +1,64 @@
|
||||
//
|
||||
// Created by sfd on 25-5-28.
|
||||
//
|
||||
|
||||
#ifndef SCENCECAMERA_H
|
||||
#define SCENCECAMERA_H
|
||||
|
||||
#include "Camera.h"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class HAZEL_API ScenceCamera : public Camera
|
||||
{
|
||||
public:
|
||||
enum class ProjectionType {Perspective = 0, Orthographic = 1};
|
||||
public:
|
||||
ScenceCamera();
|
||||
virtual ~ScenceCamera() = default;
|
||||
|
||||
void SetOrthographic(const float size, const float nearClip, const float farClip);
|
||||
void SetPerspective(const float verticalFOV, const float nearClip, const float farClip);
|
||||
void SetViewPortSize(uint32_t width, uint32_t height);
|
||||
|
||||
|
||||
// Perspective getters
|
||||
float GetPerspectiveVerticalFOV() const { return m_PerspectiveFOV;};
|
||||
float GetPerspectiveNearCLip() const { return m_PerspectiveNear; }
|
||||
float GetPerspectiveFarCLip() const { return m_PerspectiveFar; }
|
||||
// Perspective setters
|
||||
void SetPerspectiveVerticalFOV(const float fov) { m_PerspectiveFOV = fov; RecalculateProjection(); }
|
||||
void SetPerspectiveNearClip(const float nearClip) {m_PerspectiveNear = nearClip; RecalculateProjection();}
|
||||
void SetPerspectiveFarClip(const float farClip) {m_PerspectiveFar = farClip; RecalculateProjection();}
|
||||
|
||||
|
||||
// Orthographic getters
|
||||
float GetOrthographicSize() const { return m_OrthographicSize; }
|
||||
float GetOrthographicNearCLip() const { return m_OrthographicNear; }
|
||||
float GetOrthographicFarCLip() const { return m_OrthographicFar; }
|
||||
// Orthographic setters
|
||||
void SetOrthographicSize(const float size) { m_OrthographicSize = size; RecalculateProjection(); }
|
||||
void SetOrthographicNearClip(const float nearClip) {m_OrthographicNear = nearClip; RecalculateProjection();}
|
||||
void SetOrthographicFarClip(const float farClip) {m_OrthographicFar = farClip; RecalculateProjection();}
|
||||
|
||||
|
||||
|
||||
ProjectionType GetProjectionType() const { return m_ProjectionType; }
|
||||
void SetProjectionType(const ProjectionType type) { m_ProjectionType = type; RecalculateProjection(); }
|
||||
private:
|
||||
void RecalculateProjection();
|
||||
private:
|
||||
ProjectionType m_ProjectionType = ProjectionType::Orthographic;
|
||||
|
||||
float m_OrthographicSize = 10.0f;
|
||||
float m_OrthographicNear = -1.0f, m_OrthographicFar = 1.0f;
|
||||
|
||||
float m_PerspectiveFOV = glm::radians(45.f);
|
||||
float m_PerspectiveNear = 0.01f, m_PerspectiveFar = 1000.0f;
|
||||
|
||||
float m_AspectRatio = 1.0f;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //SCENCECAMERA_H
|
||||
@ -22,7 +22,7 @@ namespace Hazel
|
||||
HZ_CORE_ERROR("NONE is not Support!");
|
||||
return nullptr;
|
||||
case RendererAPI::API::OPENGL:
|
||||
return std::make_shared<OpenGLVertexArray>();
|
||||
return CreateRef<OpenGLVertexArray>();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
77
Hazel/src/Hazel/Scene/Components.h
Normal file
77
Hazel/src/Hazel/Scene/Components.h
Normal file
@ -0,0 +1,77 @@
|
||||
//
|
||||
// Created by sfd on 25-5-26.
|
||||
//
|
||||
|
||||
#ifndef COMPONENTS_H
|
||||
#define COMPONENTS_H
|
||||
#include <Hazel/Renderer/Camera.h>
|
||||
#include <Hazel/Renderer/ScenceCamera.h>
|
||||
|
||||
#include "ScriptableEntity.h"
|
||||
#include "glm/glm.hpp"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
struct TransformComponent
|
||||
{
|
||||
glm::mat4 Transform{1.0f};
|
||||
TransformComponent() = default;
|
||||
TransformComponent(const TransformComponent&) = default;
|
||||
|
||||
TransformComponent(const glm::mat4& transform) : Transform(transform)
|
||||
{
|
||||
}
|
||||
|
||||
operator glm::mat4&() { return Transform; }
|
||||
operator const glm::mat4&() const { return Transform; }
|
||||
};
|
||||
|
||||
struct SpriteRendererComponent
|
||||
{
|
||||
glm::vec4 Color{1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
SpriteRendererComponent() = default;
|
||||
SpriteRendererComponent(const SpriteRendererComponent&) = default;
|
||||
|
||||
SpriteRendererComponent(const glm::vec4& color) : Color(color)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct TagComponent
|
||||
{
|
||||
std::string Tag;
|
||||
|
||||
TagComponent(const TagComponent&) = default;
|
||||
TagComponent(const std::string& tag) : Tag(tag) {}
|
||||
};
|
||||
|
||||
|
||||
struct CameraComponent
|
||||
{
|
||||
ScenceCamera Camera;
|
||||
bool Primary = true; //TODO: 考虑多相机如何同步, 考虑移至Scence中
|
||||
bool FixedAspectRatio = false;
|
||||
CameraComponent() = default;
|
||||
CameraComponent(const CameraComponent&) = default;
|
||||
};
|
||||
|
||||
struct NativeScriptComponent
|
||||
{
|
||||
ScriptableEntity* Instance = nullptr;
|
||||
|
||||
|
||||
ScriptableEntity* (*InstantiateScript)();
|
||||
void (*DestroyScript)(NativeScriptComponent*);
|
||||
|
||||
template<typename T>
|
||||
void Bind()
|
||||
{
|
||||
InstantiateScript = []() { return static_cast<ScriptableEntity*>(new T()); };
|
||||
DestroyScript = [](NativeScriptComponent* nsc) { delete nsc->Instance; nsc->Instance = nullptr; };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //COMPONENTS_H
|
||||
13
Hazel/src/Hazel/Scene/Entity.cpp
Normal file
13
Hazel/src/Hazel/Scene/Entity.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// Created by sfd on 25-5-28.
|
||||
//
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
Entity::Entity(entt::entity handle, Scene* scene)
|
||||
: m_EntityHandle(handle), m_Scene(scene)
|
||||
{
|
||||
}
|
||||
}
|
||||
82
Hazel/src/Hazel/Scene/Entity.h
Normal file
82
Hazel/src/Hazel/Scene/Entity.h
Normal file
@ -0,0 +1,82 @@
|
||||
//
|
||||
// Created by sfd on 25-5-28.
|
||||
//
|
||||
|
||||
#ifndef ENTITY_H
|
||||
#define ENTITY_H
|
||||
#include <Hazel/Core/Log.h>
|
||||
|
||||
#include "Scene.h"
|
||||
|
||||
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class HAZEL_API Entity
|
||||
{
|
||||
public:
|
||||
Entity() = default;
|
||||
Entity(entt::entity handle, Scene* scene);
|
||||
Entity(const Entity& other) = default;
|
||||
|
||||
|
||||
template<typename T, typename... Args>
|
||||
T& AddComponent(Args&&... args)
|
||||
{
|
||||
if (HasComponent<T>())
|
||||
{
|
||||
HZ_CORE_WARN("Entity already has this Component!");
|
||||
return GetComponent<T>();
|
||||
}
|
||||
|
||||
return m_Scene->m_Registry.emplace<T>(m_EntityHandle, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& GetComponent()
|
||||
{
|
||||
if (!HasComponent<T>())
|
||||
{
|
||||
HZ_CORE_ERROR("Entity has no component!");
|
||||
assert(-1);
|
||||
}
|
||||
return m_Scene->m_Registry.get<T>(m_EntityHandle);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void RemoveComponent() const
|
||||
{
|
||||
if (!HasComponent<T>())
|
||||
{
|
||||
HZ_CORE_WARN("Entity has no component!");
|
||||
return;
|
||||
}
|
||||
m_Scene->m_Registry.remove<T>(m_EntityHandle);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool HasComponent() const
|
||||
{
|
||||
if (auto entity = m_Scene->m_Registry.try_get<T>(m_EntityHandle))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
explicit operator bool() const { return m_EntityHandle != entt::null; }
|
||||
operator uint32_t() const { return static_cast<uint32_t>(m_EntityHandle); }
|
||||
|
||||
bool operator==(const Entity& other) const { return m_EntityHandle == other.m_EntityHandle && m_Scene == other.m_Scene; }
|
||||
bool operator!=(const Entity& other) const { return !(*this==other); }
|
||||
|
||||
private:
|
||||
entt::entity m_EntityHandle{ entt::null };
|
||||
Scene* m_Scene = nullptr;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //ENTITY_H
|
||||
105
Hazel/src/Hazel/Scene/Scene.cpp
Normal file
105
Hazel/src/Hazel/Scene/Scene.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
//
|
||||
// Created by sfd on 25-5-26.
|
||||
//
|
||||
|
||||
#include "Scene.h"
|
||||
|
||||
#include <Hazel/Renderer/Renderer2D.h>
|
||||
|
||||
#include "Components.h"
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
Scene::Scene()
|
||||
{
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
}
|
||||
|
||||
Entity Scene::CreateEntity(const std::string& name)
|
||||
{
|
||||
Entity entity = {m_Registry.create(), this};
|
||||
entity.AddComponent<TransformComponent>();
|
||||
entity.AddComponent<TagComponent>(name.empty() ? "Entity" : name);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
void Scene::OnUpdate(TimeStep& ts)
|
||||
{
|
||||
|
||||
// Update scripts
|
||||
{
|
||||
m_Registry.view<NativeScriptComponent>().each([=](auto entity, auto& nsc)
|
||||
{
|
||||
// TODO: move to Scene::OnScenePlay
|
||||
if (!nsc.Instance)
|
||||
{
|
||||
nsc.Instance = nsc.InstantiateScript();
|
||||
nsc.Instance->m_Entity = Entity{entity, this};
|
||||
nsc.Instance->OnCreate();
|
||||
}
|
||||
|
||||
nsc.Instance->OnUpdate(ts);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// Renderer 2D
|
||||
Camera* mainCamera = nullptr;
|
||||
glm::mat4* cameraTranform = nullptr;
|
||||
{
|
||||
for (auto view = m_Registry.view<TransformComponent, CameraComponent>(); const auto entity : view)
|
||||
{
|
||||
auto&& [transform, camera] = view.get<TransformComponent, CameraComponent>(entity);
|
||||
|
||||
if (camera.Primary)
|
||||
{
|
||||
mainCamera = &camera.Camera;
|
||||
cameraTranform = &transform.Transform;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mainCamera != nullptr)
|
||||
{
|
||||
|
||||
Renderer2D::BeginScene(mainCamera->GetProjection(), *cameraTranform);
|
||||
|
||||
auto group = m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
|
||||
for (auto entity : group)
|
||||
{
|
||||
auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity);
|
||||
|
||||
Renderer2D::DrawQuad(transform, sprite.Color);
|
||||
}
|
||||
|
||||
Renderer2D::EndScene();
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::OnViewportResize(uint32_t width, uint32_t height)
|
||||
{
|
||||
m_ViewportWidth = width;
|
||||
m_ViewportHeight = height;
|
||||
|
||||
//Reisze our non-fixedAspectRatio Cameras
|
||||
|
||||
auto view = m_Registry.view<CameraComponent>();
|
||||
for (auto entity : view)
|
||||
{
|
||||
auto& cameraComponent = view.get<CameraComponent>(entity);
|
||||
if (!cameraComponent.FixedAspectRatio)
|
||||
{
|
||||
cameraComponent.Camera.SetViewPortSize(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
41
Hazel/src/Hazel/Scene/Scene.h
Normal file
41
Hazel/src/Hazel/Scene/Scene.h
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// Created by sfd on 25-5-26.
|
||||
//
|
||||
|
||||
#ifndef SCENE_H
|
||||
#define SCENE_H
|
||||
|
||||
|
||||
#include <Hazel/Core/TimeStep.h>
|
||||
|
||||
#include "entt.hpp"
|
||||
#include "Hazel/Core/Core.h"
|
||||
|
||||
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class Entity;
|
||||
|
||||
class HAZEL_API Scene {
|
||||
public:
|
||||
Scene();
|
||||
~Scene();
|
||||
|
||||
Entity CreateEntity(const std::string& name = "");
|
||||
|
||||
void OnUpdate(TimeStep& ts);
|
||||
void OnViewportResize(uint32_t width, uint32_t height);
|
||||
|
||||
private:
|
||||
entt::registry m_Registry;
|
||||
|
||||
uint32_t m_ViewportWidth = 0, m_ViewportHeight = 0;
|
||||
|
||||
friend class Entity;
|
||||
friend class SceneHierachyPanel;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //SCENE_H
|
||||
5
Hazel/src/Hazel/Scene/ScriptableEntity.cpp
Normal file
5
Hazel/src/Hazel/Scene/ScriptableEntity.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by sfd on 25-5-28.
|
||||
//
|
||||
|
||||
#include "ScriptableEntity.h"
|
||||
37
Hazel/src/Hazel/Scene/ScriptableEntity.h
Normal file
37
Hazel/src/Hazel/Scene/ScriptableEntity.h
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// Created by sfd on 25-5-28.
|
||||
//
|
||||
|
||||
#ifndef SCRIPTABLEENTITY_H
|
||||
#define SCRIPTABLEENTITY_H
|
||||
|
||||
#include "Entity.h"
|
||||
#include "Hazel/Core/Core.h"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class HAZEL_API ScriptableEntity{
|
||||
public:
|
||||
|
||||
virtual ~ScriptableEntity() {}
|
||||
|
||||
template<typename T>
|
||||
T& GetComponent()
|
||||
{
|
||||
return m_Entity.GetComponent<T>();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void OnCreate(){}
|
||||
virtual void OnDestroy(){}
|
||||
virtual void OnUpdate(TimeStep ts) {}
|
||||
|
||||
private:
|
||||
Entity m_Entity;
|
||||
|
||||
friend class Scene;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //SCRIPTABLEENTITY_H
|
||||
109
Hazel/src/Platform/OpenGL/OpenGLFrameBuffer.cpp
Normal file
109
Hazel/src/Platform/OpenGL/OpenGLFrameBuffer.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
//
|
||||
// Created by sfd on 25-5-25.
|
||||
//
|
||||
|
||||
#include "OpenGLFrameBuffer.h"
|
||||
#include <glad/glad.h>
|
||||
#include <Hazel/Core/Log.h>
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
|
||||
static constexpr uint32_t s_MaxFrameBufferSize = 8192;
|
||||
|
||||
OpenGLFrameBuffer::OpenGLFrameBuffer(const FrameBufferSpecification& spec)
|
||||
: m_Specification(spec)
|
||||
{
|
||||
Invalidata();
|
||||
}
|
||||
|
||||
OpenGLFrameBuffer::~OpenGLFrameBuffer()
|
||||
{
|
||||
glDeleteFramebuffers(1, &m_RendererID);
|
||||
glDeleteTextures(1, &m_ColorAttachment);
|
||||
glDeleteTextures(1, &m_DepthAttachment);
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::Bind()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID);
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::UnBind()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::Resize(const uint32_t width, const uint32_t height)
|
||||
{
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
HZ_CORE_WARN("attempting to resize framebuffer to {0}x{1}", width, height);
|
||||
}
|
||||
|
||||
m_Specification.Width = width > s_MaxFrameBufferSize ? s_MaxFrameBufferSize : width;
|
||||
m_Specification.Height = height > s_MaxFrameBufferSize ? s_MaxFrameBufferSize : height;
|
||||
|
||||
Invalidata();
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::Invalidata()
|
||||
{
|
||||
|
||||
if (m_RendererID)
|
||||
{
|
||||
glDeleteFramebuffers(1, &m_RendererID);
|
||||
glDeleteTextures(1, &m_ColorAttachment);
|
||||
glDeleteTextures(1, &m_DepthAttachment);
|
||||
|
||||
glViewport(0, 0, m_Specification.Width, m_Specification.Height);
|
||||
}
|
||||
|
||||
glCreateFramebuffers(1, &m_RendererID);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID);
|
||||
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &m_ColorAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_ColorAttachment, 0);
|
||||
|
||||
|
||||
glCreateTextures(GL_TEXTURE_2D, 1, &m_DepthAttachment);
|
||||
glBindTexture(GL_TEXTURE_2D, m_DepthAttachment);
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height);
|
||||
// glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthAttachment, 0);
|
||||
|
||||
{
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
switch(status) {
|
||||
case GL_FRAMEBUFFER_COMPLETE:
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNDEFINED: /* 默认帧缓冲不存在 */
|
||||
HZ_CORE_ERROR("默认缓冲不存在!"); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: /* 附件不完整 */
|
||||
HZ_CORE_ERROR("附件不完整!"); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: /* 缺少颜色附件 */
|
||||
HZ_CORE_ERROR("附件不完整!"); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: /* 颜色附件索引无效 */
|
||||
HZ_CORE_ERROR("颜色附件索引无效!"); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: /* 读取缓冲区设置错误 */
|
||||
HZ_CORE_ERROR("读取缓冲区设置错误!"); break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED: /* 格式组合不支持 */
|
||||
HZ_CORE_ERROR("格式组合不支持!"); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: /* 多重采样不一致 */
|
||||
HZ_CORE_ERROR("多重采样不一致!"); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: /* 图层目标不完整 */
|
||||
HZ_CORE_ERROR("图层目标不完整!"); break;
|
||||
default: /* 未知错误 */
|
||||
HZ_CORE_ERROR("未知错误!"); break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
}
|
||||
34
Hazel/src/Platform/OpenGL/OpenGLFrameBuffer.h
Normal file
34
Hazel/src/Platform/OpenGL/OpenGLFrameBuffer.h
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// Created by sfd on 25-5-25.
|
||||
//
|
||||
|
||||
#ifndef OPENGLFRAMEBUFFER_H
|
||||
#define OPENGLFRAMEBUFFER_H
|
||||
#include <Hazel/Renderer/FrameBuffer.h>
|
||||
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class OpenGLFrameBuffer : public FrameBuffer
|
||||
{
|
||||
public:
|
||||
OpenGLFrameBuffer(const FrameBufferSpecification& spec);
|
||||
virtual ~OpenGLFrameBuffer();
|
||||
|
||||
void Bind() override;
|
||||
void UnBind() override;
|
||||
|
||||
virtual const FrameBufferSpecification& GetSpecification() const override { return m_Specification; }
|
||||
virtual uint32_t GetColorAttachmentID() const override { return m_ColorAttachment; }
|
||||
virtual void Resize(uint32_t width, uint32_t height) override;
|
||||
|
||||
void Invalidata();
|
||||
|
||||
private:
|
||||
uint32_t m_RendererID = 0;
|
||||
uint32_t m_ColorAttachment = 0, m_DepthAttachment = 0;
|
||||
FrameBufferSpecification m_Specification;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //OPENGLFRAMEBUFFER_H
|
||||
@ -21,8 +21,8 @@ namespace Hazel
|
||||
Init(props);
|
||||
}
|
||||
|
||||
Window* Window::Create(const WindowProps& props) {
|
||||
return new WindowsWindow(props);
|
||||
Scope<Window> Window::Create(const WindowProps& props) {
|
||||
return CreateScope<WindowsWindow>(props);
|
||||
}
|
||||
|
||||
|
||||
|
||||
21
Hazel/vendor/entt/LICENSE
vendored
Normal file
21
Hazel/vendor/entt/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-2025 Michele Caini, author of EnTT
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copy of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copy or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
93963
Hazel/vendor/entt/entt.hpp
vendored
Normal file
93963
Hazel/vendor/entt/entt.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,34 +1,24 @@
|
||||
set(PROJECT_NAME "Sandbox")
|
||||
set(PROJECT_NAME "HazelApp")
|
||||
|
||||
# SandBox
|
||||
project(${PROJECT_NAME})
|
||||
file(GLOB_RECURSE SOURCES
|
||||
src/SandboxApp.cpp
|
||||
src/SandBox2D/*.cpp)
|
||||
src/Sandbox2D/**.cpp)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Hazel)
|
||||
|
||||
|
||||
# demo App
|
||||
set(DEMO_PROJECT "${PROJECT_NAME}-Demo")
|
||||
file(GLOB_RECURSE DEMO_SOURCES
|
||||
|
||||
# Hazel-Editor
|
||||
set(PROJECT_NAME "${PROJECT_NAME}-Editor")
|
||||
project(${PROJECT_NAME})
|
||||
file(GLOB_RECURSE SOURCES
|
||||
src/SandboxApp.cpp
|
||||
src/DemoBox/*.cpp)
|
||||
src/Editor/**.cpp)
|
||||
|
||||
add_executable(${DEMO_PROJECT} ${DEMO_SOURCES})
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
|
||||
target_link_libraries(${DEMO_PROJECT} PRIVATE Hazel)
|
||||
|
||||
|
||||
# Example
|
||||
|
||||
set(EXAMPLE_PROJECT "${PROJECT_NAME}-Example")
|
||||
file(GLOB_RECURSE EXAMPLE_SOURCES
|
||||
src/SandboxApp.cpp
|
||||
src/Example/*.cpp)
|
||||
|
||||
add_executable(${EXAMPLE_PROJECT} ${EXAMPLE_SOURCES})
|
||||
|
||||
target_link_libraries(${EXAMPLE_PROJECT} PRIVATE Hazel)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Hazel)
|
||||
|
||||
258
Sandbox/src/Editor/EditorLayer.cpp
Normal file
258
Sandbox/src/Editor/EditorLayer.cpp
Normal file
@ -0,0 +1,258 @@
|
||||
//
|
||||
// Created by sfd on 25-5-25.
|
||||
//
|
||||
|
||||
#include "EditorLayer.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <iostream>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include "glm/ext/matrix_clip_space.hpp"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
EditorLayer::EditorLayer()
|
||||
: Layer("HazelEditor"), m_CameraController((float)Application::Get().GetWindow().GetWidth() / (float)Application::Get().GetWindow().GetHeight())
|
||||
{
|
||||
}
|
||||
|
||||
void EditorLayer::OnAttach()
|
||||
{
|
||||
|
||||
FrameBufferSpecification spec;
|
||||
spec.Width = Application::Get().GetWindow().GetWidth();
|
||||
spec.Height = Application::Get().GetWindow().GetHeight();
|
||||
m_FrameBuffer = FrameBuffer::Create(spec);
|
||||
|
||||
m_ViewPortSize = { spec.Width, spec.Height };
|
||||
|
||||
m_LogoTexture = Texture2D::Create("assets/textures/iceLogo.png");
|
||||
m_CheckerBoardTexture = Texture2D::Create("assets/textures/Checkerboard.png");
|
||||
|
||||
m_ActiveScene = CreateRef<Scene>();
|
||||
|
||||
// Entity
|
||||
m_SquareEntity = m_ActiveScene->CreateEntity("Square A");
|
||||
m_SquareEntity.AddComponent<SpriteRendererComponent>(glm::vec4{0.2f, 0.3f, 0.8f, 1.0f});
|
||||
|
||||
auto redSquare = m_ActiveScene->CreateEntity("Square B");
|
||||
redSquare.AddComponent<SpriteRendererComponent>(glm::vec4{1.0f, 0.0f, 0.0f, 1.0f});
|
||||
|
||||
|
||||
|
||||
|
||||
m_CameraEntity = m_ActiveScene->CreateEntity("Camera A");
|
||||
m_CameraEntity.AddComponent<CameraComponent>();
|
||||
m_PrimaryCamera = true;
|
||||
|
||||
|
||||
m_SecondCamera = m_ActiveScene->CreateEntity("Camera B");
|
||||
m_SecondCamera.AddComponent<CameraComponent>();
|
||||
m_SecondCamera.GetComponent<CameraComponent>().Primary = false;
|
||||
|
||||
|
||||
class CameraController : public ScriptableEntity
|
||||
{
|
||||
public:
|
||||
void OnUpdate(const TimeStep ts)
|
||||
{
|
||||
auto& transform = GetComponent<TransformComponent>().Transform;
|
||||
static const auto state = SDL_GetKeyboardState(nullptr);
|
||||
if (state[SDL_SCANCODE_A])
|
||||
transform[3][0] -= ts * speed;
|
||||
if (state[SDL_SCANCODE_D])
|
||||
transform[3][0] += ts * speed;
|
||||
if (state[SDL_SCANCODE_W])
|
||||
transform[3][1] += ts * speed;
|
||||
if (state[SDL_SCANCODE_S])
|
||||
transform[3][1] -= ts * speed;
|
||||
}
|
||||
private:
|
||||
float speed = 2.0f;
|
||||
};
|
||||
|
||||
m_CameraEntity.AddComponent<NativeScriptComponent>().Bind<CameraController>();
|
||||
m_SecondCamera.AddComponent<NativeScriptComponent>().Bind<CameraController>();
|
||||
|
||||
|
||||
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
||||
}
|
||||
|
||||
void EditorLayer::OnDetech()
|
||||
{
|
||||
}
|
||||
|
||||
void EditorLayer::OnUpdate(TimeStep& ts)
|
||||
{
|
||||
// reset Renderer Draw Stats
|
||||
Renderer2D::ResetStats();
|
||||
|
||||
if (const auto& spec = m_FrameBuffer->GetSpecification();
|
||||
spec.Width != m_ViewPortSize.x || spec.Height != m_ViewPortSize.y)
|
||||
{
|
||||
m_FrameBuffer->Resize((uint32_t)m_ViewPortSize.x, (uint32_t)m_ViewPortSize.y);
|
||||
m_CameraController.OnResize(m_ViewPortSize.x, m_ViewPortSize.y);
|
||||
|
||||
m_ActiveScene->OnViewportResize(m_ViewPortSize.x, m_ViewPortSize.y);
|
||||
|
||||
}
|
||||
|
||||
// update camera
|
||||
if (m_ViewportFocused && m_ViewportHovered)
|
||||
{
|
||||
m_CameraController.OnUpdate(ts);
|
||||
}
|
||||
|
||||
// update Renderer
|
||||
m_FrameBuffer->Bind();
|
||||
RendererCommand::SetClearColor(m_BackgroundColor);
|
||||
RendererCommand::Clear();
|
||||
|
||||
|
||||
// Renderer2D::BeginScene(m_cameraController.GetCamera());
|
||||
|
||||
// update Scene
|
||||
m_ActiveScene->OnUpdate(ts);
|
||||
|
||||
// Renderer2D::DrawQuad({0, 0.5f}, {1.0f, 1.0f}, {0.2f, 0.3f, 0.8f, 1.0f});
|
||||
// Renderer2D::DrawQuad({0, -0.5f}, {1.0f, 1.0f}, {0.8f, 0.2f, 0.2f, 1.0f});
|
||||
// Renderer2D::DrawQuad({-1, 0}, {1, 1}, m_LogoTexture);
|
||||
// Renderer2D::DrawQuad({1, 0}, {1, 1}, m_CheckerBoardTexture);
|
||||
|
||||
// Renderer2D::EndScene();
|
||||
m_FrameBuffer->UnBind();
|
||||
}
|
||||
|
||||
void EditorLayer::OnImGuiRender()
|
||||
{
|
||||
static bool showDockspace = true;
|
||||
if (showDockspace)
|
||||
{
|
||||
static bool dockspaceOpen = true;
|
||||
static bool opt_fullscreen = true;
|
||||
static bool opt_padding = false;
|
||||
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
|
||||
|
||||
// We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into,
|
||||
// because it would be confusing to have two docking targets within each others.
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
||||
if (opt_fullscreen)
|
||||
{
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoMove;
|
||||
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||
}
|
||||
else
|
||||
{
|
||||
dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode;
|
||||
}
|
||||
|
||||
// When using ImGuiDockNodeFlags_PassthruCentralNode, DockSpace() will render our background
|
||||
// and handle the pass-thru hole, so we ask Begin() to not render a background.
|
||||
if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode)
|
||||
window_flags |= ImGuiWindowFlags_NoBackground;
|
||||
|
||||
// Important: note that we proceed even if Begin() returns false (aka window is collapsed).
|
||||
// This is because we want to keep our DockSpace() active. If a DockSpace() is inactive,
|
||||
// all active windows docked into it will lose their parent and become undocked.
|
||||
// We cannot preserve the docking relationship between an active window and an inactive docking, otherwise
|
||||
// any change of dockspace/settings would lead to windows being stuck in limbo and never being visible.
|
||||
if (!opt_padding)
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::Begin("DockSpace Demo", &dockspaceOpen, window_flags);
|
||||
if (!opt_padding)
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
if (opt_fullscreen)
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
// Submit the DockSpace
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
|
||||
{
|
||||
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
{
|
||||
// Disabling fullscreen would allow the window to be moved to the front of other windows,
|
||||
// which we can't undo at the moment without finer window depth/z control.
|
||||
// ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen);
|
||||
// ImGui::MenuItem("Padding", NULL, &opt_padding);
|
||||
// ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("Exit")) { Hazel::Application::Get().Close(); }
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
m_SceneHierachyPanel.OnImGuiRender();
|
||||
{
|
||||
ImGui::Begin("Render Status");
|
||||
|
||||
auto stats = Renderer2D::GetStats();
|
||||
ImGui::Text("Renderer BatchInfo: ");
|
||||
ImGui::Text("Draw Calls: %d", stats.DrawCalls);
|
||||
ImGui::Text("Quads: %d", stats.QuadCount);
|
||||
ImGui::Text("Vertices: %d", stats.GetTotalVertexCount());
|
||||
ImGui::Text("Indices: %d", stats.GetTotalIndexCount());
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::Checkbox("Camera A", &m_PrimaryCamera))
|
||||
{
|
||||
m_CameraEntity.GetComponent<CameraComponent>().Primary = m_PrimaryCamera;
|
||||
m_SecondCamera.GetComponent<CameraComponent>().Primary = !m_PrimaryCamera;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("viewPortSize: (%.2f, %.2f)", m_ViewPortSize.x, m_ViewPortSize.y);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {0.0f, 0.0f});
|
||||
ImGui::Begin("Viewport");
|
||||
m_ViewportFocused = ImGui::IsWindowFocused();
|
||||
m_ViewportHovered = ImGui::IsWindowHovered();
|
||||
|
||||
|
||||
ImVec2 viewPortPanelSize = ImGui::GetContentRegionAvail();
|
||||
if (m_ViewPortSize != *reinterpret_cast<glm::vec2*>(&viewPortPanelSize))
|
||||
{
|
||||
m_ViewPortSize = {viewPortPanelSize.x, viewPortPanelSize.y};
|
||||
}
|
||||
// ImGui::Text("Viewport: (%.2f, %.2f)", viewPortPanelSize.x, viewPortPanelSize.y);
|
||||
ImGui::Image(m_FrameBuffer->GetColorAttachmentID(), {m_ViewPortSize.x, m_ViewPortSize.y}, {0, 1},
|
||||
{1, 0});
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorLayer::OnEvent(SDL_Event& e)
|
||||
{
|
||||
if (m_ViewportFocused && m_ViewportHovered)
|
||||
{
|
||||
m_CameraController.OnEvent(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
Sandbox/src/Editor/EditorLayer.h
Normal file
53
Sandbox/src/Editor/EditorLayer.h
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// Created by sfd on 25-5-25.
|
||||
//
|
||||
|
||||
#ifndef EDITORLAYER_H
|
||||
#define EDITORLAYER_H
|
||||
#include <Hazel.h>
|
||||
|
||||
#include "Panels/SceneHierachyPanel.h"
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class EditorLayer : public Layer
|
||||
{
|
||||
public:
|
||||
EditorLayer();
|
||||
virtual ~EditorLayer() = default;
|
||||
|
||||
virtual void OnAttach() override;
|
||||
virtual void OnDetech() override;
|
||||
|
||||
virtual void OnUpdate(TimeStep& ts) override;
|
||||
virtual void OnImGuiRender() override;
|
||||
virtual void OnEvent(SDL_Event& e) override;
|
||||
|
||||
private:
|
||||
OrthographicCameraController m_CameraController;
|
||||
|
||||
Ref<Texture2D> m_LogoTexture;
|
||||
Ref<Texture2D> m_CheckerBoardTexture;
|
||||
|
||||
Ref<Scene> m_ActiveScene;
|
||||
Entity m_SquareEntity;
|
||||
Entity m_CameraEntity;
|
||||
Entity m_SecondCamera;
|
||||
|
||||
bool m_PrimaryCamera = false;
|
||||
|
||||
glm::vec4 m_BackgroundColor = { 0.2f, 0.2f, 0.2f, 1.0f };
|
||||
glm::vec4 m_SquareColor = { 0.2f, 0.2f, 0.2f, 1.0f };
|
||||
|
||||
bool m_ViewportFocused = false, m_ViewportHovered = false;
|
||||
glm::vec2 m_ViewPortSize = {0, 0};
|
||||
|
||||
Ref<FrameBuffer> m_FrameBuffer;
|
||||
|
||||
SceneHierachyPanel m_SceneHierachyPanel;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //EDITORLAYER_H
|
||||
168
Sandbox/src/Editor/Panels/SceneHierachyPanel.cpp
Normal file
168
Sandbox/src/Editor/Panels/SceneHierachyPanel.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
//
|
||||
// Created by sfd on 25-5-29.
|
||||
//
|
||||
|
||||
#include "SceneHierachyPanel.h"
|
||||
|
||||
#include <imgui.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <Hazel/Scene/Components.h>
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
SceneHierachyPanel::SceneHierachyPanel(const Ref<Scene>& context)
|
||||
{
|
||||
SetContext(context);
|
||||
}
|
||||
|
||||
void SceneHierachyPanel::SetContext(const Ref<Scene>& context)
|
||||
{
|
||||
m_Context = context;
|
||||
}
|
||||
|
||||
void SceneHierachyPanel::OnImGuiRender()
|
||||
{
|
||||
ImGui::Begin("Scene Hierachy");
|
||||
|
||||
for (const auto entityID : m_Context->m_Registry.view<entt::entity>())
|
||||
{
|
||||
DrawEntityNode({entityID, m_Context.get()});
|
||||
}
|
||||
|
||||
if (ImGui::IsMouseDown(0) && ImGui::IsWindowHovered())
|
||||
{
|
||||
m_SelectionContext = { };
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
ImGui::Begin("Properties");
|
||||
if (m_SelectionContext)
|
||||
{
|
||||
DrawComponents(m_SelectionContext);
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
void SceneHierachyPanel::DrawEntityNode(Entity entity)
|
||||
{
|
||||
auto& tag = entity.GetComponent<TagComponent>().Tag;
|
||||
|
||||
ImGuiTreeNodeFlags flags = ((m_SelectionContext == entity) ? ImGuiTreeNodeFlags_Selected : 0) | ImGuiTreeNodeFlags_OpenOnArrow;
|
||||
const bool isopened = ImGui::TreeNodeEx((void*)(uint64_t)(uint32_t)entity, flags, tag.c_str());
|
||||
if (ImGui::IsItemClicked())
|
||||
{
|
||||
m_SelectionContext = entity;
|
||||
}
|
||||
|
||||
if (isopened)
|
||||
{
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneHierachyPanel::DrawComponents(Entity entity)
|
||||
{
|
||||
|
||||
if (entity.HasComponent<TagComponent>())
|
||||
{
|
||||
auto& tag = entity.GetComponent<TagComponent>().Tag;
|
||||
|
||||
char buffer[256] = {};
|
||||
strcpy_s(buffer,sizeof(buffer), tag.c_str());
|
||||
if (ImGui::InputText("Tag", buffer, sizeof(buffer)))
|
||||
{
|
||||
tag = std::string(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.HasComponent<TransformComponent>())
|
||||
{
|
||||
if (ImGui::TreeNodeEx((void*)(uint64_t)typeid(TransformComponent).hash_code(), ImGuiTreeNodeFlags_DefaultOpen, "Transform"))
|
||||
{
|
||||
auto& transform = entity.GetComponent<TransformComponent>().Transform;
|
||||
ImGui::DragFloat3("Position", glm::value_ptr(transform[3]), 0.01f);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.HasComponent<CameraComponent>())
|
||||
{
|
||||
if (ImGui::TreeNodeEx((void*)(uint64_t)typeid(CameraComponent).hash_code(), ImGuiTreeNodeFlags_DefaultOpen, "Transform"))
|
||||
{
|
||||
auto& cameraComponent = entity.GetComponent<CameraComponent>();
|
||||
auto& camera = cameraComponent.Camera;
|
||||
|
||||
ImGui::Checkbox("isPrimary", &cameraComponent.Primary);
|
||||
|
||||
static const char* projectionTypeStrings[] = { "Perspective", "Orthographic" };
|
||||
|
||||
const char* currentProjectionTypeString = projectionTypeStrings[(int)camera.GetProjectionType()];
|
||||
if (ImGui::BeginCombo("Projection", currentProjectionTypeString))
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
const bool isSelected = currentProjectionTypeString == projectionTypeStrings[i];
|
||||
if (ImGui::Selectable(projectionTypeStrings[i], isSelected))
|
||||
{
|
||||
currentProjectionTypeString = projectionTypeStrings[i];
|
||||
camera.SetProjectionType(static_cast<ScenceCamera::ProjectionType>(i));
|
||||
}
|
||||
|
||||
if (isSelected)
|
||||
{
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (camera.GetProjectionType() == ScenceCamera::ProjectionType::Perspective)
|
||||
{
|
||||
float fov = glm::degrees(camera.GetPerspectiveVerticalFOV());
|
||||
if (ImGui::DragFloat("FOV", &fov, 0.1f))
|
||||
camera.SetPerspectiveVerticalFOV(glm::radians(fov));
|
||||
|
||||
float near = camera.GetPerspectiveNearCLip();
|
||||
if (ImGui::DragFloat("Near", &near))
|
||||
camera.SetPerspectiveNearClip(near);
|
||||
|
||||
float far = camera.GetPerspectiveFarCLip();
|
||||
if (ImGui::DragFloat("Far", &far))
|
||||
camera.SetPerspectiveFarClip(far);
|
||||
}
|
||||
if (camera.GetProjectionType() == ScenceCamera::ProjectionType::Orthographic)
|
||||
{
|
||||
float size = camera.GetOrthographicSize();
|
||||
if (ImGui::DragFloat("Size", &size))
|
||||
camera.SetOrthographicSize(size);
|
||||
|
||||
float near = camera.GetOrthographicNearCLip();
|
||||
if (ImGui::DragFloat("Near", &near))
|
||||
camera.SetOrthographicNearClip(near);
|
||||
|
||||
float far = camera.GetOrthographicFarCLip();
|
||||
if (ImGui::DragFloat("Far", &far))
|
||||
camera.SetOrthographicFarClip(far);
|
||||
|
||||
ImGui::Checkbox("Fixed Aspect Ratio", &cameraComponent.FixedAspectRatio);
|
||||
}
|
||||
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.HasComponent<SpriteRendererComponent>())
|
||||
{
|
||||
if (ImGui::TreeNodeEx((void*)(uint64_t)typeid(SpriteRendererComponent).hash_code(), ImGuiTreeNodeFlags_DefaultOpen, "Sprite Renderer"))
|
||||
{
|
||||
auto& spriteRendererComponent = entity.GetComponent<SpriteRendererComponent>();
|
||||
ImGui::ColorEdit4("Color", glm::value_ptr(spriteRendererComponent.Color));
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Sandbox/src/Editor/Panels/SceneHierachyPanel.h
Normal file
35
Sandbox/src/Editor/Panels/SceneHierachyPanel.h
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Created by sfd on 25-5-29.
|
||||
//
|
||||
|
||||
#ifndef SCENEHIERACHYPANEL_H
|
||||
#define SCENEHIERACHYPANEL_H
|
||||
#include <Hazel/Core/Core.h>
|
||||
#include <Hazel/Scene/Entity.h>
|
||||
#include <Hazel/Scene/Scene.h>
|
||||
|
||||
namespace Hazel
|
||||
{
|
||||
class SceneHierachyPanel
|
||||
{
|
||||
public:
|
||||
SceneHierachyPanel() = default;
|
||||
SceneHierachyPanel(const Ref<Scene>& context);
|
||||
|
||||
void SetContext(const Ref<Scene>& context);
|
||||
void OnImGuiRender();
|
||||
|
||||
void DrawComponents(Entity entity);
|
||||
|
||||
private:
|
||||
void DrawEntityNode(Entity entity);
|
||||
|
||||
private:
|
||||
|
||||
Ref<Scene> m_Context;
|
||||
Entity m_SelectionContext;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //SCENEHIERACHYPANEL_H
|
||||
@ -8,8 +8,26 @@
|
||||
|
||||
#include "glm/gtc/type_ptr.hpp"
|
||||
|
||||
static constexpr uint32_t s_MapWidth = 24;
|
||||
static const char* s_MapTiles =
|
||||
"WWWWWWWDDDDDDDDWWWAWWWWW"
|
||||
"WWWWWWWDWWWWWWWWWWWWWWWW"
|
||||
"WWWWWWWWWDDDDDDDDDDWWWWW"
|
||||
"WWWWWWWDDDDDDDWWWWWWWWWW"
|
||||
"WWWWWDDDDDDDDDDWWWWWWWWW"
|
||||
"WWWWDDDDDDDDDDWDDDDDWWWW"
|
||||
"WWDDDDDDWWWWWWWWDDDDDWWW"
|
||||
"WDDDDDDWWWWWWWWWDDDDWWWW"
|
||||
"WDDDDDDDDDDWWWWDDDDWWWWW"
|
||||
"WWWWDDDDDDDDDDDDDDWWWWWW"
|
||||
"WWWWWWWWWWWWWWWWWWWWWWWW"
|
||||
"WWWWWWWWWWWWWWWWWWWWWWWW";
|
||||
|
||||
SandBox2D::SandBox2D()
|
||||
: Layer("SandBox2D"), m_CameraController((float)Hazel::Application::Get().GetWindow().GetWidth() / (float)Hazel::Application::Get().GetWindow().GetHeight())
|
||||
: Layer("SandBox2D"),
|
||||
m_CameraController(
|
||||
(float)Hazel::Application::Get().GetWindow().GetWidth() / (float)Hazel::Application::Get().GetWindow().
|
||||
GetHeight())
|
||||
{
|
||||
}
|
||||
|
||||
@ -17,17 +35,28 @@ void SandBox2D::OnAttach()
|
||||
{
|
||||
HZ_PROFILE_FUNCTION();
|
||||
m_LogoTexture = Hazel::Texture2D::Create("assets/textures/iceLogo.png");
|
||||
m_Texture = Hazel::Texture2D::Create("assets/textures/spritesheet-tiles-double.png");
|
||||
m_SubTexture = Hazel::SubTexture2D::CreateFromCoords(m_Texture, {8, 5}, {128, 128}, {1, 2});
|
||||
m_Texture = Hazel::Texture2D::Create("assets/textures/spritesheet-tiles-double.png");
|
||||
|
||||
m_Particle.ColorBegin = {0 / 255.f, 212 /255.f, 123 / 255.f,1.0f};
|
||||
m_Particle.ColorEnd = {254 / 255.f, 109 /255.f, 41 / 255.f,1.0f};
|
||||
m_Particle.SizeBegin = 0.3f, m_Particle.SizeVariation = 0.3f, m_Particle.SizeEnd = 0.0f;
|
||||
m_Particle.LifeTime = 1.0f;
|
||||
m_Particle.Velocity = {0.0f, 0.0f};
|
||||
m_MapWidth = s_MapWidth;
|
||||
m_MapHeight = strlen(s_MapTiles) / s_MapWidth;
|
||||
|
||||
m_defaultTexture = Hazel::SubTexture2D::CreateFromCoords(m_Texture, {13, 3}, {128, 128});
|
||||
|
||||
m_TextureMap['D'] = Hazel::SubTexture2D::CreateFromCoords(m_Texture, {1, 2}, {128, 128});
|
||||
m_TextureMap['W'] = Hazel::SubTexture2D::CreateFromCoords(m_Texture, {0, 11}, {128, 128});
|
||||
// m_SubTexture = Hazel::SubTexture2D::CreateFromCoords(m_Texture, {8, 5}, {128, 128}, {1, 2});
|
||||
Hazel::FrameBufferSpecification specification;
|
||||
specification.Width = 1280;
|
||||
specification.Height = 720;
|
||||
m_FrameBuffer = Hazel::FrameBuffer::Create(specification);
|
||||
|
||||
m_Particle.ColorBegin = {0 / 255.f, 212 / 255.f, 123 / 255.f, 1.0f};
|
||||
m_Particle.ColorEnd = {254 / 255.f, 109 / 255.f, 41 / 255.f, 1.0f};
|
||||
m_Particle.SizeBegin = 0.3f, m_Particle.SizeVariation = 0.3f, m_Particle.SizeEnd = 0.0f;
|
||||
m_Particle.LifeTime = 1.0f;
|
||||
m_Particle.Velocity = {0.0f, 0.0f};
|
||||
m_Particle.VelocityVariation = {2.0f, 2.0f};
|
||||
m_Particle.Position = {0.0f, 0.0f};
|
||||
|
||||
m_Particle.Position = {0.0f, 0.0f};
|
||||
}
|
||||
|
||||
void SandBox2D::OnDetech()
|
||||
@ -46,47 +75,51 @@ void SandBox2D::OnUpdate(Hazel::TimeStep& ts)
|
||||
|
||||
{
|
||||
HZ_PROFILE_SCOPE("Renderer Prep");
|
||||
// Hazel::RendererCommand::SetClearColor({0.2f, 0.2f, 0.2f, 1.0f});
|
||||
|
||||
m_FrameBuffer->Bind();
|
||||
Hazel::RendererCommand::SetClearColor(m_BackgroundColor);
|
||||
Hazel::RendererCommand::Clear();
|
||||
}
|
||||
|
||||
{
|
||||
HZ_PROFILE_SCOPE("Renderer Draw");
|
||||
Hazel::Renderer2D::BeginScene(m_CameraController.GetCamera());
|
||||
|
||||
for (unsigned int y = 0; y < m_MapHeight; y++)
|
||||
{
|
||||
for (unsigned int x = 0; x < m_MapWidth; x++)
|
||||
{
|
||||
const char tileType = s_MapTiles[y * m_MapWidth + x];
|
||||
Hazel::Ref<Hazel::SubTexture2D> texture;
|
||||
if (m_TextureMap.find(tileType) != m_TextureMap.end())
|
||||
{
|
||||
texture = m_TextureMap[tileType];
|
||||
}else
|
||||
{
|
||||
texture = m_defaultTexture;
|
||||
}
|
||||
|
||||
// Hazel::Renderer2D::DrawQuad({0, 0}, {1.0f,1.0f}, {1.0f, 1.0f, 1.0f, 1.0f});
|
||||
Hazel::Renderer2D::DrawRotateQuad({-0.5f, 0}, {1.0f,1.0f}, glm::radians(0.f), m_LogoTexture);
|
||||
// Hazel::Renderer2D::DrawQuad({0.5f, 0}, {1.0f,1.0f}, m_Texture);
|
||||
Hazel::Renderer2D::DrawQuad({0.5f, 0}, {1.0f,2.0f}, m_SubTexture);
|
||||
|
||||
// Hazel::Renderer2D::DrawRotateQuad({-1.0f, 0.0f}, {0.5f, 0.5f}, 75.f, {1.0f, 0.0f, 1.0f, 1.0f});
|
||||
// Hazel::Renderer2D::DrawRotateQuad({0.0f, 0.0f}, {1.0f, 1.0f}, rotation, m_LogoTexture, 10.f);
|
||||
|
||||
for (float y = -5.0f; y < 5.0f; y += 0.5f)
|
||||
{
|
||||
for (float x = -5.0f; x < 5.0f; x += 0.5f)
|
||||
{
|
||||
auto color = glm::vec4((x + 5.0f ) /10.0f, 0.4f, (y + 5.0f) / 10.0f, 1.0f);
|
||||
Hazel::Renderer2D::DrawQuad({x, y, -0.1f}, {0.45f, 0.45f}, m_LogoTexture, 1, color);
|
||||
}
|
||||
}
|
||||
Hazel::Renderer2D::DrawQuad({x - m_MapWidth / 2.0f, m_MapHeight / 2.0f - y, -0.1f}, {1.0f, 1.0f}, texture);
|
||||
}
|
||||
}
|
||||
|
||||
Hazel::Renderer2D::EndScene();
|
||||
if ((mouseState & SDL_BUTTON_LMASK) && m_CurrentWindowID == Hazel::Application::Get().GetWindow().GetMainWindowID())
|
||||
|
||||
if ((mouseState & SDL_BUTTON_LMASK) && m_CurrentWindowID == Hazel::Application::Get().GetWindow().
|
||||
GetMainWindowID())
|
||||
{
|
||||
auto width = Hazel::Application::Get().GetWindow().GetWidth();
|
||||
auto width = Hazel::Application::Get().GetWindow().GetWidth();
|
||||
auto height = Hazel::Application::Get().GetWindow().GetHeight();
|
||||
|
||||
float x, y;
|
||||
SDL_GetMouseState(&x, &y);
|
||||
auto bounds = m_CameraController.GetBounds();
|
||||
auto bounds = m_CameraController.GetBounds();
|
||||
auto cameraPos = m_CameraController.GetCamera().GetPosition();
|
||||
|
||||
x = (x / width) * bounds.GetWidth() - bounds.GetWidth() * 0.5f;
|
||||
y = bounds.GetHeight() * 0.5f - (y / height) * bounds.GetHeight();
|
||||
x = (x / width) * bounds.GetWidth() - bounds.GetWidth() * 0.5f;
|
||||
y = bounds.GetHeight() * 0.5f - (y / height) * bounds.GetHeight();
|
||||
m_Particle.Position = {x + cameraPos.x, y + cameraPos.y};
|
||||
for (int i = 0; i < 5; i ++)
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
m_ParticleSystem.Emit(m_Particle);
|
||||
}
|
||||
@ -95,57 +128,145 @@ void SandBox2D::OnUpdate(Hazel::TimeStep& ts)
|
||||
m_ParticleSystem.OnUpdate(ts);
|
||||
m_ParticleSystem.OnRender(m_CameraController.GetCamera());
|
||||
}
|
||||
m_FrameBuffer->UnBind();
|
||||
|
||||
}
|
||||
|
||||
void SandBox2D::OnImGuiRender()
|
||||
{
|
||||
// const auto cameraRotation = m_CameraController.GetCamera().GetRotation();
|
||||
const auto cameraPosition = m_CameraController.GetCamera().GetPosition();
|
||||
const auto windowWidth = Hazel::Application::Get().GetWindow().GetWidth();
|
||||
const auto windowHeight = Hazel::Application::Get().GetWindow().GetHeight();
|
||||
|
||||
auto stats = Hazel::Renderer2D::GetStats();
|
||||
|
||||
ImGui::Begin("Hazel Layer");
|
||||
|
||||
ImGui::Text("Renderer BatchInfo: ");
|
||||
ImGui::Text("Draw Calls: %d", stats.DrawCalls);
|
||||
ImGui::Text("Quads: %d", stats.QuadCount);
|
||||
ImGui::Text("Vertices: %d", stats.GetTotalVertexCount());
|
||||
ImGui::Text("Indices: %d", stats.GetTotalIndexCount());
|
||||
|
||||
ImGui::Text("WindowSize: (%u, %u)", windowWidth, windowHeight);
|
||||
|
||||
ImGui::Text("Camera");
|
||||
// ImGui::Text("Camera Rotation: %f", cameraRotation);
|
||||
ImGui::Text("Camera Position: ( %.2f, %.2f, %.2f)", cameraPosition.x, cameraPosition.y, cameraPosition.z);
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::Text("frame: %.3f", ImGui::GetIO().Framerate);
|
||||
ImGui::ColorEdit4("Square Color", glm::value_ptr(m_BackgroundColor));
|
||||
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::ColorEdit4("begin Color", glm::value_ptr(m_Particle.ColorBegin));
|
||||
ImGui::ColorEdit4("End Color", glm::value_ptr(m_Particle.ColorEnd));
|
||||
|
||||
ImGui::NewLine();
|
||||
for (auto& profileResult : m_ProfileResults)
|
||||
{
|
||||
ImGui::Text("%s: %.3fms", profileResult.Name, profileResult.Time);
|
||||
}
|
||||
m_ProfileResults.clear();
|
||||
|
||||
ImGui::NewLine();
|
||||
static bool isSync = Hazel::Application::Get().GetWindow().IsVSync();
|
||||
bool laststate = isSync;
|
||||
ImGui::Checkbox("isVSync", &isSync);
|
||||
if (isSync != laststate)
|
||||
{
|
||||
Hazel::Application::Get().GetWindow().SetVSync(isSync);
|
||||
}
|
||||
|
||||
ImGui::Begin("Settings");
|
||||
ImGui::Image(m_FrameBuffer->GetColorAttachmentID(), {1280.f, 720.f});
|
||||
ImGui::End();
|
||||
|
||||
static bool showDockspace = false;
|
||||
if (showDockspace)
|
||||
{
|
||||
// const auto cameraRotation = m_CameraController.GetCamera().GetRotation();
|
||||
const auto cameraPosition = m_CameraController.GetCamera().GetPosition();
|
||||
const auto windowWidth = Hazel::Application::Get().GetWindow().GetWidth();
|
||||
const auto windowHeight = Hazel::Application::Get().GetWindow().GetHeight();
|
||||
|
||||
auto stats = Hazel::Renderer2D::GetStats();
|
||||
|
||||
|
||||
static bool dockspaceOpen = true;
|
||||
static bool opt_fullscreen = true;
|
||||
static bool opt_padding = false;
|
||||
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
|
||||
|
||||
// We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into,
|
||||
// because it would be confusing to have two docking targets within each others.
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
||||
if (opt_fullscreen)
|
||||
{
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoMove;
|
||||
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||
}
|
||||
else
|
||||
{
|
||||
dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode;
|
||||
}
|
||||
|
||||
// When using ImGuiDockNodeFlags_PassthruCentralNode, DockSpace() will render our background
|
||||
// and handle the pass-thru hole, so we ask Begin() to not render a background.
|
||||
if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode)
|
||||
window_flags |= ImGuiWindowFlags_NoBackground;
|
||||
|
||||
// Important: note that we proceed even if Begin() returns false (aka window is collapsed).
|
||||
// This is because we want to keep our DockSpace() active. If a DockSpace() is inactive,
|
||||
// all active windows docked into it will lose their parent and become undocked.
|
||||
// We cannot preserve the docking relationship between an active window and an inactive docking, otherwise
|
||||
// any change of dockspace/settings would lead to windows being stuck in limbo and never being visible.
|
||||
if (!opt_padding)
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::Begin("DockSpace Demo", &dockspaceOpen, window_flags);
|
||||
if (!opt_padding)
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
if (opt_fullscreen)
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
// Submit the DockSpace
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
|
||||
{
|
||||
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
{
|
||||
// Disabling fullscreen would allow the window to be moved to the front of other windows,
|
||||
// which we can't undo at the moment without finer window depth/z control.
|
||||
// ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen);
|
||||
// ImGui::MenuItem("Padding", NULL, &opt_padding);
|
||||
// ImGui::Separator();
|
||||
|
||||
if (ImGui::MenuItem("Exit")) { Hazel::Application::Get().Close(); }
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
{
|
||||
ImGui::Begin("Hazel Layer");
|
||||
|
||||
ImGui::Text("Renderer BatchInfo: ");
|
||||
ImGui::Text("Draw Calls: %d", stats.DrawCalls);
|
||||
ImGui::Text("Quads: %d", stats.QuadCount);
|
||||
ImGui::Text("Vertices: %d", stats.GetTotalVertexCount());
|
||||
ImGui::Text("Indices: %d", stats.GetTotalIndexCount());
|
||||
|
||||
ImGui::Text("WindowSize: (%u, %u)", windowWidth, windowHeight);
|
||||
|
||||
ImGui::Text("Camera");
|
||||
// ImGui::Text("Camera Rotation: %f", cameraRotation);
|
||||
ImGui::Text("Camera Position: ( %.2f, %.2f, %.2f)", cameraPosition.x, cameraPosition.y, cameraPosition.z);
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::Text("frame: %.3f", ImGui::GetIO().Framerate);
|
||||
ImGui::ColorEdit4("Square Color", glm::value_ptr(m_BackgroundColor));
|
||||
|
||||
|
||||
ImGui::NewLine();
|
||||
ImGui::ColorEdit4("begin Color", glm::value_ptr(m_Particle.ColorBegin));
|
||||
ImGui::ColorEdit4("End Color", glm::value_ptr(m_Particle.ColorEnd));
|
||||
|
||||
ImGui::NewLine();
|
||||
for (auto& profileResult : m_ProfileResults)
|
||||
{
|
||||
ImGui::Text("%s: %.3fms", profileResult.Name, profileResult.Time);
|
||||
}
|
||||
m_ProfileResults.clear();
|
||||
|
||||
ImGui::NewLine();
|
||||
static bool isSync = Hazel::Application::Get().GetWindow().IsVSync();
|
||||
bool laststate = isSync;
|
||||
ImGui::Checkbox("isVSync", &isSync);
|
||||
if (isSync != laststate)
|
||||
{
|
||||
Hazel::Application::Get().GetWindow().SetVSync(isSync);
|
||||
}
|
||||
uint32_t textureID = m_FrameBuffer->GetColorAttachmentID();
|
||||
ImGui::Image(textureID, ImVec2(1280.f, 720.f));
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
void SandBox2D::OnEvent(SDL_Event& e)
|
||||
@ -153,5 +274,5 @@ void SandBox2D::OnEvent(SDL_Event& e)
|
||||
if (m_CurrentWindowID != e.window.windowID)
|
||||
m_CurrentWindowID = e.window.windowID;
|
||||
|
||||
m_CameraController.OnEvent(e);
|
||||
m_CameraController.OnEvent(e);
|
||||
}
|
||||
|
||||
@ -24,7 +24,8 @@ private:
|
||||
Hazel::Ref<Hazel::Shader> m_FlatColorShader;
|
||||
Hazel::Ref<Hazel::Texture2D> m_Texture;
|
||||
Hazel::Ref<Hazel::Texture2D> m_LogoTexture;
|
||||
Hazel::Ref<Hazel::SubTexture2D> m_SubTexture;
|
||||
Hazel::Ref<Hazel::SubTexture2D> m_defaultTexture;
|
||||
Hazel::Ref<Hazel::FrameBuffer> m_FrameBuffer;
|
||||
|
||||
glm::vec4 m_BackgroundColor = {0.2f, 0.2f, 0.2f, 1.0f};
|
||||
|
||||
@ -35,6 +36,8 @@ private:
|
||||
};
|
||||
|
||||
std::vector<ProfileResult> m_ProfileResults;
|
||||
std::unordered_map<char, Hazel::Ref<Hazel::SubTexture2D>> m_TextureMap;
|
||||
uint32_t m_MapWidth, m_MapHeight;
|
||||
|
||||
ParticleSystem m_ParticleSystem;
|
||||
ParticleProp m_Particle;
|
||||
|
||||
@ -1,31 +1,28 @@
|
||||
#include <Hazel.h>
|
||||
#include "Hazel/Core/EntryPoint.h"
|
||||
|
||||
#include "SandBox2D/SandBox2D.h"
|
||||
// #include "DemoBox/GameLayer.h"
|
||||
// #include "Example/ExampleLayer.h"
|
||||
#include "Editor/EditorLayer.h"
|
||||
|
||||
|
||||
|
||||
class Sandbox : public Hazel::Application
|
||||
namespace Hazel
|
||||
{
|
||||
public:
|
||||
Sandbox()
|
||||
class HazelEditor : public Application
|
||||
{
|
||||
// PushLayer(new ExampleLayer());
|
||||
PushLayer(new SandBox2D());
|
||||
// PushLayer(new GameLayer());
|
||||
public:
|
||||
HazelEditor()
|
||||
: Application("Hazel Editor", 1280, 720)
|
||||
{
|
||||
PushLayer(new EditorLayer());
|
||||
}
|
||||
|
||||
~HazelEditor() = default;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
Application* CreateApplication()
|
||||
{
|
||||
return new HazelEditor();
|
||||
}
|
||||
|
||||
~Sandbox();
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
Sandbox::~Sandbox() = default;
|
||||
|
||||
Hazel::Application* Hazel::CreateApplication()
|
||||
{
|
||||
return new Sandbox();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user