添加简单的可视化三维控件,添加简单的摄像机控制,添加简单全局输入事件

This commit is contained in:
2025-06-05 19:38:50 +08:00
parent b47fce6fce
commit b2c7a45902
28 changed files with 653 additions and 146 deletions

3
.gitmodules vendored
View File

@ -14,3 +14,6 @@
[submodule "Hazel/vendor/yaml-cpp"]
path = Hazel/vendor/yaml-cpp
url = https://github.com/jbeder/yaml-cpp.git
[submodule "Hazel/vendor/ImGuizmo"]
path = Hazel/vendor/ImGuizmo
url = https://github.com/CedricGuillemet/ImGuizmo.git

View File

@ -12,12 +12,12 @@ file(GLOB_RECURSE SOURCES "src/**.cpp")
# stb_image
set(STB_INCLUDE_DIR vendor/stb)
include_directories(${SRB_INCLUDE_DIR}/include)
file(GLOB_RECURSE STB ${STB_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/*)
#file(GLOB_RECURSE ENTT ${ENTT_INCLUDE_DIR}/include/*)
# imgui
set(IMGUI_INCLUDE_DIR vendor/imgui)
@ -26,15 +26,20 @@ file(GLOB IMGUI ${IMGUI_INCLUDE_DIR}/*.cpp
${IMGUI_INCLUDE_DIR}/backends/imgui_impl_opengl3.cpp
${IMGUI_INCLUDE_DIR}/backends/imgui_impl_sdl3.cpp)
set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries" FORCE)
add_subdirectory(vendor/SDL)
set(SDL3_SHARED ON CACHE BOOL "Build SDL as shared library" FORCE)
# ImGuizmo
set(IMGUIZMO_INCLUDE_DIR vendor/ImGuizmo)
include_directories(${IMGUIZMO_INCLUDE_DIR})
file(GLOB IMGUIZMO ${IMGUIZMO_INCLUDE_DIR}/*.cpp)
add_library(${PROJECT_NAME} SHARED
# set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries" FORCE)
add_subdirectory(vendor/SDL)
#set(SDL3_SHARED ON CACHE BOOL "Build SDL as shared library" FORCE)
add_library(${PROJECT_NAME} STATIC
${SOURCES}
${STB}
${ENTT}
${IMGUI}
${IMGUIZMO}
)
target_include_directories(${PROJECT_NAME}
@ -43,6 +48,7 @@ target_include_directories(${PROJECT_NAME}
${STB_INCLUDE_DIR}
${IMGUI_INCLUDE_DIR}
${ENTT_INCLUDE_DIR}
${IMGUIZMO_INCLUDE_DIR}
)
@ -53,15 +59,17 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
opengl32
glm::glm
yaml-cpp::yaml-cpp
)
target_compile_definitions(${PROJECT_NAME} PRIVATE HZ_BUILD_DLL STB_IMAGE_IMPLEMENTATION HZ_PROFILE)# 编译DLL时定义
# target_compile_definitions(${PROJECT_NAME} PRIVATE HZ_BUILD_DLL IMGUI_API=__declspec\(dllexport\) STB_IMAGE_IMPLEMENTATION)# 编译DLL时定义
target_compile_definitions(${PROJECT_NAME} PRIVATE STB_IMAGE_IMPLEMENTATION)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(${PROJECT_NAME} PUBLIC HZ_PROFILE)# 编译DLL时定义
endif ()
if(WIN32)
target_compile_definitions(${PROJECT_NAME} PUBLIC HZ_PLATFORM_WINDOWS IMGUI_API=__declspec\(dllexport\))# 编译DLL时定义
target_compile_definitions(${PROJECT_NAME} PUBLIC HZ_PLATFORM_WINDOWS)# 编译DLL时定义
set(CMAKE_SHARED_LIBRARY_PREFIX "")
endif ()

View File

@ -1,7 +1,7 @@
#pragma once
#define STB_IMAGE_IMPLEMENTATION
// #define STB_IMAGE_IMPLEMENTATION
// For use by Hazel Applications
#include "Hazel/Core/Application.h"

View File

@ -4,7 +4,7 @@
#ifdef HZ_BUILD_DLL
#define HAZEL_API __declspec(dllexport)
#else
#define HAZEL_API __declspec(dllimport)
#define HAZEL_API
#endif
#else

View File

@ -0,0 +1,5 @@
//
// Created by sfd on 25-6-5.
//
#include "Input.h"

View File

@ -0,0 +1,29 @@
//
// Created by sfd on 25-6-5.
//
#ifndef INPUT_H
#define INPUT_H
#include <utility>
#include "Core.h"
namespace Hazel
{
class HAZEL_API Input{
public:
virtual ~Input() = default;
static bool IsKeyPressed(int key);
static bool IsMouseButtonPressed(int button);
static std::pair<float, float> GetMousePosition();
static float GetMouseX();
static float GetMouseY();
};
}
#endif //INPUT_H

View File

@ -9,7 +9,7 @@
#include <imgui_impl_sdl3.h>
#include <Hazel/Core/Application.h>
#include <Hazel/Debug/Instrumentor.h>
#include "ImGuizmo.h"
namespace Hazel
{
@ -73,10 +73,9 @@ namespace Hazel
void ImGuiLayer::OnEvent(SDL_Event& e)
{
// if (m_BlockEvent)
// {
// if (m_BlockEvent){}
ImGui_ImplSDL3_ProcessEvent(&e);
// }
}
void ImGuiLayer::OnImGuiRender()
@ -89,7 +88,7 @@ namespace Hazel
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame();
ImGuizmo::BeginFrame();
}
void ImGuiLayer::End()

View File

@ -0,0 +1,90 @@
//
// Created by sfd on 25-6-4.
//
#include "Math.h"
#include <glm/glm.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/matrix_decompose.hpp>
#include <Hazel/Core/Log.h>
namespace Hazel::Math
{
bool DecomposeTransform(const glm::mat4& transform, glm::vec3& translation, glm::vec3& rotation, glm::vec3& scale)
{
// From glm::decompose in matrix_decompose.inl
using namespace glm;
using T = float;
mat4 LocalMatrix(transform);
// Normalize the matrix.
if (epsilonEqual(LocalMatrix[3][3], static_cast<float>(0), epsilon<T>()))
return false;
// First, isolate perspective. This is the messiest.
if (
epsilonNotEqual(LocalMatrix[0][3], static_cast<T>(0), epsilon<T>()) ||
epsilonNotEqual(LocalMatrix[1][3], static_cast<T>(0), epsilon<T>()) ||
epsilonNotEqual(LocalMatrix[2][3], static_cast<T>(0), epsilon<T>()))
{
// Clear the perspective partition
LocalMatrix[0][3] = LocalMatrix[1][3] = LocalMatrix[2][3] = static_cast<T>(0);
LocalMatrix[3][3] = static_cast<T>(1);
}
// Next take care of translation (easy).
translation = vec3(LocalMatrix[3]);
LocalMatrix[3] = vec4(0, 0, 0, LocalMatrix[3].w);
vec3 Row[3], Pdum3;
// Now get scale and shear.
for (length_t i = 0; i < 3; ++i)
for (length_t j = 0; j < 3; ++j)
Row[i][j] = LocalMatrix[i][j];
// Compute X scale factor and normalize first row.
scale.x = length(Row[0]);
Row[0] = detail::scale(Row[0], static_cast<T>(1));
scale.y = length(Row[1]);
Row[1] = detail::scale(Row[1], static_cast<T>(1));
scale.z = length(Row[2]);
Row[2] = detail::scale(Row[2], static_cast<T>(1));
// At this point, the matrix (in rows[]) is orthonormal.
// Check for a coordinate system flip. If the determinant
// is -1, then negate the matrix and the scaling factors.
#if 0
Pdum3 = cross(Row[1], Row[2]); // v3Cross(row[1], row[2], Pdum3);
if (dot(Row[0], Pdum3) < 0)
{
for (length_t i = 0; i < 3; i++)
{
scale[i] *= static_cast<T>(-1);
Row[i] *= static_cast<T>(-1);
}
}
#endif
rotation.y = asin(-Row[0][2]);
if (cos(rotation.y) != 0)
{
rotation.x = atan2(Row[1][2], Row[2][2]);
rotation.z = atan2(Row[0][1], Row[0][0]);
}
else
{
rotation.x = atan2(-Row[2][0], Row[1][1]);
rotation.z = 0;
}
return true;
}
}

View File

@ -0,0 +1,17 @@
//
// Created by sfd on 25-6-4.
//
#ifndef MATH_H
#define MATH_H
#include <glm/glm.hpp>
namespace Hazel
{
namespace Math
{
bool DecomposeTransform(const glm::mat4& transform, glm::vec3& outTranslation, glm::vec3& outRotation, glm::vec3& outScale);
}
}
#endif //MATH_H

View File

@ -57,7 +57,6 @@ namespace Hazel
return nullptr;
case RendererAPI::API::OPENGL:
return std::make_shared<OpenGLIndexBuffer>(indices, count);
break;
default:
break;
}

View File

@ -11,12 +11,12 @@ namespace Hazel {
class HAZEL_API Camera{
public:
Camera() = default;
Camera(const glm::mat4& projection) : m_Projection(projection) {}
Camera(const glm::mat4& projection) : m_ProjectionMatrix(projection) {}
virtual ~Camera() = default;
const glm::mat4& GetProjection() const { return m_Projection; }
const glm::mat4& GetProjection() const { return m_ProjectionMatrix; }
protected:
glm::mat4 m_Projection = glm::mat4(1.0f);
glm::mat4 m_ProjectionMatrix = glm::mat4(1.0f);
};
}

View File

@ -0,0 +1,152 @@
//
// Created by sfd on 25-6-5.
//
#include "EditorCamera.h"
#define GLM_ENABLE_EXPERIMENTAL
#include <Hazel/Core/Input.h>
#include <Hazel/Core/Log.h>
#include "glm/detail/type_quat.hpp"
#include "glm/ext/matrix_clip_space.hpp"
#include "glm/gtx/quaternion.hpp"
namespace Hazel
{
EditorCamera::EditorCamera(float fov, float aspectRatio, float nearClip, float farClip)
: m_FOV(fov), m_AspectRatio(aspectRatio), m_NearClip(nearClip), m_FarClip(farClip), Camera(glm::perspective(glm::radians(fov), aspectRatio, nearClip, farClip))
{
m_Position = CalculatePosition();
UpdateView();
}
void EditorCamera::UpdateProjection()
{
m_AspectRatio = m_ViewportWidth / m_ViewportHeight;
m_ProjectionMatrix = glm::perspective(glm::radians(m_FOV), m_AspectRatio, m_NearClip, m_FarClip);
}
void EditorCamera::UpdateView()
{
// m_Yaw = m_Pitch = 0.0f; // Lock the camera's rotation
m_Position = CalculatePosition();
glm::quat orientation = GetOrientation();
m_ViewMatrix = glm::translate(glm::mat4(1.0f), m_Position) * glm::toMat4(orientation);
m_ViewMatrix = glm::inverse(m_ViewMatrix);
}
std::pair<float, float> EditorCamera::PanSpeed() const
{
float x = std::min(m_ViewportWidth / 1000.0f, 2.4f); // max = 2.4f
float xFactor = 0.0366f * (x * x) - 0.1778f * x + 0.3021f;
float y = std::min(m_ViewportHeight / 1000.0f, 2.4f); // max = 2.4f
float yFactor = 0.0366f * (y * y) - 0.1778f * y + 0.3021f;
return { xFactor, yFactor };
}
float EditorCamera::RotationSpeed() const
{
return 0.8f;
}
float EditorCamera::ZoomSpeed() const
{
float distance = m_Distance * 0.2f;
distance = std::max(distance, 0.0f);
float speed = distance * distance;
speed = std::min(speed, 100.0f); // max speed = 100
return speed;
}
void EditorCamera::OnUpdate(TimeStep ts)
{
if (Input::IsKeyPressed(SDL_SCANCODE_LALT))
{
const glm::vec2& mouse{ Input::GetMouseX(), Input::GetMouseY() };
const glm::vec2 delta = (mouse - m_InitialMousePosition) * 0.003f;
m_InitialMousePosition = mouse;
if (Input::IsMouseButtonPressed(SDL_BUTTON_MIDDLE))
MousePan(delta);
else if (Input::IsMouseButtonPressed(SDL_BUTTON_LEFT))
MouseRotate(delta);
else if (Input::IsMouseButtonPressed(SDL_BUTTON_RIGHT))
MouseZoom(delta.y);
}
UpdateView();
}
void EditorCamera::OnEvent(SDL_Event& e)
{
OnMouseScroll(e);
}
bool EditorCamera::OnMouseScroll(SDL_Event& e)
{
if (e.type == SDL_EVENT_MOUSE_WHEEL)
{
const float delta = e.motion.y * 0.1f;
MouseZoom(delta);
UpdateView();
return true;
}
return false;
}
void EditorCamera::MousePan(const glm::vec2& delta)
{
auto [xSpeed, ySpeed] = PanSpeed();
m_FocalPoint += -GetRightDirection() * delta.x * xSpeed * m_Distance;
m_FocalPoint += GetUpDirection() * delta.y * ySpeed * m_Distance;
}
void EditorCamera::MouseRotate(const glm::vec2& delta)
{
float yawSign = GetUpDirection().y < 0 ? -1.0f : 1.0f;
m_Yaw += yawSign * delta.x * RotationSpeed();
m_Pitch += delta.y * RotationSpeed();
}
void EditorCamera::MouseZoom(float delta)
{
m_Distance -= delta * ZoomSpeed();
if (m_Distance < 1.0f)
{
m_FocalPoint += GetForwardDirection();
m_Distance = 1.0f;
}
}
glm::vec3 EditorCamera::GetUpDirection() const
{
return glm::rotate(GetOrientation(), glm::vec3(0.0f, 1.0f, 0.0f));
}
glm::vec3 EditorCamera::GetRightDirection() const
{
return glm::rotate(GetOrientation(), glm::vec3(1.0f, 0.0f, 0.0f));
}
glm::vec3 EditorCamera::GetForwardDirection() const
{
auto rotate = glm::rotate(GetOrientation(), glm::vec3(0.0f, 0.0f, -1.0f));
return rotate;
}
glm::vec3 EditorCamera::CalculatePosition() const
{
return m_FocalPoint - GetForwardDirection() * m_Distance;
}
glm::quat EditorCamera::GetOrientation() const
{
return glm::quat(glm::vec3(-m_Pitch, -m_Yaw, 0.0f));
}
}

View File

@ -0,0 +1,80 @@
//
// Created by sfd on 25-6-5.
//
#ifndef EDITORCAMERA_H
#define EDITORCAMERA_H
#include <Hazel/Core/TimeStep.h>
#include <SDL3/SDL_events.h>
#include "Camera.h"
#include <glm/glm.hpp>
namespace Hazel
{
class EditorCamera : public Camera
{
public:
EditorCamera() = default;
EditorCamera(float fov, float aspectRatio, float nearClip, float farClip);
void OnUpdate(TimeStep ts);
void OnEvent(SDL_Event& e);
inline float GetDistance() const { return m_Distance; }
inline void SetDistance(const float distance) { m_Distance = distance; }
inline void SetViewPortSize(const float width, const float height)
{
m_ViewportWidth = width;
m_ViewportHeight = height;
UpdateProjection();
}
const glm::mat4& GetViewMatrix() const { return m_ViewMatrix; }
glm::mat4 GetViewProjection() const { return m_ProjectionMatrix * m_ViewMatrix; }
glm::vec3 GetUpDirection() const;
glm::vec3 GetRightDirection() const;
glm::vec3 GetForwardDirection() const;
glm::vec3 GetPosition() const { return m_Position; }
glm::quat GetOrientation() const;
float GetPitch() const { return m_Pitch; }
float GetYaw() const { return m_Yaw; }
private:
void UpdateProjection();
void UpdateView();
bool OnMouseScroll(SDL_Event& e);
void MousePan(const glm::vec2& delta);
void MouseRotate(const glm::vec2& delta);
void MouseZoom(float delta);
glm::vec3 CalculatePosition() const;
std::pair<float, float> PanSpeed() const;
float RotationSpeed() const;
float ZoomSpeed() const;
private:
float m_FOV = 45.0f, m_AspectRatio = 1.778f, m_NearClip = 0.1f, m_FarClip = 1000.0f;
glm::mat4 m_ViewMatrix;
glm::vec3 m_Position = {0.0f, 0.0f, 0.0f};
glm::vec3 m_FocalPoint = {0.0f, 0.0f, 0.0f};
glm::vec2 m_InitialMousePosition = {0.0f, 0.0f};
float m_Distance = 10.0f;
float m_Pitch = 0.0f, m_Yaw = 0.0f;
float m_ViewportWidth = 1280, m_ViewportHeight = 720;
};
}
#endif //EDITORCAMERA_H

View File

@ -137,10 +137,19 @@ namespace Hazel
s_Data.TextureShader->Bind();
s_Data.TextureShader->SetMat4("u_ViewProjection", viewProjection);
s_Data.QuadIndexCount = 0;
s_Data.QuadVertexBufferPtr = s_Data.QuadVertexBufferBase;
StartBatch();
}
s_Data.TextureSlotIndex = 1;
void Renderer2D::BeginScene(const EditorCamera& camera)
{
HZ_PROFILE_FUNCTION();
const glm::mat4 vieweProjection = camera.GetViewProjection();
s_Data.TextureShader->Bind();
s_Data.TextureShader->SetMat4("u_ViewProjection", vieweProjection);
StartBatch();
}
void Renderer2D::BeginScene(const OrthographicCamera& camera)
@ -149,10 +158,7 @@ namespace Hazel
s_Data.TextureShader->Bind();
s_Data.TextureShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
s_Data.QuadIndexCount = 0;
s_Data.QuadVertexBufferPtr = s_Data.QuadVertexBufferBase;
s_Data.TextureSlotIndex = 1;
StartBatch();
}
void Renderer2D::EndScene()
@ -170,11 +176,20 @@ namespace Hazel
{
s_Data.TextureSlots[i]->Bind(i);
}
if (s_Data.TextureSlotIndex == 0)
RendererCommand::DrawIndexed(s_Data.QuadVertexArray, s_Data.QuadIndexCount);
s_Data.Stats.DrawCalls++;
}
void Renderer2D::StartBatch()
{
s_Data.QuadIndexCount = 0;
s_Data.QuadVertexBufferPtr = s_Data.QuadVertexBufferBase;
s_Data.TextureSlotIndex = 1;
}
void Renderer2D::Shutdown()
{
HZ_PROFILE_FUNCTION();

View File

@ -6,6 +6,7 @@
#define RENDERER2D_H
#include "Camera.h"
#include "EditorCamera.h"
#include "OrthographicCamera.h"
#include "SubTexture2D.h"
#include "Texture.h"
@ -27,10 +28,12 @@ namespace Hazel
static void Init();
static void BeginScene(const Camera& camera, const glm::mat4& tranform);
static void BeginScene(const EditorCamera& camera); // TODO: remove this
static void BeginScene(const OrthographicCamera& camera); // TODO: remove this
static void EndScene();
static void Flush();
static void StartBatch();
static void DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color);
static void DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color);

View File

@ -44,7 +44,7 @@ namespace Hazel
{
if (m_ProjectionType == ProjectionType::Perspective)
{
m_Projection = glm::perspective(m_PerspectiveFOV, m_AspectRatio, m_PerspectiveNear, m_PerspectiveFar);
m_ProjectionMatrix = glm::perspective(m_PerspectiveFOV, m_AspectRatio, m_PerspectiveNear, m_PerspectiveFar);
}
else
{
@ -54,7 +54,7 @@ namespace Hazel
const float orthoTop = m_OrthographicSize * 0.5f;
m_Projection = glm::ortho(orthoLeft, orthoRight, orthoBottom, orthoTop, m_OrthographicNear,
m_ProjectionMatrix = glm::ortho(orthoLeft, orthoRight, orthoBottom, orthoTop, m_OrthographicNear,
m_OrthographicFar);
}
}

View File

@ -4,12 +4,15 @@
#ifndef COMPONENTS_H
#define COMPONENTS_H
#include <glm/ext/matrix_transform.hpp>
#include <Hazel/Renderer/Camera.h>
#include <Hazel/Renderer/ScenceCamera.h>
#include "ScriptableEntity.h"
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/ext/matrix_transform.hpp>
#include "glm/glm.hpp"
#include "glm/gtx/quaternion.hpp"
namespace Hazel
{
@ -28,9 +31,11 @@ namespace Hazel
glm::mat4 GetTransform() const
{
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), Rotation.x, glm::vec3(1.0f, 0.0f, 0.0f))
* glm::rotate(glm::mat4(1.0f), Rotation.y, glm::vec3(0.0f, 1.0f, 0.0f))
* glm::rotate(glm::mat4(1.0f), Rotation.z, glm::vec3(0.0f, 0.0f, 1.0f));
// glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), Rotation.x, glm::vec3(1.0f, 0.0f, 0.0f))
// * glm::rotate(glm::mat4(1.0f), Rotation.y, glm::vec3(0.0f, 1.0f, 0.0f))
// * glm::rotate(glm::mat4(1.0f), Rotation.z, glm::vec3(0.0f, 0.0f, 1.0f));
const glm::mat4 rotation = glm::toMat4(glm::quat(Rotation));
return glm::translate(glm::mat4(1.0f), Translation) * rotation * glm::scale(glm::mat4(1.0f), Scale);
}

View File

@ -34,7 +34,7 @@ namespace Hazel
m_Registry.destroy(entity);
}
void Scene::OnUpdate(TimeStep& ts)
void Scene::OnUpdateRuntime(TimeStep& ts)
{
// Update scripts
@ -89,6 +89,22 @@ namespace Hazel
}
}
void Scene::OnUpdateEditor(TimeStep & ts, const EditorCamera & camera)
{
Renderer2D::BeginScene(camera);
auto group = m_Registry.group<TransformComponent>(entt::get<SpriteRendererComponent>);
for (auto entity : group)
{
auto [transform, sprite] = group.get<TransformComponent, SpriteRendererComponent>(entity);
Renderer2D::DrawQuad(transform.GetTransform(), sprite.Color);
}
Renderer2D::EndScene();
}
void Scene::OnViewportResize(uint32_t width, uint32_t height)
{
m_ViewportWidth = width;
@ -108,6 +124,18 @@ namespace Hazel
}
Entity Scene::GetPrimaryCameraEntity()
{
auto view = m_Registry.view<CameraComponent>();
for (auto entity : view)
{
auto& cameraComponent = view.get<CameraComponent>(entity);
if (cameraComponent.Primary)
return Entity{entity, this};
}
return {};
}
template <typename T>
void Scene::OnComponentAdded(Entity entity, T& component)
{

View File

@ -7,6 +7,7 @@
#include <Hazel/Core/TimeStep.h>
#include <Hazel/Renderer/EditorCamera.h>
#include "entt.hpp"
#include "Hazel/Core/Core.h"
@ -26,9 +27,13 @@ namespace Hazel
void DestoryEntity(Entity entity);
void OnUpdate(TimeStep& ts);
void OnUpdateRuntime(TimeStep& ts);
void OnUpdateEditor(TimeStep& ts, const EditorCamera& camera);
void OnViewportResize(uint32_t width, uint32_t height);
Entity GetPrimaryCameraEntity();
private:
template<typename T>

View File

@ -57,7 +57,7 @@ namespace Hazel
////////////////////////////////////////////////////////////////////
////////////////////// IndexBuffer ///////////////////////////
////////////////////////////////////////////////////////////////////
OpenGLIndexBuffer::OpenGLIndexBuffer(uint32_t* indices, uint32_t count) : m_Count(count)
OpenGLIndexBuffer::OpenGLIndexBuffer(const uint32_t* indices, const uint32_t count) : m_Count(count)
{
HZ_PROFILE_FUNCTION();
glCreateBuffers(1, &m_RendererID);

View File

@ -28,7 +28,7 @@ namespace Hazel
class OpenGLIndexBuffer : public IndexBuffer
{
public:
OpenGLIndexBuffer(uint32_t* indices, uint32_t count);
OpenGLIndexBuffer(const uint32_t* indices, uint32_t count);
virtual ~OpenGLIndexBuffer();
virtual void Bind() const override;
virtual void Unbind() const override;

View File

@ -33,11 +33,10 @@ namespace Hazel
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void OpenGLRendererAPI::DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray, uint32_t indexCount)
void OpenGLRendererAPI::DrawIndexed(const std::shared_ptr<Hazel::VertexArray>& vertexArray, const uint32_t indexCount)
{
// uint32_t count = indexCount == 0 ? vertexArray->GetIndexBuffer()->GetCount() : indexCount;
uint32_t count = indexCount ? indexCount : vertexArray->GetIndexBuffer()->GetCount();
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0);
const uint32_t count = indexCount ? indexCount : vertexArray->GetIndexBuffer()->GetCount();
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, nullptr);
glBindTexture(GL_TEXTURE_2D, 0);
}
}

View File

@ -71,12 +71,12 @@ namespace Hazel
uint32_t index = 0;
for (auto& element : vertexBuffer->GetLayout())
for (const auto& element : vertexBuffer->GetLayout())
{
glEnableVertexAttribArray(index);
glVertexAttribPointer(index, element.GetComponentCount(), ShaderDataTypeToOpenGLBaseType(element.Type),
element.Normalized ? GL_TRUE : GL_FALSE, vertexBuffer->GetLayout().GetStride(),
reinterpret_cast<void*>(element.Offset));
(void*)element.Offset);
index ++;
}

View File

@ -0,0 +1,41 @@
//
// Created by sfd on 25-6-5.
//
#include <Hazel/Core/Application.h>
#include <Hazel/Core/Input.h>
#include <SDL3/SDL_video.h>
namespace Hazel
{
bool Input::IsKeyPressed(const int key)
{
const auto state = SDL_GetKeyboardState(nullptr);
return state[key];
}
bool Input::IsMouseButtonPressed(const int button)
{
const auto mod = SDL_GetMouseState(nullptr, nullptr);
return mod & SDL_BUTTON_MASK(button);
}
std::pair<float, float> Input::GetMousePosition()
{
float xpos, ypos;
SDL_GetMouseState(&xpos, &ypos);
return {xpos, ypos};
}
float Input::GetMouseX()
{
return GetMousePosition().first;
}
float Input::GetMouseY()
{
return GetMousePosition().second;
}
}

1
Hazel/vendor/ImGuizmo vendored Submodule

Submodule Hazel/vendor/ImGuizmo added at 2310acda82

View File

@ -5,10 +5,15 @@
#include "EditorLayer.h"
#include <imgui.h>
#include <ImGuizmo.h>
#include <glm/gtc/type_ptr.hpp>
#include <Hazel/Core/Input.h>
#include <Hazel/Math/Math.h>
#include <Hazel/Scene/SceneSerializer.h>
#include <Hazel/Utils/PlatformUtils.h>
#include "glm/gtx/matrix_decompose.hpp"
namespace Hazel
{
EditorLayer::EditorLayer()
@ -31,51 +36,9 @@ namespace Hazel
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) override
{
auto& translation = GetComponent<TransformComponent>().Translation;
const auto state = SDL_GetKeyboardState(nullptr);
if (state[SDL_SCANCODE_A])
translation.x -= ts * speed;
if (state[SDL_SCANCODE_D])
translation.x += ts * speed;
if (state[SDL_SCANCODE_W])
translation.y += ts * speed;
if (state[SDL_SCANCODE_S])
translation.y -= ts * speed;
}
private:
float speed = 2.0f;
};
m_CameraEntity.AddComponent<NativeScriptComponent>().Bind<CameraController>();
m_SecondCamera.AddComponent<NativeScriptComponent>().Bind<CameraController>();
m_EditorCamera = EditorCamera(45.0f, 1.667f, 0.1f, 1000.0f);
m_SceneHierachyPanel.SetContext(m_ActiveScene);
m_State = SDL_GetKeyboardState(nullptr);
}
void EditorLayer::OnDetech()
@ -93,7 +56,8 @@ namespace Hazel
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);
m_EditorCamera.SetViewPortSize(m_ViewPortSize.x, m_ViewPortSize.y);
m_ActiveScene->OnViewportResize((uint32_t)m_ViewPortSize.x, (uint32_t)m_ViewPortSize.y);
}
@ -101,6 +65,7 @@ namespace Hazel
if (m_ViewportFocused && m_ViewportHovered)
{
m_CameraController.OnUpdate(ts);
m_EditorCamera.OnUpdate(ts);
}
// update Renderer
@ -112,7 +77,7 @@ namespace Hazel
// Renderer2D::BeginScene(m_CameraController.GetCamera());
// update Scene
m_ActiveScene->OnUpdate(ts);
m_ActiveScene->OnUpdateEditor(ts, m_EditorCamera);
// 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});
@ -192,22 +157,13 @@ namespace Hazel
// ImGui::MenuItem("Padding", NULL, &opt_padding);
// ImGui::Separator();
if (ImGui::MenuItem("New", "Ctrl+N"))
{
NewScene();
}
if (ImGui::MenuItem("Open...", "Ctrl+O"))
{
OpenScene();
}
if (ImGui::MenuItem("Save As...", "Ctrl+Shift+S"))
{
SaveScene();
}
ImGui::Separator();
if (ImGui::MenuItem("Exit")) { Hazel::Application::Get().Close(); }
ImGui::EndMenu();
@ -216,7 +172,10 @@ namespace Hazel
ImGui::EndMenuBar();
}
// Scene Hierachy Panel
m_SceneHierachyPanel.OnImGuiRender();
// Render Status
{
ImGui::Begin("Render Status");
@ -229,18 +188,11 @@ namespace Hazel
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();
}
// ViewPort
{
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {0.0f, 0.0f});
ImGui::Begin("Viewport");
@ -257,46 +209,69 @@ namespace Hazel
ImGui::Image(m_FrameBuffer->GetColorAttachmentID(), {m_ViewPortSize.x, m_ViewPortSize.y}, {0, 1},
{1, 0});
Entity selectedEntity = m_SceneHierachyPanel.GetSelectedEntity();
if (selectedEntity)
{
ImGuizmo::SetOrthographic(false);
ImGuizmo::SetDrawlist();
const float windowWidth = ImGui::GetWindowWidth();
const float windowHeight = ImGui::GetWindowHeight();
const ImVec2 windowPos = ImGui::GetWindowPos();
ImGuizmo::SetRect(windowPos.x,windowPos.y,windowWidth,windowHeight);
// auto cameraEntity = m_ActiveScene->GetPrimaryCameraEntity();
if (m_GizmoType != -1)
{
// const auto& camera = cameraEntity.GetComponent<CameraComponent>().Camera;
auto& tc = selectedEntity.GetComponent<TransformComponent>();
// const glm::mat4& cameraProjection = camera.GetProjection();
// glm::mat4 cameraView = glm::inverse(cameraEntity.GetComponent<TransformComponent>().GetTransform());
glm::mat4 cameraProjection = m_EditorCamera.GetProjection();
glm::mat4 cameraView = m_EditorCamera.GetViewMatrix();
glm::mat4 transform = tc.GetTransform();
bool snap = SDL_GetModState() & SDL_KMOD_CTRL;
float snapValue = 0.5f;
if (m_GizmoType == ImGuizmo::OPERATION::TRANSLATE)
snapValue = 0.25f;
else if (m_GizmoType == ImGuizmo::OPERATION::ROTATE)
snapValue = 15.0f;
else if (m_GizmoType == ImGuizmo::OPERATION::SCALE)
snapValue = 0.25f;
float snapValues[3] = { snapValue, snapValue, snapValue };
if (ImGuizmo::Manipulate(glm::value_ptr(cameraView), glm::value_ptr(cameraProjection), ImGuizmo::OPERATION(m_GizmoType), ImGuizmo::LOCAL,glm::value_ptr(transform), nullptr, snap ? snapValues : nullptr))
{
if (ImGuizmo::IsUsing())
{
glm::vec3 translation, rotation, scale;
Hazel::Math::DecomposeTransform(transform, translation, rotation, scale);
glm::vec3 deltaRotation = rotation - tc.Rotation;
tc.Translation = translation;
tc.Rotation += deltaRotation;
tc.Scale = scale;
}
}
}
}
ImGui::End();
ImGui::PopStyleVar();
}
ImGui::End();
}
}
void EditorLayer::OnEvent(SDL_Event& e)
{
if (m_ViewportFocused && m_ViewportHovered)
{
m_CameraController.OnEvent(e);
}
#define SHORTCUT_NEW (SDL_KMOD_CTRL | SDLK_N)
#define SHORTCUT_OPEN (SDL_KMOD_CTRL | SDLK_O)
#define SHORTCUT_SAVE_ALL (SDL_KMOD_CTRL | SDL_KMOD_SHIFT | SDLK_S)
const auto mod = SDL_GetModState();
const auto ctrl = (mod & SDL_KMOD_CTRL) ? SDL_KMOD_CTRL : 0;
const auto shift = (mod & SDL_KMOD_SHIFT) ? SDL_KMOD_SHIFT : 0;
switch (ctrl | shift | e.key.key)
{
case SHORTCUT_NEW:
NewScene();
break;
case SHORTCUT_OPEN:
OpenScene();
break;
case SHORTCUT_SAVE_ALL:
SaveScene();
break;
default:
break;
}
}
void EditorLayer::SaveScene()
void EditorLayer::SaveScene() const
{
std::string filepath = FileDiaglogs::SaveFile("Hazel Scene (*.scene)\0*.scene\0");
if (!filepath.empty())
@ -326,4 +301,59 @@ namespace Hazel
m_ActiveScene->OnViewportResize((uint32_t)m_ViewPortSize.x, (uint32_t)m_ViewPortSize.y);
m_SceneHierachyPanel.SetContext(m_ActiveScene);
}
void EditorLayer::ChangeOptMode(unsigned int mode)
{
if (m_ViewportHovered)
m_GizmoType = mode;
}
void EditorLayer::OnEvent(SDL_Event& e)
{
if (m_ViewportFocused && m_ViewportHovered)
{
m_CameraController.OnEvent(e);
m_EditorCamera.OnEvent(e);
}
#define SHORTCUT_NEW (SDL_KMOD_CTRL | SDLK_N)
#define SHORTCUT_OPEN (SDL_KMOD_CTRL | SDLK_O)
#define SHORTCUT_SAVE_ALL (SDL_KMOD_CTRL | SDL_KMOD_SHIFT | SDLK_S)
const auto mod = SDL_GetModState();
const auto ctrl = (mod & SDL_KMOD_CTRL) ? SDL_KMOD_CTRL : 0;
const auto shift = (mod & SDL_KMOD_SHIFT) ? SDL_KMOD_SHIFT : 0;
switch (ctrl | shift | e.key.key)
{
case SHORTCUT_NEW:
NewScene();
break;
case SHORTCUT_OPEN:
OpenScene();
break;
case SHORTCUT_SAVE_ALL:
SaveScene();
break;
// GIZMO
case SDLK_Q:
ChangeOptMode(-1);
break;
case SDLK_W:
ChangeOptMode(ImGuizmo::OPERATION::TRANSLATE);
break;
case SDLK_E:
ChangeOptMode(ImGuizmo::OPERATION::SCALE);
break;
case SDLK_R:
ChangeOptMode(ImGuizmo::OPERATION::ROTATE);
break;
default:
break;
}
}
}

View File

@ -23,10 +23,11 @@ namespace Hazel
virtual void OnImGuiRender() override;
virtual void OnEvent(SDL_Event& e) override;
private:
void SaveScene();
void SaveScene() const;
void OpenScene();
void NewScene();
void ChangeOptMode(unsigned int mode);
private:
OrthographicCameraController m_CameraController;
@ -34,11 +35,7 @@ namespace Hazel
Ref<Texture2D> m_CheckerBoardTexture;
Ref<Scene> m_ActiveScene;
Entity m_SquareEntity;
Entity m_CameraEntity;
Entity m_SecondCamera;
bool m_PrimaryCamera = false;
EditorCamera m_EditorCamera;
glm::vec4 m_BackgroundColor = { 0.2f, 0.2f, 0.2f, 1.0f };
glm::vec4 m_SquareColor = { 0.2f, 0.2f, 0.2f, 1.0f };
@ -49,8 +46,8 @@ namespace Hazel
Ref<FrameBuffer> m_FrameBuffer;
SceneHierachyPanel m_SceneHierachyPanel;
const bool* m_State = nullptr;
int m_GizmoType = 0;
};
}

View File

@ -21,6 +21,7 @@ namespace Hazel
void DrawComponents(Entity entity);
Entity GetSelectedEntity() const { return m_SelectionContext; }
private:
void DrawEntityNode(Entity entity);