#ifndef _APPLICATIONCLASS_H_ #define _APPLICATIONCLASS_H_ /////////////////////// // MY CLASS INCLUDES // /////////////////////// #include "d_3d_class.h" #include "camera_class.h" #include "light_class.h" #include "macro.h" #include "Fmod/core/inc/fmod.hpp" #include "bitmap_class.h" #include "sprite_class.h" #include "timer_class.h" #include "font_shader_class.h" #include "font_class.h" #include "text_class.h" #include "fps_class.h" #include "input_class.h" #include "shader_manager_class.h" #include "modellistclass.h" #include "position_class.h" #include "frustumclass.h" #include "render_texture_class.h" #include "display_plane_class.h" #include "translate_shader_class.h" #include "reflection_shader_class.h" #include "physics.h" #include "frustum.h" #include "skybox.h" #include "shadow_map.h" #include "stats.h" #include "ecs/components/identity_component.h" #include "ecs/components/render_component.h" #include "ecs/components/transform_component.h" #include "ecs/components/physics_component.h" #include "ecs/components/shader_component.h" #include "ecs/systems/render_system.h" #include "ecs/components/model_path_component.h" #include #include #include // Pour _com_error #include #include #include #include #include #include #include #include #include #include "ecs/entity_manager.h" ///////////// // GLOBALS // ///////////// constexpr bool full_screen = false; static std::map> g_model_cache; struct input { bool key_left = false; bool key_right = false; bool key_up = false; bool key_down = false; }; //////////////////////////////////////////////////////////////////////////////// // Class name: application_class //////////////////////////////////////////////////////////////////////////////// class application_class { public: /** * @brief Constructor for the application class. * Initializes member variables and sets up the application. */ application_class(); ~application_class(); virtual d_3d_class* get_direct_3d(); void set_direct_3d(d_3d_class* direct_3d) { direct_3d_ = direct_3d; }; /** * Get the scene texture, which is used for rendering the scene. * @return Pointer to the scene texture. */ render_texture_class* get_scene_texture() const { return scene_texture_; }; /** * Get the display plane used for rendering. * @return Pointer to the display plane. */ render_texture_class* get_render_texture() const { return render_texture_; }; /** * Get the refraction texture used for rendering water effects. * @return Pointer to the refraction texture. */ render_texture_class* get_refraction_texture() const { return refraction_texture_; }; /** * Get the reflection texture used for rendering reflections. * @return Pointer to the reflection texture. */ render_texture_class* get_reflection_texture() const { return reflection_texture_; }; /** * @brief Create a big cube with a specified number of little cube per sides. * @param side_count The number of cubes per sides for the big cube. * @return True if the cube was created successfully, false otherwise. */ bool create_big_cube(int side_count); /** * initialize the application with the given parameters. * * @param screen_width The width of the screen. * @param screen_height The height of the screen. * @param hwdn The handle to the window. * @param is_vulkan Whether to use Vulkan for rendering. * @return True if the initialization was successful, false otherwise. */ virtual bool initialize(int screen_width, int screen_height, HWND hwdn, bool is_vulkan); /** * Shutdown the application and release resources. */ void shutdown(); /** * @brief Run the main loop of the application. * This function will handle the main loop, including rendering and updating the application. * @return True if the application should continue running, false if it should quit. */ virtual bool frame(input_class*); /** * @brief Thread function for handling physics updates. * this function will run in a separate thread to handle physics updates at a fixed rate (50 fps by default). */ void physics_thread_function(); /** * Get the physics tick rate. * @return The physics tick rate in frames per second as an integer. */ int get_physics_tick_rate() const { return physics_tick_rate_; }; /** * Set the physics tick rate. * @param physics_tick_rate The new physics tick rate in frames per second. */ void set_physics_tick_rate(int physics_tick_rate) { physics_tick_rate_ = physics_tick_rate; }; /** * Get the screen width. * @return The width of the screen in pixels as an integer. */ int get_screen_width() const; /** * Set the screen width. * @param screen_width The new width of the screen in pixels as an integer. */ void set_screen_width(int screen_width); /** * Get the screen height. * @return The height of the screen in pixels as an integer. */ int get_screen_height() const; /** * Set the screen height. * @param screen_height The new height of the screen in pixels as an integer. */ void set_screen_height(int screen_height); /** * Get the speed value. * An old value used for the demo spinning object. * This value is not used in the current implementation. * @return The speed value as a float. */ float get_speed() const { return speed_; }; /** * Set the speed value. * An old value used for the demo spinning object. * This value is not used in the current implementation. * @param speed The new speed value as a float. */ void set_speed(const float speed) { this->speed_ = speed; }; /** * Add a basic cube to the scene. */ void add_cube(); /** * Delete an entity by its ID. * @param entity_id The ID of the entity to delete. */ void delete_entity_by_id(int entity_id); /** * Create a new entity with the specified model path. * @param filepath */ void add_kobject(std::wstring& filepath); /** * Set the executable path of the engine. * @param path */ void set_path(WCHAR* path) { path_ = path; }; /** * Set the working folder of the engine. */ void set_w_folder(const std::filesystem::path& w_folder) { w_folder_ = w_folder; }; /** * Get the working folder of the engine. * @return The working folder as a std::filesystem::path. */ std::filesystem::path get_w_folder() const { return w_folder_; }; /** * Get the number of entities with the ObjectType set as Terrain in the scene. * @return The count of terrain entities as an integer. */ int get_terrain_entity_count(); /** * Get the object ID. * @return The object ID as an integer. */ int get_object_id() const { return object_id_; }; /** * Set the object ID. * @param object_id The new object ID as an integer. */ void set_object_id(int object_id) { object_id_ = object_id; }; /** * Generate a flat terrain for test purposes using plane entities. */ void generate_terrain(); /** * Delete the flat terrain/Big Cubes from the scene. */ void delete_terrain(); /** * Get the position for a specific light index. * @param index * @return The position of the light as an XMVECTOR. */ XMVECTOR get_light_position(int index); /** * Get the color for a specific light index. * @param index * @return The color of the light as an XMVECTOR. */ XMVECTOR get_light_color(int index); /** * Set the position for a specific light index. * @param index The index of the light to set the position for. * @param position The new position as an XMVECTOR. */ void set_light_position(int index, XMVECTOR position); /** * Set the color for a specific light index. * @param index The index of the light to set the color for. * @param color The new color as an XMVECTOR. */ void set_light_color(int index, XMVECTOR color); /** * Get all the lights in the scene. * @return A vector of pointers to light_class objects representing the lights in the scene. */ std::vector get_lights() const { return lights_; }; /** * Get the sun light in the scene. * @return The sun light as a pointer to a light_class object. */ light_class* get_sun_light() const { return sun_light_; }; /** * Get the should_quit flag. * This flag indicates whether the application should quit. * @return The should_quit flag as a boolean. */ bool get_should_quit() const { return should_quit_; }; /** * Set the should_quit flag. * This flag indicates whether the application should quit. * @param should_quit The new value for the should_quit flag as a boolean. */ void set_should_quit(const bool should_quit) { should_quit_ = should_quit; }; /** * Set the cel shading mode. * This function isn't used in the current implementation. * It's an old function that was used for cel shading effects before the complete implementation of the cel shading shader. * @param enable */ void set_cel_shading(const bool enable) { enable_cel_shading_ = enable; }; /** * Set the V-sync state. * @param vsync */ void set_vsync(bool vsync) { vsync_enabled_ = vsync; if (direct_3d_) { direct_3d_->set_vsync(vsync); Logger::Get().Log("Setting Vsync to " + std::to_string(vsync), __FILE__, __LINE__); } }; /** * Get the V-sync state. * @return The V-sync state as a boolean. */ bool get_vsync() const { return vsync_enabled_; }; /** * Get the handle to the window. * @return The handle to the window as an HWND. */ HWND get_hwnd() const { return hwnd_; }; /** * Set the handle to the window. * @param hwnd The new handle to the window as an HWND. */ void set_hwnd(HWND hwnd) { hwnd_ = hwnd; }; /** * Check if the application is running in windowed mode. * @return True if the application is in windowed mode, false otherwise. */ bool is_windowed() const { return windowed_; }; /** * Set the windowed mode state. * @param windowed True to set the application in windowed mode, false for full screen. */ void set_windowed(bool windowed) { windowed_ = windowed; }; /** * Set the window size for an ImGui window. * This isn't used in the current implementation. * @param size */ void set_window_size(const ImVec2 size) { window_size_ = size; }; /** * Get the window size for an ImGui window. * This isn't used in the current implementation. * @return The window size as an ImVec2. */ ImVec2 get_window_size() const { return window_size_; }; /** * Get the aspect ratio of the screen. * @return The aspect ratio as a float. */ float get_aspect_ratio() const { return static_cast(screen_width_) / static_cast(screen_height_); }; /** * Get the physics engine instance. * @return Pointer to the physics engine instance. */ physics* get_physics() const { return physics_; }; // ----------------------------------- // // ------------- Culling ------------- // // ----------------------------------- // /** * Get the frustum used for culling. * @return The frustum used for culling as a frustum object. */ frustum get_frustum() const { return frustum_culling_; }; /** * Set the frustum used for culling. * @param frustum The new frustum to set for culling. */ void set_frustum(const frustum& frustum) { frustum_culling_ = frustum; }; /** * Construct the frustum for culling. * This function will calculate the frustum based on the current camera view and projection matrices. */ void construct_frustum(frustum& frustum, float screen_depth, XMMATRIX projectionMatrix, XMMATRIX viewMatrix); /** * Get the number of objects rendered in the current frame. * @return */ int get_render_count() const { return render_count_; }; /** * Set the number of objects rendered in the current frame. * @param render_count The new render count as an integer. */ void set_render_count(const int render_count) { render_count_ = render_count; }; /** * Get the frustum culling tolerance. * This value is used to determine how much an object must be outside the frustum to be culled. * @return The frustum culling tolerance as a float. */ float get_frustum_tolerance() const { return frustum_culling_tolerance_; }; /** * Set the frustum culling tolerance. * This value is used to determine how much an object must be outside the frustum to be culled. * @param frustum_tolerance The new frustum culling tolerance as a float. */ void set_frustum_tolerance(const float frustum_tolerance) { frustum_culling_tolerance_ = frustum_tolerance; }; /** * Get the flag indicating whether the application can perform fixed updates. * @return True if fixed updates are allowed, false otherwise. */ bool get_can_fixed_update() const { return can_fixed_update_; }; /** * Set the flag indicating whether the application can perform fixed updates. * @param can_fixed_update True to allow fixed updates, false to disallow them. */ void set_can_fixed_update(bool can_fixed_update) { can_fixed_update_ = can_fixed_update; }; /** * Get the Direct3D back buffer texture. * @return Pointer to the Direct3D back buffer texture. */ ID3D11ShaderResourceView* get_back_buffer_srv() const {return back_buffer_srv_;}; /** * Get the Stats manager instance. * @return Pointer to the Stats manager instance. */ stats* get_stats() const { return stats_; }; /** * Get the FPS manager instance. * @return Pointer to the FPS manager instance. */ fps_class* get_fps() const { return fps_; }; /** * Get the entity manager instance. * @return Pointer to the entity manager instance. */ ecs::EntityManager* get_entity_manager() const { return entity_manager_.get(); }; /** * Update the stats after an update in the scene. */ void update_stats_after_modification(); /** * Get the global model cache. * The model cache is a static map that stores shared pointers to model_class objects. * This cache is used to avoid loading the same model multiple times. * @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; } /** * Get the sky entity ID. * @return The sky entity ID as an integer. */ int get_sky_id() const { return sky_id_; } /** Get the Sky entity as a shared pointer. * @return A shared pointer to the sky entity. */ std::shared_ptr get_sky_entity_shared_ptr() const { return sky_entity_; } /** * Update the screen depth. */ bool update_screen_depth(float new_screen_depth); /** * Update the screen near. */ bool update_screen_near(float new_screen_near); /** * Get the screen depth. * @return The screen depth as a float. */ float get_screen_depth() const { return screen_depth; } /** * Get the screen near. * @return The screen near as a float. */ float get_screen_near() const { return screen_near; } /** * Get the target fps for the application. * @return The target fps as an integer. */ int get_target_fps() const { return target_fps_; }; /** * Set the target fps for the application. * @param target_fps The new target fps as an integer. */ void set_target_fps(int target_fps) { target_fps_ = target_fps; }; private: /** * Do the rendering of the scene by calling the appropriate rendering functions. * @param rotation The rotation angle in radians use for the demo spinning object. * @param x The x position of the demo spinning object. * @param y The y position of the demo spinning object. * @param z The z position of the demo spinning object. * @param textureTranslation This isn't used in the current implementation. * @return True if the rendering was successful, false otherwise. */ bool render(float, float, float, float, float); /** * Update the physics engine with the delta time. * @param delta_time * @return True if the physics update was successful, false otherwise. */ bool render_physics(float delta_time); /** * Update the mouse strings displayed on the screen. * @param mouseX The x position of the mouse cursor. * @param mouseY The y position of the mouse cursor. * @param mouseDown Whether the left mouse button is pressed or not. * @return True if the mouse strings were updated successfully, false otherwise. */ bool update_mouse_strings(int, int, bool); /** * Update the frames per second (FPS) counter. * @return True if the FPS was updated successfully, false otherwise. */ bool update_fps(); /** * Update the render count string displayed on the screen. * @param render_count The number of objects rendered in the current frame. * @return True if the render count string was updated successfully, false otherwise. */ bool update_render_count_string(int); /** * Render the scene to a texture. * This function will render the scene to a texture for further processing, such as reflections or refractions. * @param rotation The rotation angle in radians used for the demo spinning object. * @return True if the scene was rendered to the texture successfully, false otherwise. */ bool render_scene_to_texture(float); /** * Render the refraction of the scene to a texture. * This function will render the refraction effects, such as water or glass, to a texture. * @return True if the refraction was rendered to the texture successfully, false otherwise. */ bool render_refraction_to_texture(); /** * Render the shadow map texture for the scene. * @return True if the shadow map was rendered successfully, false otherwise. */ bool render_shadow_map(); /** * Render the reflection of the scene to a texture. * This function will render the reflection effects, such as water or mirrors, to a texture. * @return True if the reflection was rendered to the texture successfully, false otherwise. */ bool render_reflection_to_texture(); /** * Render All the Objects in the scene. * The Skysphere is rendered first, then the objects in the scene. * The Skysphere isn't a entity, but a static object that is always rendered in the background. * The other objects are render using the entity manager. * @param diffuse * @param position * @param ambient * @param view * @param projection * @return True if the rendering was successful, false otherwise. */ bool render_pass(XMFLOAT4* diffuse, XMFLOAT4* position, XMFLOAT4* ambient, XMMATRIX view, XMMATRIX projection); /** * Update the position of the skysphere based on the camera position. * The skyphere is a sphere rendered first without depth to be the background of the scene. * This function will update the position of the skysphere to match the camera position. */ void update_skybox_position(); /** * The thread function for culling objects in the scene. */ void culling_thread_function(); /** * A thread function to handle culling of objects no visible by sun light. */ void sun_culling_thread_function(); /** * Create the skysphere entity. */ bool create_skysphere(); public : std::vector textures; private : // Thread de culling std::thread culling_thread_; std::atomic culling_active_; std::mutex objects_mutex_; // Thread de culling pour les shadows std::thread culling_sun_thread_; std::atomic culling_sun_active_; std::mutex objects_sun_mutex_; std::mutex terrain_mutex_; std::vector> terrain_generation_data_; bool terrain_generation_ready_; int next_terrain_object_id_; // ------------------------------------- // // ------------- DIRECT3D -------------- // // ------------------------------------- // d_3d_class* direct_3d_; IDXGISwapChain* swap_chain_; model_class* model_,* ground_model_, * wall_model_, * bath_model_, * water_model_; ModelListClass* model_list_; bool vsync_enabled_ = true; HWND hwnd_; bool windowed_; float screen_depth = 1000.0f; float screen_near = 0.3f; // ------------------------------------- // // ------------- RENDERING ------------- // // ------------------------------------- // XMMATRIX base_view_matrix_; render_texture_class* render_texture_, * refraction_texture_, * reflection_texture_,* shadow_texture_ ; render_texture_class* scene_texture_; display_plane_class* display_plane_; int screen_width_, screen_height_; camera_class* camera_; camera_class* sun_camera_; camera_class* active_camera_; position_class* position_; shadow_map* shadow_map_; ID3D11ShaderResourceView* shadow_map_srv_; // ------------------------------------ // // ------------- OBJECTS -------------- // // ------------------------------------ // std::unique_ptr entity_manager_; object* selected_object_; float speed_ = 0.1f; // speed for the demo spinning object std::vector imported_object_; int object_id_ = 0; int sky_id_ = -1; std::shared_ptr sky_entity_; // ----------------------------------- // // ------------- LIGHTS -------------- // // ----------------------------------- // light_class* m_light_; std::vector lights_; int num_lights_; light_class* sun_light_; XMFLOAT3 true_light_position_; model_class* light_model_; // ----------------------------------- // // ------------- SHADERS ------------- // // ----------------------------------- // shader_manager_class* shader_manager_; font_shader_class* font_shader_; bitmap_class* bitmap_; sprite_class* sprite_; bool enable_cel_shading_; // ----------------------------------- // // ------------ VARIABLES ------------ // // ----------------------------------- // float water_height_, water_translation_; wchar_t* path_; std::filesystem::path w_folder_; // ------------------------------------------------- // // ------------- FPS AND INFO ON SCREEN ------------ // // ------------------------------------------------- // timer_class* timer_; text_class* mouse_strings_; text_class* render_count_string_; font_class* font_; fps_class* fps_; text_class* fps_string_; int previous_fps_; // ------------------------------------------------- // // ------------------- OTHER ----------------------- // // ------------------------------------------------- // bool should_quit_; physics* physics_; float gravity_; XMVECTOR previous_position_; ImVec2 window_size_; int physics_tick_rate_ = 50; bool can_fixed_update_ = false; std::thread physics_thread_; ID3D11Texture2D* back_buffer_texture_; ID3D11ShaderResourceView* back_buffer_srv_; stats* stats_; int target_fps_ = 60; // ------------------------------------------------- // // ------------------- Culling --------------------- // // ------------------------------------------------- // frustum frustum_culling_; frustum sun_culling_; int render_count_; float frustum_culling_tolerance_ = 5.f; // ------------------------------------------------- // // -------------------- Input ---------------------- // // ------------------------------------------------- // input inputs_; bool tab_was_pressed_; std::shared_ptr camera_input_; // ------------------------------------------------- // // ------------------- SOUND ----------------------- // // ------------------------------------------------- // // shared pointer to the FMOD system FMOD::System* sound_system_; }; #endif