#pragma once #include "../entity_manager.h" #include "../components/render_component.h" #include "../components/transform_component.h" #include "../components/shader_component.h" #include "shader_manager_class.h" #include namespace ecs { class RenderSystem { public: /** * Builder for the RenderSystem class. * This class is responsible for rendering entities with the necessary components. * @param deviceContext * @param shaderManager */ RenderSystem(ID3D11DeviceContext* deviceContext, shader_manager_class* shaderManager) : m_deviceContext(deviceContext), m_shaderManager(shaderManager) {} /** * Render an entity with the necessary components. * This method checks if the entity has the required components and renders it using the appropriate shader. * @param entity The entity to render. * @param viewMatrix The view matrix for rendering. * @param projectionMatrix The projection matrix for rendering. * @param diffuseColors Array of diffuse colors for lighting. * @param lightPositions Array of light positions for lighting. * @param ambientColors Array of ambient colors for lighting. * @param cameraPosition The position of the camera in world space. * @param sunlightDiffuse The diffuse color of sunlight. * @param sunlightAmbient The ambient color of sunlight. * @param sunlightDirection The direction of sunlight in world space. * @param sunlightIntensity The intensity of sunlight. * @return True if rendering was successful, false otherwise. */ bool RenderEntity(std::shared_ptr entity, const DirectX::XMMATRIX& viewMatrix, const DirectX::XMMATRIX& projectionMatrix, const DirectX::XMFLOAT4* diffuseColors, const DirectX::XMFLOAT4* lightPositions, const DirectX::XMFLOAT4* ambientColors, const DirectX::XMFLOAT3& cameraPosition, const DirectX::XMFLOAT4& sunlightDiffuse, const DirectX::XMFLOAT4& sunlightAmbient, const DirectX::XMFLOAT3& sunlightDirection, float sunlightIntensity) { // Vérifier si l'entité a tous les composants nécessaires auto transform = entity->GetComponent(); auto render = entity->GetComponent(); auto shader = entity->GetComponent(); if (!transform || !render || !shader || !render->GetModel()) R_FALSE // Calculer la matrice monde XMMATRIX scaleMatrix = transform->GetScaleMatrix(); XMMATRIX rotateMatrix = transform->GetRotateMatrix(); XMMATRIX translateMatrix = transform->GetTranslateMatrix(); XMMATRIX worldMatrix = XMMatrixMultiply( XMMatrixMultiply(scaleMatrix, rotateMatrix), translateMatrix ); // Rendre le modèle render->Render(m_deviceContext); // Sélectionner le shader approprié switch (shader->GetActiveShader()) { case ShaderType::ALPHA_MAPPING: return m_shaderManager->render_alpha_map_shader( m_deviceContext, render->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, render->GetTexture(TextureType::Diffuse, 0), render->GetTexture(TextureType::Diffuse, 1), render->GetTexture(TextureType::Alpha, 0) ); case ShaderType::CEL_SHADING: return m_shaderManager->render_cel_shading_shader( m_deviceContext, render->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, render->GetTexture(TextureType::Diffuse, 0), sunlightDiffuse, sunlightAmbient, sunlightDirection, sunlightIntensity ); case ShaderType::NORMAL_MAPPING: return m_shaderManager->render_normal_map_shader( m_deviceContext, render->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, render->GetTexture(TextureType::Diffuse, 0), render->GetTexture(TextureType::Normal, 0), sunlightDirection, sunlightDiffuse ); case ShaderType::SPECULAR_MAPPING: return m_shaderManager->render_spec_map_shader( m_deviceContext, render->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, render->GetTexture(TextureType::Diffuse, 0), render->GetTexture(TextureType::Normal, 0), render->GetTexture(TextureType::Specular, 0), sunlightDirection, sunlightDiffuse, cameraPosition, sunlightDiffuse, // Couleur speculaire (à ajuster) 16.0f // Puissance speculaire (à ajuster) ); case ShaderType::LIGHTING: { // Créer des copies locales non constantes des tableaux DirectX::XMFLOAT4 localDiffuseColors[4]; DirectX::XMFLOAT4 localLightPositions[4]; DirectX::XMFLOAT4 localAmbientColors[4]; // Copier les données for (int i = 0; i < 4; i++) { localDiffuseColors[i] = diffuseColors[i]; localLightPositions[i] = lightPositions[i]; localAmbientColors[i] = ambientColors[i]; } return m_shaderManager->renderlight_shader( m_deviceContext, render->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, render->GetTexture(TextureType::Diffuse, 0), localDiffuseColors, localLightPositions, localAmbientColors ); } case ShaderType::SUNLIGHT: return m_shaderManager->render_sunlight_shader( m_deviceContext, render->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, render->GetTexture(TextureType::Diffuse, 0), sunlightDiffuse, sunlightAmbient, sunlightDirection, sunlightIntensity ); case ShaderType::SKYBOX: return m_shaderManager->render_skybox_shader( m_deviceContext, render->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, render->GetTexture(TextureType::Diffuse, 0), sunlightDiffuse, sunlightAmbient, sunlightDirection, sunlightIntensity ); case ShaderType::TEXTURE: default: return m_shaderManager->render_texture_shader( m_deviceContext, render->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, render->GetTexture(TextureType::Diffuse, 0) ); } } /** * Render all entities in the EntityManager that have the necessary components. * This method iterates through all entities and renders them if they have the required components. * @param entityManager The EntityManager containing the entities to render. * @param viewMatrix The view matrix for rendering. * @param projectionMatrix The projection matrix for rendering. * @param diffuseColors Array of diffuse colors for lighting. * @param lightPositions Array of light positions for lighting. * @param ambientColors Array of ambient colors for lighting. * @param cameraPos The position of the camera in world space. * @param sunlightDiffuse The diffuse color of sunlight. * @param sunlightAmbient The ambient color of sunlight. * @param sunlightDirection The direction of sunlight in world space. * @param sunlightIntensity The intensity of sunlight. * @return The number of entities rendered successfully. */ int RenderAllEntities(EntityManager* entityManager, const DirectX::XMMATRIX& viewMatrix, const DirectX::XMMATRIX& projectionMatrix, const DirectX::XMFLOAT4* diffuseColors, const DirectX::XMFLOAT4* lightPositions, const DirectX::XMFLOAT4* ambientColors, const DirectX::XMFLOAT3& cameraPos, const DirectX::XMFLOAT4& sunlightDiffuse, const DirectX::XMFLOAT4& sunlightAmbient, const DirectX::XMFLOAT3& sunlightDirection, float sunlightIntensity) { int renderCount = 0; // Récupérer toutes les entités qui ont les composants RenderComponent et TransformComponent auto entities = entityManager->GetEntitiesWithComponent(); for (auto& entity : entities) { auto render = entity->GetComponent(); // Vérifier si l'entité a un TransformComponent auto transform = entity->GetComponent(); if (!transform) continue; // 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, sunlightDiffuse, sunlightAmbient, sunlightDirection, sunlightIntensity)) { renderCount++; } } return renderCount; } private: ID3D11DeviceContext* m_deviceContext; shader_manager_class* m_shaderManager; }; } // namespace ecs