Khaotic Engine Reborn
Loading...
Searching...
No Matches
application_class.cpp
1#include "application_class.h"
2
3#include "depth_shader_class.h"
4#include "system_class.h"
5
7{
8 direct_3d_ = nullptr;
9 camera_ = nullptr;
10 model_ = nullptr;
11 bitmap_ = nullptr;
12 sprite_ = nullptr;
13 timer_ = nullptr;
14 mouse_strings_ = nullptr;
15 font_shader_ = nullptr;
16 font_ = nullptr;
17 fps_ = nullptr;
18 fps_string_ = nullptr;
19 shader_manager_ = nullptr;
20 render_count_string_ = nullptr;
21 model_list_ = nullptr;
22 position_ = nullptr;
23 display_plane_ = nullptr;
24 bath_model_ = nullptr;
25 water_model_ = nullptr;
26 m_light_ = nullptr;
27 refraction_texture_ = nullptr;
28 reflection_texture_ = nullptr;
29 scene_texture_ = nullptr;
30 physics_ = nullptr;
31 skybox_.clear();
32 lights_.clear();
33 sun_light_ = nullptr;
34 swap_chain_ = nullptr;
35 ground_model_ = nullptr;
36 wall_model_ = nullptr;
37 hwnd_ = nullptr;
38 base_view_matrix_ = XMMatrixIdentity();
39 render_texture_ = nullptr;
40 screen_width_ = 0;
41 screen_height_ = 0;
42 num_lights_ = 0;
43 water_height_ = 0.0f;
44 water_translation_ = 0.0f;
45 true_light_position_ = XMFLOAT3(0.0f, 0.0f, 0.0f);
46 light_model_ = nullptr;
47 render_count_ = 0;
48 tab_was_pressed_ = false;
49}
50
51application_class::~application_class()
52{
53 should_quit_ = true;
54 culling_active_ = false;
55
56 // Joindre les threads pour s'assurer qu'ils se terminent correctement
57 if (physics_thread_.joinable())
58 {
59 physics_thread_.join();
60 }
61
62 if (culling_thread_.joinable())
63 {
64 culling_thread_.join();
65 }
66
67}
68
69
70bool application_class::initialize(int screenWidth, int screenHeight, HWND hwnd, bool is_vulkan)
71{
72
73 Logger::Get().Log("Initializing application class", __FILE__, __LINE__, Logger::LogLevel::Initialize);
74
75 try
76 {
77 char mouseString1[32], mouseString2[32], mouseString3[32];
78 char modelFilename[128], renderString[32];
79 char bitmapFilename[128];
80 char spriteFilename[128];
81 char fpsString[32];
82 bool result;
83 HRESULT Hresult;
84
85 // create entity manager
86 entity_manager_ = std::make_unique<ecs::EntityManager>();
87
88 screen_width_ = screenWidth;
89 screen_height_ = screenHeight;
90
91 set_hwnd(hwnd);
92 set_windowed(full_screen);
93 set_screen_height(screenHeight);
94 set_screen_width(screenWidth);
95
96 // Create the Direct3D object.
97 direct_3d_ = new d_3d_class;
98 if (!direct_3d_)
99 {
100 Logger::Get().Log("Could not create the Direct3D object", __FILE__, __LINE__, Logger::LogLevel::Error);
101 return false;
102 }
103
104 result = direct_3d_->initialize(screen_width_, screen_height_, vsync_enabled_, hwnd, full_screen, screen_depth, screen_near);
105 if (!result)
106 {
107 Logger::Get().Log("Could not initialize Direct3D", __FILE__, __LINE__, Logger::LogLevel::Error);
108 return false;
109 }
110
111 // Create the camera object.
112 camera_ = new camera_class;
113 if (!camera_)
114 {
115 Logger::Get().Log("Could not create the camera object", __FILE__, __LINE__, Logger::LogLevel::Error);
116 return false;
117 }
118
119 sun_camera_ = new camera_class;
120 if (!sun_camera_)
121 {
122 Logger::Get().Log("Could not create the sun camera object", __FILE__, __LINE__, Logger::LogLevel::Error);
123 return false;
124 }
125
126 sun_camera_->set_position(0.0f,0.0f,0.0f);
127 sun_camera_->set_rotation(0.0f, 0.0f, 0.0f);
128 sun_camera_->render();
129 sun_camera_->get_view_matrix(base_view_matrix_);
130
131 // Set the initial position of the camera.
132 camera_->set_position(0.0f, 0.0f, -12.0f);
133 camera_->set_rotation(0.0f, 0.0f, 0.0f);
134 camera_->render();
135 camera_->get_view_matrix(base_view_matrix_);
136
137 active_camera_ = camera_;
138
139 // Create and initialize the font shader object.
140 font_shader_ = new font_shader_class;
141
142 result = font_shader_->initialize(direct_3d_->get_device(), hwnd);
143 if (!result)
144 {
145 Logger::Get().Log("Could not initialize the font shader object", __FILE__, __LINE__, Logger::LogLevel::Error);
146 return false;
147 }
148
149 // Create and initialize the font object.
150 font_ = new font_class;
151
152 result = font_->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), 0);
153 if (!result)
154 {
155 Logger::Get().Log("Could not initialize the font object", __FILE__, __LINE__, Logger::LogLevel::Error);
156 return false;
157 }
158
159 // Create and initialize the render to texture object.
160 render_texture_ = new render_texture_class;
161
162 result = render_texture_->Initialize(direct_3d_->get_device(), 256, 256, screen_depth, screen_near, 1);
163 if (!result)
164 {
165 Logger::Get().Log("Could not initialize the render texture object", __FILE__, __LINE__, Logger::LogLevel::Error);
166 return false;
167 }
168
169 //ImVec2 availableSize = ImGui::GetContentRegionAvail();
170
171 // Create and initialize the scene render to texture object.
172 scene_texture_ = new render_texture_class();
173 result = scene_texture_->Initialize(direct_3d_->get_device(), 256, 256, screen_depth, screen_near, 1);
174 if (!result)
175 {
176 Logger::Get().Log("Could not initialize the render texture object", __FILE__, __LINE__, Logger::LogLevel::Error);
177 return false;
178 }
179
180 // Create and initialize the display plane object.
181 display_plane_ = new display_plane_class;
182
183 result = display_plane_->Initialize(direct_3d_->get_device(), 1.0f, 1.0f);
184 if (!result)
185 {
186 Logger::Get().Log("Could not initialize the display plane object", __FILE__, __LINE__, Logger::LogLevel::Error);
187 return false;
188 }
189
190
191 // Set the sprite info file we will be using.
192 //
193 strcpy_s(spriteFilename, "sprite_data_01.txt");
194
195 // Create and initialize the sprite object.
196 sprite_ = new sprite_class;
197
198 result = sprite_->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), screenWidth, screenHeight, spriteFilename, 50, 50);
199 if (!result)
200 {
201 Logger::Get().Log("Could not initialize the sprite object", __FILE__, __LINE__, Logger::LogLevel::Error);
202 return false;
203 }
204
205 // Set the initial mouse strings.
206 strcpy_s(mouseString1, "Mouse X: 0");
207 strcpy_s(mouseString2, "Mouse Y: 0");
208 strcpy_s(mouseString3, "Mouse Button: No");
209
210 // Create and initialize the text objects for the mouse strings.
211 mouse_strings_ = new text_class[3];
212
213 for (int i = 0; i < 3; i++)
214 {
215 int y = 10 + (i * 25);
216 result = mouse_strings_[i].Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), screenWidth, screenHeight, 32, font_, mouseString1, 10, y, 1.0f, 1.0f, 1.0f);
217 if (!result)
218 {
219 Logger::Get().Log("Could not initialize the mouse strings", __FILE__, __LINE__, Logger::LogLevel::Error);
220 return false;
221 }
222 }
223
224 // Set the file name of the bitmap file.
225 strcpy_s(bitmapFilename, "assets/Texture/stone01.tga");
226
227 // Create and initialize the bitmap object.
228 bitmap_ = new bitmap_class;
229
230 result = bitmap_->initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), screenWidth, screenHeight, bitmapFilename, 50, 50);
231 if (!result)
232 {
233 Logger::Get().Log("Could not initialize the bitmap object", __FILE__, __LINE__, Logger::LogLevel::Error);
234 return false;
235 }
236
237 // Set the file name of the model.
238 strcpy_s(modelFilename, "assets/Model/TXT/cube.txt");
239
240 // Charger les textures_
241 std::vector<std::wstring> textureFilenames = {
242 L"assets/Texture/stone01.png"
243 };
244
245 TextureContainer CubeTextures;
246
247 for (const auto& textureFilename : textureFilenames)
248 {
249 ID3D11ShaderResourceView* texture = nullptr;
250 Hresult = DirectX::CreateWICTextureFromFile(direct_3d_->get_device(), direct_3d_->get_device_context(), textureFilename.c_str(), nullptr, &texture);
251 if (FAILED(Hresult))
252 {
253 Logger::Get().Log("Failed to load texture: " + std::string(textureFilename.begin(), textureFilename.end()), __FILE__, __LINE__, Logger::LogLevel::Error);
254 return false;
255 }
256 CubeTextures.diffuse.push_back(texture);
257 }
258
259 // Create and initialize the model object.
260 model_ = new model_class;
261
262
263 result = model_->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), modelFilename, CubeTextures);
264 if (!result)
265 {
266 Logger::Get().Log("Could not initialize the model object", __FILE__, __LINE__, Logger::LogLevel::Error);
267 return false;
268 }
269
270 // Create and initialize the light object.
271 m_light_ = new light_class;
272
273 m_light_->SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f);
274 m_light_->SetDirection(0.0f, 0.0f, -1.0f);
275 m_light_->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f);
276 m_light_->SetSpecularColor(1.0f, 1.0f, 1.0f, 1.0f);
277 m_light_->SetSpecularPower(16.0f);
278
279 // Set the number of lights we will use.
280 num_lights_ = 4;
281 // Create and initialize the light objects array.
282 lights_.resize(num_lights_);
283
284 lights_[0] = new light_class;
285 lights_[0]->SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); // White
286 lights_[0]->SetDirection(0.0f, 0.0f, -1.0f);
287 lights_[0]->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f);
288 lights_[0]->SetSpecularColor(1.0f, 1.0f, 1.0f, 1.0f);
289 lights_[0]->SetSpecularPower(16.0f);
290 lights_[0]->SetPosition(10.0f, 7.0f, -5.0f);
291
292 lights_[1] = new light_class;
293 lights_[1]->SetDiffuseColor(1.0f, 0.0f, 0.0f, 1.0f); // Red
294 lights_[1]->SetDirection(0.0f, 0.0f, -1.0f);
295 lights_[1]->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f);
296 lights_[1]->SetSpecularColor(1.0f, 0.0f, 0.0f, 1.0f);
297 lights_[1]->SetSpecularPower(16.0f);
298 lights_[1]->SetPosition(-10.0f, 7.0f, -5.0f);
299
300 lights_[2] = new light_class;
301 lights_[2]->SetDiffuseColor(0.0f, 1.0f, 0.0f, 1.0f); // Green
302 lights_[2]->SetDirection(0.0f, 0.0f, -1.0f);
303 lights_[2]->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f);
304 lights_[2]->SetSpecularColor(0.0f, 1.0f, 0.0f, 1.0f);
305 lights_[2]->SetSpecularPower(16.0f);
306 lights_[2]->SetPosition(10.0f, 7.0f, 5.0f);
307
308 lights_[3] = new light_class;
309 lights_[3]->SetDiffuseColor(0.0f, 0.0f, 1.0f, 1.0f); // Blue
310 lights_[3]->SetDirection(0.0f, 0.0f, -1.0f);
311 lights_[3]->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f);
312 lights_[3]->SetSpecularColor(0.0f, 0.0f, 1.0f, 1.0f);
313 lights_[3]->SetSpecularPower(16.0f);
314 lights_[3]->SetPosition(-10.0f, 7.0f, 5.0f);
315
316 // ------------------------------------------------------------- //
317 // ----------------------- || THE SUN || ----------------------- //
318 // ------------------------------------------------------------- //
319
320 sun_light_ = new light_class;
321 sun_light_->SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); // White
322 sun_light_->SetDirection(0.0f, -1.0f, 0.0f);
323 sun_light_->SetAmbientColor(0.15f, 0.15f, 0.15f, 1.0f);
324 sun_light_->SetPosition(0.0f, 100.0f, 0.0f);
325 sun_light_->SetIntensity(1.0f);
326
327 sun_camera_->set_position(sun_light_->GetPosition().x, sun_light_->GetPosition().y, sun_light_->GetPosition().z);
328 sun_camera_->set_rotation(0.0f, 0.0f, 0.0f);
329 sun_camera_->render();
330
331 // Create and initialize the normal map shader object.
332 shader_manager_ = new shader_manager_class;
333
334 result = shader_manager_->initialize(direct_3d_->get_device(), hwnd);
335 if (!result)
336 {
337 Logger::Get().Log("Could not initialize the shader manager object", __FILE__, __LINE__, Logger::LogLevel::Error);
338 return false;
339 }
340
341 // Set the initial render count string.
342 strcpy_s(renderString, "render Count: 0");
343
344 // Create and initialize the text object for the render count string.
345 render_count_string_ = new text_class;
346
347 result = render_count_string_->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), screenWidth, screenHeight, 32, font_, renderString, 10, 10, 1.0f, 1.0f, 1.0f);
348 if (!result)
349 {
350 Logger::Get().Log("Could not initialize the render count string", __FILE__, __LINE__, Logger::LogLevel::Error);
351 return false;
352 }
353
354 // Create and initialize the model list object.
355 model_list_ = new ModelListClass;
356 model_list_->Initialize(25);
357
358 // Charger les textures_ initiales pour bath_model_
359 std::vector<std::wstring> bathTextures = {
360 L"assets/Texture/marble01.png"
361 };
362
363 TextureContainer BathTextures;
364
365 textures.clear();
366 for (const auto& textureFilename : bathTextures)
367 {
368 ID3D11ShaderResourceView* texture = nullptr;
369 Hresult = DirectX::CreateWICTextureFromFile(direct_3d_->get_device(), direct_3d_->get_device_context(), textureFilename.c_str(), nullptr, &texture);
370 if (FAILED(Hresult))
371 {
372 Logger::Get().Log("Failed to load texture: " + std::string(textureFilename.begin(), textureFilename.end()), __FILE__, __LINE__, Logger::LogLevel::Error);
373 return false;
374 }
375 BathTextures.diffuse.push_back(texture);
376 }
377
378 // Set the file name of the bath model.
379 strcpy_s(modelFilename, "assets/Model/TXT/bath.txt");
380
381 // Create and initialize the bath model object.
382 bath_model_ = new model_class;
383
384 result = bath_model_->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), modelFilename, BathTextures);
385 if (!result)
386 {
387 MessageBox(hwnd, L"Could not initialize the bath model object.", L"Error", MB_OK);
388 return false;
389 }
390
391 // Set the file names of the water model.
392 strcpy_s(modelFilename, "assets/Model/TXT/water.txt");
393 // replace first element with the new filename
394 std::vector<std::wstring> waterTextures = {
395 L"assets/Texture/water01.png"
396 };
397
398 TextureContainer WaterTextures;
399
400 textures.clear();
401 for (const auto& textureFilename : waterTextures)
402 {
403 ID3D11ShaderResourceView* texture = nullptr;
404 Hresult = DirectX::CreateWICTextureFromFile(direct_3d_->get_device(), direct_3d_->get_device_context(), textureFilename.c_str(), nullptr, &texture);
405 if (FAILED(Hresult))
406 {
407 Logger::Get().Log("Failed to load texture: " + std::string(textureFilename.begin(), textureFilename.end()), __FILE__, __LINE__, Logger::LogLevel::Error);
408 return false;
409 }
410 WaterTextures.diffuse.push_back(texture);
411 }
412
413 // Create and initialize the water model object.
414 water_model_ = new model_class;
415
416 result = water_model_->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), modelFilename, WaterTextures);
417 if (!result)
418 {
419 MessageBox(hwnd, L"Could not initialize the water model object.", L"Error", MB_OK);
420 return false;
421 }
422
423 // Create and initialize the refraction render to texture object.
424 refraction_texture_ = new render_texture_class;
425
426 result = refraction_texture_->Initialize(direct_3d_->get_device(), screenWidth, screenHeight, screen_depth, screen_near, 1);
427 if (!result)
428 {
429 MessageBox(hwnd, L"Could not initialize the refraction render texture object.", L"Error", MB_OK);
430 return false;
431 }
432
433 // Create and initialize the reflection render to texture object.
434 reflection_texture_ = new render_texture_class;
435
436 result = reflection_texture_->Initialize(direct_3d_->get_device(), screenWidth, screenHeight, screen_depth, screen_near, 1);
437 if (!result)
438 {
439 MessageBox(hwnd, L"Could not initialize the reflection render texture object.", L"Error", MB_OK);
440 return false;
441 }
442
443 // Set the height of the water.
444 water_height_ = -9.25f;
445
446 // initialize the position of the water.
447 water_translation_ = 100.0f;
448
449 // Create and initialize the timer object.
450 timer_ = new timer_class;
451
452 result = timer_->Initialize();
453 if (!result)
454 {
455 Logger::Get().Log("Could not initialize the timer object", __FILE__, __LINE__, Logger::LogLevel::Error);
456 return false;
457 }
458
459 // Create the position class object.
460 position_ = new position_class;
461
462 // Create and initialize the fps object.
463 fps_ = new fps_class();
464
465 fps_->Initialize();
466
467 // Set the initial fps and fps string.
468 previous_fps_ = -1;
469 strcpy_s(fpsString, "Fps: 0");
470
471 // Create and initialize the text object for the fps string.
472 fps_string_ = new text_class;
473
474 result = fps_string_->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), screenWidth, screenHeight, 32, font_, fpsString, 10, 10, 0.0f, 1.0f, 0.0f);
475 if (!result)
476 {
477 Logger::Get().Log("Could not initialize the fps string", __FILE__, __LINE__, Logger::LogLevel::Error);
478 return false;
479 }
480
481 shadow_map_ = new shadow_map();
482 if (!shadow_map_->initialize(direct_3d_->get_device(), 2048, 2048))
483 {
484 Logger::Get().Log("Could not initialize the shadow map object", __FILE__, __LINE__, Logger::LogLevel::Error);
485 return false;
486 }
487
488 stats_ = new stats();
489 if (!stats_->initialize(this))
490 {
491 Logger::Get().Log("Could not initialize the stats object", __FILE__, __LINE__, Logger::LogLevel::Error);
492 return false;
493 }
494
495 physics_ = new physics;
496
497 physics_thread_ = std::thread(&application_class::physics_thread_function, this);
498
499 //ConstructSkyboxWithPlanes();
500 Skybox* skybox = new Skybox;
501 skybox->Initialize(direct_3d_);
502 skybox_.push_back(skybox->ConstructSkybox(this));
503
504 culling_active_ = true;
505 culling_thread_ = std::thread(&application_class::culling_thread_function, this);
506
507 }
508 catch (const std::exception& e)
509 {
510 Logger::Get().Log(std::string("Exception caught during initialization: ") + e.what(), __FILE__, __LINE__, Logger::LogLevel::Error);
511 return false;
512 }
513 Logger::Get().Log("Application class initialized", __FILE__, __LINE__, Logger::LogLevel::Initialize);
514
515
516
517 return true;
518}
519
521{
522 Logger::Get().Log("Shutting down application class", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
523
524 // Release the shader manager object.
525 if (shader_manager_)
526 {
527 Logger::Get().Log("Releasing the shader manager object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
528
529 shader_manager_->shutdown();
530 delete shader_manager_;
531 shader_manager_ = 0;
532
533 Logger::Get().Log("Shader manager object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
534 }
535
536 // Release the reflection render texture object.
537 if (reflection_texture_)
538 {
539 reflection_texture_->Shutdown();
540 delete reflection_texture_;
541 reflection_texture_ = 0;
542 }
543
544 // Release the refraction render texture object.
545 if (refraction_texture_)
546 {
547 refraction_texture_->Shutdown();
548 delete refraction_texture_;
549 refraction_texture_ = 0;
550 }
551
552 // Release the water model object.
553 if (water_model_)
554 {
555 water_model_->Shutdown();
556 delete water_model_;
557 water_model_ = 0;
558 }
559
560 // Release the bath model object.
561 if (bath_model_)
562 {
563 bath_model_->Shutdown();
564 delete bath_model_;
565 bath_model_ = 0;
566 }
567 // Release the physics object.
568 if (physics_)
569 {
570 delete physics_;
571 physics_ = 0;
572 }
573
574 // Release the display plane object.
575 if (display_plane_)
576 {
577 Logger::Get().Log("Releasing the display plane object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
578
579 display_plane_->Shutdown();
580 delete display_plane_;
581 display_plane_ = 0;
582
583 Logger::Get().Log("Display plane object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
584 }
585
586 // Release the position object.
587 if (position_)
588 {
589 Logger::Get().Log("Releasing the position object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
590
591 delete position_;
592 position_ = 0;
593
594 Logger::Get().Log("Position object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
595 }
596
597 // Release the model list object.
598 if (model_list_)
599 {
600 Logger::Get().Log("Releasing the model list object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
601
602 model_list_->Shutdown();
603 delete model_list_;
604 model_list_ = 0;
605
606 Logger::Get().Log("Model list object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
607 }
608
609 // Release the text objects for the render count string.
610 if (render_count_string_)
611 {
612 Logger::Get().Log("Releasing the render count string object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
613
614 render_count_string_->Shutdown();
615 delete render_count_string_;
616 render_count_string_ = 0;
617
618 Logger::Get().Log("render count string object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
619 }
620
621 // Release the text objects for the mouse strings.
622 if (mouse_strings_)
623 {
624 Logger::Get().Log("Releasing the mouse strings", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
625
626 mouse_strings_[0].Shutdown();
627 mouse_strings_[1].Shutdown();
628 mouse_strings_[2].Shutdown();
629
630 delete[] mouse_strings_;
631 mouse_strings_ = 0;
632
633 Logger::Get().Log("Mouse strings released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
634 }
635
636 // Release the text object for the fps string.
637 if (fps_string_)
638 {
639 Logger::Get().Log("Releasing the fps string object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
640
641 fps_string_->Shutdown();
642 delete fps_string_;
643 fps_string_ = 0;
644
645 Logger::Get().Log("Fps string object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
646 }
647
648 // Release the fps object.
649 if (fps_)
650 {
651 Logger::Get().Log("Releasing the fps object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
652
653 delete fps_;
654 fps_ = 0;
655
656 Logger::Get().Log("Fps object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
657 }
658
659 // Release the font object.
660 if (font_)
661 {
662 Logger::Get().Log("Releasing the font object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
663
664 font_->Shutdown();
665 delete font_;
666 font_ = 0;
667
668 Logger::Get().Log("Font object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
669 }
670
671 // Release the font shader object.
672 if (font_shader_)
673 {
674 Logger::Get().Log("Releasing the font shader object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
675
676 font_shader_->shutdown();
677 delete font_shader_;
678 font_shader_ = 0;
679
680 Logger::Get().Log("Font shader object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
681 }
682
683 // Release the timer object.
684 if (timer_)
685 {
686 Logger::Get().Log("Releasing the timer object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
687
688 delete timer_;
689 timer_ = 0;
690
691 Logger::Get().Log("Timer object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
692 }
693
694 // Release the sprite object.
695 if (sprite_)
696 {
697 Logger::Get().Log("Releasing the sprite object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
698
699 sprite_->Shutdown();
700 delete sprite_;
701 sprite_ = 0;
702
703 Logger::Get().Log("Sprite object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
704 }
705
706 for (auto light : lights_)
707 {
708 Logger::Get().Log("Releasing the light object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
709 if (light)
710 {
711 delete light;
712 light = 0;
713 }
714 Logger::Get().Log("Light object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
715 }
716
717 // Release the light object.
718 if (m_light_)
719 {
720 Logger::Get().Log("Releasing the light object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
721 delete m_light_;
722 m_light_ = 0;
723 Logger::Get().Log("Light object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
724 }
725
726 // Release the model object.
727 if (model_)
728 {
729 Logger::Get().Log("Releasing the model object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
730 model_->Shutdown();
731 delete model_;
732 model_ = 0;
733 Logger::Get().Log("Model object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
734 }
735
736 if (scene_texture_)
737 {
738 scene_texture_->Shutdown();
739 delete scene_texture_;
740 scene_texture_ = nullptr;
741 }
742
743 if (sun_camera_)
744 {
745 Logger::Get().Log("Releasing the sun camera object", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
746 delete sun_camera_;
747 sun_camera_ = nullptr;
748 Logger::Get().Log("Sun camera object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
749 }
750
751 if (shadow_map_) {
752 shadow_map_->shutdown();
753 delete shadow_map_;
754 shadow_map_ = nullptr;
755 }
756
757 Logger::Get().Log("Application class shut down", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
758}
759
761{
762 stats_->reset_draw_call_count();
763
764 int mouseX, mouseY, currentMouseX, currentMouseY;
765 bool result, leftMouseDown, rightMouseDown, buttonQ, buttonD, buttonZ, buttonS, buttonA, buttonE, scrollUp, scrollDown;
766 float rotationY, rotationX, positionX, positionY, positionZ;
767 static float textureTranslation = 0.0f;
768
769 float frameTime;
770
771 static int lastMouseX = 0, lastMouseY = 0;
772
773 static float rotation = 360.0f;
774 static float x = 0.0f;
775 static float y = 3.0f;
776 static float z = 0.0f;
777
778 // Update the system stats.
779 timer_->Frame();
780
781 // Get the current frame time.
782 frameTime = timer_->GetTime();
783
784 // Check if the user pressed escape and wants to exit the application.
785 if (Input->IsEscapePressed())
786 {
787 Logger::Get().Log("User pressed escape, exiting application", __FILE__, __LINE__, Logger::LogLevel::Input);
788 should_quit_ = true;
789 }
790
791 // Get the location of the mouse from the input object,
792 Input->GetMouseLocation(mouseX, mouseY);
793
794 // Check if the mouse has been pressed.
795 leftMouseDown = Input->IsLeftMousePressed();
796 rightMouseDown = Input->IsRightMousePressed();
797
798 currentMouseX = mouseX;
799
800 int deltaX = currentMouseX - lastMouseX; // Calculate the mouse movement.
801 lastMouseX = currentMouseX; // Update the last mouse position for the next frame
802
803 currentMouseY = mouseY;
804
805 int deltaY = currentMouseY - lastMouseY; // Calculate the mouse movement.
806 lastMouseY = currentMouseY; // Update the last mouse position for the next frame
807
808 // Set the frame time for calculating the updated position.
809 position_->SetFrameTime(timer_->GetTime());
810
811 position_->TurnMouse((float)deltaX, (float)deltaY, 0.1f, rightMouseDown);
812
813 // Get the current view point rotation.
814 position_->GetRotation(rotationY, rotationX);
815
816 scrollUp = Input->IsScrollUp();
817 scrollDown = Input->IsScrollDown();
818
819 // Check if the a(q), d, w(z), s, q(a), e have been pressed, if so move the camera accordingly.
820 buttonQ = Input->IsAPressed();
821 buttonD = Input->IsDPressed();
822 buttonZ = Input->IsWPressed();
823 buttonS = Input->IsSPressed();
824 buttonA = Input->IsQPressed();
825 buttonE = Input->IsEPressed();
826 position_->MoveCamera(buttonZ, buttonS, buttonQ, buttonD, buttonE, buttonA, scrollUp, scrollDown, rightMouseDown);
827 position_->GetPosition(positionX, positionY, positionZ);
828
829 XMFLOAT3 dir = sun_light_->GetDirection();
830 float pitch = asinf(-dir.y) * (180.0f / XM_PI); // en degrés
831 float yaw = atan2f(dir.x, dir.z) * (180.0f / XM_PI); // en degrés
832 float roll = 0.0f;
833
834 if (Input->is_key_pressed(DIK_TAB)) {
835 if (!tab_was_pressed_) {
836 // Alterner la caméra active
837 if (active_camera_ == camera_)
838 active_camera_ = sun_camera_;
839 else
840 active_camera_ = camera_;
841 tab_was_pressed_ = true;
842 }
843 } else {
844 tab_was_pressed_ = false;
845 }
846
847 if (active_camera_ == camera_) {
848 // Update the camera position and rotation based on the position class.
849 camera_->set_position(positionX, positionY, positionZ);
850 camera_->set_rotation(rotationX, rotationY, 0.0f);
851 } else {
852 // Update the sun camera position and rotation based on the light position.
853 sun_camera_->set_position(sun_light_->GetPosition().x, sun_light_->GetPosition().y, sun_light_->GetPosition().z);
854 sun_camera_->set_rotation(pitch, yaw, roll);
855
856 // sun_camera_->set_position(positionX, positionY, positionZ);
857 // sun_camera_->set_rotation(rotationX, rotationY, 0.0f);
858 }
859
860 active_camera_->render();
861
862 // render the static graphics scene.
863 result = render(rotation, x, y, z, textureTranslation);
864 if (!result)
865 {
866 Logger::Get().Log("Could not render the graphics scene", __FILE__, __LINE__, Logger::LogLevel::Error);
867 return false;
868 }
869
870 // Update the frames per second each frame.
871 result = update_fps();
872 if (!result)
873 {
874 Logger::Get().Log("Could not update the frames per second", __FILE__, __LINE__, Logger::LogLevel::Error);
875 return false;
876 }
877
878 // Update the rotation variable each frame.
879 rotation -= 0.0174532925f * speed_;
880 if (rotation < 0.0f)
881 {
882 rotation += 360.0f;
883 }
884
885 // Update the position of the water to simulate motion.
886 water_translation_ += 0.001f;
887 if (water_translation_ > 1.0f)
888 {
889 water_translation_ -= 1.0f;
890 }
891
892 // render the refraction of the scene to a texture.
893 result = render_refraction_to_texture();
894 if (!result)
895 {
896 return false;
897 }
898
899 // render the reflection of the scene to a texture.
900 result = render_reflection_to_texture();
901 if (!result)
902 {
903 return false;
904 }
905
906 inputs_.key_left = Input->IsLeftArrowPressed();
907 inputs_.key_right = Input->IsRightArrowPressed();
908 inputs_.key_up = Input->IsUpArrowPressed();
909 inputs_.key_down = Input->IsDownArrowPressed();
910
911 // render the scene to a render texture.
912 result = render_scene_to_texture(rotation);
913 if (!result)
914 {
915 Logger::Get().Log("Could not render the scene to the render texture", __FILE__, __LINE__, Logger::LogLevel::Error);
916 return false;
917 }
918
919 // Update the mouse strings each frame.
920 result = update_mouse_strings(mouseX, mouseY, leftMouseDown);
921 if (!result)
922 {
923 Logger::Get().Log("Could not update the mouse strings", __FILE__, __LINE__, Logger::LogLevel::Error);
924 return false;
925 }
926
927 // Update the sprite object using the frame time.
928 sprite_->Update(frameTime);
929
930 // Increment the texture translation.
931 textureTranslation += 0.01f;
932 if (textureTranslation > 1.0f)
933 {
934 textureTranslation -= 1.0f;
935 }
936
937 return true;
938}
939
940bool application_class::render_refraction_to_texture()
941{
942 XMMATRIX worldMatrix, viewMatrix, projectionMatrix;
943 XMFLOAT4 diffuseColor[4], lightPosition[4], ambientColor[4];
944 XMFLOAT4 clipPlane;
945 int i;
946 bool result;
947
948 // Setup a clipping plane based on the height of the water to clip everything above it.
949 clipPlane = XMFLOAT4(0.0f, -1.0f, 0.0f, water_height_ + 0.1f);
950
951 // Set the render target to be the refraction render to texture and clear it.
952 refraction_texture_->SetRenderTarget(direct_3d_->get_device_context());
953 refraction_texture_->ClearRenderTarget(direct_3d_->get_device_context(), 0.0f, 0.0f, 0.0f, 1.0f);
954
955 // Generate the view matrix based on the camera's position.
956 camera_->render();
957 camera_->get_view_matrix(viewMatrix);
958 projectionMatrix = direct_3d_->get_projection_matrix();
959
960 // Get the light properties.
961 for (i = 0; i < num_lights_; i++)
962 {
963 // Create the diffuse color array from the four light colors.
964 diffuseColor[i] = lights_[i]->GetDiffuseColor();
965
966 // Create the light position array from the four light positions.
967 lightPosition[i] = lights_[i]->GetPosition();
968
969 // Create the light position array from the four light positions.
970 ambientColor[i] = lights_[i]->GetAmbientColor();
971 }
972
973 // Translate to where the bath model will be rendered.
974 worldMatrix = XMMatrixTranslation(0.0f, -10.0f, 0.0f);
975
976 // render the bath model using the refraction shader.
977 bath_model_->Render(direct_3d_->get_device_context());
978
979 result = shader_manager_->render_refraction_shader(direct_3d_->get_device_context(), bath_model_->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
980 bath_model_->GetTexture(TextureType::Diffuse,0), lights_[0]->GetDirection(), ambientColor, diffuseColor, lightPosition, clipPlane);
981 if (!result)
982 {
983 return false;
984 }
985
986 // Reset the render target back to the original back buffer and not the render to texture anymore. And reset the viewport back to the original.
987 direct_3d_->set_back_buffer_render_target();
988 direct_3d_->reset_viewport();
989
990 return true;
991}
992
993bool application_class::render_reflection_to_texture()
994{
995 XMMATRIX reflectionViewMatrix;
996
997 // Set the render target to be the reflection render to texture and clear it.
998 reflection_texture_->SetRenderTarget(direct_3d_->get_device_context());
999 reflection_texture_->ClearRenderTarget(direct_3d_->get_device_context(), 0.0f, 0.0f, 0.0f, 1.0f);
1000
1001 // Use the camera to render the reflection and create a reflection view matrix.
1002 camera_->render_reflection(water_height_);
1003
1004 // Get the camera reflection view matrix instead of the normal view matrix.
1005 camera_->get_reflection_view_matrix(reflectionViewMatrix);
1006
1007 // Reset the render target back to the original back buffer and not the render to texture anymore. And reset the viewport back to the original.
1008 direct_3d_->set_back_buffer_render_target();
1009 direct_3d_->reset_viewport();
1010
1011 return true;
1012}
1013
1014bool application_class::render_scene_to_texture(float rotation)
1015{
1016 XMMATRIX worldMatrix, viewMatrix, projectionMatrix;
1017 bool result;
1018
1019 // Set the render target to be the render texture and clear it.
1020 render_texture_->SetRenderTarget(direct_3d_->get_device_context());
1021 render_texture_->ClearRenderTarget(direct_3d_->get_device_context(), 0.0f, 0.5f, 1.0f, 1.0f);
1022
1023 // Set the position of the camera for viewing the cube.
1024 camera_->render();
1025
1026 camera_->get_view_matrix(viewMatrix);
1027 render_texture_->GetProjectionMatrix(projectionMatrix);
1028
1029 // Rotate the world matrix by the rotation value so that the cube will spin.
1030 worldMatrix = XMMatrixRotationY(rotation);
1031
1032 // render the model using the texture shader.
1033 model_->Render(direct_3d_->get_device_context());
1034
1035 result = shader_manager_->render_texture_shader(direct_3d_->get_device_context(), model_->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
1036 model_->GetTexture(TextureType::Diffuse,0));
1037 if (!result)
1038 {
1039 return false;
1040 }
1041
1042 // Reset the render target back to the original back buffer and not the render to texture anymore. And reset the viewport back to the original.
1043 direct_3d_->set_back_buffer_render_target();
1044 direct_3d_->reset_viewport();
1045
1046 return true;
1047}
1048
1049bool application_class::render(float rotation, float x, float y, float z, float textureTranslation)
1050{
1051 XMMATRIX worldMatrix, viewMatrix, orthoMatrix, projectionMatrix, rotateMatrix, translateMatrix, scaleMatrix, srMatrix, reflectionMatrix;
1052 XMFLOAT4 diffuseColor[4], lightPosition[4], ambientColor[4];
1053 int i;
1054 bool result;
1055 float blendAmount;
1056
1057 // Set the blending amount to 10%.
1058 blendAmount = 0.1f;
1059
1060 // Generate the view matrix based on the camera's position.
1061 active_camera_->render();
1062
1063 // Get the world, view, and projection matrices from the camera and d3d objects.
1064 worldMatrix = direct_3d_->get_world_matrix();
1065 active_camera_->get_view_matrix(viewMatrix);
1066 projectionMatrix = direct_3d_->get_projection_matrix();
1067 orthoMatrix = direct_3d_->get_ortho_matrix();
1068
1069 //render Sky box
1070 //RenderSkybox(viewMatrix, projectionMatrix);
1071
1072 // Get the light properties.
1073 for (i = 0; i < num_lights_; i++)
1074 {
1075 // Create the diffuse color array from the four light colors.
1076 diffuseColor[i] = lights_[i]->GetDiffuseColor();
1077
1078 // Create the light position array from the four light positions.
1079 lightPosition[i] = lights_[i]->GetPosition();
1080
1081 // Create the light position array from the four light positions.
1082 ambientColor[i] = lights_[i]->GetPosition();
1083 }
1084
1085 // Redimensionner la texture de rendu si nécessaire
1086 if (DEBUG_MODE)
1087 {
1088 if ((float)scene_texture_->GetTextureWidth() != window_size_.x || (float)scene_texture_->GetTextureHeight() != window_size_.y)
1089 {
1090 scene_texture_->Shutdown();
1091 scene_texture_->Initialize(direct_3d_->get_device(), (int)window_size_.x, (int)window_size_.y, screen_depth, screen_near, 1);
1092 }
1093
1094 direct_3d_->set_back_buffer_render_target();
1095 direct_3d_->reset_viewport();
1096 }
1097
1099
1100
1101 //scene_texture_->SetRenderTarget(direct_3d_->get_device_context());
1102 //scene_texture_->ClearRenderTarget(direct_3d_->get_device_context(), 0.0f, 0.0f, 0.0f, 0.0f);
1103
1104 scaleMatrix = XMMatrixScaling(0.5f, 0.5f, 0.5f); // Build the scaling matrix.
1105 rotateMatrix = XMMatrixRotationY(rotation); // Build the rotation matrix.
1106 translateMatrix = XMMatrixTranslation(x, y, z); // Build the translation matrix.
1107
1108 // Multiply the scale, rotation, and translation matrices together to create the final world transformation matrix.
1109 srMatrix = XMMatrixMultiply(scaleMatrix, rotateMatrix);
1110 worldMatrix = XMMatrixMultiply(srMatrix, translateMatrix);
1111
1112 // Put the model vertex and index buffers on the graphics pipeline to prepare them for drawing.
1113 model_->Render(direct_3d_->get_device_context());
1114
1115 // render the model using the light shader.
1116 result = shader_manager_->renderlight_shader(direct_3d_->get_device_context(), model_->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, model_->GetTexture(TextureType::Diffuse,0),
1117 diffuseColor, lightPosition, ambientColor);
1118
1119 update_skybox_position(); // Update the position of the skybox to match the camera position.
1120
1121 direct_3d_->turn_z_buffer_on(); // Enable the Z buffer after rendering the skybox.
1122
1123 // -------------------------------------------------------- //
1124 // ------------ render the object in the queue ------------ //
1125 // -------------------------------------------------------- //
1126
1127 // set the active camera to the sun camera for rendering the shadow map.
1128 // active_camera_ = sun_camera_;
1129 // active_camera_->render();
1130 // // Render the objects in the render queues. with depth only pass.
1131 // active_camera_->get_view_matrix(viewMatrix);
1132 result = render_pass(diffuseColor, lightPosition, ambientColor, viewMatrix, projectionMatrix);
1133 if (!result)
1134 {
1135 Logger::Get().Log("Could not render the model using any shader", __FILE__, __LINE__, Logger::LogLevel::Error);
1136 return false;
1137 }
1138
1139 // Reset the active camera to the main camera.
1140 // active_camera_ = camera_;
1141 // active_camera_->render();
1142 // active_camera_->get_view_matrix(viewMatrix);
1143 //
1144 // // render the objects in the render queues. with standard pass.
1145 // result = render_pass(render_queues_, diffuseColor, lightPosition, ambientColor, viewMatrix, projectionMatrix);
1146 // if (!result)
1147 // {
1148 // Logger::Get().Log("Could not render the model using any shader", __FILE__, __LINE__, Logger::LogLevel::Error);
1149 // return false;
1150 // }
1151
1152 // stats_->update_geometric_stats();
1153
1154 // Update the render count text.
1155 result = update_render_count_string(get_render_count());
1156 if (!result)
1157 {
1158 Logger::Get().Log("Could not update the render count string", __FILE__, __LINE__, Logger::LogLevel::Error);
1159 return false;
1160 }
1161
1162
1163 // Translate to where the bath model will be rendered.
1164 worldMatrix = XMMatrixTranslation(0.0f, -10.0f, 0.0f);
1165
1166 // Put the bath model vertex and index buffers on the graphics pipeline to prepare them for drawing.
1167 bath_model_->Render(direct_3d_->get_device_context());
1168
1169 // render the bath model using the light shader.
1170 result = shader_manager_->renderlight_shader(direct_3d_->get_device_context(), bath_model_->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix,
1171 bath_model_->GetTexture(TextureType::Diffuse,0), diffuseColor, lightPosition, ambientColor);
1172 if (!result)
1173 {
1174 return false;
1175 }
1176
1177 // Reset the world matrix.
1178 worldMatrix = direct_3d_->get_world_matrix();
1179
1180 // Get the camera reflection view matrix.
1181 camera_->get_reflection_view_matrix(reflectionMatrix);
1182
1183 // Translate to where the water model will be rendered.
1184 worldMatrix = XMMatrixTranslation(0.0f, water_height_, 0.0f);
1185
1186 // Put the water model vertex and index buffers on the graphics pipeline to prepare them for drawing.
1187 water_model_->Render(direct_3d_->get_device_context());
1188
1189 // render the water model using the water shader.
1190 result = shader_manager_->render_water_shader(direct_3d_->get_device_context(), water_model_->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, reflectionMatrix,
1191 reflection_texture_->GetShaderResourceView(), refraction_texture_->GetShaderResourceView(), water_model_->GetTexture(TextureType::Diffuse,0),
1192 water_translation_, 0.01f);
1193 if (!result)
1194 {
1195 return false;
1196 }
1197
1198 // Disable the Z buffer and enable alpha blending for 2D rendering.
1199 direct_3d_->turn_z_buffer_off();
1200 direct_3d_->enable_alpha_blending();
1201
1202 // Reset the world matrix.
1203 worldMatrix = direct_3d_->get_world_matrix();
1204
1205 // render the render count text string using the font shader.
1206 render_count_string_->Render(direct_3d_->get_device_context());
1207
1208 result = font_shader_->render(direct_3d_->get_device_context(), render_count_string_->GetIndexCount(), worldMatrix, base_view_matrix_, orthoMatrix,
1209 font_->GetTexture(), render_count_string_->GetPixelColor());
1210 if (!result)
1211 {
1212 Logger::Get().Log("Could not render the render count text string using the font shader", __FILE__, __LINE__, Logger::LogLevel::Error);
1213 return false;
1214 }
1215
1216 // render the fps text string using the font shader.
1217 fps_string_->Render(direct_3d_->get_device_context());
1218
1219 result = font_shader_->render(direct_3d_->get_device_context(), fps_string_->GetIndexCount(), worldMatrix, base_view_matrix_, orthoMatrix,
1220 font_->GetTexture(), fps_string_->GetPixelColor());
1221 if (!result)
1222 {
1223 Logger::Get().Log("Could not render the fps text string using the font shader", __FILE__, __LINE__, Logger::LogLevel::Error);
1224 return false;
1225 }
1226
1227 // render the mouse text strings using the font shader.
1228 for (i = 0; i < 3; i++)
1229 {
1230 mouse_strings_[i].Render(direct_3d_->get_device_context());
1231
1232 result = font_shader_->render(direct_3d_->get_device_context(), mouse_strings_[i].GetIndexCount(), worldMatrix, base_view_matrix_, orthoMatrix,
1233 font_->GetTexture(), mouse_strings_[i].GetPixelColor());
1234 if (!result)
1235 {
1236 Logger::Get().Log("Could not render the mouse text strings using the font shader", __FILE__, __LINE__, Logger::LogLevel::Error);
1237 return false;
1238 }
1239 }
1240
1241 // Put the sprite vertex and index buffers on the graphics pipeline to prepare them for drawing.
1242 result = sprite_->Render(direct_3d_->get_device_context());
1243 if (!result)
1244 {
1245 return false;
1246 }
1247
1248 // render the sprite with the texture shader.
1249 result = shader_manager_->render_texture_shader(direct_3d_->get_device_context(), model_->GetIndexCount(), worldMatrix, viewMatrix, orthoMatrix,
1250 sprite_->GetTexture());
1251 if (!result)
1252 {
1253 Logger::Get().Log("Could not render the sprite using the texture shader", __FILE__, __LINE__, Logger::LogLevel::Error);
1254 return false;
1255 }
1256
1257 // Turn off alpha blending after rendering the 2D text.
1258 direct_3d_->disable_alpha_blending();
1259
1260 // turn on the Z buffer
1261 direct_3d_->turn_z_buffer_on();
1262
1263 // Get the light properties.
1264 for (i = 0; i < num_lights_; i++)
1265 {
1266 // Create the diffuse color array from the four light colors.
1267 diffuseColor[i] = lights_[i]->GetDiffuseColor();
1268
1269 // Create the light position array from the four light positions.
1270 lightPosition[i] = lights_[i]->GetPosition();
1271 }
1272 // Réinitialiser la cible de rendu au back buffer.
1273 direct_3d_->set_back_buffer_render_target();
1274
1275 return true;
1276}
1277
1278d_3d_class* application_class::get_direct_3d()
1279{
1280 return direct_3d_;
1281}
1282
1284{
1285 return GetSystemMetrics(SM_CXSCREEN);
1286}
1287
1289{
1290 return GetSystemMetrics(SM_CYSCREEN);
1291}
1292
1294{
1295 Logger::Get().Log("Génération du terrain avec ECS", __FILE__, __LINE__, Logger::LogLevel::Info);
1296
1297 // delete previous terrain if it exists
1299
1300 // Dimensions du terrain
1301 float scaleX = 10.0f;
1302 float scaleY = 1.0f;
1303 float scaleZ = 10.0f;
1304 int gridSizeX = 20;
1305 int gridSizeZ = 20;
1306
1307 // Vérifier si le modèle existe déjà dans le cache
1308 std::string modelName = "assets/Model/OBJ/plane.obj";
1309 std::shared_ptr<model_class> sharedModel;
1310
1311 auto it = g_model_cache.find(modelName);
1312 if (it != g_model_cache.end()) {
1313 // Utiliser le modèle existant du cache
1314 Logger::Get().Log("Using cached model for terrain: " + modelName, __FILE__, __LINE__);
1315 sharedModel = it->second;
1316 }
1317 else {
1318 // Créer un conteneur de textures partagé
1319 TextureContainer textureContainer;
1320 textureContainer.diffusePaths.push_back(L"assets/Texture/Bricks2K.png");
1321 textureContainer.normalPaths.push_back(L"assets/Texture/BricksNRM2K.png");
1322 textureContainer.specularPaths.push_back(L"assets/Texture/BricksGLOSS2K.png");
1323
1324 // Créer et initialiser le modèle si non trouvé
1325 char modelFilename[128];
1326 strcpy_s(modelFilename, modelName.c_str());
1327
1328 auto newModel = std::make_shared<model_class>();
1329 newModel->PreloadTextures(direct_3d_->get_device(), direct_3d_->get_device_context(), textureContainer);
1330
1331 if (!newModel->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), modelFilename, textureContainer)) {
1332 Logger::Get().Log("Impossible d'initialiser le modèle du terrain", __FILE__, __LINE__, Logger::LogLevel::Error);
1333 return;
1334 }
1335
1336 // Ajouter le modèle au cache
1337 g_model_cache[modelName] = newModel;
1338 sharedModel = newModel;
1339 Logger::Get().Log("Added terrain model to cache: " + modelName, __FILE__, __LINE__);
1340 }
1341
1342 // Vérifier si l'entity manager est disponible
1343 if (entity_manager_) {
1344 // Générer les tuiles de terrain avec le système ECS
1345 for (int i = 0; i < gridSizeX; i++) {
1346 for (int j = 0; j < gridSizeZ; j++) {
1347 // Créer une entité
1348 auto entity = entity_manager_->CreateEntity();
1349
1350 // Ajouter un composant d'identité
1351 auto identity = entity->AddComponent<ecs::IdentityComponent>(object_id_++);
1352 identity->SetName("TerrainTile_" + std::to_string(i) + "_" + std::to_string(j));
1353 identity->SetType(ecs::ObjectType::Terrain);
1354
1355 // Ajouter un composant de transformation
1356 auto transform = entity->AddComponent<ecs::TransformComponent>();
1357 transform->SetPosition(XMVectorSet(i * scaleX, -12.0f, j * scaleZ, 0.0f));
1358 transform->SetScale(XMVectorSet(scaleX, scaleY, scaleZ, 0.0f));
1359 transform->UpdateWorldMatrix();
1360
1361 // Ajouter un composant de rendu
1362 auto render = entity->AddComponent<ecs::RenderComponent>();
1363 render->InitializeWithModel(sharedModel);
1364
1365 // Ajouter un composant de shader
1366 auto shader = entity->AddComponent<ecs::ShaderComponent>();
1367 shader->SetActiveShader(ecs::ShaderType::SUNLIGHT);
1368 }
1369 }
1370 }
1371
1373
1374 int totalTiles = gridSizeX * gridSizeZ;
1375 Logger::Get().Log("Terrain généré avec " + std::to_string(totalTiles) + " tuiles", __FILE__, __LINE__, Logger::LogLevel::Info);
1376}
1377
1378void application_class::add_kobject(std::wstring& filepath)
1379{
1380 std::lock_guard<std::mutex> lock(objects_mutex_);
1381 Logger::Get().Log("Adding object", __FILE__, __LINE__);
1382
1383 char modelFilename[128];
1384 TextureContainer KobjectsTextures;
1385 filesystem::path p(filepath);
1386 string filename = p.stem().string();
1387
1388 size_t convertedChars = 0;
1389 (void)wcstombs_s(&convertedChars, modelFilename, sizeof(modelFilename), filepath.c_str(), _TRUNCATE);
1390
1391 filesystem::current_path(w_folder_);
1392
1393 // Liste des fichiers de texture
1394 std::vector<std::wstring> kobjTexture = {
1395 L"assets/Texture/Bricks2K.png",
1396 L"assets/Texture/BricksNRM2K.png",
1397 L"assets/Texture/BricksGLOSS2K.png"
1398 };
1399
1400 // Configurer les chemins des textures dans le conteneur
1401 KobjectsTextures.diffusePaths.push_back(kobjTexture[0]);
1402 if (kobjTexture.size() > 1) KobjectsTextures.normalPaths.push_back(kobjTexture[1]);
1403 if (kobjTexture.size() > 2) KobjectsTextures.specularPaths.push_back(kobjTexture[2]);
1404
1405 // Vérifier si le modèle existe déjà dans le cache
1406 std::string modelKey = std::string(modelFilename);
1407 std::shared_ptr<model_class> sharedModel;
1408
1409 auto it = g_model_cache.find(modelKey);
1410 if (it != g_model_cache.end()) {
1411 // Utiliser le modèle existant du cache
1412 Logger::Get().Log("Using cached model for " + modelKey, __FILE__, __LINE__);
1413 sharedModel = it->second;
1414 }
1415 else {
1416 // Créer un nouveau modèle
1417 sharedModel = std::make_shared<model_class>();
1418
1419 // Précharger les textures
1420 sharedModel->PreloadTextures(direct_3d_->get_device(), direct_3d_->get_device_context(), KobjectsTextures);
1421
1422 // Initialiser le modèle
1423 if (!sharedModel->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), modelFilename, KobjectsTextures)) {
1424 Logger::Get().Log("Failed to initialize model for object: " + modelKey, __FILE__, __LINE__, Logger::LogLevel::Error);
1425 return;
1426 }
1427
1428 // Ajouter le modèle au cache
1429 g_model_cache[modelKey] = sharedModel;
1430 Logger::Get().Log("Added model to cache: " + modelKey, __FILE__, __LINE__);
1431 }
1432
1433 // Créer une nouvelle entité
1434 auto entity = entity_manager_->CreateEntity();
1435
1436 // Ajouter un composant d'identité
1437 auto identity = entity->AddComponent<ecs::IdentityComponent>(object_id_++);
1438 identity->SetName(filename);
1439 identity->SetType(ecs::ObjectType::Unknown);
1440
1441 // Ajouter un composant de transformation
1442 auto transform = entity->AddComponent<ecs::TransformComponent>();
1443 transform->SetPosition(XMVectorSet(0.0f, 50.0f, 0.0f, 0.0f));
1444 transform->SetScale(XMVectorSet(1.0f, 1.0f, 1.0f, 0.0f));
1445 transform->UpdateWorldMatrix();
1446
1447 // Ajouter un composant de rendu avec le modèle partagé
1448 auto render = entity->AddComponent<ecs::RenderComponent>();
1449 render->InitializeWithModel(sharedModel);
1450
1451 // Ajouter un composant de shader
1452 auto shader = entity->AddComponent<ecs::ShaderComponent>();
1453 shader->SetActiveShader(ecs::ShaderType::LIGHTING);
1454
1455 // Stocker le chemin du modèle
1456 auto modelPath = entity->AddComponent<ecs::ModelPathComponent>();
1457 modelPath->SetPath(filepath);
1458
1459 Logger::Get().Log("ECS entity created with ID: " + std::to_string(identity->GetId()), __FILE__, __LINE__);
1460
1462}
1463
1465{
1466 std::lock_guard<std::mutex> lock(objects_mutex_);
1467 Logger::Get().Log("Adding cube", __FILE__, __LINE__);
1468
1469 std::string model_name = "assets/Model/TXT/cube.txt";
1470 std::shared_ptr<model_class> sharedModel;
1471
1472 auto it = g_model_cache.find(model_name);
1473 if (it != g_model_cache.end())
1474 {
1475 Logger::Get().Log("Using cached model: " + model_name, __FILE__, __LINE__);
1476 sharedModel = it->second;
1477 }
1478 else
1479 {
1480 TextureContainer cube_textures;
1481 cube_textures.diffusePaths.push_back(L"assets/Texture/Bricks2K.png");
1482 cube_textures.normalPaths.push_back(L"assets/Texture/BricksNRM2K.png");
1483 cube_textures.specularPaths.push_back(L"assets/Texture/BricksGLOSS2K.png");
1484
1485 char model_filename[128];
1486 strcpy_s(model_filename, model_name.c_str());
1487
1488 auto newModel = std::make_shared<model_class>();
1489 newModel->PreloadTextures(direct_3d_->get_device(), direct_3d_->get_device_context(), cube_textures);
1490 if (!newModel->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(), model_filename, cube_textures)) {
1491 Logger::Get().Log("Failed to initialize cube model", __FILE__, __LINE__, Logger::LogLevel::Error);
1492 return;
1493 }
1494
1495 g_model_cache[model_name] = newModel;
1496 sharedModel = newModel;
1497 Logger::Get().Log("Added cube model to cache: " + model_name, __FILE__, __LINE__);
1498
1499
1500 if (entity_manager_)
1501 {
1502 auto entity = entity_manager_->CreateEntity();
1503
1504 auto identity = entity->AddComponent<ecs::IdentityComponent>(object_id_++);
1505 identity->SetName("Cube");
1506 identity->SetType(ecs::ObjectType::Cube);
1507
1508 auto transform = entity->AddComponent<ecs::TransformComponent>();
1509 transform->SetPosition(XMVectorSet(0.0f, 10.0f, 0.0f, 0.0f));
1510 transform->SetScale(XMVectorSet(1.0f, 1.0f, 1.0f, 0.0f));
1511 transform->UpdateWorldMatrix();
1512
1513 auto render = entity->AddComponent<ecs::RenderComponent>();
1514 render->InitializeWithModel(sharedModel);
1515
1516 auto shader = entity->AddComponent<ecs::ShaderComponent>();
1517 shader->SetActiveShader(ecs::ShaderType::TEXTURE);
1518 }
1519 }
1520
1522 Logger::Get().Log("Cube added successfully", __FILE__, __LINE__, Logger::LogLevel::Info);
1523
1524}
1525
1527{
1528 std::lock_guard<std::mutex> lock(objects_mutex_);
1529 Logger::Get().Log("Deleting entity with ID: " + std::to_string(entity_id), __FILE__, __LINE__, Logger::LogLevel::Info);
1530
1531 if (entity_manager_) {
1532 // Rechercher l'entité avec l'ID spécifié via le composant IdentityComponent
1533 auto entities_with_identity = entity_manager_->GetEntitiesWithComponent<ecs::IdentityComponent>();
1534 for (auto& entity : entities_with_identity) {
1535 auto identity = entity->GetComponent<ecs::IdentityComponent>();
1536 if (identity && identity->GetId() == entity_id) {
1537 // Supprimer l'entité
1538 entity_manager_->DestroyEntity(entity->GetID());
1539 Logger::Get().Log("Entity with ID " + std::to_string(entity_id) + " successfully deleted", __FILE__, __LINE__, Logger::LogLevel::Info);
1540 break;
1541 }
1542 }
1543 }
1544
1546}
1547
1549{
1550 std::lock_guard<std::mutex> lock(objects_mutex_);
1551 Logger::Get().Log("Deleting terrain", __FILE__, __LINE__, Logger::LogLevel::Info);
1552
1553 // Get all entities with the Terrain type
1554 auto entities_with_terrain = entity_manager_->GetEntitiesWithComponent<ecs::IdentityComponent>();
1555 for (auto& entity : entities_with_terrain) {
1556 auto identity = entity->GetComponent<ecs::IdentityComponent>();
1557 if (identity && identity->GetType() == ecs::ObjectType::Terrain) {
1558 // Destroy the entity
1559 entity_manager_->DestroyEntity(entity->GetID());
1560 Logger::Get().Log("Terrain entity with ID " + std::to_string(identity->GetId()) + " successfully deleted", __FILE__, __LINE__, Logger::LogLevel::Info);
1561 }
1562 }
1563
1565}
1566
1567bool application_class::update_mouse_strings(int mouseX, int mouseY, bool mouseDown)
1568{
1569 char tempString[16], finalString[32];
1570 bool result;
1571
1572
1573 // Convert the mouse X integer to string format.
1574 sprintf_s(tempString, "%d", mouseX);
1575
1576 // Setup the mouse X string.
1577 strcpy_s(finalString, "Mouse X: ");
1578 strcat_s(finalString, tempString);
1579
1580 // Update the sentence vertex buffer with the new string information.
1581 result = mouse_strings_[0].UpdateText(direct_3d_->get_device_context(), font_, finalString, 10, 50, 1.0f, 1.0f, 1.0f);
1582 if (!result)
1583 {
1584 Logger::Get().Log("Could not update the mouse X string", __FILE__, __LINE__, Logger::LogLevel::Error);
1585 return false;
1586 }
1587
1588 // Convert the mouse Y integer to string format.
1589 sprintf_s(tempString, "%d", mouseY);
1590
1591 // Setup the mouse Y string.
1592 strcpy_s(finalString, "Mouse Y: ");
1593 strcat_s(finalString, tempString);
1594
1595 // Update the sentence vertex buffer with the new string information.
1596 result = mouse_strings_[1].UpdateText(direct_3d_->get_device_context(), font_, finalString, 10, 75, 1.0f, 1.0f, 1.0f);
1597 if (!result)
1598 {
1599 Logger::Get().Log("Could not update the mouse Y string", __FILE__, __LINE__, Logger::LogLevel::Error);
1600 return false;
1601 }
1602
1603 // Setup the mouse button string.
1604 if (mouseDown)
1605 {
1606 strcpy_s(finalString, "Mouse Button: Yes");
1607 }
1608 else
1609 {
1610 strcpy_s(finalString, "Mouse Button: No");
1611 }
1612
1613 // Update the sentence vertex buffer with the new string information.
1614 result = mouse_strings_[2].UpdateText(direct_3d_->get_device_context(), font_, finalString, 10, 100, 1.0f, 1.0f, 1.0f);
1615
1616 if (!result)
1617 {
1618 Logger::Get().Log("Could not update the mouse button string", __FILE__, __LINE__, Logger::LogLevel::Error);
1619 return false;
1620 }
1621
1622 return true;
1623}
1624
1625bool application_class::update_fps()
1626{
1627 int fps;
1628 char tempString[16], finalString[16];
1629 float red, green, blue;
1630 bool result;
1631
1632
1633 // Update the fps each frame.
1634 fps_->Frame();
1635
1636 stats_->update_display_stats(); // Update the stats display with the latest information from fps class.
1637
1638 // Get the current fps.
1639 fps = fps_->GetFps();
1640
1641 // Check if the fps from the previous frame was the same, if so don't need to update the text string.
1642 if (previous_fps_ == fps)
1643 {
1644 return true;
1645 }
1646
1647 // Store the fps for checking next frame.
1648 previous_fps_ = fps;
1649
1650 // Truncate the fps to below 100,000.
1651 if (fps > 99999)
1652 {
1653 fps = 99999;
1654 }
1655
1656 // Convert the fps integer to string format.
1657 sprintf_s(tempString, "%d", fps);
1658
1659 // Setup the fps string.
1660 strcpy_s(finalString, "Fps: ");
1661 strcat_s(finalString, tempString);
1662
1663 // If fps is 60 or above set the fps color to green.
1664 if (fps >= 60)
1665 {
1666 red = 0.0f;
1667 green = 1.0f;
1668 blue = 0.0f;
1669 }
1670
1671 // If fps is below 60 set the fps color to yellow.
1672 if (fps < 60)
1673 {
1674 red = 1.0f;
1675 green = 1.0f;
1676 blue = 0.0f;
1677 }
1678
1679 // If fps is below 30 set the fps color to red.
1680 if (fps < 30)
1681 {
1682 red = 1.0f;
1683 green = 0.0f;
1684 blue = 0.0f;
1685 }
1686
1687 // Update the sentence vertex buffer with the new string information.
1688 result = fps_string_->UpdateText(direct_3d_->get_device_context(), font_, finalString, 10, 10, red, green, blue);
1689 if (!result)
1690 {
1691 Logger::Get().Log("Could not update the fps string", __FILE__, __LINE__, Logger::LogLevel::Error);
1692 return false;
1693 }
1694
1695 return true;
1696}
1697
1698bool application_class::update_render_count_string(int renderCount)
1699{
1700 char tempString[16], finalString[32];
1701 bool result;
1702
1703
1704 // Convert the render count integer to string format.
1705 sprintf_s(tempString, "%d", renderCount);
1706
1707 // Setup the render count string.
1708 strcpy_s(finalString, "render Count: ");
1709 strcat_s(finalString, tempString);
1710
1711 // Update the sentence vertex buffer with the new string information.
1712 result = render_count_string_->UpdateText(direct_3d_->get_device_context(), font_, finalString, 10, 30, 1.0f, 1.0f, 1.0f);
1713 if (!result)
1714 {
1715 Logger::Get().Log("Could not update the render count string", __FILE__, __LINE__, Logger::LogLevel::Error);
1716 return false;
1717 }
1718
1719 return true;
1720}
1721
1723{
1724 //convert to XMVECTOR
1725 XMVECTOR lightColor = XMVectorSet(lights_[index]->GetDiffuseColor().x, lights_[index]->GetDiffuseColor().y, lights_[index]->GetDiffuseColor().z, 1.0f);
1726
1727 return lightColor;
1728}
1729
1731{
1732 //convert to XMVECTOR
1733 XMVECTOR lightPosition = XMVectorSet(lights_[index]->GetPosition().x, lights_[index]->GetPosition().y, lights_[index]->GetPosition().z, 1.0f);
1734
1735 return lightPosition;
1736}
1737
1738void application_class::set_light_color(int index, XMVECTOR color)
1739{
1740 //convert to XMFLOAT4
1741 XMFLOAT4 lightColor;
1742 XMStoreFloat4(&lightColor, color);
1743
1744 //set the color
1745 lights_[index]->SetDiffuseColor(lightColor.x, lightColor.y, lightColor.z, 1.0f);
1746}
1747
1748void application_class::set_light_position(int index, XMVECTOR position)
1749{
1750 //convert to XMFLOAT4
1751 XMFLOAT4 lightPosition;
1752 XMStoreFloat4(&lightPosition, position);
1753
1754 //set the position
1755 lights_[index]->SetPosition(lightPosition.x, lightPosition.y, lightPosition.z);
1756}
1757
1759{
1760 // log the new screen height
1761 Logger::Get().Log("Setting screen height to " + std::to_string(height), __FILE__, __LINE__);
1762 screen_height_ = height;
1763}
1764
1766{
1767 // log the new screen width
1768 Logger::Get().Log("Setting screen width to " + std::to_string(width), __FILE__, __LINE__);
1769 screen_width_ = width;
1770}
1771
1772void application_class::culling_thread_function()
1773{
1774 Logger::Get().Log("Thread de culling démarré", __FILE__, __LINE__, Logger::LogLevel::Info);
1775
1776 while (culling_active_)
1777 {
1778 // Construction du frustum une fois par cycle de culling
1780
1781 // S'assurer que la skybox est toujours visible
1782 {
1783 std::lock_guard<std::mutex> lock(objects_mutex_);
1784 for (auto* skyboxObject : skybox_)
1785 {
1786 if (skyboxObject)
1787 {
1788 skyboxObject->SetVisible(true);
1789 }
1790 }
1791 }
1792
1793 // Traitement des files d'objets normaux (sans la skybox)
1794 auto all_entity = entity_manager_->GetAllEntities();
1795
1796 for (auto& entity : all_entity)
1797 {
1798 std::lock_guard<std::mutex> lock(objects_mutex_);
1799 auto renderComponent = entity->GetComponent<ecs::RenderComponent>();
1800 if (renderComponent && renderComponent->GetModel())
1801 {
1802 // Extraction des données de position via le composant TransformComponent
1803 auto transformComponent = entity->GetComponent<ecs::TransformComponent>();
1804 if (transformComponent)
1805 {
1806 XMVECTOR transformPosition = transformComponent->GetPosition();
1807 float x = XMVectorGetX(transformPosition);
1808 float y = XMVectorGetY(transformPosition);
1809 float z = XMVectorGetZ(transformPosition);
1810
1811 // Calcul du rayon approximatif
1812 XMVECTOR scale = transformComponent->GetScale();
1813 float radius = max(max(XMVectorGetX(scale), XMVectorGetY(scale)), XMVectorGetZ(scale));
1814
1815 // verification du frustum
1816 bool visible = frustum_culling_.CheckCube(x, y, z, radius, get_frustum_tolerance());
1817 renderComponent->SetVisible(visible);
1818 }
1819
1820 }
1821 }
1822
1823 // Pause pour éviter de surcharger le CPU
1824 std::this_thread::sleep_for(std::chrono::milliseconds(16)); // ~60 Hz
1825 }
1826
1827 Logger::Get().Log("Thread de culling terminé", __FILE__, __LINE__, Logger::LogLevel::Info);
1828}
1829
1830
1831
1832bool application_class::render_pass(XMFLOAT4* diffuse, XMFLOAT4* position, XMFLOAT4* ambient, XMMATRIX view, XMMATRIX projection)
1833{
1834 std::lock_guard<std::mutex> lock(objects_mutex_);
1835 XMMATRIX scaleMatrix, rotateMatrix, translateMatrix;
1836 bool result;
1837
1838 int renderCount = 0;
1839 int i;
1840
1841 // render skybox
1842 for (auto& skyboxObject : skybox_)
1843 {
1844 if (skyboxObject == nullptr)
1845 {
1846 Logger::Get().Log("skyboxObject is null", __FILE__, __LINE__, Logger::LogLevel::Error);
1847 return false;
1848 }
1849
1850 if (!skyboxObject->IsVisible())
1851 {
1852 continue;
1853 }
1854
1855 direct_3d_->turn_z_buffer_off();
1856
1857 scaleMatrix = skyboxObject->GetScaleMatrix();
1858 rotateMatrix = skyboxObject->GetRotateMatrix();
1859 translateMatrix = skyboxObject->GetTranslateMatrix();
1860
1861 XMMATRIX worldMatrix = XMMatrixMultiply(
1862 XMMatrixMultiply(scaleMatrix, rotateMatrix),
1863 translateMatrix
1864 );
1865
1866 renderCount++;
1867
1868 skyboxObject->get_model()->Render(direct_3d_->get_device_context());
1869
1870 result = shader_manager_->render_skybox_shader(
1871 direct_3d_->get_device_context(),
1872 skyboxObject->get_model()->GetIndexCount(),
1873 worldMatrix,
1874 view,
1875 projection,
1876 skyboxObject->get_model()->GetTexture(TextureType::Diffuse,0),
1877 sun_light_->GetDiffuseColor(),
1878 sun_light_->GetAmbientColor(),
1879 sun_light_->GetDirection(),
1880 sun_light_->GetIntensity()
1881 );
1882 if (!result)
1883 {
1884 Logger::Get().Log("Could not render the object model using the skybox shader", __FILE__, __LINE__, Logger::LogLevel::Error);
1885 return false;
1886 }
1887 direct_3d_->turn_z_buffer_on(); // Réactiver le Z-buffer après le rendu de la skybox
1888
1889 break;
1890
1891 }
1892
1893 // Rendu des entités du système ECS s'il est disponible
1894 if (entity_manager_) {
1895 // Créer le système de rendu pour les entités
1896 ecs::RenderSystem renderSystem(direct_3d_->get_device_context(), shader_manager_);
1897
1898 // Données pour le système de rendu
1899 XMFLOAT4 sunlightDiffuse = sun_light_->GetDiffuseColor();
1900 XMFLOAT4 sunlightAmbient = sun_light_->GetAmbientColor();
1901 XMFLOAT3 sunlightDirection = sun_light_->GetDirection();
1902 float sunlightIntensity = sun_light_->GetIntensity();
1903
1904 // Effectuer le rendu de toutes les entités
1905 int entitiesRendered = renderSystem.RenderAllEntities(
1906 entity_manager_.get(),
1907 view,
1908 projection,
1909 diffuse,
1910 position,
1911 ambient,
1912 camera_->get_position(),
1913 sunlightDiffuse,
1914 sunlightAmbient,
1915 sunlightDirection,
1916 sunlightIntensity
1917 );
1918
1919 renderCount += entitiesRendered;
1920 }
1921
1922 // Rendu des objets traditionnels comme avant
1923 // if (active_camera_ == sun_camera_)
1924 // {
1925 // shadow_map_->set_render_target(direct_3d_->get_device_context());
1926 // shadow_map_->clear_render_target(direct_3d_->get_device_context());
1927 // }
1928
1929 // if (active_camera_ == sun_camera_)
1930 // {
1931 // direct_3d_->set_back_buffer_render_target();
1932 // direct_3d_->reset_viewport();
1933 // }
1934
1935 set_render_count(renderCount);
1936
1937 return true;
1938}
1939
1941{
1942 XMMATRIX projectionMatrix = direct_3d_->get_projection_matrix();
1943 XMMATRIX viewMatrix;
1944 active_camera_->get_view_matrix(viewMatrix);
1945
1946 frustum_culling_.ConstructFrustum(screen_depth, projectionMatrix, viewMatrix);
1947}
1948
1949// Update the position of the skybox based on the camera position
1950void application_class::update_skybox_position()
1951{
1952
1953 if (skybox_.empty())
1954 {
1955 Logger::Get().Log("Skybox is empty", __FILE__, __LINE__, Logger::LogLevel::Error);
1956 return;
1957 }
1958
1959 skybox_[0]->SetTranslateMatrix(XMMatrixTranslation(active_camera_->get_position().x, active_camera_->get_position().y, active_camera_->get_position().z));
1960
1961}
1962
1963bool application_class::render_physics(float delta_time) {
1964
1965 // update the physical entity if they have the physics component
1966 auto entities_with_physics = entity_manager_->GetEntitiesWithComponent<ecs::PhysicsComponent>();
1967 for (auto& entity : entities_with_physics) {
1968 auto physicsComponent = entity->GetComponent<ecs::PhysicsComponent>();
1969 if (physicsComponent) {
1970 // Update the physics component with the input keys and delta time
1971 physicsComponent->Update(delta_time);
1972 }
1973 }
1974
1975 return true;
1976}
1977
1979{
1980 auto fixedUpdateInterval = std::chrono::milliseconds(1000 / physics_tick_rate_);
1981 auto lastTime = std::chrono::steady_clock::now();
1982
1983 while (!should_quit_)
1984 {
1985 auto now = std::chrono::steady_clock::now();
1986 if (now - lastTime >= fixedUpdateInterval)
1987 {
1988 lastTime = now;
1989
1990 float deltaTime = 1.0f / static_cast<float>(physics_tick_rate_);
1991 bool result = render_physics(deltaTime);
1992 if (!result)
1993 {
1994 Logger::Get().Log("Could not render the physics scene", __FILE__, __LINE__, Logger::LogLevel::Error);
1995 return;
1996 }
1997 }
1998 // Attendre un peu pour éviter de surcharger le CPU
1999 std::this_thread::sleep_for(std::chrono::milliseconds(1));
2000 }
2001}
2002
2004{
2005 std::string modelName = "assets/Model/TXT/cube.txt";
2006 std::shared_ptr<model_class> sharedModel;
2007
2008 // Vérifier si le modèle existe déjà
2009 auto it = g_model_cache.find(modelName);
2010 if (it != g_model_cache.end()) {
2011 sharedModel = it->second;
2012 } else {
2013 // copy le string en char*
2014 char model_file[128];
2015 size_t convertedChars = 0;
2016 (void)wcstombs_s(&convertedChars, model_file, sizeof(model_file), std::wstring(modelName.begin(), modelName.end()).c_str(), _TRUNCATE);
2017
2018 // Créer et initialiser le modèle si non trouvé
2019 auto newModel = std::make_shared<model_class>();
2020 TextureContainer textures;
2021 textures.diffusePaths.push_back(L"assets/Texture/Bricks2K.png");
2022 textures.normalPaths.push_back(L"assets/Texture/BricksNRM2K.png");
2023 textures.specularPaths.push_back(L"assets/Texture/BricksGLOSS2K.png");
2024 newModel->PreloadTextures(direct_3d_->get_device(), direct_3d_->get_device_context(), textures);
2025 if (!newModel->Initialize(direct_3d_->get_device(), direct_3d_->get_device_context(),model_file, textures)) {
2026 Logger::Get().Log("Impossible d'initialiser le modèle du gros cube", __FILE__, __LINE__, Logger::LogLevel::Error);
2027 return false;
2028 }
2029 g_model_cache[modelName] = newModel;
2030 sharedModel = newModel;
2031 }
2032
2033 for (int x = 0; x < side_count; x++) {
2034 for (int y = 0; y < side_count; y++) {
2035 for (int z = 0; z < side_count; z++) {
2036 // Créer une entité
2037 auto entity = entity_manager_->CreateEntity();
2038
2039 // Ajouter un composant d'identité
2040 auto identity = entity->AddComponent<ecs::IdentityComponent>(object_id_++);
2041 identity->SetName("CubePart_" + std::to_string(x) + "_" + std::to_string(y) + "_" + std::to_string(z));
2042 identity->SetType(ecs::ObjectType::Terrain);
2043
2044 // Ajouter un composant de transformation
2045 auto transform = entity->AddComponent<ecs::TransformComponent>();
2046 transform->SetPosition(XMVectorSet(static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), 0.0f));
2047 transform->SetScale(XMVectorSet(1.0f, 1.0f, 1.0f, 0.0f));
2048 transform->UpdateWorldMatrix();
2049
2050 // Ajouter un composant de rendu
2051 auto render = entity->AddComponent<ecs::RenderComponent>();
2052 render->InitializeWithModel(sharedModel);
2053
2054 // Ajouter un composant de shader
2055 auto shader = entity->AddComponent<ecs::ShaderComponent>();
2056 shader->SetActiveShader(ecs::ShaderType::LIGHTING);
2057 }
2058 }
2059 }
2060
2062
2063 return true;
2064}
2065
2067{
2068 if (stats_)
2069 {
2070 stats_ -> update_geometric_stats();
2071 }
2072}
2073
2075{
2076 std::lock_guard<std::mutex> lock(objects_mutex_);
2077 int terrainCount = 0;
2078
2079 // Get all entities with the Terrain type
2080 auto entities_with_terrain = entity_manager_->GetEntitiesWithComponent<ecs::IdentityComponent>();
2081 for (auto& entity : entities_with_terrain) {
2082 auto identity = entity->GetComponent<ecs::IdentityComponent>();
2083 if (identity && identity->GetType() == ecs::ObjectType::Terrain) {
2084 terrainCount++;
2085 }
2086 }
2087
2088 return terrainCount;
2089}
static Logger & Get()
Definition Logger.h:20
void Log(const std::string &message, const std::string &fileName, int lineNumber, LogLevel level=LogLevel::Info)
Definition Logger.h:158
Definition Skybox.h:8
object * ConstructSkybox(application_class *app)
Definition Skybox.cpp:26
void Initialize(d_3d_class *d3dClassRef)
Definition Skybox.cpp:21
virtual bool frame(input_class *)
Run the main loop of the application. This function will handle the main loop, including rendering an...
void set_light_position(int index, XMVECTOR position)
void set_render_count(const int render_count)
virtual bool initialize(int screen_width, int screen_height, HWND hwdn, bool is_vulkan)
void set_hwnd(HWND hwnd)
XMVECTOR get_light_position(int index)
void delete_entity_by_id(int entity_id)
void set_light_color(int index, XMVECTOR color)
bool create_big_cube(int side_count)
Create a big cube with a specified number of little cube per sides.
void set_windowed(bool windowed)
XMVECTOR get_light_color(int index)
void add_kobject(std::wstring &filepath)
float get_frustum_tolerance() const
void physics_thread_function()
Thread function for handling physics updates. this function will run in a separate thread to handle p...
application_class()
Constructor for the application class. Initializes member variables and sets up the application.
void set_screen_width(int screen_width)
int get_render_count() const
void set_screen_height(int screen_height)
void render()
Updates the camera's view matrix based on its position and rotation. This method recalculates the vie...
void set_rotation(float, float, float)
Sets the rotation of the camera in 3D space.
void set_position(float, float, float)
Sets the position of the camera in 3D space.
void render_reflection(float)
Renders the reflection of the scene from the camera's perspective.
XMMATRIX get_view_matrix(XMMATRIX &view_matrix) const
Retrieves the current view matrix of the camera.
void get_reflection_view_matrix(XMMATRIX &) const
Retrieves the reflection view matrix of the camera.
XMFLOAT3 get_position()
Gets the current position of the camera.
void turn_z_buffer_on()
ID3D11Device * get_device()
Gets the Direct3D device.
XMMATRIX get_world_matrix() const
Definition d_3d_class.h:115
void set_back_buffer_render_target()
ID3D11DeviceContext * get_device_context()
Gets the Direct3D device context.
void reset_viewport()
XMMATRIX get_projection_matrix() const
Definition d_3d_class.h:109
void enable_alpha_blending()
void disable_alpha_blending()
XMMATRIX get_ortho_matrix() const
Definition d_3d_class.h:121
virtual bool initialize(int, int, bool, HWND, bool, float, float)
Initializes the Direct3D device and related resources.
void turn_z_buffer_off()
void SetName(const std::string &name)
void SetPath(const std::wstring &path)
void SetActiveShader(ShaderType shader)
void SetPosition(XMVECTOR position)
void ConstructFrustum(float screenDepth, XMMATRIX projectionMatrix, XMMATRIX viewMatrix)
Definition frustum.cpp:3
bool CheckCube(float xCenter, float yCenter, float zCenter, float radius, float tolerance)
Definition frustum.cpp:59
Definition stats.h:13