diff --git a/EclipseEngine/EclipseEditor/EclipseEditor.vcxproj b/EclipseEngine/EclipseEditor/EclipseEditor.vcxproj
index 35f47c6b..abbba648 100644
--- a/EclipseEngine/EclipseEditor/EclipseEditor.vcxproj
+++ b/EclipseEngine/EclipseEditor/EclipseEditor.vcxproj
@@ -135,6 +135,8 @@
+
+
@@ -147,6 +149,8 @@
+
+
diff --git a/EclipseEngine/EclipseEditor/EclipseEditor.vcxproj.filters b/EclipseEngine/EclipseEditor/EclipseEditor.vcxproj.filters
index 6ba33ce2..b9816630 100644
--- a/EclipseEngine/EclipseEditor/EclipseEditor.vcxproj.filters
+++ b/EclipseEngine/EclipseEditor/EclipseEditor.vcxproj.filters
@@ -175,5 +175,17 @@
Resource Files\Shaders
+
+ Resource Files\Shaders
+
+
+ Resource Files\Shaders
+
+
+ Resource Files\Shaders
+
+
+ Resource Files\Shaders
+
\ No newline at end of file
diff --git a/EclipseEngine/EclipseEditor/EditorRenderer.cpp b/EclipseEngine/EclipseEditor/EditorRenderer.cpp
index 8b8a9fe4..5f481ab2 100644
--- a/EclipseEngine/EclipseEditor/EditorRenderer.cpp
+++ b/EclipseEngine/EclipseEditor/EditorRenderer.cpp
@@ -1,7 +1,7 @@
#include "App.h"
#include "EditorRenderer.h"
-EditorRenderer::EditorRenderer()
+EditorRenderer::EditorRenderer(App* application) : app(application)
{
fbo = new Framebuffer(core->window->GetWidth(), core->window->GetHeight());
}
@@ -25,6 +25,7 @@ bool EditorRenderer::Initialize()
optionShader = normalShader = new Shader("Shaders/normal.vert", "Shaders/normal.frag");
outliningShader = new Shader("Shaders/outline.vert", "Shaders/outline.frag");
aabbShader = new Shader("Shaders/aabb.vert", "Shaders/aabb.frag");
+ frustumShader = new Shader("Shaders/frustum.vert", "Shaders/frustum.frag");
glEnable(GL_CULL_FACE); // Backface culling testing
glEnable(GL_STENCIL_TEST); // Stencil testing
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
@@ -51,6 +52,21 @@ void EditorRenderer::Render(Scene* scene, Camera* editorCamera, std::shared_ptr<
{
if (!scene) return;
+ ViewportPanel* viewport = app->panelHandler->viewportPanel;
+
+ if (!viewport) {
+ std::cerr << "Error: Viewport Panel not found!" << std::endl;
+ return;
+ }
+
+ bool showSkybox = viewport->showSkybox;
+ bool showGrid = viewport->showGrid;
+ bool showGizmo = viewport->showGizmo;
+
+ if (showSkybox && scene->skybox) {
+ scene->skybox->Draw(*editorCamera);
+ }
+
// Normal object rendering
glStencilFunc(GL_ALWAYS, 1, 0xFF); // Write 1 to the stencil buffer for all objects
glStencilMask(0xFF); // Enable writing to the stencil buffer
@@ -84,6 +100,20 @@ void EditorRenderer::Render(Scene* scene, Camera* editorCamera, std::shared_ptr<
}
}
+ // Ensure correct OpenGL state for drawing lines
+ glDisable(GL_DEPTH_TEST);
+ glLineWidth(1.0f);
+
+ for (const auto& gameObject : scene->GetObjects()) {
+ if (Camera* camera = gameObject->GetComponent()) {
+ auto frustumVertices = camera->GetFrustumVertices(camera->nearPlane, camera->farPlane); // Adjust near and far planes as needed
+ DrawFrustum(frustumVertices, *frustumShader, editorCamera->GetViewMatrix(), editorCamera->GetProjectionMatrix());
+ }
+ }
+
+ glEnable(GL_DEPTH_TEST);
+ glLineWidth(1.0f);
+
if (selectedObject != nullptr)
{
// Calculate the world transform for the selected object
@@ -102,8 +132,15 @@ void EditorRenderer::Render(Scene* scene, Camera* editorCamera, std::shared_ptr<
glStencilFunc(GL_ALWAYS, 1, 0xFF); // Reset stencil function
glEnable(GL_DEPTH_TEST); // Re-enable depth testing
- RenderGrid(grid, editorCamera);
- RenderGuizmo();
+ // Render Grid if enabled
+ if (showGrid) {
+ RenderGrid(grid, editorCamera);
+ }
+
+ // Render Gizmo if enabled
+ if (showGizmo) {
+ RenderGuizmo();
+ }
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
@@ -168,3 +205,37 @@ void EditorRenderer::RenderAABB(AABB aabb, Shader& shader)
glDeleteBuffers(1, &EBO);
glDeleteVertexArrays(1, &VAO);
}
+
+void EditorRenderer::DrawFrustum(const std::array& frustumVertices, Shader& shader, const glm::mat4& view, const glm::mat4& projection) {
+ std::vector lines = {
+ frustumVertices[0], frustumVertices[1], frustumVertices[1], frustumVertices[2],
+ frustumVertices[2], frustumVertices[3], frustumVertices[3], frustumVertices[0],
+ frustumVertices[4], frustumVertices[5], frustumVertices[5], frustumVertices[6],
+ frustumVertices[6], frustumVertices[7], frustumVertices[7], frustumVertices[4],
+ frustumVertices[0], frustumVertices[4], frustumVertices[1], frustumVertices[5],
+ frustumVertices[2], frustumVertices[6], frustumVertices[3], frustumVertices[7]
+ };
+
+ GLuint VAO, VBO;
+ glGenVertexArrays(1, &VAO);
+ glGenBuffers(1, &VBO);
+
+ glBindVertexArray(VAO);
+ glBindBuffer(GL_ARRAY_BUFFER, VBO);
+ glBufferData(GL_ARRAY_BUFFER, lines.size() * sizeof(glm::vec3), lines.data(), GL_STATIC_DRAW);
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
+ glEnableVertexAttribArray(0);
+
+ shader.Activate();
+ shader.SetMat4("view", view);
+ shader.SetMat4("projection", projection);
+
+ glDrawArrays(GL_LINES, 0, lines.size());
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+
+ glDeleteBuffers(1, &VBO);
+ glDeleteVertexArrays(1, &VAO);
+}
diff --git a/EclipseEngine/EclipseEditor/EditorResources/skybox.png b/EclipseEngine/EclipseEditor/EditorResources/skybox.png
new file mode 100644
index 00000000..707e9701
Binary files /dev/null and b/EclipseEngine/EclipseEditor/EditorResources/skybox.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/back.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/back.png
new file mode 100644
index 00000000..1ee798dd
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/back.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/bottom.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/bottom.png
new file mode 100644
index 00000000..e0647d8a
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/bottom.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/front.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/front.png
new file mode 100644
index 00000000..17622b96
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/front.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/left.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/left.png
new file mode 100644
index 00000000..2bf105be
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/left.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/right.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/right.png
new file mode 100644
index 00000000..f3a6c55a
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/right.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/top.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/top.png
new file mode 100644
index 00000000..0d1e5ff0
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox1/top.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/back.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/back.png
new file mode 100644
index 00000000..e9d0441e
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/back.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/bottom.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/bottom.png
new file mode 100644
index 00000000..e82e003d
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/bottom.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/front.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/front.png
new file mode 100644
index 00000000..45b0fe46
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/front.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/left.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/left.png
new file mode 100644
index 00000000..7b6560ae
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/left.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/right.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/right.png
new file mode 100644
index 00000000..197de443
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/right.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/top.png b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/top.png
new file mode 100644
index 00000000..b20e9cad
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skybox2/top.png differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/back.bmp b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/back.bmp
new file mode 100644
index 00000000..7b6ad259
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/back.bmp differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/bottom.bmp b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/bottom.bmp
new file mode 100644
index 00000000..dabfa9a6
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/bottom.bmp differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/front.bmp b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/front.bmp
new file mode 100644
index 00000000..ad94baba
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/front.bmp differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/left.bmp b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/left.bmp
new file mode 100644
index 00000000..292993d8
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/left.bmp differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/right.bmp b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/right.bmp
new file mode 100644
index 00000000..1fc706fc
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/right.bmp differ
diff --git a/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/top.bmp b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/top.bmp
new file mode 100644
index 00000000..59bfb91d
Binary files /dev/null and b/EclipseEngine/EclipseEditor/Resources/skybox/skycube_1/top.bmp differ
diff --git a/EclipseEngine/EclipseEditor/Shaders/skybox.frag b/EclipseEngine/EclipseEditor/Shaders/skybox.frag
new file mode 100644
index 00000000..77a85127
--- /dev/null
+++ b/EclipseEngine/EclipseEditor/Shaders/skybox.frag
@@ -0,0 +1,10 @@
+#version 330 core
+out vec4 FragColor;
+
+in vec3 TexCoords;
+
+uniform samplerCube skybox;
+
+void main() {
+ FragColor = texture(skybox, TexCoords);
+}
diff --git a/EclipseEngine/EclipseEditor/Shaders/skybox.vert b/EclipseEngine/EclipseEditor/Shaders/skybox.vert
new file mode 100644
index 00000000..30189477
--- /dev/null
+++ b/EclipseEngine/EclipseEditor/Shaders/skybox.vert
@@ -0,0 +1,13 @@
+#version 330 core
+layout (location = 0) in vec3 aPos;
+
+out vec3 TexCoords;
+
+uniform mat4 view;
+uniform mat4 projection;
+
+void main() {
+ TexCoords = aPos;
+ vec4 pos = projection * view * vec4(aPos, 1.0);
+ gl_Position = pos.xyww; // Make sure depth is always 1.0
+}
diff --git a/EclipseEngine/EclipseEditor/ViewportPanel.cpp b/EclipseEngine/EclipseEditor/ViewportPanel.cpp
index abecd837..b8376a5b 100644
--- a/EclipseEngine/EclipseEditor/ViewportPanel.cpp
+++ b/EclipseEngine/EclipseEditor/ViewportPanel.cpp
@@ -21,6 +21,7 @@ ViewportPanel::ViewportPanel(const std::string& name, Framebuffer* framebuffer,
m_Trans = std::make_unique("EditorResources/trans.png", "icon", 0, GL_RGBA, GL_UNSIGNED_BYTE);
m_Rot = std::make_unique("EditorResources/rot.png", "icon", 0, GL_RGBA, GL_UNSIGNED_BYTE);
m_Sca = std::make_unique("EditorResources/sca.png", "icon", 0, GL_RGBA, GL_UNSIGNED_BYTE);
+ m_Skybox = std::make_unique("EditorResources/skybox.png", "icon", 0, GL_RGBA, GL_UNSIGNED_BYTE);
}
void ViewportPanel::Render()
@@ -120,6 +121,27 @@ void ViewportPanel::Render()
ImGui::EndDragDropTarget();
}
+ // Toggle buttons
+ ImGui::SetCursorScreenPos(ImVec2(viewportPosition.x + 600, viewportPosition.y + 15));
+
+ //if (ImGui::ImageButton(reinterpret_cast(static_cast(m_Framebuffer->GetTextureID())), ImVec2(15, 15)))
+ //{
+ // showGrid = !showGrid;
+ //}
+ //ImGui::SameLine();
+
+ if (ImGui::ImageButton(reinterpret_cast(static_cast(m_Skybox->textureID)), ImVec2(20, 20)))
+ {
+ showSkybox = !showSkybox;
+ }
+ ImGui::SameLine();
+
+ //if (ImGui::ImageButton(reinterpret_cast(static_cast(m_Framebuffer->GetTextureID())), ImVec2(15, 15)))
+ //{
+ // showGizmo = !showGizmo;
+ //}
+
+
// Function to set button colors based on the active state
auto setActiveButtonColor = [](bool isActive) {
if (isActive) {
@@ -189,7 +211,7 @@ void ViewportPanel::Render()
}
// Gizmo manipulation (only active if not idle)
- if (operation != ManipulationOperation::IDLE && m_SelectedObject)
+ if (operation != ManipulationOperation::IDLE && m_SelectedObject && showGizmo)
{
ImGuizmo::SetOrthographic(false);
ImGuizmo::SetDrawlist(ImGui::GetWindowDrawList());
diff --git a/EclipseEngine/EclipseEditor/ViewportPanel.h b/EclipseEngine/EclipseEditor/ViewportPanel.h
index 1d1d12de..e4f95036 100644
--- a/EclipseEngine/EclipseEditor/ViewportPanel.h
+++ b/EclipseEngine/EclipseEditor/ViewportPanel.h
@@ -30,6 +30,9 @@ class ViewportPanel : public Panel
void Resize(int width, int height);
+ bool showGrid = true;
+ bool showSkybox = true;
+ bool showGizmo = true;
private:
Framebuffer* m_Framebuffer;
Camera* m_camera;
@@ -41,9 +44,11 @@ class ViewportPanel : public Panel
std::unique_ptr m_Trans;
std::unique_ptr m_Rot;
std::unique_ptr m_Sca;
+ std::unique_ptr m_Skybox;
const float iconSize = 25.0f;
const float iconSpacing = 5.0f; //spacing between icons
+
};
#endif // VIEWPORTPANEL_H
\ No newline at end of file
diff --git a/EclipseEngine/EclipseEngine/EclipseEngine.vcxproj b/EclipseEngine/EclipseEngine/EclipseEngine.vcxproj
index 2381622e..d77044f8 100644
--- a/EclipseEngine/EclipseEngine/EclipseEngine.vcxproj
+++ b/EclipseEngine/EclipseEngine/EclipseEngine.vcxproj
@@ -91,6 +91,7 @@
+
@@ -113,6 +114,7 @@
+
diff --git a/EclipseEngine/EclipseEngine/EclipseEngine.vcxproj.filters b/EclipseEngine/EclipseEngine/EclipseEngine.vcxproj.filters
index 853803b8..3fa50ad5 100644
--- a/EclipseEngine/EclipseEngine/EclipseEngine.vcxproj.filters
+++ b/EclipseEngine/EclipseEngine/EclipseEngine.vcxproj.filters
@@ -72,6 +72,9 @@
Source Files
+
+ Source Files
+
@@ -137,5 +140,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/EclipseEngine/EclipseEngine/Scene.cpp b/EclipseEngine/EclipseEngine/Scene.cpp
index c3ae34b0..b0134236 100644
--- a/EclipseEngine/EclipseEngine/Scene.cpp
+++ b/EclipseEngine/EclipseEngine/Scene.cpp
@@ -17,9 +17,24 @@ bool Scene::Initialize()
cameraGO->name = "Main Camera";
cameraGO->AddComponent(1500, 844, glm::vec3(7.0f, 4.0f, -7.0f));
SetActiveCamera(cameraGO->GetComponent());
+ activeCamera->SetNearPlane(5.0f);
+ activeCamera->SetFarPlane(100.0f);
AddGameObject(cameraGO);
//auto initScene = modelLoader.LoadModel("Resources/Assets/fbx_files/Street/untitled.fbx");
//AddGameObject(initScene);
+
+ std::vector cubemapFaces = {
+ "Resources/skybox/skybox1/right.png", "Resources/skybox/skybox1/left.png", "Resources/skybox/skybox1/top.png",
+ "Resources/skybox/skybox1/bottom.png", "Resources/skybox/skybox1/front.png", "Resources/skybox/skybox1/back.png"
+ };
+
+ //std::vector cubemapFaces = {
+ //"Resources/skybox/skycube_1/right.bmp", "Resources/skybox/skycube_1/left.bmp", "Resources/skybox/skycube_1/top.bmp",
+ //"Resources/skybox/skycube_1/bottom.bmp", "Resources/skybox/skycube_1/front.bmp", "Resources/skybox/skycube_1/back.bmp"
+ //};
+
+ skybox = std::make_unique(cubemapFaces);
+
return true;
}
diff --git a/EclipseEngine/EclipseEngine/Scene.h b/EclipseEngine/EclipseEngine/Scene.h
index d27254a1..1d4d331f 100644
--- a/EclipseEngine/EclipseEngine/Scene.h
+++ b/EclipseEngine/EclipseEngine/Scene.h
@@ -6,6 +6,7 @@
#include "GameObject.h"
#include "Camera.h"
#include "ModelLoader.h"
+#include "Skybox.h"
class Scene
{
@@ -26,6 +27,7 @@ class Scene
void AddCube();
+ std::unique_ptr skybox;
private:
std::list> gameObjects;
Camera* activeCamera = nullptr;
diff --git a/EclipseEngine/EclipseEngine/SkyBox.cpp b/EclipseEngine/EclipseEngine/SkyBox.cpp
new file mode 100644
index 00000000..9a492d08
--- /dev/null
+++ b/EclipseEngine/EclipseEngine/SkyBox.cpp
@@ -0,0 +1,106 @@
+#include "Skybox.h"
+#include
+
+// Skybox cube vertices (only positions needed)
+float skyboxVertices[] = {
+ -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
+
+ -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
+ -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
+
+ 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
+
+ -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
+
+ -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f,
+
+ -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
+ 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f
+};
+
+// Skybox constructor
+Skybox::Skybox(const std::vector& faces) {
+ // Load cubemap
+ cubemapTexture = LoadCubemap(faces);
+
+ // Setup skybox VAO & VBO
+ glGenVertexArrays(1, &skyboxVAO);
+ glGenBuffers(1, &skyboxVBO);
+ glBindVertexArray(skyboxVAO);
+ glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), skyboxVertices, GL_STATIC_DRAW);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
+ glBindVertexArray(0);
+
+ // Load and configure shader
+ skyboxShader = std::make_unique("Shaders/skybox.vert", "Shaders/skybox.frag");
+ skyboxShader->Activate();
+ skyboxShader->SetInt("skybox", 0);
+}
+
+// Destructor
+Skybox::~Skybox() {
+ glDeleteVertexArrays(1, &skyboxVAO);
+ glDeleteBuffers(1, &skyboxVBO);
+ glDeleteTextures(1, &cubemapTexture);
+}
+
+// Load cubemap texture using DevIL
+GLuint Skybox::LoadCubemap(const std::vector& faces) {
+ GLuint textureID;
+ glGenTextures(1, &textureID);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
+
+ for (GLuint i = 0; i < faces.size(); i++) {
+ ILuint imageID;
+ ilGenImages(1, &imageID);
+ ilBindImage(imageID);
+
+ if (!ilLoadImage((const wchar_t*)faces[i].c_str())) {
+ std::cerr << "Failed to load cubemap texture: " << faces[i] << std::endl;
+ ilDeleteImages(1, &imageID);
+ continue;
+ }
+
+ ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
+
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA,
+ ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT),
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, ilGetData());
+
+ ilDeleteImages(1, &imageID);
+ }
+
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
+ return textureID;
+}
+
+// Render the skybox
+void Skybox::Draw(const Camera& camera) {
+ glDepthFunc(GL_LEQUAL);
+
+ skyboxShader->Activate();
+ glm::mat4 view = glm::mat4(glm::mat3(camera.GetViewMatrix())); // Remove translation
+ glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)camera.width / camera.height, 0.1f, 100.0f);
+
+ skyboxShader->SetMat4("view", view);
+ skyboxShader->SetMat4("projection", projection);
+
+ glBindVertexArray(skyboxVAO);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
+ glDrawArrays(GL_TRIANGLES, 0, 36);
+ glBindVertexArray(0);
+
+ glDepthFunc(GL_LESS);
+}
diff --git a/EclipseEngine/EclipseEngine/SkyBox.h b/EclipseEngine/EclipseEngine/SkyBox.h
new file mode 100644
index 00000000..9a247e9a
--- /dev/null
+++ b/EclipseEngine/EclipseEngine/SkyBox.h
@@ -0,0 +1,29 @@
+#ifndef SKYBOX_H
+#define SKYBOX_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "Shader.h"
+#include "Camera.h"
+
+class Skybox {
+public:
+ Skybox(const std::vector& faces);
+ ~Skybox();
+
+ void Draw(const Camera& camera);
+
+private:
+ GLuint skyboxVAO, skyboxVBO;
+ GLuint cubemapTexture;
+ std::unique_ptr skyboxShader;
+
+ GLuint LoadCubemap(const std::vector& faces);
+};
+
+#endif // SKYBOX_H