From 4b47346208ee684448df54469d333e22d5543ea9 Mon Sep 17 00:00:00 2001 From: CatChow0 Date: Mon, 29 Sep 2025 19:08:43 +0200 Subject: [PATCH] Minor - Rework skysphere from Object to Entity - V14.2.0 Introduces a skysphere entity to the scene. Creates the skysphere during application initialization and manages its visibility via Z-buffer enabling/disabling in the render system. The skysphere is now an ECS entity. The culling thread skips the skybox entity to avoid unnecessary calculations since it's always visible. The position of the skybox is updated with the active camera. --- .../src/inc/system/application_class.h | 11 +- .../src/inc/system/ecs/entity_manager.h | 4 + .../inc/system/ecs/systems/render_system.h | 10 ++ .../src/src/system/application_class.cpp | 167 ++++++++++-------- x64/Debug/config.txt | 2 +- x64/Release/config.txt | 2 +- 6 files changed, 117 insertions(+), 79 deletions(-) diff --git a/enginecustom/src/inc/system/application_class.h b/enginecustom/src/inc/system/application_class.h index 94089b6..17096c2 100644 --- a/enginecustom/src/inc/system/application_class.h +++ b/enginecustom/src/inc/system/application_class.h @@ -450,6 +450,8 @@ public: * @return A reference to the global model cache as a map of strings to shared pointers of model_class. */ std::map>& get_model_cache() { return g_model_cache; } + + int get_sky_id() const { return sky_id_; } private: /** @@ -530,6 +532,11 @@ private: * The thread function for culling objects in the scene. */ void culling_thread_function(); + + /** + * Create the skysphere entity. + */ + bool create_skysphere(); public : std::vector textures; @@ -587,7 +594,9 @@ private : float speed_ = 0.1f; // speed for the demo spinning object std::vector imported_object_; int object_id_ = 0; - std::vector skybox_; + //std::vector skybox_; + int sky_id_ = -1; + std::shared_ptr sky_entity_; // ----------------------------------- // // ------------- LIGHTS -------------- // diff --git a/enginecustom/src/inc/system/ecs/entity_manager.h b/enginecustom/src/inc/system/ecs/entity_manager.h index f641876..cc27969 100644 --- a/enginecustom/src/inc/system/ecs/entity_manager.h +++ b/enginecustom/src/inc/system/ecs/entity_manager.h @@ -178,6 +178,9 @@ public: ID3D11Device* GetDevice() const { return device; } ID3D11DeviceContext* GetContext() const { return context; } + int GetSkyID() const { return sky_id_; } + void SetSkyID(int id) { sky_id_ = id; } + private: EntityID m_NextEntityID; std::unordered_map> m_Entities; @@ -186,6 +189,7 @@ private: FMOD::System* sound_system_ = nullptr; ID3D11Device* device; ID3D11DeviceContext* context; + int sky_id_ = -1; }; } // namespace ecs diff --git a/enginecustom/src/inc/system/ecs/systems/render_system.h b/enginecustom/src/inc/system/ecs/systems/render_system.h index 7b64516..02608d4 100644 --- a/enginecustom/src/inc/system/ecs/systems/render_system.h +++ b/enginecustom/src/inc/system/ecs/systems/render_system.h @@ -238,6 +238,16 @@ public: // Vérifier si le modèle est visible if (!render->IsVisible()) continue; + // check if the id the sky id to disabled the z buffer + if (entity->GetID() == entityManager->GetSkyID()) + { + // Désactiver le Z-buffer pour le skysphere + m_deviceContext->OMSetDepthStencilState(nullptr, 0); + } else { + // Activer le Z-buffer pour les autres entités + m_deviceContext->OMSetDepthStencilState(nullptr, 1); + } + // Effectuer le rendu if (RenderEntity(entity, viewMatrix, projectionMatrix, diffuseColors, lightPositions, ambientColors,cameraPos, diff --git a/enginecustom/src/src/system/application_class.cpp b/enginecustom/src/src/system/application_class.cpp index 23e5b57..92e4592 100644 --- a/enginecustom/src/src/system/application_class.cpp +++ b/enginecustom/src/src/system/application_class.cpp @@ -28,7 +28,6 @@ application_class::application_class() : should_quit_(false) reflection_texture_ = nullptr; scene_texture_ = nullptr; physics_ = nullptr; - skybox_.clear(); lights_.clear(); sun_light_ = nullptr; swap_chain_ = nullptr; @@ -498,9 +497,6 @@ bool application_class::initialize(int screenWidth, int screenHeight, HWND hwnd, physics_thread_ = std::thread(&application_class::physics_thread_function, this); //ConstructSkyboxWithPlanes(); - Skybox* skybox = new Skybox; - skybox->Initialize(direct_3d_); - skybox_.push_back(skybox->ConstructSkybox(this)); culling_active_ = true; culling_thread_ = std::thread(&application_class::culling_thread_function, this); @@ -523,12 +519,13 @@ bool application_class::initialize(int screenWidth, int screenHeight, HWND hwnd, entity_manager_->SetSoundSystem(sound_system_); entity_manager_->SetDevice(direct_3d_->get_device()); entity_manager_->SetContext(direct_3d_->get_device_context()); - + + create_skysphere(); } catch (const std::exception& e) { - Logger::Get().Log(std::string("Exception caught during initialization: ") + e.what(), __FILE__, __LINE__, Logger::LogLevel::Error); + Logger::Get().Log(std::string("Exception caught during initialization: ") + e.what() , __FILE__, __LINE__, Logger::LogLevel::Error); return false; } Logger::Get().Log("Application class initialized", __FILE__, __LINE__, Logger::LogLevel::Initialize); @@ -1800,23 +1797,18 @@ void application_class::culling_thread_function() // Construction du frustum une fois par cycle de culling construct_frustum(); - // S'assurer que la skybox est toujours visible - { - std::lock_guard lock(objects_mutex_); - for (auto* skyboxObject : skybox_) - { - if (skyboxObject) - { - skyboxObject->SetVisible(true); - } - } - } - // Traitement des files d'objets normaux (sans la skybox) auto all_entity = entity_manager_->GetAllEntities(); for (auto& entity : all_entity) { + + if (entity->GetID() == sky_id_) + { + // skipped the skybox entity to avoid unnecessary calculations since it's always visible + continue; + } + std::lock_guard lock(objects_mutex_); auto renderComponent = entity->GetComponent(); if (renderComponent && renderComponent->GetModel()) @@ -1860,58 +1852,6 @@ bool application_class::render_pass(XMFLOAT4* diffuse, XMFLOAT4* position, XMFLO int renderCount = 0; int i; - // render skybox - for (auto& skyboxObject : skybox_) - { - if (skyboxObject == nullptr) - { - Logger::Get().Log("skyboxObject is null", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; - } - - if (!skyboxObject->IsVisible()) - { - continue; - } - - direct_3d_->turn_z_buffer_off(); - - scaleMatrix = skyboxObject->GetScaleMatrix(); - rotateMatrix = skyboxObject->GetRotateMatrix(); - translateMatrix = skyboxObject->GetTranslateMatrix(); - - XMMATRIX worldMatrix = XMMatrixMultiply( - XMMatrixMultiply(scaleMatrix, rotateMatrix), - translateMatrix - ); - - renderCount++; - - skyboxObject->get_model()->Render(direct_3d_->get_device_context()); - - result = shader_manager_->render_skybox_shader( - direct_3d_->get_device_context(), - skyboxObject->get_model()->GetIndexCount(), - worldMatrix, - view, - projection, - skyboxObject->get_model()->GetTexture(TextureType::Diffuse,0), - sun_light_->GetDiffuseColor(), - sun_light_->GetAmbientColor(), - sun_light_->GetDirection(), - sun_light_->GetIntensity() - ); - if (!result) - { - Logger::Get().Log("Could not render the object model using the skybox shader", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; - } - direct_3d_->turn_z_buffer_on(); // Réactiver le Z-buffer après le rendu de la skybox - - break; - - } - // Rendu des entités du système ECS s'il est disponible if (entity_manager_) { // Créer le système de rendu pour les entités @@ -1972,14 +1912,17 @@ void application_class::construct_frustum() void application_class::update_skybox_position() { - if (skybox_.empty()) - { - Logger::Get().Log("Skybox is empty", __FILE__, __LINE__, Logger::LogLevel::Error); - return; - } + if (sky_id_ == -1) return; - skybox_[0]->SetTranslateMatrix(XMMatrixTranslation(active_camera_->get_position().x, active_camera_->get_position().y, active_camera_->get_position().z)); + if (!sky_entity_) return; + auto transformComponent = sky_entity_->GetComponent(); + if (!transformComponent) return; + + // convert the camera position to XMVECTOR manually + XMVECTOR cameraPosition = XMVectorSet(camera_->get_position().x, camera_->get_position().y, camera_->get_position().z, 0.0f); + transformComponent->SetPosition(cameraPosition); + transformComponent->UpdateWorldMatrix(); } bool application_class::render_physics(float delta_time) { @@ -2109,3 +2052,75 @@ int application_class::get_terrain_entity_count() return terrainCount; } + +bool application_class::create_skysphere() +{ + + char modelFilename[128]; + TextureContainer textures; + + size_t convertedChars = 0; + (void)wcstombs_s(&convertedChars, modelFilename, sizeof(modelFilename), L"assets/Model/OBJ/skysphere.obj", _TRUNCATE); + + + std::vector sky_textures = { + L"assets/Skybox/skybox.png" + }; + + textures.diffusePaths.push_back(sky_textures[0]); + if (sky_textures.size() > 1) textures.normalPaths.push_back(sky_textures[1]); + if (sky_textures.size() > 2) textures.specularPaths.push_back(sky_textures[2]); + + std::string modelKey = std::string(modelFilename); + std::shared_ptr sharedModel; + + auto it = g_model_cache.find(modelKey); + if (it != g_model_cache.end()) + { + Logger::Get().Log("Using cached model for sky sphere: " + modelKey, __FILE__, __LINE__); + sharedModel = it->second; + } + else + { + sharedModel = std::make_shared(); + sharedModel->PreloadTextures(direct_3d_->get_device(), direct_3d_->get_device_context(), textures); + if (!sharedModel->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), modelFilename, textures)) + { + Logger::Get().Log("Failed to initialize model for sky sphere", __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } + g_model_cache[modelKey] = sharedModel; + Logger::Get().Log("Added sky sphere model to cache: " + modelKey, __FILE__, __LINE__); + } + + + sky_entity_ = entity_manager_->CreateEntity(); + if (!sky_entity_) + { + Logger::Get().Log("Failed to create sky entity", __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } + + sky_id_ = sky_entity_->GetID(); + entity_manager_->SetSkyID(sky_id_); + + auto identity = sky_entity_->AddComponent(object_id_++); + identity->SetName("SkySphere"); + identity->SetType(ecs::ObjectType::Unknown); + + auto transform = sky_entity_->AddComponent(); + transform->SetPosition(XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f)); + transform->SetScale(XMVectorSet(2.0f, 2.0f, 2.0f, 0.0f)); + transform->UpdateWorldMatrix(); + + auto render = sky_entity_->AddComponent(); + render->InitializeWithModel(sharedModel); + + auto modelpath = sky_entity_->AddComponent(); + modelpath->SetPath(L"assets/Model/OBJ/skysphere.obj"); + + auto shader = sky_entity_->AddComponent(); + shader->SetActiveShader(ecs::ShaderType::SKYBOX); + + return true; +} \ No newline at end of file diff --git a/x64/Debug/config.txt b/x64/Debug/config.txt index 6a478b5..7451438 100644 --- a/x64/Debug/config.txt +++ b/x64/Debug/config.txt @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f10276fc7b03d157f658a34c61a69c39b6849eac0b4c35b5f3c4e063c10c5753 +oid sha256:650c8d5dcda7df59eaa6db23e5e1c5f391d64360781facb9b3b297baaed5b921 size 8 diff --git a/x64/Release/config.txt b/x64/Release/config.txt index 6a478b5..7451438 100644 --- a/x64/Release/config.txt +++ b/x64/Release/config.txt @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f10276fc7b03d157f658a34c61a69c39b6849eac0b4c35b5f3c4e063c10c5753 +oid sha256:650c8d5dcda7df59eaa6db23e5e1c5f391d64360781facb9b3b297baaed5b921 size 8