diff --git a/$tmpPly.polys b/$tmpPly.polys new file mode 100644 index 0000000..1da24d5 --- /dev/null +++ b/$tmpPly.polys @@ -0,0 +1,85 @@ +Entities: + - ID: 0 + Name: Light + Components: + Transform: + Position: [-1.6726234, -0.228918433, 0.638042808] + Rotation: [1.5, 2.70000005, 342.5] + Scale: [1, 1, 1] + Light: + Type: 0 + Intensity: 1 + Color: [0, 1, 0] + Constant: 1 + Linear: 0.0900000036 + Quadratic: 0.0320000015 + cutOff: 0 + outerCutOff: 39.7900009 + Direction: [-0.200000003, -1, -0.300000012] + - ID: 1 + Name: Cube + Components: + Transform: + Position: [0, 0, 0] + Rotation: [0, -166.600006, 0] + Scale: [0.100000001, 0.100000001, 0.100000001] + Render: + MeshName: model + Color: [1, 1, 1] + - ID: 2 + Name: Environment + Components: + Render: + MeshName: WhiteCube + Color: [1, 1, 1] + Transform: + Position: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [18.7000008, 7.4000001, 10] + - ID: 3 + Name: LightBlue + Components: + Light: + Type: 0 + Intensity: 2 + Color: [0, 0, 1] + Constant: 1 + Linear: 0 + Quadratic: 0.200000003 + cutOff: 12.5 + outerCutOff: 17.5 + Direction: [-0.200000003, -1, -0.300000012] + Transform: + Position: [0, 1.8090117, 3.07234383] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + - ID: 4 + Name: LightRed + Components: + Light: + Type: 0 + Intensity: 1 + Color: [1, 0, 0] + Constant: 1 + Linear: 0.0900000036 + Quadratic: 0.0320000015 + cutOff: 12.5 + outerCutOff: 17.5 + Direction: [-0.200000003, -1, -0.300000012] + Transform: + Position: [-2.94120026, 1.60229158, -1.5770874] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + - ID: 5 + Name: Camera + Components: + Camera: + Zoom: 10 + FOV: 45 + Orthographic: false + NearPlane: 0.100000001 + FarPlane: 1000 + Transform: + Position: [0, 0, 0] + Rotation: [0, 26.2000008, 0] + Scale: [0.100000001, 0.100000001, -0.100000001] \ No newline at end of file diff --git a/assets/Empty.polys b/assets/Empty.polys new file mode 100644 index 0000000..e69de29 diff --git a/assets/Example.polys b/assets/Example.polys new file mode 100644 index 0000000..74b1f4b --- /dev/null +++ b/assets/Example.polys @@ -0,0 +1,85 @@ +Entities: + - ID: 0 + Name: Light + Components: + Transform: + Position: [-1.6726234, -0.228918433, 0.638042808] + Rotation: [1.5, 2.70000005, 342.5] + Scale: [1, 1, 1] + Light: + Type: 0 + Intensity: 1 + Color: [0, 1, 0] + Constant: 1 + Linear: 0.0900000036 + Quadratic: 0.0320000015 + cutOff: 0 + outerCutOff: 39.7900009 + Direction: [-0.200000003, -1, -0.300000012] + - ID: 1 + Name: Cube + Components: + Transform: + Position: [-1.21370173, 1.20000005, 0] + Rotation: [55.3640938, 313.355988, 2.4872179e-05] + Scale: [1, 1, 1] + Render: + MeshName: WhiteCube + Color: [1, 1, 1] + - ID: 2 + Name: Environment + Components: + Render: + MeshName: WhiteCube + Color: [1, 1, 1] + Transform: + Position: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [18.7000008, 7.4000001, 10] + - ID: 3 + Name: LightBlue + Components: + Light: + Type: 0 + Intensity: 2 + Color: [0, 0, 1] + Constant: 1 + Linear: 0 + Quadratic: 0.200000003 + cutOff: 12.5 + outerCutOff: 17.5 + Direction: [-0.200000003, -1, -0.300000012] + Transform: + Position: [0, 1.8090117, 3.07234383] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + - ID: 4 + Name: LightRed + Components: + Light: + Type: 0 + Intensity: 1 + Color: [1, 0, 0] + Constant: 1 + Linear: 0.0900000036 + Quadratic: 0.0320000015 + cutOff: 12.5 + outerCutOff: 17.5 + Direction: [-0.200000003, -1, -0.300000012] + Transform: + Position: [-2.94120026, 1.60229158, -1.5770874] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + - ID: 5 + Name: Camera + Components: + Camera: + Zoom: 10 + FOV: 45 + Orthographic: false + NearPlane: 0.100000001 + FarPlane: 1000 + Transform: + Position: [-7.4000001, 0.899999976, -1.60000002] + Rotation: [0, 106.199997, 0] + Scale: [1, 1, 1] \ No newline at end of file diff --git a/assets/Example_House.polys b/assets/Example_House.polys new file mode 100644 index 0000000..3b259bc --- /dev/null +++ b/assets/Example_House.polys @@ -0,0 +1,85 @@ +Entities: + - ID: 0 + Name: Light + Components: + Light: + Type: 0 + Intensity: 1 + Color: [0, 1, 0] + Constant: 1 + Linear: 0.0900000036 + Quadratic: 0.0320000015 + cutOff: 0 + outerCutOff: 39.7900009 + Direction: [-0.200000003, -1, -0.300000012] + Transform: + Position: [-1.6726234, -0.228918433, 0.638042808] + Rotation: [1.5, 2.70000005, 342.5] + Scale: [1, 1, 1] + - ID: 1 + Name: Cube + Components: + Render: + MeshName: model + Color: [1, 1, 1] + Transform: + Position: [0, 0, 0] + Rotation: [0, -166.600006, 0] + Scale: [0.100000001, 0.100000001, 0.100000001] + - ID: 2 + Name: Environment + Components: + Transform: + Position: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [18.7000008, 7.4000001, 10] + Render: + MeshName: WhiteCube + Color: [1, 1, 1] + - ID: 3 + Name: LightBlue + Components: + Transform: + Position: [0, 1.8090117, 3.07234383] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + Light: + Type: 0 + Intensity: 2 + Color: [0, 0, 1] + Constant: 1 + Linear: 0 + Quadratic: 0.200000003 + cutOff: 12.5 + outerCutOff: 17.5 + Direction: [-0.200000003, -1, -0.300000012] + - ID: 4 + Name: LightRed + Components: + Transform: + Position: [-2.94120026, 1.60229158, -1.5770874] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + Light: + Type: 0 + Intensity: 1 + Color: [1, 0, 0] + Constant: 1 + Linear: 0.0900000036 + Quadratic: 0.0320000015 + cutOff: 12.5 + outerCutOff: 17.5 + Direction: [-0.200000003, -1, -0.300000012] + - ID: 5 + Name: Camera + Components: + Transform: + Position: [-4.12095118, 0.57130301, -1.16569459] + Rotation: [0, 106.199997, 0] + Scale: [1, 1, 1] + Camera: + Zoom: 10 + FOV: 45 + Orthographic: false + NearPlane: 0.100000001 + FarPlane: 1000 \ No newline at end of file diff --git a/assets/Scene.polys b/assets/Scene.polys new file mode 100644 index 0000000..7e7720c --- /dev/null +++ b/assets/Scene.polys @@ -0,0 +1,28 @@ +Entities: + - ID: 0 + Name: Light + Components: + Light: + Type: 2 + Intensity: 9.30000019 + Color: [1, 1, 1] + Constant: 1 + Linear: 0.0900000036 + Quadratic: 0.0320000015 + cutOff: 0 + outerCutOff: 39.7900009 + Direction: [-0.200000003, -1, -0.300000012] + Transform: + Position: [-1.70000005, -0.200000003, -0.100000001] + Rotation: [1.5, 2.70000005, -17.5] + Scale: [1, 1, 1] + - ID: 1 + Name: Cube + Components: + Render: + MeshName: WhiteCube + Color: [1, 1, 1] + Transform: + Position: [-1.21370173, 1.20000005, 0] + Rotation: [1.34287302e-05, -41.9440002, 1.62548586e-05] + Scale: [1, 1, 1] \ No newline at end of file diff --git a/assets/light.polys b/assets/light.polys new file mode 100644 index 0000000..16ab721 --- /dev/null +++ b/assets/light.polys @@ -0,0 +1,18 @@ +Entities: + - ID: 0 + Name: Entity 0 + Components: + Light: + Type: 0 + Intensity: 1 + Color: [1, 1, 1] + Constant: 1 + Linear: 0.0900000036 + Quadratic: 0.0320000015 + cutOff: 12.5 + outerCutOff: 17.5 + Direction: [-0.200000003, -1, -0.300000012] + Transform: + Position: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] \ No newline at end of file diff --git a/assets/scene1.polys b/assets/scene1.polys new file mode 100644 index 0000000..5ad53b8 --- /dev/null +++ b/assets/scene1.polys @@ -0,0 +1,8 @@ +Entities: + - ID: 0 + Name: Entity 0 + Components: + Transform: + Position: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] \ No newline at end of file diff --git a/build/CameraComponent.o b/build/CameraComponent.o new file mode 100644 index 0000000..b7aa542 Binary files /dev/null and b/build/CameraComponent.o differ diff --git a/build/Entity.o b/build/Entity.o index 44bb306..83e83c5 100644 Binary files a/build/Entity.o and b/build/Entity.o differ diff --git a/build/Shader.o b/build/Shader.o index c0daf0a..5b3d6e3 100644 Binary files a/build/Shader.o and b/build/Shader.o differ diff --git a/build/game_engine.exe b/build/game_engine.exe index af224c2..6c1997c 100644 Binary files a/build/game_engine.exe and b/build/game_engine.exe differ diff --git a/build/main.o b/build/main.o index fdfe693..f255aa8 100644 Binary files a/build/main.o and b/build/main.o differ diff --git a/imgui.ini b/imgui.ini index 94a5842..156a1a3 100644 --- a/imgui.ini +++ b/imgui.ini @@ -1,6 +1,6 @@ [Window][DockSpace Window] Pos=0,20 -Size=1280,720 +Size=1920,1177 Collapsed=0 [Window][Debug##Default] @@ -16,44 +16,60 @@ DockId=0x00000005,0 [Window][Game View] Pos=312,28 -Size=626,322 +Size=607,779 Collapsed=0 -DockId=0x00000009,0 +DockId=0x0000000D,0 [Window][Asset Panel] -Pos=8,379 -Size=302,353 +Pos=8,607 +Size=302,582 Collapsed=0 DockId=0x00000008,0 [Window][Inspector] -Pos=940,28 -Size=332,704 +Pos=1527,28 +Size=385,779 Collapsed=0 -DockId=0x00000004,0 +DockId=0x0000000B,0 [Window][Scene] Pos=8,28 -Size=302,349 +Size=302,577 Collapsed=0 DockId=0x00000007,0 [Window][Info] -Pos=312,352 -Size=626,380 +Pos=312,809 +Size=1213,380 Collapsed=0 DockId=0x0000000A,0 -[Docking][Data] -DockSpace ID=0xC746EC7D Window=0x9DF47A72 Pos=8,28 Size=1264,704 Split=X Selected=0x642CEEBB - DockNode ID=0x00000003 Parent=0xC746EC7D SizeRef=1570,1161 Split=X - DockNode ID=0x00000001 Parent=0x00000003 SizeRef=302,1161 Split=Y Selected=0x9D571615 - DockNode ID=0x00000007 Parent=0x00000001 SizeRef=580,577 Selected=0xE192E354 - DockNode ID=0x00000008 Parent=0x00000001 SizeRef=580,582 Selected=0x9D571615 - DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1600,1161 Split=X - DockNode ID=0x00000005 Parent=0x00000002 SizeRef=197,1161 Selected=0x4E0EE8E4 - DockNode ID=0x00000006 Parent=0x00000002 SizeRef=1035,1161 Split=Y Selected=0x642CEEBB - DockNode ID=0x00000009 Parent=0x00000006 SizeRef=1266,779 CentralNode=1 Selected=0x642CEEBB - DockNode ID=0x0000000A Parent=0x00000006 SizeRef=1266,380 Selected=0xE534E588 - DockNode ID=0x00000004 Parent=0xC746EC7D SizeRef=332,1161 Selected=0xE7039252 +[Window][Settings] +Pos=1527,809 +Size=385,380 +Collapsed=0 +DockId=0x0000000C,0 + +[Window][Camera Preview] +Pos=921,28 +Size=604,779 +Collapsed=0 +DockId=0x0000000E,0 + +[Docking][Data] +DockSpace ID=0xC746EC7D Window=0x9DF47A72 Pos=8,28 Size=1904,1161 Split=X Selected=0x642CEEBB + DockNode ID=0x00000003 Parent=0xC746EC7D SizeRef=1517,1161 Split=X + DockNode ID=0x00000001 Parent=0x00000003 SizeRef=302,1161 Split=Y Selected=0x9D571615 + DockNode ID=0x00000007 Parent=0x00000001 SizeRef=580,577 Selected=0xE192E354 + DockNode ID=0x00000008 Parent=0x00000001 SizeRef=580,582 Selected=0x9D571615 + DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1213,1161 Split=X + DockNode ID=0x00000005 Parent=0x00000002 SizeRef=197,1161 Selected=0x4E0EE8E4 + DockNode ID=0x00000006 Parent=0x00000002 SizeRef=1035,1161 Split=Y Selected=0x642CEEBB + DockNode ID=0x00000009 Parent=0x00000006 SizeRef=1266,779 Split=X Selected=0x642CEEBB + DockNode ID=0x0000000D Parent=0x00000009 SizeRef=607,779 CentralNode=1 Selected=0x642CEEBB + DockNode ID=0x0000000E Parent=0x00000009 SizeRef=604,779 Selected=0x111AC246 + DockNode ID=0x0000000A Parent=0x00000006 SizeRef=1266,380 Selected=0xE534E588 + DockNode ID=0x00000004 Parent=0xC746EC7D SizeRef=385,1161 Split=Y Selected=0xE7039252 + DockNode ID=0x0000000B Parent=0x00000004 SizeRef=385,779 Selected=0xE7039252 + DockNode ID=0x0000000C Parent=0x00000004 SizeRef=385,380 Selected=0x54723243 diff --git a/scene.polys b/scene.polys new file mode 100644 index 0000000..a2ff8a2 --- /dev/null +++ b/scene.polys @@ -0,0 +1,85 @@ +Entities: + - ID: 0 + Name: Light + Components: + Light: + Type: 0 + Intensity: 1 + Color: [0, 1, 0] + Constant: 1 + Linear: 0.0900000036 + Quadratic: 0.0320000015 + cutOff: 0 + outerCutOff: 39.7900009 + Direction: [-0.200000003, -1, -0.300000012] + Transform: + Position: [-1.6726234, -0.228918433, 0.638042808] + Rotation: [1.5, 2.70000005, 342.5] + Scale: [1, 1, 1] + - ID: 1 + Name: Cube + Components: + Render: + MeshName: model + Color: [1, 1, 1] + Transform: + Position: [0, 0, 0] + Rotation: [0, -166.600006, 0] + Scale: [0.100000001, 0.100000001, 0.100000001] + - ID: 2 + Name: Environment + Components: + Transform: + Position: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [18.7000008, 7.4000001, 10] + Render: + MeshName: WhiteCube + Color: [1, 1, 1] + - ID: 3 + Name: LightBlue + Components: + Transform: + Position: [0, 1.8090117, 3.07234383] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + Light: + Type: 0 + Intensity: 2 + Color: [0, 0, 1] + Constant: 1 + Linear: 0 + Quadratic: 0.200000003 + cutOff: 12.5 + outerCutOff: 17.5 + Direction: [-0.200000003, -1, -0.300000012] + - ID: 4 + Name: LightRed + Components: + Transform: + Position: [-2.94120026, 1.60229158, -1.5770874] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + Light: + Type: 0 + Intensity: 1 + Color: [1, 0, 0] + Constant: 1 + Linear: 0.0900000036 + Quadratic: 0.0320000015 + cutOff: 12.5 + outerCutOff: 17.5 + Direction: [-0.200000003, -1, -0.300000012] + - ID: 5 + Name: Camera + Components: + Transform: + Position: [0, 0, 0] + Rotation: [0, 26.2000008, 0] + Scale: [0.100000001, 0.100000001, -0.100000001] + Camera: + Zoom: 10 + FOV: 45 + Orthographic: false + NearPlane: 0.100000001 + FarPlane: 1000 \ No newline at end of file diff --git a/shaders/preview_fragment.glsl b/shaders/preview_fragment.glsl new file mode 100644 index 0000000..1e795c0 --- /dev/null +++ b/shaders/preview_fragment.glsl @@ -0,0 +1,25 @@ +#version 330 core +out vec4 FragColor; + +in vec3 FragPos; +in vec3 Normal; + +uniform vec3 objectColor; + +// Function to map normal vector components from [-1, 1] to [0, 1] +vec3 NormalizeNormalToColor(vec3 normal) +{ + return normal * 0.5 + 0.5; +} + +void main() +{ + // Option 1: Visualize normals as colors + vec3 colorFromNormal = NormalizeNormalToColor(normalize(Normal)); + + // Option 2: Combine with object color + // vec3 color = objectColor * colorFromNormal; + + // Choose either option based on your preference + FragColor = vec4(colorFromNormal, 1.0); +} diff --git a/shaders/preview_vertex.glsl b/shaders/preview_vertex.glsl new file mode 100644 index 0000000..628fb6c --- /dev/null +++ b/shaders/preview_vertex.glsl @@ -0,0 +1,17 @@ +#version 330 core +layout(location = 0) in vec3 aPos; +layout(location = 1) in vec3 aNormal; + +out vec3 FragPos; // Position of the fragment in world space +out vec3 Normal; // Normal of the fragment in world space + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + FragPos = vec3(model * vec4(aPos, 1.0)); + Normal = mat3(transpose(inverse(model))) * aNormal; // Transform normals properly + gl_Position = projection * view * vec4(FragPos, 1.0); +} diff --git a/src/CameraComponent.cpp b/src/CameraComponent.cpp new file mode 100644 index 0000000..60c40a5 --- /dev/null +++ b/src/CameraComponent.cpp @@ -0,0 +1,113 @@ +// src/CameraComponent.cpp + +#include "CameraComponent.h" + + + +// Constructor with default values +CameraComponent::CameraComponent() + : zoom(10.0f), + fov(45.0f), + orthographic(false), + nearPlane(0.1f), + farPlane(1000.0f) +{ +} + +// Override to provide the component's name +const std::string& CameraComponent::GetName() const +{ + static std::string name = "Camera"; + return name; +} + +// Static method to retrieve the component's name +std::string CameraComponent::GetStaticName() +{ + return "Camera"; +} + +// Computes the view matrix based on position and rotation +glm::mat4 CameraComponent::GetViewMatrix(const glm::vec3& position, const glm::vec3& rotation) const +{ + // Start with identity matrix + glm::mat4 view = glm::mat4(1.0f); + + // Apply rotations: Roll (Z), Pitch (X), then Yaw (Y) + view = glm::rotate(view, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)); // Roll + view = glm::rotate(view, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f)); // Pitch + view = glm::rotate(view, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)); // Yaw + + // Apply translation: Move the world opposite to the camera's position + view = glm::translate(view, -position); + + return view; +} + +// Computes the projection matrix based on the current projection type and aspect ratio +glm::mat4 CameraComponent::GetProjectionMatrix(float aspectRatio) const +{ + + if (orthographic) + { + float halfWidth = zoom; + float halfHeight = zoom / aspectRatio; + return glm::ortho(-halfWidth, halfWidth, -halfHeight, halfHeight, nearPlane, farPlane); + } + else + { + return glm::perspective(glm::radians(fov), aspectRatio, nearPlane, farPlane); + } +} + +// Serialization Method +YAML::Node CameraComponent::Serialize() +{ + YAML::Node node; + + // Zoom + node["Zoom"] = zoom; + + // Field of View + node["FOV"] = fov; + + // Orthographic Projection Toggle + node["Orthographic"] = orthographic; + + // Near Plane + node["NearPlane"] = nearPlane; + + // Far Plane + node["FarPlane"] = farPlane; + + return node; +} + +// Deserialization Method +void CameraComponent::Deserialize(const YAML::Node& node) +{ + if (node["Zoom"]) + { + zoom = node["Zoom"].as(); + } + + if (node["FOV"]) + { + fov = node["FOV"].as(); + } + + if (node["Orthographic"]) + { + orthographic = node["Orthographic"].as(); + } + + if (node["NearPlane"]) + { + nearPlane = node["NearPlane"].as(); + } + + if (node["FarPlane"]) + { + farPlane = node["FarPlane"].as(); + } +} diff --git a/src/CameraComponent.h b/src/CameraComponent.h index 72684a6..16c30be 100644 --- a/src/CameraComponent.h +++ b/src/CameraComponent.h @@ -1,4 +1,4 @@ -// CameraComponent.h +// include/CameraComponent.h #pragma once @@ -9,101 +9,41 @@ #include // Enumeration for Projection Types (Optional) -enum class ProjectionType { +enum class ProjectionType +{ Perspective = 0, Orthographic = 1 }; -struct CameraComponent : public Component { +class CameraComponent : public Component +{ +public: // Camera Attributes - float zoom; // Applicable for Orthographic Projection - float fov; // Field of View in degrees for Perspective Projection - bool orthographic; // Toggle between Orthographic and Perspective + float zoom; // Applicable for Orthographic Projection + float fov; // Field of View in degrees for Perspective Projection + bool orthographic; // Toggle between Orthographic and Perspective float nearPlane; float farPlane; + // Euler Angles for Rotation (in degrees) + glm::vec3 rotation; // rotation.x = Pitch, rotation.y = Yaw, rotation.z = Roll + // Constructor with default values - CameraComponent() - : zoom(10.0f), - fov(45.0f), - orthographic(false), - nearPlane(0.1f), - farPlane(1000.0f) - {} + CameraComponent(); // Override to provide the component's name - virtual const std::string& GetName() const override { - static std::string name = "Camera"; - return name; - } + virtual const std::string& GetName() const override; // Static method to retrieve the component's name - static std::string GetStaticName() { - return "Camera"; - } + static std::string GetStaticName(); - // Computes the view matrix based on position and rotation from TransformComponent - glm::mat4 GetViewMatrix(const glm::vec3& position, float rotation) const { - glm::mat4 view = glm::mat4(1.0f); - // Apply translation and rotation inversely to simulate camera movement - view = glm::translate(view, -position); - view = glm::rotate(view, glm::radians(-rotation), glm::vec3(0, 0, 1)); - return view; - } - - // Computes the projection matrix based on the current projection type and aspect ratio - glm::mat4 GetProjectionMatrix(float aspectRatio) const { - if (orthographic) { - float halfWidth = zoom / 2.0f; - float halfHeight = halfWidth / aspectRatio; - return glm::ortho(-halfWidth, halfWidth, -halfHeight, halfHeight, nearPlane, farPlane); - } else { - return glm::perspective(glm::radians(fov), aspectRatio, nearPlane, farPlane); - } - } + // Methods to compute view and projection matrices + glm::mat4 GetViewMatrix(const glm::vec3& position, const glm::vec3& rotation) const; + glm::mat4 GetProjectionMatrix(float aspectRatio) const; // Serialization Method - virtual YAML::Node Serialize() override { - YAML::Node node; - - // Zoom - node["Zoom"] = zoom; - - // Field of View - node["FOV"] = fov; - - // Orthographic Projection Toggle - node["Orthographic"] = orthographic; - - // Near Plane - node["NearPlane"] = nearPlane; - - // Far Plane - node["FarPlane"] = farPlane; - - return node; - } + virtual YAML::Node Serialize() override; // Deserialization Method - virtual void Deserialize(const YAML::Node& node) override { - if (node["Zoom"]) { - zoom = node["Zoom"].as(); - } - - if (node["FOV"]) { - fov = node["FOV"].as(); - } - - if (node["Orthographic"]) { - orthographic = node["Orthographic"].as(); - } - - if (node["NearPlane"]) { - nearPlane = node["NearPlane"].as(); - } - - if (node["FarPlane"]) { - farPlane = node["FarPlane"].as(); - } - } + virtual void Deserialize(const YAML::Node& node) override; }; diff --git a/src/Framebuffer.h b/src/Framebuffer.h new file mode 100644 index 0000000..8fdb50c --- /dev/null +++ b/src/Framebuffer.h @@ -0,0 +1,46 @@ +// src/Framebuffer.h + +#pragma once +#include +#include + +// Structure to hold framebuffer components +struct Framebuffer { + GLuint FBO; + GLuint texture; + GLuint RBO; +}; + +// Function to initialize framebuffer +Framebuffer InitFramebuffer(int width, int height) { + Framebuffer fb; + + // Generate and bind framebuffer + glGenFramebuffers(1, &fb.FBO); + glBindFramebuffer(GL_FRAMEBUFFER, fb.FBO); + + // Create texture to hold color buffer + glGenTextures(1, &fb.texture); + glBindTexture(GL_TEXTURE_2D, fb.texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + // Attach texture to framebuffer + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb.texture, 0); + + // Create renderbuffer object for depth and stencil attachment + glGenRenderbuffers(1, &fb.RBO); + glBindRenderbuffer(GL_RENDERBUFFER, fb.RBO); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); + // Attach RBO to framebuffer + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fb.RBO); + + // Check framebuffer completeness + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + std::cerr << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl; + + // Unbind framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + return fb; +} diff --git a/src/Settings.h b/src/Settings.h new file mode 100644 index 0000000..577cec2 --- /dev/null +++ b/src/Settings.h @@ -0,0 +1,14 @@ +// Settings.h + +#pragma once + +struct Settings { + bool vsyncEnabled = false; + int polygonMode = 0; + float minFPS = 30.0f; + float maxFPS = 60.0f; + int vertexCount = 0; + int lightCount = 0; + int maxLights = 10; + +}; diff --git a/src/SettingsWindow.h b/src/SettingsWindow.h new file mode 100644 index 0000000..0c0317d --- /dev/null +++ b/src/SettingsWindow.h @@ -0,0 +1,73 @@ +// SettingsWindow.h + +#pragma once + +#include "Settings.h" +#include "imgui.h" +#include +#include + +const char* polygonModeOptions[] = { "Fill", "Wireframe", "Points" }; +const int numPolygonModes = sizeof(polygonModeOptions) / sizeof(polygonModeOptions[0]); + + +// Function to draw the Settings window +void DrawSettingsWindow(Settings &settings, float currentFPS, GLFWwindow *window) +{ + ImGui::Begin("Settings"); + + // === VSync Toggle === + if (ImGui::Checkbox("VSync", &settings.vsyncEnabled)) + { + // Toggle VSync using GLFW + + if (settings.vsyncEnabled) + { + glfwSwapInterval(1); // Enable VSync + } + else + { + glfwSwapInterval(0); // Disable VSync + } + } + + // === FPS Counter === + ImGui::Text("FPS: %.1f", currentFPS); + + // === Min FPS === + // ImGui::InputFloat("Min FPS", &settings.minFPS, 1.0f, 10.0f, "%.1f"); + + // === Max FPS === + // ImGui::InputFloat("Max FPS", &settings.maxFPS, 1.0f, 10.0f, "%.1f"); + + // === Vertex Count === + ImGui::Text("Vertex Count: %d", settings.vertexCount); + + // === Light Count === + ImGui::Text("Lights: %d / %d", settings.lightCount, settings.maxLights); + + // === Additional Utilities === + // SettingsWindow.cpp or wherever your settings UI is rendered + + // Example: Dropdown for selecting polygon mode + if (ImGui::Combo("Polygon Mode", &settings.polygonMode, polygonModeOptions, numPolygonModes)) + { + switch (settings.polygonMode) + { + case 0: + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + break; + case 1: + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + break; + case 2: + glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); + break; + default: + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + break; + } + } + + ImGui::End(); +} diff --git a/src/Shader.cpp b/src/Shader.cpp index 009e553..4206b90 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -3,6 +3,10 @@ #include #include +#include +#include +#include + // Shader constructor Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath) { @@ -96,3 +100,23 @@ void Shader::setInt(const std::string& name, int value) const { glUniform1i(glGetUniformLocation(Program, name.c_str()), value); } + +void Shader::SetBool(const std::string &name, bool value) const +{ + glUniform1i(glGetUniformLocation(Program, name.c_str()), (int)value); +} + +void Shader::SetInt(const std::string &name, int value) const +{ + glUniform1i(glGetUniformLocation(Program, name.c_str()), value); +} + +void Shader::SetFloat(const std::string &name, float value) const +{ + glUniform1f(glGetUniformLocation(Program, name.c_str()), value); +} + +void Shader::SetVec3(const std::string &name, const glm::vec3 &value) const +{ + glUniform3fv(glGetUniformLocation(Program, name.c_str()), 1, glm::value_ptr(value)); +} diff --git a/src/Shader.h b/src/Shader.h index 4a0221e..5ebf864 100644 --- a/src/Shader.h +++ b/src/Shader.h @@ -4,6 +4,9 @@ #include #include +#include + + class Shader { public: GLuint Program; // The program ID @@ -16,6 +19,12 @@ public: // Utility uniform functions void setInt(const std::string& name, int value) const; + // Utility uniform functions + void SetBool(const std::string &name, bool value) const; + void SetInt(const std::string &name, int value) const; + void SetFloat(const std::string &name, float value) const; + void SetVec3(const std::string &name, const glm::vec3 &value) const; + void SetMat4(const std::string &name, const glm::mat4 &mat) const; }; #endif // SHADER_H diff --git a/src/main.cpp b/src/main.cpp index f52d8d9..211ff9e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,8 @@ #define GLM_ENABLE_EXPERIMENTAL -#define VSYNC 1 +#define POLY_VERSION_MAJOR 0 +#define POLY_VERSION_MINOR 15 // Constants matching shader definitions const int MAX_POINT_LIGHTS = 256; @@ -35,11 +36,15 @@ const int MAX_SPOT_LIGHTS = 64; #include "LogSystem.h" #include "Shader.h" +#include "Settings.h" +#include "SettingsWindow.h" +#include "Framebuffer.h" #include "ImGuiStyle.h" -// Include ImGui headers #include "imgui.h" + +// Include ImGui headers #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" @@ -63,6 +68,8 @@ const int MAX_SPOT_LIGHTS = 64; #define MAX_LIGHTS 256 +Settings settings; + // Define your Asset structure or class as needed struct Asset { @@ -75,13 +82,18 @@ int fps = 0; bool gameWindowFocused = false; +int totalLights; + // Global variables GLuint cubeVAO = 0; GLuint cubeVBO = 0; + +//? Shaders +// All of the global shader defines Shader *cubeShader = nullptr; Shader *gizmoShader = nullptr; - Shader *FrustumShader = nullptr; +Shader *previewShader = nullptr; GLuint framebuffer = 0; GLuint renderedTexture = 0; @@ -112,6 +124,8 @@ void ShowCameraComponent(std::shared_ptr entity); void ManipulateEditorCamera(EditorCamera &editorCamera, float aspectRatio); +void ShowCameraPreview(std::vector> &entities); + // Function to retrieve the active game camera (first CameraComponent found) std::shared_ptr GetActiveGameCamera(const std::vector> &entities) { @@ -430,10 +444,10 @@ void setupCube(GLfloat *vertices, size_t vertexArraySize, GLuint &cubeVAO, GLuin int main() { - + std::cout << "Poly Engine 3D version " << POLY_VERSION_MAJOR << "." << POLY_VERSION_MINOR << std::endl; std::cout << "[Poly] Initializing..." << std::endl; - std::cout << "[Poly] GLFW " << GLFW_CONTEXT_VERSION_MAJOR << "." << GLFW_CONTEXT_VERSION_MINOR << std::endl; + std::cout << "[Poly] GLFW " << GLFW_VERSION_MAJOR << "." << GLFW_VERSION_MINOR << std::endl; // Initialize GLFW if (!glfwInit()) @@ -451,7 +465,7 @@ int main() } glfwMakeContextCurrent(window); - glfwSwapInterval(VSYNC); // Disable vsync + glfwSwapInterval(settings.vsyncEnabled); // vsync // Initialize GLEW (or any other OpenGL loader) glewExperimental = GL_TRUE; @@ -466,6 +480,9 @@ int main() // Load shaders cubeShader = new Shader("./shaders/vertex_shader.glsl", "./shaders/fragment_shader.glsl"); gizmoShader = new Shader("./shaders/gizmo_vertex_shader.glsl", "./shaders/gizmo_fragment_shader.glsl"); + // Initialization code (once during setup) + previewShader = new Shader("shaders/preview_vertex.glsl", "shaders/preview_fragment.glsl"); + FrustumShader = new Shader("./shaders/cam_vertex.glsl", "./shaders/cam_frag.glsl"); @@ -601,9 +618,15 @@ int main() double previousTime = glfwGetTime(); int frameCount = 0; + settings.maxLights = MAX_LIGHTS; + // Our state + std::cout << "[Poly] Starting" << std::endl; + + AddLogMessage("PolyEngine3D Version " + std::to_string(POLY_VERSION_MAJOR) + "." + std::to_string(POLY_VERSION_MINOR)); + // Main loop while (!glfwWindowShouldClose(window)) @@ -611,6 +634,8 @@ int main() // Poll and handle events glfwPollEvents(); + settings.lightCount = totalLights; + // Measure speed double currentTime = glfwGetTime(); frameCount++; @@ -619,7 +644,7 @@ int main() { // Display the frame count here any way you want. fps = frameCount; - AddLogMessage("FPS: " + std::to_string(fps)); + //AddLogMessage("FPS: " + std::to_string(fps)); frameCount = 0; previousTime = currentTime; @@ -678,11 +703,14 @@ int main() if (!GameRunning) { SaveScene(entities, "./$tmpPly.polys"); + selectedEntity = nullptr; // Reset selected entity GameRunning = true; } else { LoadScene(entities, "./$tmpPly.polys"); + selectedEntity = nullptr; + GameRunning = false; } } @@ -696,9 +724,12 @@ int main() glfwGetFramebufferSize(window, &display_w, &display_h); // Show windows + DrawSettingsWindow(settings, fps, window); + ShowEntityComponentTree(entities, selectedEntity); ShowInspector(selectedEntity); ShowGameView(entities); + ShowCameraPreview(entities); ShowAssetPanel(assetsDir, selectedAsset); DrawLogTerminal("Info"); @@ -1296,7 +1327,7 @@ void ManipulateEditorCamera(EditorCamera &editorCamera, float aspectRatio) { // Calculate the new rotation based on the manipulation // Since we're only rotating around the Z-axis for 2D, extract that component - float angle = glm::degrees(atan2(view[0][1], view[0][0])) * -1.0f; + float angle = glm::degrees(atan2(view[0][1], view[0][0])) * 1.0f; // Assuming `angle` corresponds to `yaw`, update the yaw accordingly editorCamera.SetYaw(angle); @@ -1308,6 +1339,7 @@ void ManipulateEditorCamera(EditorCamera &editorCamera, float aspectRatio) void DrawImGuizmo(TransformComponent &transform, glm::mat4 &view, glm::mat4 &projection) { + if (GameRunning) {return;} // Ensure ImGuizmo context is initialized ImGuizmo::BeginFrame(); @@ -1398,6 +1430,112 @@ glm::mat4 GetRotationMatrix(const TransformComponent *transform) return rotation; } +void ShowCameraPreview(std::vector> &entities) +{ + ImGui::Begin("Camera Preview"); + + // Get the window size for rendering + ImVec2 windowSize = ImGui::GetContentRegionAvail(); + int texWidth = static_cast(windowSize.x); + int texHeight = static_cast(windowSize.y); + + // Initialize framebuffer if not done + static Framebuffer fb = {0, 0, 0}; + static bool framebufferInitialized = false; + + if (!framebufferInitialized || texWidth != 0 || texHeight != 0) { + if (framebufferInitialized) { + // Delete previous framebuffer resources + glDeleteFramebuffers(1, &fb.FBO); + glDeleteTextures(1, &fb.texture); + glDeleteRenderbuffers(1, &fb.RBO); + } + fb = InitFramebuffer(texWidth, texHeight); + framebufferInitialized = true; + } + + // Bind the framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, fb.FBO); + + // Set viewport to match the framebuffer size + glViewport(0, 0, texWidth, texHeight); + + // Clear the framebuffer + glEnable(GL_DEPTH_TEST); + glClearColor(0.2f, 0.2f, 0.2f, 1.0f); // Slightly lighter background for visibility + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Find the camera entity + std::shared_ptr activeGameCamera = GetActiveGameCamera(entities); + std::shared_ptr cameraEntity = FindEntityWithCamera(entities, activeGameCamera); + if (cameraEntity) + { + auto camera = cameraEntity->GetComponent(); + auto transform = cameraEntity->GetComponent(); + + if (camera && transform) + { + // Compute view and projection matrices + glm::mat4 viewMatrix = camera->GetViewMatrix(transform->position, transform->rotation); + glm::mat4 projectionMatrix = camera->GetProjectionMatrix(static_cast(texWidth) / static_cast(texHeight)); + + // Use the minimal shader + previewShader->Use(); + + // Set uniforms + glUniformMatrix4fv(glGetUniformLocation(previewShader->Program, "view"), 1, GL_FALSE, glm::value_ptr(viewMatrix)); + glUniformMatrix4fv(glGetUniformLocation(previewShader->Program, "projection"), 1, GL_FALSE, glm::value_ptr(projectionMatrix)); + + + + // Render all entities except the camera itself + for (const auto &entity : entities) + { + if (entity == cameraEntity) + continue; // Skip the camera entity + + auto render = entity->GetComponent(); + auto entityTransform = entity->GetComponent(); + + if (render && entityTransform) + { + // Compute model matrix + glm::mat4 model = glm::mat4(1.0f); + model = glm::translate(model, entityTransform->position); + model = glm::rotate(model, glm::radians(entityTransform->rotation.x), glm::vec3(1, 0, 0)); + model = glm::rotate(model, glm::radians(entityTransform->rotation.y), glm::vec3(0, 1, 0)); + model = glm::rotate(model, glm::radians(entityTransform->rotation.z), glm::vec3(0, 0, 1)); + model = glm::scale(model, entityTransform->scale); + + // Set model and object color + glUniformMatrix4fv(glGetUniformLocation(previewShader->Program, "model"), 1, GL_FALSE, glm::value_ptr(model)); + glUniform3fv(glGetUniformLocation(previewShader->Program, "objectColor"), 1, glm::value_ptr(render->color)); + + + // Bind VAO and draw + glBindVertexArray(cubeVAO); + glDrawArrays(GL_TRIANGLES, 0, 36); // Assuming a cube with 36 vertices + glBindVertexArray(0); + } + } + } + } + else + { + // No camera found, display a message + ImGui::Text("No camera entity found."); + } + + // Unbind framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDisable(GL_DEPTH_TEST); + + // Display the rendered texture in ImGui + ImGui::Image((intptr_t)fb.texture, windowSize, ImVec2(0,1), ImVec2(1,0)); + + ImGui::End(); // End of Camera Preview window +} + // Updated ShowGameView function void ShowGameView(std::vector> &entities) { @@ -1468,7 +1606,7 @@ void ShowGameView(std::vector> &entities) { // Get position and rotation from TransformComponent glm::vec3 position = transform->position; - float rotation = transform->rotation.z; // Assuming rotation around Z-axis for 2D + glm::vec3 rotation = transform->rotation; // Assuming rotation.x = Pitch, rotation.y = Yaw, rotation.z = Roll // Compute view and projection matrices using CameraComponent and TransformComponent data viewMatrix = activeGameCamera->GetViewMatrix(position, rotation); @@ -1682,13 +1820,13 @@ void ShowGameView(std::vector> &entities) // glm::vec3 position = transform->position; // RenderCameraGizmo(position, glm::vec3(0.1f,0.1f,0.1f), viewMatrix, projectionMatrix); // } - + totalLights = 0; // Render light gizmos (if any) for (const auto &lightPair : lights) { // LightComponent *light = lightPair.first; TransformComponent *lightTransform = lightPair.second; - + totalLights++; RenderLightGizmo(lightTransform->position, viewMatrix, projectionMatrix); } } @@ -1716,3 +1854,5 @@ void ShowGameView(std::vector> &entities) ImGui::End(); // End of Game View window } + +