Converted Gameobjects and componenets to Classes, added texture and mesh inspectors
This commit is contained in:
parent
d71876544a
commit
9ad51f97b7
6
Makefile
6
Makefile
@ -2,7 +2,7 @@
|
||||
|
||||
# Compiler and Flags
|
||||
CXX := g++
|
||||
CXXFLAGS := -Wall -Wextra -std=c++17 -g
|
||||
CXXFLAGS := -Wall -Wextra -std=c++17 -g -DDEBUG
|
||||
|
||||
# Directories
|
||||
SRC_DIR := src
|
||||
@ -11,7 +11,7 @@ BUILD_DIR := build
|
||||
|
||||
# Include Directories
|
||||
GLFW_INCLUDE := C:/libraries/glfw/include
|
||||
INCLUDE_DIRS := $(SRC_DIR) $(VENDOR_DIRS) $(GLFW_INCLUDE) vendor/stb/include
|
||||
INCLUDE_DIRS := $(SRC_DIR) $(VENDOR_DIRS) $(GLFW_INCLUDE) vendor/stb/include C:\msys64\mingw64\include
|
||||
INCLUDE_DIRS := $(SRC_DIR) $(VENDOR_DIRS) $(GLFW_INCLUDE) vendor/gcml
|
||||
INCLUDES := $(addprefix -I, $(INCLUDE_DIRS))
|
||||
|
||||
@ -43,7 +43,7 @@ OBJ_FILES := $(patsubst %.cpp, $(BUILD_DIR)/%.o, $(ALL_SRC))
|
||||
TARGET := TesseractEngine.exe
|
||||
|
||||
# Libraries
|
||||
LIBS := -LC:/libraries/glfw/lib -lglfw3 -lopengl32 -lgdi32 -limm32 -lole32 -loleaut32 -luuid -lwinmm -lglew32 -lglu32
|
||||
LIBS := -LC:/libraries/glfw/lib -lglfw3 -lopengl32 -lgdi32 -limm32 -lole32 -loleaut32 -luuid -lwinmm -lglew32 -lglu32 -lyaml-cpp
|
||||
|
||||
# Phony Targets
|
||||
.PHONY: all clean copy_assets
|
||||
|
10
imgui.ini
10
imgui.ini
@ -10,7 +10,7 @@ Collapsed=0
|
||||
|
||||
[Window][Inspector]
|
||||
Pos=1588,27
|
||||
Size=324,772
|
||||
Size=324,587
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
@ -21,8 +21,8 @@ Collapsed=0
|
||||
DockId=0x00000003,0
|
||||
|
||||
[Window][Performance]
|
||||
Pos=1588,801
|
||||
Size=324,368
|
||||
Pos=1588,616
|
||||
Size=324,553
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
@ -54,6 +54,6 @@ DockSpace ID=0x14621557 Window=0x3DA2F1DE Pos=8,27 Size=1904,1142 Split=
|
||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=1578,770 CentralNode=1 HiddenTabBar=1 Selected=0xF7365A5A
|
||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=1578,370 HiddenTabBar=1 Selected=0x9DD4E196
|
||||
DockNode ID=0x00000002 Parent=0x00000008 SizeRef=324,1142 Split=Y Selected=0x36DC96AB
|
||||
DockNode ID=0x00000005 Parent=0x00000002 SizeRef=324,772 HiddenTabBar=1 Selected=0x36DC96AB
|
||||
DockNode ID=0x00000006 Parent=0x00000002 SizeRef=324,368 HiddenTabBar=1 Selected=0x726D8899
|
||||
DockNode ID=0x00000005 Parent=0x00000002 SizeRef=324,587 HiddenTabBar=1 Selected=0x36DC96AB
|
||||
DockNode ID=0x00000006 Parent=0x00000002 SizeRef=324,553 HiddenTabBar=1 Selected=0x726D8899
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
//#include <yaml-cpp/yaml.h>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
class Component
|
||||
{
|
||||
@ -11,6 +11,6 @@ public:
|
||||
|
||||
|
||||
// Serialization methods
|
||||
//virtual YAML::Node Serialize() = 0;
|
||||
//virtual void Deserialize(const YAML::Node& node) = 0;
|
||||
virtual YAML::Node Serialize() = 0;
|
||||
virtual void Deserialize(const YAML::Node& node) = 0;
|
||||
};
|
99
src/Componenets/GameObject.cpp
Normal file
99
src/Componenets/GameObject.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
|
||||
#include "GameObject.h"
|
||||
#include "Transform.h"
|
||||
#include <iostream>
|
||||
|
||||
GameObject::GameObject(int id, const std::string &name)
|
||||
: id(id), name(name)
|
||||
{
|
||||
}
|
||||
|
||||
int GameObject::GetComponentCount() const
|
||||
{
|
||||
return static_cast<int>(components.size());
|
||||
}
|
||||
|
||||
|
||||
void GameObject::AddComponent(const std::shared_ptr<Component> &component)
|
||||
{
|
||||
components[component->GetName()] = component;
|
||||
//std::cout << "Added " << component->GetName() << std::endl;
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> GameObject::GetComponentByName(const std::string &name) const
|
||||
{
|
||||
auto it = components.find(name);
|
||||
if (it != components.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
return nullptr; // Component not found
|
||||
}
|
||||
|
||||
YAML::Node GameObject::Serialize()
|
||||
{
|
||||
YAML::Node node;
|
||||
node["ID"] = id;
|
||||
node["Name"] = name;
|
||||
|
||||
YAML::Node componentsNode;
|
||||
for (const auto &compPair : components)
|
||||
{
|
||||
const std::string &compName = compPair.first;
|
||||
std::shared_ptr<Component> component = compPair.second;
|
||||
componentsNode[compName] = component->Serialize();
|
||||
}
|
||||
|
||||
node["Components"] = componentsNode;
|
||||
return node;
|
||||
}
|
||||
|
||||
void GameObject::Deserialize(const YAML::Node &node)
|
||||
{
|
||||
if (node["ID"])
|
||||
{
|
||||
id = node["ID"].as<int>();
|
||||
}
|
||||
if (node["Name"])
|
||||
{
|
||||
name = node["Name"].as<std::string>();
|
||||
}
|
||||
if (node["Components"])
|
||||
{
|
||||
YAML::Node componentsNode = node["Components"];
|
||||
for (auto it = componentsNode.begin(); it != componentsNode.end(); ++it)
|
||||
{
|
||||
std::string compName = it->first.as<std::string>();
|
||||
YAML::Node compNode = it->second;
|
||||
|
||||
if (compName == TransformComponent::GetStaticName())
|
||||
{
|
||||
auto transform = std::make_shared<TransformComponent>();
|
||||
transform->Deserialize(compNode);
|
||||
AddComponent(transform);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "[Poly] [De/Serialize] [ERROR] Invalid Component Type '" << compName << "' Skipping" << std::endl;
|
||||
}
|
||||
// Add deserialization for other components as needed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//}
|
||||
//else if (compName == MeshComponent::GetStaticName())
|
||||
//{
|
||||
// auto render = std::make_shared<MeshComponent>();
|
||||
// render->Deserialize(compNode);
|
||||
// AddComponent(render);
|
||||
//}
|
||||
//else if (compName == MeshComponent::GetStaticName())
|
||||
//{
|
||||
// auto render = std::make_shared<MeshComponent>();
|
||||
// render->Deserialize(compNode);
|
||||
// AddComponent(render);
|
@ -2,14 +2,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
|
||||
#include "Component.h"
|
||||
#include "Transform.h"
|
||||
#include "Mesh.h"
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
struct GameObject
|
||||
// GetComponent<CameraComponent>()
|
||||
|
||||
class GameObject
|
||||
{
|
||||
std::string name; // Unique name for the GameObject
|
||||
Transform transform; // Position, Rotation, Scale
|
||||
Mesh mesh; // Rendering Mesh
|
||||
// Add other components as needed
|
||||
public:
|
||||
int id;
|
||||
std::string name;
|
||||
std::unordered_map<std::string, std::shared_ptr<Component>> components;
|
||||
|
||||
int GetComponentCount() const;
|
||||
|
||||
GameObject(int id, const std::string &name);
|
||||
|
||||
void AddComponent(const std::shared_ptr<Component> &component);
|
||||
std::shared_ptr<Component> GetComponentByName(const std::string &name) const;
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<T> GetComponent()
|
||||
{
|
||||
auto it = components.find(T::GetStaticName());
|
||||
if (it != components.end())
|
||||
{
|
||||
return std::dynamic_pointer_cast<T>(it->second);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Serialization methods
|
||||
YAML::Node Serialize();
|
||||
void Deserialize(const YAML::Node &node);
|
||||
};
|
||||
|
48
src/Componenets/Mesh.cpp
Normal file
48
src/Componenets/Mesh.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
#include "Mesh.h"
|
||||
|
||||
const std::string MeshComponent::name = "Mesh";
|
||||
|
||||
MeshComponent::MeshComponent()
|
||||
: vao(0), indexCount(0), textureID(0)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string& MeshComponent::GetName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const std::string& MeshComponent::GetStaticName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
YAML::Node MeshComponent::Serialize()
|
||||
{
|
||||
YAML::Node node;
|
||||
|
||||
node["vao"] = static_cast<int>(vao);
|
||||
node["indexCount"] = static_cast<int>(indexCount);
|
||||
node["textureID"] = static_cast<int>(textureID);
|
||||
|
||||
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void MeshComponent::Deserialize(const YAML::Node& node)
|
||||
{
|
||||
if (node["vao"])
|
||||
{
|
||||
vao = static_cast<int>(node["vao"].as<int>());
|
||||
}
|
||||
if (node["indexCount"])
|
||||
{
|
||||
indexCount = static_cast<int>(node["indexCount"].as<int>());
|
||||
}
|
||||
if (node["textureID"])
|
||||
{
|
||||
textureID = static_cast<int>(node["textureID"].as<int>());
|
||||
}
|
||||
}
|
@ -1,12 +1,28 @@
|
||||
|
||||
// Mesh.h
|
||||
#pragma once
|
||||
#include <GL/glew.h>
|
||||
|
||||
// A simple mesh storing a VAO, index count, and texture ID
|
||||
struct Mesh
|
||||
#include "Component.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
class MeshComponent : public Component
|
||||
{
|
||||
public:
|
||||
GLuint vao = 0; // Vertex Array Object
|
||||
GLuint indexCount = 0; // Number of indices to draw
|
||||
GLuint textureID = 0; // The texture handle
|
||||
|
||||
MeshComponent();
|
||||
virtual const std::string& GetName() const override;
|
||||
static const std::string& GetStaticName();
|
||||
|
||||
// Serialization methods
|
||||
virtual YAML::Node Serialize() override;
|
||||
virtual void Deserialize(const YAML::Node& node) override;
|
||||
|
||||
private:
|
||||
static const std::string name;
|
||||
};
|
82
src/Componenets/Transform.cpp
Normal file
82
src/Componenets/Transform.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
// TransformComponent.cpp
|
||||
#include "Transform.h"
|
||||
|
||||
const std::string TransformComponent::name = "Transform";
|
||||
|
||||
TransformComponent::TransformComponent()
|
||||
: position(0.0f), rotation(0.0f), scale(1.0f)
|
||||
{
|
||||
position = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
rotation = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
}
|
||||
|
||||
const std::string& TransformComponent::GetName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
const std::string& TransformComponent::GetStaticName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
YAML::Node TransformComponent::Serialize()
|
||||
{
|
||||
YAML::Node node;
|
||||
|
||||
// Position
|
||||
{
|
||||
YAML::Node posNode;
|
||||
posNode.SetStyle(YAML::EmitterStyle::Flow);
|
||||
posNode.push_back(position.x);
|
||||
posNode.push_back(position.y);
|
||||
posNode.push_back(position.z);
|
||||
node["Position"] = posNode;
|
||||
}
|
||||
|
||||
// Rotation
|
||||
{
|
||||
YAML::Node rotNode;
|
||||
rotNode.SetStyle(YAML::EmitterStyle::Flow);
|
||||
rotNode.push_back(rotation.x);
|
||||
rotNode.push_back(rotation.y);
|
||||
rotNode.push_back(rotation.z);
|
||||
node["Rotation"] = rotNode;
|
||||
}
|
||||
|
||||
// Scale
|
||||
{
|
||||
YAML::Node scaleNode;
|
||||
scaleNode.SetStyle(YAML::EmitterStyle::Flow);
|
||||
scaleNode.push_back(scale.x);
|
||||
scaleNode.push_back(scale.y);
|
||||
scaleNode.push_back(scale.z);
|
||||
node["Scale"] = scaleNode;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void TransformComponent::Deserialize(const YAML::Node& node)
|
||||
{
|
||||
if (node["Position"])
|
||||
{
|
||||
auto pos = node["Position"].as<std::vector<float>>();
|
||||
if (pos.size() == 3)
|
||||
position = glm::vec3(pos[0], pos[1], pos[2]);
|
||||
}
|
||||
if (node["Rotation"])
|
||||
{
|
||||
auto rot = node["Rotation"].as<std::vector<float>>();
|
||||
if (rot.size() == 3)
|
||||
rotation = glm::vec3(rot[0], rot[1], rot[2]);
|
||||
}
|
||||
if (node["Scale"])
|
||||
{
|
||||
auto scl = node["Scale"].as<std::vector<float>>();
|
||||
if (scl.size() == 3)
|
||||
scale = glm::vec3(scl[0], scl[1], scl[2]);
|
||||
}
|
||||
}
|
@ -1,14 +1,25 @@
|
||||
// Transform.h
|
||||
#pragma once
|
||||
|
||||
#include "Component.h"
|
||||
#include <glm/glm.hpp>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
// A simple transform with position, rotation, scale
|
||||
struct Transform
|
||||
class TransformComponent : public Component
|
||||
{
|
||||
glm::vec3 position {0.f, 0.f, 0.f};
|
||||
glm::vec3 rotation {0.f, 0.f, 0.f}; // Euler angles, in degrees or radians
|
||||
glm::vec3 scale {1.f, 1.f, 1.f};
|
||||
public:
|
||||
glm::vec3 position;
|
||||
glm::vec3 rotation;
|
||||
glm::vec3 scale;
|
||||
|
||||
TransformComponent();
|
||||
virtual const std::string& GetName() const override;
|
||||
static const std::string& GetStaticName();
|
||||
|
||||
// Serialization methods
|
||||
virtual YAML::Node Serialize() override;
|
||||
virtual void Deserialize(const YAML::Node& node) override;
|
||||
|
||||
private:
|
||||
static const std::string name;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
109
src/Engine.cpp
109
src/Engine.cpp
@ -1,7 +1,5 @@
|
||||
// src/Engine.cpp
|
||||
|
||||
|
||||
|
||||
// Settings
|
||||
|
||||
#define VSync 1
|
||||
@ -11,6 +9,7 @@
|
||||
#include <chrono>
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <string>
|
||||
|
||||
// Dear ImGui
|
||||
#include "imgui.h"
|
||||
@ -23,35 +22,24 @@
|
||||
#include "Windows/InspectorWindow.h"
|
||||
#include "Windows/SceneWindow.h"
|
||||
|
||||
|
||||
#include "Engine/ThemeManager.h"
|
||||
|
||||
|
||||
#define YAML_CPP_STATIC_DEFINE
|
||||
// #define YAML_CPP_STATIC_DEFINE
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
|
||||
|
||||
#include "TestModel.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AssetManager g_AssetManager;
|
||||
|
||||
LoggerWindow *g_LoggerWindow;
|
||||
|
||||
std::vector<GameObject> g_GameObjects;
|
||||
std::vector<std::shared_ptr<GameObject>> g_GameObjects;
|
||||
|
||||
int g_GPU_Triangles_drawn_to_screen = 0;
|
||||
|
||||
|
||||
GameObject *g_SelectedObject; // Pointer to the currently selected object
|
||||
|
||||
|
||||
|
||||
|
||||
bool MyEngine::Init(int width, int height, const std::string &title)
|
||||
{
|
||||
DEBUG_PRINT("[START] Engine Init");
|
||||
@ -104,7 +92,6 @@ bool MyEngine::Init(int width, int height, const std::string& title)
|
||||
// Style
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
|
||||
// Platform/Renderer bindings
|
||||
ImGui_ImplGlfw_InitForOpenGL(m_Window, true);
|
||||
ImGui_ImplOpenGL3_Init("#version 330");
|
||||
@ -116,7 +103,6 @@ bool MyEngine::Init(int width, int height, const std::string& title)
|
||||
m_InspectorWindow = std::make_unique<InspectorWindow>();
|
||||
m_SceneWindow = std::make_unique<SceneWindow>();
|
||||
|
||||
|
||||
// Some initial logs
|
||||
m_LoggerWindow->AddLog("Engine initialized.");
|
||||
m_LoggerWindow->AddLog("Welcome to Tesseract Engine!");
|
||||
@ -130,35 +116,69 @@ bool MyEngine::Init(int width, int height, const std::string& title)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MyEngine::Run()
|
||||
{
|
||||
DEBUG_PRINT("[START] Engine Run ");
|
||||
|
||||
DEBUG_PRINT("Transition to Editor");
|
||||
|
||||
// Pseudocode:
|
||||
GameObject cube;
|
||||
int newId = g_GameObjects.size();
|
||||
auto newGameObject = std::make_shared<GameObject>(newId, ("Default"));
|
||||
|
||||
cube.name = std::string("Default");
|
||||
cube.transform.position = glm::vec3(0.f, 0.f, 0.f);
|
||||
cube.transform.rotation = glm::vec3(0.f, 0.5f, 0.f);
|
||||
cube.transform.scale = glm::vec3(1.f, 1.f, 1.f);
|
||||
DEBUG_PRINT("Created Default GameObject");
|
||||
|
||||
newGameObject->AddComponent(std::make_shared<TransformComponent>());
|
||||
newGameObject->AddComponent(std::make_shared<MeshComponent>());
|
||||
|
||||
DEBUG_PRINT("Added Componenets");
|
||||
|
||||
// Suppose we loaded a VAO, an EBO with 36 indices for the cube,
|
||||
// and a texture ID from the asset manager
|
||||
cube.mesh.vao = CreateCubeVAO();
|
||||
cube.mesh.indexCount = 36;
|
||||
cube.mesh.textureID = static_cast<GLuint>(reinterpret_cast<uintptr_t>(g_AssetManager.loadAsset(AssetType::TEXTURE, "assets/textures/wood.png")));
|
||||
auto mesh = newGameObject->GetComponent<MeshComponent>();
|
||||
auto transform = newGameObject->GetComponent<TransformComponent>();
|
||||
|
||||
g_GameObjects.push_back(cube);
|
||||
DEBUG_PRINT("Got pointers to Componenets");
|
||||
|
||||
if (mesh)
|
||||
{
|
||||
// printf("Got Valid Mesh Component\n");
|
||||
mesh->vao = CreateCubeVAO();
|
||||
mesh->indexCount = 36;
|
||||
mesh->textureID = static_cast<GLuint>(reinterpret_cast<uintptr_t>(g_AssetManager.loadAsset(AssetType::TEXTURE, "assets/textures/wood.png")));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
DEBUG_PRINT("Could not find Mesh Component\n");
|
||||
}
|
||||
|
||||
if (transform)
|
||||
{
|
||||
// printf("Got Valid Transform Component\n");
|
||||
transform->position = glm::vec3(0.f, 0.f, 0.f);
|
||||
transform->rotation = glm::vec3(0.f, 0.5f, 0.f);
|
||||
transform->scale = glm::vec3(1.f, 1.f, 1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
DEBUG_PRINT("Could not find Transform Component");
|
||||
}
|
||||
|
||||
g_AssetManager.loadAsset(AssetType::TEXTURE, "assets/textures/bricks.png");
|
||||
g_AssetManager.loadAsset(AssetType::TEXTURE, "assets/textures/default.png");
|
||||
g_AssetManager.loadAsset(AssetType::TEXTURE, "assets/textures/lush_grass.png");
|
||||
|
||||
g_GameObjects.push_back(newGameObject);
|
||||
DEBUG_PRINT("Put componenent into Global Componenets Subsystem");
|
||||
|
||||
// printf("%p\n", &g_GameObjects);
|
||||
|
||||
// Possibly create more GameObjects with different positions or textures
|
||||
|
||||
|
||||
ThemeManager_ChangeTheme(2);
|
||||
|
||||
DEBUG_PRINT("Changed Theme to default");
|
||||
|
||||
while (!glfwWindowShouldClose(m_Window) && m_Running)
|
||||
{
|
||||
@ -183,25 +203,25 @@ void MyEngine::Run()
|
||||
// Show main DockSpace
|
||||
ShowDockSpace();
|
||||
|
||||
|
||||
m_InspectorWindow->Show();
|
||||
|
||||
// Show our windows
|
||||
m_RenderWindow->Show(); // The spinning triangle as ImGui::Image
|
||||
|
||||
m_PerformanceWindow->Show(m_Fps, m_Ms); // FPS & ms
|
||||
|
||||
m_LoggerWindow->Show(); // Logs
|
||||
|
||||
m_SceneWindow->Show();
|
||||
|
||||
// After rendering
|
||||
m_PerformanceWindow->UpdatePerformanceStats(-1, -1);
|
||||
|
||||
m_PerformanceWindow->UpdatePerformanceStats(-1, g_GPU_Triangles_drawn_to_screen);
|
||||
|
||||
// End frame
|
||||
EndFrame();
|
||||
}
|
||||
DEBUG_PRINT("[OK] Engine Run ");
|
||||
|
||||
}
|
||||
|
||||
void MyEngine::Cleanup()
|
||||
@ -223,7 +243,6 @@ void MyEngine::Cleanup()
|
||||
|
||||
m_Running = false;
|
||||
DEBUG_PRINT("[OK] Engine Cleanup ");
|
||||
|
||||
}
|
||||
|
||||
void MyEngine::BeginFrame()
|
||||
@ -267,7 +286,8 @@ void MyEngine::ShowDockSpace()
|
||||
{
|
||||
static bool dockspaceOpen = true;
|
||||
static bool opt_fullscreen = true;
|
||||
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
|
||||
// Initialize dockspace_flags without ImGuiDockNodeFlags_DockSpace
|
||||
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
|
||||
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
||||
if (opt_fullscreen)
|
||||
@ -276,22 +296,18 @@ void MyEngine::ShowDockSpace()
|
||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ImGuiWindowFlags_NoResize
|
||||
| ImGuiWindowFlags_NoMove;
|
||||
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus
|
||||
| ImGuiWindowFlags_NoNavFocus;
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||
}
|
||||
|
||||
// Style
|
||||
// Style adjustments
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
|
||||
ImGui::Begin("DockSpace", &dockspaceOpen, window_flags);
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
// Menu bar example
|
||||
// Menu bar
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("File"))
|
||||
@ -307,6 +323,9 @@ void MyEngine::ShowDockSpace()
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
|
||||
{
|
||||
// Optional: Log the flags for debugging
|
||||
// DEBUG_PRINT("DockSpace Flags: %d", dockspace_flags);
|
||||
|
||||
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "TestModel.h"
|
||||
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
#include "gcml.h"
|
||||
|
||||
// Forward declaration to avoid including GLFW in the header if you prefer
|
||||
|
@ -9,9 +9,6 @@
|
||||
extern std::vector<GameObject> g_GameObjects;
|
||||
extern GameObject *g_SelectedObject; // Pointer to the currently selected object
|
||||
|
||||
|
||||
|
||||
|
||||
void InspectorWindow::Show()
|
||||
{
|
||||
// Increase window/item spacing for a cleaner look
|
||||
@ -22,7 +19,13 @@ void InspectorWindow::Show()
|
||||
if (ImGui::Begin("Inspector"))
|
||||
{
|
||||
// Title label (white text)
|
||||
ImGui::TextUnformatted("Selected Object Inspector");
|
||||
const char *objectName = "No Object Selected";
|
||||
if (g_SelectedObject)
|
||||
{
|
||||
objectName = g_SelectedObject->name.c_str();
|
||||
ImGui::Text("Editing Object: %s", objectName);
|
||||
ImGui::Text("Components: %d", g_SelectedObject->GetComponentCount());
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
@ -37,7 +40,12 @@ void InspectorWindow::Show()
|
||||
if (transformOpen && g_SelectedObject) //! Funny: I did not put a null check here and it broke everything.
|
||||
{
|
||||
|
||||
Transform* transform = &g_SelectedObject->transform;
|
||||
// Transform* transform = &g_SelectedObject->transform;
|
||||
std::shared_ptr<TransformComponent> transform = g_SelectedObject->GetComponent<TransformComponent>();
|
||||
// printf("%p\n", &transform);
|
||||
if (transform)
|
||||
{
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
@ -236,7 +244,44 @@ void InspectorWindow::Show()
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Text("Error, Null Component");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 0.4f, 1.0f));
|
||||
bool meshOpen = ImGui::CollapsingHeader("Mesh##Main", ImGuiTreeNodeFlags_DefaultOpen);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
if (meshOpen && g_SelectedObject) //! Funny: I did not put a null check here and it broke everything.
|
||||
{
|
||||
|
||||
// Transform* transform = &g_SelectedObject->transform;
|
||||
std::shared_ptr<MeshComponent> mesh = g_SelectedObject->GetComponent<MeshComponent>();
|
||||
// printf("%p\n", &transform);
|
||||
if (mesh)
|
||||
{
|
||||
|
||||
int vao = static_cast<int>(mesh->vao);
|
||||
if (ImGui::DragInt("vao", &vao, 1, 0, 1024))
|
||||
{
|
||||
mesh->vao = static_cast<GLuint>(vao);
|
||||
}
|
||||
|
||||
int indexCount = static_cast<int>(mesh->indexCount);
|
||||
if (ImGui::DragInt("indexCount", &indexCount, 1, 0, 1024))
|
||||
{
|
||||
mesh->indexCount = static_cast<GLuint>(indexCount);
|
||||
}
|
||||
|
||||
int textureID = static_cast<int>(mesh->textureID);
|
||||
if (ImGui::DragInt("textureID", &textureID, 1, 0, 1024))
|
||||
{
|
||||
mesh->textureID = static_cast<GLuint>(textureID);
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::Spacing();
|
||||
|
||||
// ===========================
|
||||
@ -274,6 +319,7 @@ void InspectorWindow::Show()
|
||||
// ImGui::Spacing();
|
||||
// ImGui::Separator();
|
||||
//}
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
} //
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
|
||||
extern int LoaddedAssets;
|
||||
extern int g_GPU_Triangles_drawn_to_screen;
|
||||
|
||||
// Initialize static members
|
||||
int PerformanceWindow::m_OpenGLCallCount = 0;
|
||||
@ -41,6 +42,9 @@ void PerformanceWindow::UpdatePerformanceStats(int newCallCount, int newTriangle
|
||||
{
|
||||
m_OpenGLCallCount = newCallCount;
|
||||
m_TriangleCount = newTriangleCount;
|
||||
|
||||
g_GPU_Triangles_drawn_to_screen = 0;
|
||||
|
||||
}
|
||||
|
||||
void PerformanceWindow::Show(float fps, float ms)
|
||||
@ -138,14 +142,14 @@ void PerformanceWindow::Show(float fps, float ms)
|
||||
300.0f,
|
||||
ImVec2(0, 50));
|
||||
|
||||
ImGui::Text("Triangles: %d", m_TriangleCount);
|
||||
ImGui::PlotHistogram("Triangles",
|
||||
ImGui::Text("Indices: %d", m_TriangleCount);
|
||||
ImGui::PlotHistogram("Indices",
|
||||
s_TriangleHistory,
|
||||
IM_ARRAYSIZE(s_TriangleHistory),
|
||||
0,
|
||||
nullptr,
|
||||
0.0f,
|
||||
5000.0f,
|
||||
m_TriangleCount*2.5,
|
||||
ImVec2(0, 50));
|
||||
|
||||
ImGui::Separator();
|
||||
|
@ -8,19 +8,19 @@
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include "imgui.h"
|
||||
|
||||
#include "gcml.h"
|
||||
|
||||
|
||||
#include "Componenets/GameObject.h"
|
||||
#include "Componenets/Mesh.h"
|
||||
#include "Componenets/Transform.h"
|
||||
|
||||
extern std::vector<GameObject> g_GameObjects;
|
||||
#include "Componenets/mesh.h"
|
||||
#include "Componenets/transform.h"
|
||||
|
||||
extern std::vector<std::shared_ptr<GameObject>> g_GameObjects;
|
||||
|
||||
#define CAM_FOV 45.0f
|
||||
#define CAM_NEAR_PLAIN 0.1f
|
||||
#define CAM_FAR_PLAIN 1000.0f
|
||||
|
||||
|
||||
// Include your AssetManager & Shader headers
|
||||
#include "Engine/AssetManager.h"
|
||||
#include "Rendering/Shader.h"
|
||||
@ -28,44 +28,143 @@ extern std::vector<GameObject> g_GameObjects;
|
||||
// Extern reference to our global (or extern) asset manager
|
||||
extern AssetManager g_AssetManager;
|
||||
|
||||
extern int g_GPU_Triangles_drawn_to_screen;
|
||||
|
||||
|
||||
// Example cube data (position + UVs)
|
||||
static float g_CubeVertices[] =
|
||||
{
|
||||
// FRONT (z=+1)
|
||||
-1.f, -1.f, 1.f, 0.f, 0.f,
|
||||
1.f, -1.f, 1.f, 1.f, 0.f,
|
||||
1.f, 1.f, 1.f, 1.f, 1.f,
|
||||
-1.f, 1.f, 1.f, 0.f, 1.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
0.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
1.f,
|
||||
|
||||
// BACK (z=-1)
|
||||
-1.f, -1.f, -1.f, 1.f, 0.f,
|
||||
1.f, -1.f, -1.f, 0.f, 0.f,
|
||||
1.f, 1.f, -1.f, 0.f, 1.f,
|
||||
-1.f, 1.f, -1.f, 1.f, 1.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
0.f,
|
||||
0.f,
|
||||
1.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
0.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
|
||||
// LEFT (x=-1)
|
||||
-1.f, -1.f, -1.f, 0.f, 0.f,
|
||||
-1.f, -1.f, 1.f, 1.f, 0.f,
|
||||
-1.f, 1.f, 1.f, 1.f, 1.f,
|
||||
-1.f, 1.f, -1.f, 0.f, 1.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
0.f,
|
||||
0.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
0.f,
|
||||
1.f,
|
||||
|
||||
// RIGHT (x=+1)
|
||||
1.f, -1.f, -1.f, 1.f, 0.f,
|
||||
1.f, -1.f, 1.f, 0.f, 0.f,
|
||||
1.f, 1.f, 1.f, 0.f, 1.f,
|
||||
1.f, 1.f, -1.f, 1.f, 1.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
0.f,
|
||||
1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
|
||||
// TOP (y=+1)
|
||||
-1.f, 1.f, -1.f, 0.f, 0.f,
|
||||
1.f, 1.f, -1.f, 1.f, 0.f,
|
||||
1.f, 1.f, 1.f, 1.f, 1.f,
|
||||
-1.f, 1.f, 1.f, 0.f, 1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
0.f,
|
||||
0.f,
|
||||
1.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
1.f,
|
||||
|
||||
// BOTTOM (y=-1)
|
||||
-1.f, -1.f, -1.f, 1.f, 0.f,
|
||||
1.f, -1.f, -1.f, 0.f, 0.f,
|
||||
1.f, -1.f, 1.f, 0.f, 1.f,
|
||||
-1.f, -1.f, 1.f, 1.f, 1.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
0.f,
|
||||
0.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
0.f,
|
||||
1.f,
|
||||
-1.f,
|
||||
-1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
1.f,
|
||||
};
|
||||
|
||||
static unsigned int g_CubeIndices[] =
|
||||
@ -81,11 +180,11 @@ static unsigned int g_CubeIndices[] =
|
||||
// Top
|
||||
16, 17, 18, 18, 19, 16,
|
||||
// Bottom
|
||||
20,21,22, 22,23,20
|
||||
};
|
||||
20, 21, 22, 22, 23, 20};
|
||||
|
||||
void RenderWindow::Show()
|
||||
{
|
||||
|
||||
ImGui::Begin("OpenGL Output");
|
||||
|
||||
ImVec2 size = ImGui::GetContentRegionAvail();
|
||||
@ -98,17 +197,22 @@ void RenderWindow::Show()
|
||||
m_Initialized = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// If there's space, render to the FBO, then show it as an ImGui image
|
||||
|
||||
if (w > 0 && h > 0)
|
||||
{
|
||||
if (w != m_LastWidth || h != m_LastHeight)
|
||||
{
|
||||
|
||||
m_FBO.Create(w, h);
|
||||
m_LastWidth = w;
|
||||
m_LastHeight = h;
|
||||
}
|
||||
|
||||
RenderSceneToFBO();
|
||||
|
||||
ImGui::Image(m_FBO.GetTextureID(), size, ImVec2(0, 0), ImVec2(1, 1));
|
||||
}
|
||||
else
|
||||
@ -117,6 +221,7 @@ void RenderWindow::Show()
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
}
|
||||
|
||||
void RenderWindow::InitGLResources()
|
||||
@ -124,6 +229,7 @@ void RenderWindow::InitGLResources()
|
||||
// ----------------------------------------------------
|
||||
// 1) Load SHADER from the asset manager
|
||||
// ----------------------------------------------------
|
||||
|
||||
{
|
||||
void *shaderAsset = g_AssetManager.loadAsset(AssetType::SHADER, "assets/shaders/UnlitMaterial");
|
||||
if (!shaderAsset)
|
||||
@ -182,10 +288,12 @@ void RenderWindow::InitGLResources()
|
||||
|
||||
}
|
||||
|
||||
|
||||
void RenderWindow::RenderSceneToFBO()
|
||||
{
|
||||
m_RotationAngle += 0.1f; // spin per frame
|
||||
|
||||
|
||||
|
||||
m_RotationAngle += 0.001f; // spin per frame
|
||||
|
||||
// Bind the FBO
|
||||
m_FBO.Bind();
|
||||
@ -193,10 +301,11 @@ void RenderWindow::RenderSceneToFBO()
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glClearColor(0.1f, 0.15f, 0.2f, 1.f);
|
||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Use our loaded shader
|
||||
|
||||
if (!m_ShaderPtr)
|
||||
return; // Can't render without a shader
|
||||
|
||||
@ -209,23 +318,48 @@ void RenderWindow::RenderSceneToFBO()
|
||||
glm::mat4 proj = glm::perspective(glm::radians(CAM_FOV), aspect, CAM_NEAR_PLAIN, CAM_FAR_PLAIN);
|
||||
|
||||
// Iterate over each GameObject and render it
|
||||
|
||||
|
||||
for (auto &obj : g_GameObjects)
|
||||
{
|
||||
|
||||
// -----------------------------------
|
||||
// 1) Build MVP from obj.transform
|
||||
// 1) Build MVP from transform
|
||||
// -----------------------------------
|
||||
glm::mat4 model = glm::mat4(1.f);
|
||||
|
||||
|
||||
std::shared_ptr<TransformComponent> transform = obj->GetComponent<TransformComponent>();
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<MeshComponent> mesh = obj->GetComponent<MeshComponent>();
|
||||
|
||||
if (!transform) {
|
||||
DEBUG_PRINT("Could not find Transform Component");
|
||||
}
|
||||
|
||||
|
||||
if (transform && mesh)
|
||||
{
|
||||
|
||||
// Translate
|
||||
model = glm::translate(model, obj.transform.position);
|
||||
|
||||
g_GPU_Triangles_drawn_to_screen = static_cast<int>(mesh->indexCount);
|
||||
|
||||
model = glm::translate(model, transform->position);
|
||||
|
||||
// Rotate around X, Y, Z
|
||||
model = glm::rotate(model, glm::radians(obj.transform.rotation.x), glm::vec3(1.f, 0.f, 0.f));
|
||||
model = glm::rotate(model, glm::radians(obj.transform.rotation.y), glm::vec3(0.f, 1.f, 0.f));
|
||||
model = glm::rotate(model, glm::radians(obj.transform.rotation.z), glm::vec3(0.f, 0.f, 1.f));
|
||||
|
||||
//transform->rotation.x += m_RotationAngle;
|
||||
model = glm::rotate(model, glm::radians(transform->rotation.x), glm::vec3(1.f, 0.f, 0.f));
|
||||
model = glm::rotate(model, glm::radians(transform->rotation.y), glm::vec3(0.f, 1.f, 0.f));
|
||||
model = glm::rotate(model, glm::radians(transform->rotation.z), glm::vec3(0.f, 0.f, 1.f));
|
||||
|
||||
// Scale
|
||||
model = glm::scale(model, obj.transform.scale);
|
||||
model = glm::scale(model, transform->scale);
|
||||
|
||||
|
||||
|
||||
// Compute MVP
|
||||
glm::mat4 mvp = proj * view * model;
|
||||
@ -238,7 +372,7 @@ void RenderWindow::RenderSceneToFBO()
|
||||
// 2) Bind the object's texture
|
||||
// -----------------------------------
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, obj.mesh.textureID);
|
||||
glBindTexture(GL_TEXTURE_2D, mesh->textureID);
|
||||
|
||||
// Set the sampler uniform to texture unit 0
|
||||
GLint texLoc = glGetUniformLocation(programID, "uTexture");
|
||||
@ -247,13 +381,14 @@ void RenderWindow::RenderSceneToFBO()
|
||||
// -----------------------------------
|
||||
// 3) Draw the object's mesh
|
||||
// -----------------------------------
|
||||
glBindVertexArray(obj.mesh.vao);
|
||||
glDrawElements(GL_TRIANGLES, obj.mesh.indexCount, GL_UNSIGNED_INT, nullptr);
|
||||
glBindVertexArray(mesh->vao);
|
||||
glDrawElements(GL_TRIANGLES, mesh->indexCount, GL_UNSIGNED_INT, nullptr);
|
||||
|
||||
// Unbind for cleanliness
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
glUseProgram(0);
|
||||
|
@ -5,35 +5,46 @@
|
||||
// Include your asset manager and any other necessary headers
|
||||
#include "Engine/AssetManager.h"
|
||||
#include "TestModel.h"
|
||||
#include "gcml.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// Globals
|
||||
extern std::vector<GameObject> g_GameObjects;
|
||||
extern GameObject* g_SelectedObject;
|
||||
extern std::vector<std::shared_ptr<GameObject>> g_GameObjects;
|
||||
extern std::shared_ptr<GameObject> g_SelectedObject;
|
||||
|
||||
|
||||
extern AssetManager g_AssetManager;
|
||||
|
||||
// Constructor
|
||||
|
||||
// Helper: Create a default cube GameObject
|
||||
GameObject CreateDefaultCube() {
|
||||
GameObject cube;
|
||||
cube.name = "Cube";
|
||||
cube.transform.position = glm::vec3(0.f, 0.f, 0.f);
|
||||
cube.transform.rotation = glm::vec3(0.f, 0.5f, 0.f);
|
||||
cube.transform.scale = glm::vec3(1.f, 1.f, 1.f);
|
||||
cube.mesh.vao = CreateCubeVAO(); // Implement your VAO creation logic
|
||||
cube.mesh.indexCount = 36;
|
||||
cube.mesh.textureID = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(g_AssetManager.loadAsset(AssetType::TEXTURE, "assets/textures/wood.png")));
|
||||
return cube;
|
||||
std::shared_ptr<GameObject> CreateDefaultCube()
|
||||
{
|
||||
// Pseudocode:
|
||||
int newId = g_GameObjects.size();
|
||||
auto newGameObject = std::make_shared<GameObject>(newId, ("New GameObject"));
|
||||
newGameObject->AddComponent(std::make_shared<TransformComponent>()); // Ensure each entity has a TransformComponent by default
|
||||
newGameObject->AddComponent(std::make_shared<MeshComponent>()); // Ensure each entity has a TransformComponent by default
|
||||
|
||||
// Suppose we loaded a VAO, an EBO with 36 indices for the cube,
|
||||
// and a texture ID from the asset manager
|
||||
std::shared_ptr<MeshComponent> mesh = newGameObject->GetComponent<MeshComponent>();
|
||||
|
||||
mesh->vao = CreateCubeVAO();
|
||||
mesh->indexCount = 36;
|
||||
mesh->textureID = static_cast<GLuint>(reinterpret_cast<uintptr_t>(g_AssetManager.loadAsset(AssetType::TEXTURE, "assets/textures/wood.png")));
|
||||
|
||||
return newGameObject;
|
||||
}
|
||||
|
||||
// Show function implementation
|
||||
void SceneWindow::Show() {
|
||||
if (ImGui::Begin("Scene Window")) {
|
||||
void SceneWindow::Show()
|
||||
{
|
||||
if (ImGui::Begin("Scene Window"))
|
||||
{
|
||||
// Add Button
|
||||
if (ImGui::Button("Add Object")) {
|
||||
if (ImGui::Button("Add Object"))
|
||||
{
|
||||
AddGameObject();
|
||||
std::cout << "Added a new GameObject. Total objects: " << g_GameObjects.size() << std::endl;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
@ -41,25 +52,62 @@ void SceneWindow::Show() {
|
||||
// Begin child region for the list to make it scrollable
|
||||
ImGui::BeginChild("GameObjectList", ImVec2(0, -ImGui::GetFrameHeightWithSpacing()), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
|
||||
// List GameObjects
|
||||
for (int index = 0; index < static_cast<int>(g_GameObjects.size()); ++index) {
|
||||
GameObject& obj = g_GameObjects[index];
|
||||
bool isSelected = (g_SelectedObject == &obj);
|
||||
// Define TreeNode flags for better visuals and interaction
|
||||
ImGuiTreeNodeFlags nodeFlags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth;
|
||||
|
||||
// Create a selectable item for each GameObject
|
||||
if (ImGui::Selectable(obj.name.c_str(), isSelected)) {
|
||||
g_SelectedObject = &obj;
|
||||
// Iterate through GameObjects using index for unique identification
|
||||
for (size_t i = 0; i < g_GameObjects.size(); ++i)
|
||||
{
|
||||
auto &obj = g_GameObjects[i];
|
||||
|
||||
// Determine flags based on selection
|
||||
ImGuiTreeNodeFlags flags = nodeFlags;
|
||||
if (g_SelectedObject == obj)
|
||||
flags |= ImGuiTreeNodeFlags_Selected;
|
||||
|
||||
// Unique identifier for each GameObject node using pointer to ensure uniqueness
|
||||
// Alternatively, you can use the object's ID or address
|
||||
std::string nodeLabel = obj->name;
|
||||
bool nodeOpen = ImGui::TreeNodeEx((void *)(intptr_t)i, flags, nodeLabel.c_str());
|
||||
|
||||
// Handle selection
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Left))
|
||||
{
|
||||
g_SelectedObject = obj;
|
||||
std::cout << "Selected GameObject: " << obj->name << " with ID: " << obj->id << std::endl;
|
||||
}
|
||||
|
||||
// Right-click context menu to remove GameObject
|
||||
if (ImGui::BeginPopupContextItem()) {
|
||||
if (ImGui::MenuItem("Remove")) {
|
||||
RemoveGameObject(index);
|
||||
// Right-click context menu for GameObject actions
|
||||
if (ImGui::BeginPopupContextItem())
|
||||
{
|
||||
// Delete GameObject Option
|
||||
if (ImGui::MenuItem("Remove"))
|
||||
{
|
||||
std::cout << "Attempting to remove GameObject: " << obj->name << " with ID: " << obj->id << std::endl;
|
||||
|
||||
RemoveGameObject(static_cast<int>(i));
|
||||
std::cout << "Removed GameObject: " << obj->name << std::endl;
|
||||
|
||||
ImGui::EndPopup();
|
||||
break; // Exit the loop as the list has been modified
|
||||
// Since we've erased the current entity, adjust the loop accordingly
|
||||
// Decrement i to account for the removed element
|
||||
--i;
|
||||
continue; // Skip the rest of the loop iteration
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Optionally, implement double-click to rename or perform other actions
|
||||
|
||||
// Close the tree node
|
||||
if (nodeOpen)
|
||||
{
|
||||
// If you decide to add child nodes in the future, handle them here
|
||||
// Currently, no additional handling is required
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
@ -67,14 +115,13 @@ void SceneWindow::Show() {
|
||||
ImGui::Separator();
|
||||
|
||||
// Show currently selected object details at the bottom
|
||||
if (g_SelectedObject) {
|
||||
if (g_SelectedObject)
|
||||
{
|
||||
ImGui::Text("Selected Object: %s", g_SelectedObject->name.c_str());
|
||||
// Optionally add details or editable fields here
|
||||
// Example:
|
||||
// ImGui::DragFloat3("Position", &g_SelectedObject->transform.position.x, 0.1f);
|
||||
// ImGui::DragFloat3("Rotation", &g_SelectedObject->transform.rotation.x, 0.1f);
|
||||
// ImGui::DragFloat3("Scale", &g_SelectedObject->transform.scale.x, 0.1f);
|
||||
} else {
|
||||
// Optionally, display more details or provide editing capabilities
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::Text("No Object Selected");
|
||||
}
|
||||
}
|
||||
@ -82,25 +129,38 @@ void SceneWindow::Show() {
|
||||
}
|
||||
|
||||
// AddGameObject: Adds a new GameObject
|
||||
void SceneWindow::AddGameObject() {
|
||||
GameObject newObj = CreateDefaultCube();
|
||||
// Optionally, modify the name to ensure uniqueness
|
||||
newObj.name += " " + std::to_string(g_GameObjects.size() + 1);
|
||||
void SceneWindow::AddGameObject()
|
||||
{
|
||||
std::shared_ptr<GameObject> newObj = CreateDefaultCube();
|
||||
// Modify the name to ensure uniqueness
|
||||
newObj->name += " " + std::to_string(g_GameObjects.size());
|
||||
g_GameObjects.push_back(newObj);
|
||||
std::cout << "Added GameObject: " << newObj->name << " with ID: " << newObj->id << std::endl;
|
||||
}
|
||||
|
||||
// RemoveGameObject: Removes a GameObject by index
|
||||
void SceneWindow::RemoveGameObject(int index) {
|
||||
if (index >= 0 && index < static_cast<int>(g_GameObjects.size())) {
|
||||
void SceneWindow::RemoveGameObject(int index)
|
||||
{
|
||||
if (index >= 0 && index < static_cast<int>(g_GameObjects.size()))
|
||||
{
|
||||
// If the object to be removed is selected, clear the selection
|
||||
if (g_SelectedObject == &g_GameObjects[index]) {
|
||||
if (g_SelectedObject == g_GameObjects[index])
|
||||
{
|
||||
g_SelectedObject = nullptr;
|
||||
std::cout << "Cleared selection as the selected GameObject was removed." << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "Removing GameObject: " << g_GameObjects[index]->name << " with ID: " << g_GameObjects[index]->id << std::endl;
|
||||
g_GameObjects.erase(g_GameObjects.begin() + index);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Attempted to remove GameObject with invalid index: " << index << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// GetSelectedObject function implementation
|
||||
GameObject* SceneWindow::GetSelectedObject() const {
|
||||
std::shared_ptr<GameObject> SceneWindow::GetSelectedObject() const
|
||||
{
|
||||
return g_SelectedObject;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
class SceneWindow {
|
||||
public:
|
||||
void Show();
|
||||
GameObject* GetSelectedObject() const;
|
||||
std::shared_ptr<GameObject> GetSelectedObject() const;
|
||||
|
||||
private:
|
||||
void AddGameObject(); // Adds a new game object
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
DEBUG_PRINT("[START] Creating Global Engine ");
|
||||
|
Loading…
Reference in New Issue
Block a user