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.
This commit is contained in:
@@ -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<std::string, std::shared_ptr<model_class>>& 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<ID3D11ShaderResourceView*> textures;
|
||||
@@ -587,7 +594,9 @@ private :
|
||||
float speed_ = 0.1f; // speed for the demo spinning object
|
||||
std::vector<object*> imported_object_;
|
||||
int object_id_ = 0;
|
||||
std::vector<object*> skybox_;
|
||||
//std::vector<object*> skybox_;
|
||||
int sky_id_ = -1;
|
||||
std::shared_ptr<ecs::Entity> sky_entity_;
|
||||
|
||||
// ----------------------------------- //
|
||||
// ------------- LIGHTS -------------- //
|
||||
|
||||
@@ -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<EntityID, std::shared_ptr<Entity>> m_Entities;
|
||||
@@ -186,6 +189,7 @@ private:
|
||||
FMOD::System* sound_system_ = nullptr;
|
||||
ID3D11Device* device;
|
||||
ID3D11DeviceContext* context;
|
||||
int sky_id_ = -1;
|
||||
};
|
||||
|
||||
} // namespace ecs
|
||||
|
||||
@@ -238,6 +238,16 @@ public:
|
||||
// V<>rifier si le mod<6F>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<69>s
|
||||
m_deviceContext->OMSetDepthStencilState(nullptr, 1);
|
||||
}
|
||||
|
||||
// Effectuer le rendu
|
||||
if (RenderEntity(entity, viewMatrix, projectionMatrix,
|
||||
diffuseColors, lightPositions, ambientColors,cameraPos,
|
||||
|
||||
@@ -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<std::mutex> 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<std::mutex> lock(objects_mutex_);
|
||||
auto renderComponent = entity->GetComponent<ecs::RenderComponent>();
|
||||
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<70>s le rendu de la skybox
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Rendu des entit<69>s du syst<73>me ECS s'il est disponible
|
||||
if (entity_manager_) {
|
||||
// Cr<43>er le syst<73>me de rendu pour les entit<69>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<ecs::TransformComponent>();
|
||||
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<std::wstring> 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<model_class> 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<model_class>();
|
||||
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<ecs::IdentityComponent>(object_id_++);
|
||||
identity->SetName("SkySphere");
|
||||
identity->SetType(ecs::ObjectType::Unknown);
|
||||
|
||||
auto transform = sky_entity_->AddComponent<ecs::TransformComponent>();
|
||||
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<ecs::RenderComponent>();
|
||||
render->InitializeWithModel(sharedModel);
|
||||
|
||||
auto modelpath = sky_entity_->AddComponent<ecs::ModelPathComponent>();
|
||||
modelpath->SetPath(L"assets/Model/OBJ/skysphere.obj");
|
||||
|
||||
auto shader = sky_entity_->AddComponent<ecs::ShaderComponent>();
|
||||
shader->SetActiveShader(ecs::ShaderType::SKYBOX);
|
||||
|
||||
return true;
|
||||
}
|
||||
BIN
x64/Debug/config.txt
(Stored with Git LFS)
BIN
x64/Debug/config.txt
(Stored with Git LFS)
Binary file not shown.
BIN
x64/Release/config.txt
(Stored with Git LFS)
BIN
x64/Release/config.txt
(Stored with Git LFS)
Binary file not shown.
Reference in New Issue
Block a user