添加场景加载与保存功能
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -11,3 +11,6 @@
|
|||||||
[submodule "Hazel/vendor/glm"]
|
[submodule "Hazel/vendor/glm"]
|
||||||
path = Hazel/vendor/glm
|
path = Hazel/vendor/glm
|
||||||
url = https://github.com/g-truc/glm.git
|
url = https://github.com/g-truc/glm.git
|
||||||
|
[submodule "Hazel/vendor/yaml-cpp"]
|
||||||
|
path = Hazel/vendor/yaml-cpp
|
||||||
|
url = https://github.com/jbeder/yaml-cpp.git
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
set(PROJECT_NAME Hazel)
|
set(PROJECT_NAME Hazel)
|
||||||
project(${PROJECT_NAME})
|
project(${PROJECT_NAME})
|
||||||
|
|
||||||
add_subdirectory(vendor/SDL)
|
|
||||||
set(SDL3_SHARED ON CACHE BOOL "Build SDL as shared library" FORCE)
|
|
||||||
|
|
||||||
add_subdirectory(vendor/spdlog)
|
add_subdirectory(vendor/spdlog)
|
||||||
add_subdirectory(vendor/GLAD)
|
add_subdirectory(vendor/GLAD)
|
||||||
add_subdirectory(vendor/glm)
|
add_subdirectory(vendor/glm)
|
||||||
|
add_subdirectory(vendor/yaml-cpp)
|
||||||
|
|
||||||
file(GLOB_RECURSE SOURCES "src/*.cpp")
|
file(GLOB_RECURSE SOURCES "src/**.cpp")
|
||||||
|
|
||||||
# stb_image
|
# stb_image
|
||||||
set(STB_INCLUDE_DIR vendor/stb)
|
set(STB_INCLUDE_DIR vendor/stb)
|
||||||
@ -27,6 +26,10 @@ file(GLOB IMGUI ${IMGUI_INCLUDE_DIR}/*.cpp
|
|||||||
${IMGUI_INCLUDE_DIR}/backends/imgui_impl_opengl3.cpp
|
${IMGUI_INCLUDE_DIR}/backends/imgui_impl_opengl3.cpp
|
||||||
${IMGUI_INCLUDE_DIR}/backends/imgui_impl_sdl3.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)
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} SHARED
|
add_library(${PROJECT_NAME} SHARED
|
||||||
${SOURCES}
|
${SOURCES}
|
||||||
${STB}
|
${STB}
|
||||||
@ -49,6 +52,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
|
|||||||
glad
|
glad
|
||||||
opengl32
|
opengl32
|
||||||
glm::glm
|
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 STB_IMAGE_IMPLEMENTATION HZ_PROFILE)# 编译DLL时定义
|
||||||
|
|
||||||
|
|||||||
@ -26,11 +26,11 @@ namespace Hazel
|
|||||||
void OrthographicCameraController::OnUpdate(TimeStep ts)
|
void OrthographicCameraController::OnUpdate(TimeStep ts)
|
||||||
{
|
{
|
||||||
HZ_PROFILE_FUNCTION();
|
HZ_PROFILE_FUNCTION();
|
||||||
static const bool* state = SDL_GetKeyboardState(NULL);
|
const bool* state = SDL_GetKeyboardState(nullptr);
|
||||||
float time = ts;
|
float time = ts;
|
||||||
|
|
||||||
if (state[SDL_SCANCODE_A])
|
if (state[SDL_SCANCODE_A])
|
||||||
m_CameraPosition.x -= m_CameraTranslationSpeed * time;
|
m_CameraPosition.x -= m_CameraTranslationSpeed * time;
|
||||||
else if (state[SDL_SCANCODE_D])
|
else if (state[SDL_SCANCODE_D])
|
||||||
m_CameraPosition.x += m_CameraTranslationSpeed * time;
|
m_CameraPosition.x += m_CameraTranslationSpeed * time;
|
||||||
|
|
||||||
|
|||||||
@ -34,14 +34,12 @@ namespace Hazel
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void OnComponentAdded(Entity entity, T& component);
|
void OnComponentAdded(Entity entity, T& component);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
entt::registry m_Registry;
|
entt::registry m_Registry;
|
||||||
|
|
||||||
uint32_t m_ViewportWidth = 0, m_ViewportHeight = 0;
|
uint32_t m_ViewportWidth = 0, m_ViewportHeight = 0;
|
||||||
|
|
||||||
friend class Entity;
|
friend class Entity;
|
||||||
|
friend class SceneSerializer;
|
||||||
friend class SceneHierachyPanel;
|
friend class SceneHierachyPanel;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
260
Hazel/src/Hazel/Scene/SceneSerializer.cpp
Normal file
260
Hazel/src/Hazel/Scene/SceneSerializer.cpp
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-5-31.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SceneSerializer.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "Components.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
#include "yaml-cpp/yaml.h"
|
||||||
|
|
||||||
|
namespace YAML
|
||||||
|
{
|
||||||
|
template<>
|
||||||
|
struct convert<glm::vec3>
|
||||||
|
{
|
||||||
|
static Node encode(const glm::vec3& out)
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
node.push_back(out.x);
|
||||||
|
node.push_back(out.y);
|
||||||
|
node.push_back(out.z);
|
||||||
|
node.SetStyle(EmitterStyle::Flow);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool decode(const Node& node, glm::vec3& out)
|
||||||
|
{
|
||||||
|
if (node.size() != 3 && !node.IsSequence())
|
||||||
|
return false;
|
||||||
|
out.x = node[0].as<float>();
|
||||||
|
out.y = node[1].as<float>();
|
||||||
|
out.z = node[2].as<float>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct convert<glm::vec4>
|
||||||
|
{
|
||||||
|
static Node encode(const glm::vec4& out)
|
||||||
|
{
|
||||||
|
Node node;
|
||||||
|
node.push_back(out.x);
|
||||||
|
node.push_back(out.y);
|
||||||
|
node.push_back(out.z);
|
||||||
|
node.push_back(out.w);
|
||||||
|
node.SetStyle(EmitterStyle::Flow);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool decode(const Node& node, glm::vec4& out)
|
||||||
|
{
|
||||||
|
if (node.size() != 4 && !node.IsSequence())
|
||||||
|
return false;
|
||||||
|
out.x = node[0].as<float>();
|
||||||
|
out.y = node[1].as<float>();
|
||||||
|
out.z = node[2].as<float>();
|
||||||
|
out.w = node[3].as<float>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Emitter& operator<<(Emitter& out, const glm::vec3& value)
|
||||||
|
{
|
||||||
|
out << Flow;
|
||||||
|
out << BeginSeq << value.x << value.y << value.z << EndSeq;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
Emitter& operator<<(Emitter& out, const glm::vec4& value)
|
||||||
|
{
|
||||||
|
out << Flow;
|
||||||
|
out << BeginSeq << value.x << value.y << value.z << value.w << EndSeq;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Hazel
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SceneSerializer::SceneSerializer(const Ref<Scene> scene)
|
||||||
|
: m_Scene(scene)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SerializeEntity(YAML::Emitter& out, Entity entity)
|
||||||
|
{
|
||||||
|
out << YAML::BeginMap; // entity
|
||||||
|
out << YAML::Key << "Entity" << YAML::Value << "123479283"; // TODO: entity ID goes here
|
||||||
|
|
||||||
|
if (entity.HasComponent<TagComponent>())
|
||||||
|
{
|
||||||
|
out << YAML::Key << "TagComponent";
|
||||||
|
|
||||||
|
out << YAML::BeginMap; // TagComponent
|
||||||
|
|
||||||
|
const auto& tag = entity.GetComponent<TagComponent>().Tag;
|
||||||
|
out << YAML::Key << "Tag" << YAML::Value << tag;
|
||||||
|
|
||||||
|
out << YAML::EndMap; // TagComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.HasComponent<TransformComponent>())
|
||||||
|
{
|
||||||
|
out << YAML::Key << "TransformComponent";
|
||||||
|
out << YAML::BeginMap; // TransformComponent
|
||||||
|
|
||||||
|
auto& transform = entity.GetComponent<TransformComponent>();
|
||||||
|
out << YAML::Key << "Translation" << YAML::Value << transform.Translation;
|
||||||
|
out << YAML::Key << "Rotation" << YAML::Value << transform.Rotation;
|
||||||
|
out << YAML::Key << "Scale" << YAML::Value << transform.Scale;
|
||||||
|
|
||||||
|
out << YAML::EndMap; // TransformComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.HasComponent<CameraComponent>())
|
||||||
|
{
|
||||||
|
out << YAML::Key << "CameraComponent";
|
||||||
|
|
||||||
|
out << YAML::BeginMap; // CameraComponent
|
||||||
|
|
||||||
|
auto& cameraComponent = entity.GetComponent<CameraComponent>();
|
||||||
|
auto& camera = cameraComponent.Camera;
|
||||||
|
|
||||||
|
out << YAML::Key << "Camera" << YAML::Value; // CameraComponent
|
||||||
|
out << YAML::BeginMap; // Camera
|
||||||
|
|
||||||
|
out << YAML::Key << "ProjectionType" << YAML::Value << (int)camera.GetProjectionType();
|
||||||
|
out << YAML::Key << "PerspectiveVerticalFOV" << YAML::Value << camera.GetPerspectiveVerticalFOV();
|
||||||
|
out << YAML::Key << "PerspectiveNear" << YAML::Value << camera.GetPerspectiveNearCLip();
|
||||||
|
out << YAML::Key << "PerspectiveFar" << YAML::Value << camera.GetPerspectiveFarCLip();
|
||||||
|
out << YAML::Key << "OrthographicSize" << YAML::Value << camera.GetOrthographicSize();
|
||||||
|
out << YAML::Key << "OrthographicNear" << YAML::Value << camera.GetOrthographicNearCLip();
|
||||||
|
out << YAML::Key << "OrthographicFar" << YAML::Value << camera.GetOrthographicFarCLip();
|
||||||
|
|
||||||
|
out << YAML::Key << "Primary" << YAML::Value << cameraComponent.Primary;
|
||||||
|
out << YAML::Key << "FixedAspectRatio" << YAML::Value << cameraComponent.FixedAspectRatio;
|
||||||
|
|
||||||
|
out << YAML::EndMap; // Camera
|
||||||
|
out << YAML::EndMap; // CameraComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.HasComponent<SpriteRendererComponent>())
|
||||||
|
{
|
||||||
|
out << YAML::Key << "SpriteRendererComponent";
|
||||||
|
|
||||||
|
out << YAML::BeginMap; // SpriteRendererComponent
|
||||||
|
auto& spriteRendererComponent = entity.GetComponent<SpriteRendererComponent>();
|
||||||
|
out << YAML::Key << "Color" << YAML::Value << spriteRendererComponent.Color;
|
||||||
|
out << YAML::EndMap; // SpriteRendererComponent
|
||||||
|
}
|
||||||
|
|
||||||
|
out << YAML::EndMap; // entity
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneSerializer::Serialize(const std::string& filepath) const
|
||||||
|
{
|
||||||
|
YAML::Emitter out;
|
||||||
|
out << YAML::BeginMap;
|
||||||
|
out << YAML::Key << "Scene" << YAML::Value << "Untitled";
|
||||||
|
out << YAML::Key << "Entities" << YAML::Value << YAML::BeginSeq;
|
||||||
|
m_Scene->m_Registry.view<entt::entity>().each([&](auto entityID)
|
||||||
|
{
|
||||||
|
const Entity entity = {entityID, m_Scene.get()};
|
||||||
|
if (!entity)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SerializeEntity(out, entity);
|
||||||
|
});
|
||||||
|
|
||||||
|
std::ofstream fout(filepath);
|
||||||
|
fout << out.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneSerializer::SerializeRuntime(const std::string& filepath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SceneSerializer::Deserialize(const std::string& filepath)
|
||||||
|
{
|
||||||
|
const std::ifstream stream(filepath);
|
||||||
|
std::stringstream strStream;
|
||||||
|
strStream << stream.rdbuf();
|
||||||
|
|
||||||
|
YAML::Node data = YAML::Load(strStream.str());
|
||||||
|
if (!data["Scene"])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto sceneName = data["Scene"].as<std::string>();
|
||||||
|
|
||||||
|
HZ_CORE_TRACE("Deserializing Scene {}", strStream.str());
|
||||||
|
|
||||||
|
auto entities = data["Entities"];
|
||||||
|
if (entities)
|
||||||
|
{
|
||||||
|
for (auto entity : entities)
|
||||||
|
{
|
||||||
|
uint64_t uuid = entity["Entity"].as<uint64_t>(); // TODO
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
auto TagComponent = entity["TagComponent"];
|
||||||
|
if (TagComponent)
|
||||||
|
name = TagComponent["Tag"].as<std::string>();
|
||||||
|
|
||||||
|
HZ_CORE_TRACE("Deserializing Entity: {0}:({1})", name, uuid);
|
||||||
|
|
||||||
|
Entity deserializedEntity = m_Scene->CreateEntity(name);
|
||||||
|
|
||||||
|
auto transformComponent = entity["TransformComponent"];
|
||||||
|
if (transformComponent)
|
||||||
|
{
|
||||||
|
auto& transform = deserializedEntity.GetComponent<TransformComponent>();
|
||||||
|
transform.Translation = transformComponent["Translation"].as<glm::vec3>();
|
||||||
|
transform.Rotation = transformComponent["Rotation"].as<glm::vec3>();
|
||||||
|
transform.Scale = transformComponent["Scale"].as<glm::vec3>();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cameraComponent = entity["CameraComponent"];
|
||||||
|
if (cameraComponent)
|
||||||
|
{
|
||||||
|
auto& camera = deserializedEntity.AddComponent<CameraComponent>();
|
||||||
|
|
||||||
|
auto cameraProps = cameraComponent["Camera"];
|
||||||
|
camera.Camera.SetProjectionType((ScenceCamera::ProjectionType)cameraProps["ProjectionType"].as<int>());
|
||||||
|
|
||||||
|
camera.Camera.SetPerspectiveVerticalFOV(cameraProps["PerspectiveVerticalFOV"].as<float>());
|
||||||
|
camera.Camera.SetPerspectiveNearClip(cameraProps["PerspectiveNear"].as<float>());
|
||||||
|
camera.Camera.SetPerspectiveFarClip(cameraProps["PerspectiveFar"].as<float>());
|
||||||
|
|
||||||
|
camera.Camera.SetOrthographicSize(cameraProps["OrthographicSize"].as<float>());
|
||||||
|
camera.Camera.SetOrthographicNearClip(cameraProps["OrthographicNear"].as<float>());
|
||||||
|
camera.Camera.SetOrthographicFarClip(cameraProps["OrthographicFar"].as<float>());
|
||||||
|
|
||||||
|
camera.Primary = cameraProps["Primary"].as<bool>();
|
||||||
|
camera.FixedAspectRatio = cameraProps["FixedAspectRatio"].as<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto spriteRendererComponent = entity["SpriteRendererComponent"];
|
||||||
|
if (spriteRendererComponent)
|
||||||
|
{
|
||||||
|
auto& sprite = deserializedEntity.AddComponent<SpriteRendererComponent>();
|
||||||
|
sprite.Color = spriteRendererComponent["Color"].as<glm::vec4>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SceneSerializer::DeserializeRuntime(const std::string& filepath)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
27
Hazel/src/Hazel/Scene/SceneSerializer.h
Normal file
27
Hazel/src/Hazel/Scene/SceneSerializer.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-5-31.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SCENESERIALIZER_H
|
||||||
|
#define SCENESERIALIZER_H
|
||||||
|
#include "Scene.h"
|
||||||
|
|
||||||
|
namespace Hazel
|
||||||
|
{
|
||||||
|
class HAZEL_API SceneSerializer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SceneSerializer(const Ref<Scene> scene);
|
||||||
|
|
||||||
|
void Serialize(const std::string& filepath) const;
|
||||||
|
void SerializeRuntime(const std::string& filepath);
|
||||||
|
|
||||||
|
bool Deserialize(const std::string& filepath);
|
||||||
|
bool DeserializeRuntime(const std::string& filepath);
|
||||||
|
private:
|
||||||
|
Ref<Scene> m_Scene;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //SCENESERIALIZER_H
|
||||||
5
Hazel/src/Hazel/Utils/PlatformUtils.cpp
Normal file
5
Hazel/src/Hazel/Utils/PlatformUtils.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-5-31.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "PlatformUtils.h"
|
||||||
23
Hazel/src/Hazel/Utils/PlatformUtils.h
Normal file
23
Hazel/src/Hazel/Utils/PlatformUtils.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-5-31.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef PLATFORMUTILS_H
|
||||||
|
#define PLATFORMUTILS_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "Hazel/Core/Core.h"
|
||||||
|
|
||||||
|
namespace Hazel
|
||||||
|
{
|
||||||
|
class HAZEL_API FileDiaglogs
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// return empty strings if cancelled
|
||||||
|
static std::string OpenFile(const char* filter);
|
||||||
|
static std::string SaveFile(const char* filter);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //PLATFORMUTILS_H
|
||||||
5
Hazel/src/Platform/Windows/WindowsPlatformUtils.cpp
Normal file
5
Hazel/src/Platform/Windows/WindowsPlatformUtils.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-5-31.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "WindowsPlatformUtils.h"
|
||||||
74
Hazel/src/Platform/Windows/WindowsPlatformUtils.h
Normal file
74
Hazel/src/Platform/Windows/WindowsPlatformUtils.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// Created by sfd on 25-5-31.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef WINDOWSPLATFORMUTILS_H
|
||||||
|
#define WINDOWSPLATFORMUTILS_H
|
||||||
|
|
||||||
|
#include <AsyncInfo.h>
|
||||||
|
#include <commdlg.h>
|
||||||
|
|
||||||
|
#include <Hazel/Utils/PlatformUtils.h>
|
||||||
|
#include <Hazel/Core/Application.h>
|
||||||
|
|
||||||
|
namespace Hazel
|
||||||
|
{
|
||||||
|
std::string FileDiaglogs::OpenFile(const char* filter)
|
||||||
|
{
|
||||||
|
OPENFILENAME ofn; // common diaglog box structure
|
||||||
|
CHAR szFile[260] = { 0 };
|
||||||
|
|
||||||
|
|
||||||
|
SDL_PropertiesID props = SDL_GetWindowProperties((SDL_Window*)Application::Get().GetWindow().GetNativeWindow());
|
||||||
|
void * hwnd_ptr = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr);
|
||||||
|
|
||||||
|
// Init OPENFILENAME
|
||||||
|
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
||||||
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||||
|
ofn.hwndOwner = (HWND)hwnd_ptr;
|
||||||
|
ofn.lpstrFile = szFile;
|
||||||
|
ofn.nMaxFile = sizeof(szFile);
|
||||||
|
ofn.lpstrFilter = filter;
|
||||||
|
ofn.nFilterIndex = 1;
|
||||||
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
|
||||||
|
if (GetOpenFileName(&ofn) == TRUE)
|
||||||
|
{
|
||||||
|
return ofn.lpstrFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string FileDiaglogs::SaveFile(const char* filter)
|
||||||
|
{
|
||||||
|
OPENFILENAME ofn; // common diaglog box structure
|
||||||
|
CHAR szFile[260] = { 0 };
|
||||||
|
|
||||||
|
|
||||||
|
SDL_PropertiesID props = SDL_GetWindowProperties((SDL_Window*)Application::Get().GetWindow().GetNativeWindow());
|
||||||
|
void * hwnd_ptr = SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr);
|
||||||
|
|
||||||
|
// Init OPENFILENAME
|
||||||
|
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
||||||
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||||
|
ofn.hwndOwner = (HWND)hwnd_ptr;
|
||||||
|
ofn.lpstrFile = szFile;
|
||||||
|
ofn.nMaxFile = sizeof(szFile);
|
||||||
|
ofn.lpstrFilter = filter;
|
||||||
|
ofn.nFilterIndex = 1;
|
||||||
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
|
||||||
|
if (GetSaveFileName(&ofn) == TRUE)
|
||||||
|
{
|
||||||
|
return ofn.lpstrFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //WINDOWSPLATFORMUTILS_H
|
||||||
1
Hazel/vendor/yaml-cpp
vendored
Submodule
1
Hazel/vendor/yaml-cpp
vendored
Submodule
Submodule Hazel/vendor/yaml-cpp added at 2f86d13775
@ -1,53 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by sfd on 25-5-18.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "GameLayer.h"
|
|
||||||
|
|
||||||
#include <Hazel/Core/Application.h>
|
|
||||||
#include <Hazel/Renderer/Renderer2D.h>
|
|
||||||
#include <Hazel/Renderer/RendererCommand.h>
|
|
||||||
|
|
||||||
GameLayer::GameLayer() : Layer("GameLayer") , m_cameraController((float)(Application::Get().GetWindow().GetWidth()) / (float)(Application::Get().GetWindow().GetHeight()))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GameLayer::OnAttach()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameLayer::OnDetech()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameLayer::OnUpdate(TimeStep& ts)
|
|
||||||
{
|
|
||||||
auto mouseState = SDL_GetMouseState(NULL, NULL);
|
|
||||||
static Uint32 prevMouseState = 0;
|
|
||||||
m_cameraController.OnUpdate(ts);
|
|
||||||
|
|
||||||
RendererCommand::SetClearColor({0.2f, 0.2f, 0.2f, 1.0f});
|
|
||||||
RendererCommand::Clear();
|
|
||||||
|
|
||||||
Renderer2D::BeginScene(m_cameraController.GetCamera());
|
|
||||||
|
|
||||||
Hazel::Renderer2D::DrawQuad({0.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f});
|
|
||||||
|
|
||||||
Renderer2D::EndScene();
|
|
||||||
|
|
||||||
if ((mouseState & SDL_BUTTON_LMASK) && !(prevMouseState & SDL_BUTTON_LMASK))
|
|
||||||
{
|
|
||||||
HZ_CORE_INFO("LEFT Mouse Clicked!");
|
|
||||||
}
|
|
||||||
prevMouseState = mouseState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameLayer::OnEvent(SDL_Event& e)
|
|
||||||
{
|
|
||||||
m_cameraController.OnEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameLayer::OnImGuiRender()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by sfd on 25-5-18.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef GAMELAYER_H
|
|
||||||
#define GAMELAYER_H
|
|
||||||
#include <Hazel/Core/Layer.h>
|
|
||||||
#include <Hazel/Renderer/OrthographicCameraController.h>
|
|
||||||
|
|
||||||
|
|
||||||
using namespace Hazel;
|
|
||||||
|
|
||||||
class GameLayer : public Layer{
|
|
||||||
public:
|
|
||||||
GameLayer();
|
|
||||||
~GameLayer() = default;
|
|
||||||
|
|
||||||
void OnAttach() override;
|
|
||||||
void OnDetech() override;
|
|
||||||
void OnUpdate(TimeStep& ts) override;
|
|
||||||
void OnEvent(SDL_Event& e) override;
|
|
||||||
void OnImGuiRender() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
OrthographicCameraController m_cameraController;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //GAMELAYER_H
|
|
||||||
@ -5,21 +5,20 @@
|
|||||||
#include "EditorLayer.h"
|
#include "EditorLayer.h"
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <iostream>
|
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include <Hazel/Scene/SceneSerializer.h>
|
||||||
#include "glm/ext/matrix_clip_space.hpp"
|
#include <Hazel/Utils/PlatformUtils.h>
|
||||||
|
|
||||||
namespace Hazel
|
namespace Hazel
|
||||||
{
|
{
|
||||||
EditorLayer::EditorLayer()
|
EditorLayer::EditorLayer()
|
||||||
: Layer("HazelEditor"), m_CameraController((float)Application::Get().GetWindow().GetWidth() / (float)Application::Get().GetWindow().GetHeight())
|
: Layer("HazelEditor"), m_CameraController((float)Application::Get().GetWindow().GetWidth() / (float)Application::Get().GetWindow().GetHeight())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorLayer::OnAttach()
|
void EditorLayer::OnAttach()
|
||||||
{
|
{
|
||||||
|
|
||||||
FrameBufferSpecification spec;
|
FrameBufferSpecification spec;
|
||||||
spec.Width = Application::Get().GetWindow().GetWidth();
|
spec.Width = Application::Get().GetWindow().GetWidth();
|
||||||
spec.Height = Application::Get().GetWindow().GetHeight();
|
spec.Height = Application::Get().GetWindow().GetHeight();
|
||||||
@ -40,8 +39,6 @@ namespace Hazel
|
|||||||
redSquare.AddComponent<SpriteRendererComponent>(glm::vec4{1.0f, 0.0f, 0.0f, 1.0f});
|
redSquare.AddComponent<SpriteRendererComponent>(glm::vec4{1.0f, 0.0f, 0.0f, 1.0f});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
m_CameraEntity = m_ActiveScene->CreateEntity("Camera A");
|
m_CameraEntity = m_ActiveScene->CreateEntity("Camera A");
|
||||||
m_CameraEntity.AddComponent<CameraComponent>();
|
m_CameraEntity.AddComponent<CameraComponent>();
|
||||||
m_PrimaryCamera = true;
|
m_PrimaryCamera = true;
|
||||||
@ -55,10 +52,10 @@ namespace Hazel
|
|||||||
class CameraController : public ScriptableEntity
|
class CameraController : public ScriptableEntity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void OnUpdate(const TimeStep ts)
|
void OnUpdate(const TimeStep ts) override
|
||||||
{
|
{
|
||||||
auto& translation = GetComponent<TransformComponent>().Translation;
|
auto& translation = GetComponent<TransformComponent>().Translation;
|
||||||
static const auto state = SDL_GetKeyboardState(nullptr);
|
const auto state = SDL_GetKeyboardState(nullptr);
|
||||||
if (state[SDL_SCANCODE_A])
|
if (state[SDL_SCANCODE_A])
|
||||||
translation.x -= ts * speed;
|
translation.x -= ts * speed;
|
||||||
if (state[SDL_SCANCODE_D])
|
if (state[SDL_SCANCODE_D])
|
||||||
@ -77,6 +74,8 @@ namespace Hazel
|
|||||||
|
|
||||||
|
|
||||||
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
||||||
|
|
||||||
|
m_State = SDL_GetKeyboardState(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorLayer::OnDetech()
|
void EditorLayer::OnDetech()
|
||||||
@ -110,7 +109,7 @@ namespace Hazel
|
|||||||
RendererCommand::Clear();
|
RendererCommand::Clear();
|
||||||
|
|
||||||
|
|
||||||
// Renderer2D::BeginScene(m_cameraController.GetCamera());
|
// Renderer2D::BeginScene(m_CameraController.GetCamera());
|
||||||
|
|
||||||
// update Scene
|
// update Scene
|
||||||
m_ActiveScene->OnUpdate(ts);
|
m_ActiveScene->OnUpdate(ts);
|
||||||
@ -192,6 +191,22 @@ namespace Hazel
|
|||||||
// ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen);
|
// ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen);
|
||||||
// ImGui::MenuItem("Padding", NULL, &opt_padding);
|
// ImGui::MenuItem("Padding", NULL, &opt_padding);
|
||||||
// ImGui::Separator();
|
// 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(); }
|
if (ImGui::MenuItem("Exit")) { Hazel::Application::Get().Close(); }
|
||||||
|
|
||||||
@ -256,5 +271,59 @@ namespace Hazel
|
|||||||
{
|
{
|
||||||
m_CameraController.OnEvent(e);
|
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()
|
||||||
|
{
|
||||||
|
std::string filepath = FileDiaglogs::SaveFile("Hazel Scene (*.scene)\0*.scene\0");
|
||||||
|
if (!filepath.empty())
|
||||||
|
{
|
||||||
|
SceneSerializer serializer(m_ActiveScene);
|
||||||
|
serializer.Serialize(filepath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorLayer::OpenScene()
|
||||||
|
{
|
||||||
|
std::string filepath = FileDiaglogs::OpenFile("Hazel Scene (*.scene)\0*.scene\0");
|
||||||
|
if (!filepath.empty())
|
||||||
|
{
|
||||||
|
m_ActiveScene = CreateRef<Scene>();
|
||||||
|
m_ActiveScene->OnViewportResize((uint32_t)m_ViewPortSize.x, (uint32_t)m_ViewPortSize.y);
|
||||||
|
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
||||||
|
|
||||||
|
SceneSerializer serializer(m_ActiveScene);
|
||||||
|
serializer.Deserialize(filepath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorLayer::NewScene()
|
||||||
|
{
|
||||||
|
m_ActiveScene = CreateRef<Scene>();
|
||||||
|
m_ActiveScene->OnViewportResize((uint32_t)m_ViewPortSize.x, (uint32_t)m_ViewPortSize.y);
|
||||||
|
m_SceneHierachyPanel.SetContext(m_ActiveScene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,10 @@ namespace Hazel
|
|||||||
virtual void OnUpdate(TimeStep& ts) override;
|
virtual void OnUpdate(TimeStep& ts) override;
|
||||||
virtual void OnImGuiRender() override;
|
virtual void OnImGuiRender() override;
|
||||||
virtual void OnEvent(SDL_Event& e) override;
|
virtual void OnEvent(SDL_Event& e) override;
|
||||||
|
private:
|
||||||
|
void SaveScene();
|
||||||
|
void OpenScene();
|
||||||
|
void NewScene();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OrthographicCameraController m_CameraController;
|
OrthographicCameraController m_CameraController;
|
||||||
@ -45,6 +49,7 @@ namespace Hazel
|
|||||||
Ref<FrameBuffer> m_FrameBuffer;
|
Ref<FrameBuffer> m_FrameBuffer;
|
||||||
|
|
||||||
SceneHierachyPanel m_SceneHierachyPanel;
|
SceneHierachyPanel m_SceneHierachyPanel;
|
||||||
|
const bool* m_State = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,16 +18,17 @@ namespace Hazel
|
|||||||
void SceneHierachyPanel::SetContext(const Ref<Scene>& context)
|
void SceneHierachyPanel::SetContext(const Ref<Scene>& context)
|
||||||
{
|
{
|
||||||
m_Context = context;
|
m_Context = context;
|
||||||
|
m_SelectionContext = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneHierachyPanel::OnImGuiRender()
|
void SceneHierachyPanel::OnImGuiRender()
|
||||||
{
|
{
|
||||||
ImGui::Begin("Scene Hierachy");
|
ImGui::Begin("Scene Hierachy");
|
||||||
|
|
||||||
for (const auto entityID : m_Context->m_Registry.view<entt::entity>())
|
m_Context->m_Registry.view<entt::entity>().each([&](auto entityID)
|
||||||
{
|
{
|
||||||
DrawEntityNode({entityID, m_Context.get()});
|
DrawEntityNode({entityID, m_Context.get()});
|
||||||
}
|
});
|
||||||
|
|
||||||
if (ImGui::IsMouseDown(0) && ImGui::IsWindowHovered())
|
if (ImGui::IsMouseDown(0) && ImGui::IsWindowHovered())
|
||||||
{
|
{
|
||||||
@ -185,6 +186,7 @@ namespace Hazel
|
|||||||
|
|
||||||
if (entity.HasComponent<T>())
|
if (entity.HasComponent<T>())
|
||||||
{
|
{
|
||||||
|
ImGui::PushID(&entity);
|
||||||
auto& component = entity.GetComponent<T>();
|
auto& component = entity.GetComponent<T>();
|
||||||
|
|
||||||
ImVec2 contextReginAvail = ImGui::GetContentRegionAvail();
|
ImVec2 contextReginAvail = ImGui::GetContentRegionAvail();
|
||||||
@ -219,7 +221,8 @@ namespace Hazel
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (removeComponent)
|
if (removeComponent)
|
||||||
entity.RemoveComponent<SpriteRendererComponent>();
|
entity.RemoveComponent<T>();
|
||||||
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user