Wildvine Engine
Referencia Doxygen del codigo propio de Wildvine Engine.
Cargando...
Buscando...
Nada coincide
BaseApp.cpp
Ir a la documentación de este archivo.
1
6#include "BaseApp.h"
7#include "ResourceManager.h"
8#include <algorithm>
9#include <cctype>
10#include <fstream>
11#include <iomanip>
12
13HRESULT
15 HRESULT hr = S_OK;
16
17 // Inicializacion de dlls y elementos externos al motor.
19
20 // Log Success Message
21 MESSAGE("Main", "Awake", "Application awake successfully.");
22 return hr;
23}
24
25int
26BaseApp::run(HINSTANCE hInst, int nCmdShow) {
27 // 1) Initialize Window
28 if (FAILED(m_window.init(hInst, nCmdShow, WndProc, this))) {
29 ERROR("Main", "Run", "Failed to initialize window.");
30 return 0;
31 }
32 // 2) Awake Application
33 if (FAILED(awake())) {
34 ERROR("Main", "Run", "Failed to awake application.");
35 return 0;
36 }
37 // 3) Initialize Device and Device Context
38 if (FAILED(init())) {
39 ERROR("Main", "Run", "Failed to initialize device and device context.");
40 return 0;
41 }
42 // 4) Initialize GUI
44 m_guiInitialized = true;
45
46 // Main message loop
47 MSG msg = {};
48 LARGE_INTEGER freq, prev;
49 QueryPerformanceFrequency(&freq);
50 QueryPerformanceCounter(&prev);
51 while (WM_QUIT != msg.message)
52 {
53 if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
54 {
55 TranslateMessage(&msg);
56 DispatchMessage(&msg);
57 }
58 else
59 {
60 LARGE_INTEGER curr;
61 QueryPerformanceCounter(&curr);
62 float deltaTime = static_cast<float>(curr.QuadPart - prev.QuadPart) / freq.QuadPart;
63 prev = curr;
64 update(deltaTime);
65 render();
66 }
67 }
68 return (int)msg.wParam;
69}
70
71HRESULT
73 HRESULT hr = S_OK;
74
75 // Crear swapchain
77
78 if (FAILED(hr)) {
79 ERROR("Main", "InitDevice",
80 ("Failed to initialize SwpaChian. HRESULT: " + std::to_string(hr)).c_str());
81 return hr;
82 }
83
84 // Crear render target view
85 hr = m_renderTargetView.init(m_device, m_backBuffer, DXGI_FORMAT_R8G8B8A8_UNORM);
86
87 if (FAILED(hr)) {
88 ERROR("Main", "InitDevice",
89 ("Failed to initialize RenderTargetView. HRESULT: " + std::to_string(hr)).c_str());
90 return hr;
91 }
92
93 // Crear textura de depth stencil
97 DXGI_FORMAT_D24_UNORM_S8_UINT,
98 D3D11_BIND_DEPTH_STENCIL,
99 4,
100 0);
101
102 if (FAILED(hr)) {
103 ERROR("Main", "InitDevice",
104 ("Failed to initialize DepthStencil. HRESULT: " + std::to_string(hr)).c_str());
105 return hr;
106 }
107
108 // Crear el depth stencil view
111 DXGI_FORMAT_D24_UNORM_S8_UINT);
112
113 if (FAILED(hr)) {
114 ERROR("Main", "InitDevice",
115 ("Failed to initialize DepthStencilView. HRESULT: " + std::to_string(hr)).c_str());
116 return hr;
117 }
118
119 // Crear el m_viewport
121
122 if (FAILED(hr)) {
123 ERROR("Main", "InitDevice",
124 ("Failed to initialize Viewport. HRESULT: " + std::to_string(hr)).c_str());
125 return hr;
126 }
127 m_d3dReady = true;
128
129 // Load Resources -> Modelos, Texturas e Interfaz de usuario
130 std::array<std::string, 6> faces = {
131 "Skybox/cubemap_0.png",
132 "Skybox/cubemap_1.png",
133 "Skybox/cubemap_2.png",
134 "Skybox/cubemap_3.png",
135 "Skybox/cubemap_4.png",
136 "Skybox/cubemap_5.png"
137 };
139
140 // Set CyberGun Actor
141 m_cyberGun = EU::MakeShared<Actor>(m_device);
142 m_drakefirePistol = EU::MakeShared<Actor>(m_device);
143
144 if (!m_cyberGun.isNull()) {
145 m_model = new Model3D("CyberGun.fbx", ModelType::FBX);
146 if (!m_model || !m_model->load("CyberGun.fbx")) {
147 ERROR("Main", "InitDevice", "Failed to load CyberGun model.");
148 return E_FAIL;
149 }
150
151 hr = m_AlbedoSRV.init(m_device, "Textures/CyberGun/base.tga", PNG);
152 if (FAILED(hr)) {
153 ERROR("Main", "InitDevice",
154 ("Failed to initialize DrakePistol Texture. HRESULT: " + std::to_string(hr)).c_str());
155 return hr;
156 }
157 hr = m_MetallicSRV.init(m_device, "Textures/CyberGun/metallic.tga", PNG);
158 if (FAILED(hr)) {
159 ERROR("Main", "InitDevice",
160 ("Failed to initialize DrakePistol Texture. HRESULT: " + std::to_string(hr)).c_str());
161 return hr;
162 }
163 hr = m_RoughnessSRV.init(m_device, "Textures/CyberGun/roughness.tga", PNG);
164 if (FAILED(hr)) {
165 ERROR("Main", "InitDevice",
166 ("Failed to initialize DrakePistol Texture. HRESULT: " + std::to_string(hr)).c_str());
167 return hr;
168 }
169 hr = m_AOSRV.init(m_device, "Textures/CyberGun/ao.tga", PNG);
170 if (FAILED(hr)) {
171 ERROR("Main", "InitDevice",
172 ("Failed to initialize DrakePistol Texture. HRESULT: " + std::to_string(hr)).c_str());
173 return hr;
174 }
175 hr = m_NormalSRV.init(m_device, "Textures/CyberGun/normal.tga", PNG);
176 if (FAILED(hr)) {
177 ERROR("Main", "InitDevice",
178 ("Failed to initialize DrakePistol Texture. HRESULT: " + std::to_string(hr)).c_str());
179 return hr;
180 }
181 HRESULT emissiveHr = m_EmissiveSRV.init(m_device, "Textures/CyberGun/Emissive.tga", PNG);
182 if (FAILED(emissiveHr)) {
183 MESSAGE("Main", "InitDevice", "CyberGun emissive texture not found. Continuing without emissive map.");
184 }
185 m_cyberGun->setName("CyberGun");
186 m_actors.push_back(m_cyberGun);
187
188 m_cyberGun->getComponent<Transform>()->setTransform(EU::Vector3(2.0f, -1.90f, 11.60f),
189 EU::Vector3(-0.60f, 3.0f, -0.20f),
190 EU::Vector3(1.0f, 1.0f, 1.0f));
191 }
192 else {
193 ERROR("Main", "InitDevice", "Failed to create cyber Gun Actor.");
194 return E_FAIL;
195 }
196
197 if (!m_drakefirePistol.isNull()) {
198 m_drakefireModel = new Model3D("Models/drakefire_pistol_low_OBJ/drakefire_pistol_low.obj", ModelType::OBJ);
199 if (!m_drakefireModel || !m_drakefireModel->load("Models/drakefire_pistol_low_OBJ/drakefire_pistol_low.obj")) {
200 ERROR("Main", "InitDevice", "Failed to load Drakefire pistol model.");
201 return E_FAIL;
202 }
203
204 hr = m_drakefireAlbedoSRV.init(m_device, "Textures/drakefire_pistol_low_Textures/base_albedo", JPG);
205 if (FAILED(hr)) {
206 ERROR("Main", "InitDevice",
207 ("Failed to initialize Drakefire albedo texture. HRESULT: " + std::to_string(hr)).c_str());
208 return hr;
209 }
210 hr = m_drakefireNormalSRV.init(m_device, "Textures/drakefire_pistol_low_Textures/base_normal", JPG);
211 if (FAILED(hr)) {
212 ERROR("Main", "InitDevice",
213 ("Failed to initialize Drakefire normal texture. HRESULT: " + std::to_string(hr)).c_str());
214 return hr;
215 }
216 hr = m_drakefireMetallicSRV.init(m_device, "Textures/drakefire_pistol_low_Textures/base_metallic", JPG);
217 if (FAILED(hr)) {
218 ERROR("Main", "InitDevice",
219 ("Failed to initialize Drakefire metallic texture. HRESULT: " + std::to_string(hr)).c_str());
220 return hr;
221 }
222 hr = m_drakefireRoughnessSRV.init(m_device, "Textures/drakefire_pistol_low_Textures/base_roughness", JPG);
223 if (FAILED(hr)) {
224 ERROR("Main", "InitDevice",
225 ("Failed to initialize Drakefire roughness texture. HRESULT: " + std::to_string(hr)).c_str());
226 return hr;
227 }
228 hr = m_drakefireAOSRV.init(m_device, "Textures/drakefire_pistol_low_Textures/base_AO", JPG);
229 if (FAILED(hr)) {
230 ERROR("Main", "InitDevice",
231 ("Failed to initialize Drakefire AO texture. HRESULT: " + std::to_string(hr)).c_str());
232 return hr;
233 }
234
235 m_drakefirePistol->setName("Drakefire Pistol");
236 m_actors.push_back(m_drakefirePistol);
237 m_drakefirePistol->getComponent<Transform>()->setTransform(EU::Vector3(-2.5f, -1.90f, 9.5f),
238 EU::Vector3(-0.30f, 0.45f, 0.0f),
239 EU::Vector3(1.0f, 1.0f, 1.0f));
240 }
241 else {
242 ERROR("Main", "InitDevice", "Failed to create Drakefire pistol Actor.");
243 return E_FAIL;
244 }
245
246 // Store the Actors in the Scene Graph
247 for (auto& actor : m_actors) {
248 m_sceneGraph.addEntity(actor.get());
249 }
250
251 LayoutBuilder builder;
252
253 builder.Add("POSITION", DXGI_FORMAT_R32G32B32_FLOAT)
254 .Add("NORMAL", DXGI_FORMAT_R32G32B32_FLOAT)
255 .Add("TANGENT", DXGI_FORMAT_R32G32B32_FLOAT)
256 .Add("BITANGENT", DXGI_FORMAT_R32G32B32_FLOAT)
257 .Add("TEXCOORD", DXGI_FORMAT_R32G32_FLOAT);
258
259 // Create the Shader Program
260 hr = m_shaderProgram.init(m_device, "PBRShader.hlsl", builder);
261 if (FAILED(hr)) {
262 ERROR("Main", "InitDevice",
263 ("Failed to initialize ShaderProgram. HRESULT: " + std::to_string(hr)).c_str());
264 return hr;
265 }
266
267 // Create the constant buffers
268 hr = m_constantBuffer.init(m_device, sizeof(CBMain));
269 if (FAILED(hr)) {
270 ERROR("Main", "InitDevice",
271 ("Failed to initialize m_constantBuffer Buffer. HRESULT: " + std::to_string(hr)).c_str());
272 return hr;
273 }
274
275 m_camera.setLens(XM_PIDIV4, m_window.m_width / (float)m_window.m_height, 0.01f, 100.0f);
276 m_camera.setPosition(0.0f, 3.0f, -6.0f);
277
279 m_constantBufferStruct.LightDir = EU::Vector3(-0.20f, -1.0f, 1.0f);
280
281 // Initialize the Skybox pass -> Carga de textura + creacion de buffers/shaders especificos para el skybox
283
284 // Initialize default states (Rasterizer, DepthStencil)
285 hr = m_defaultRasterizer.init(m_device, D3D11_FILL_SOLID, D3D11_CULL_BACK, false, true);
286 if (FAILED(hr)) {
287 ERROR("Main", "InitDevice",
288 ("Failed to initialize default Rasterizer. HRESULT: " + std::to_string(hr)).c_str());
289 return hr;
290 }
291 hr = m_defaultDepthStencil.init(m_device, true, D3D11_DEPTH_WRITE_MASK_ALL, D3D11_COMPARISON_LESS);
292 if (FAILED(hr)) {
293 ERROR("Main", "InitDevice",
294 ("Failed to initialize default DepthStencilState. HRESULT: " + std::to_string(hr)).c_str());
295 return hr;
296 }
298 if (FAILED(hr)) {
299 ERROR("Main", "InitDevice",
300 ("Failed to initialize default SamplerState. HRESULT: " + std::to_string(hr)).c_str());
301 return hr;
302 }
303
310
317
326 }
327 m_cyberGunMaterial.getParams().baseColor = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
334
341 m_drakefireMaterial.getParams().baseColor = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
347
349 for (const MeshComponent& meshComponent : m_model->GetMeshes()) {
350 Submesh submesh{};
351 hr = submesh.vertexBuffer.init(m_device, meshComponent, D3D11_BIND_VERTEX_BUFFER);
352 if (FAILED(hr)) {
353 ERROR("Main", "InitDevice",
354 ("Failed to initialize CyberGun vertex buffer. HRESULT: " + std::to_string(hr)).c_str());
355 return hr;
356 }
357
358 hr = submesh.indexBuffer.init(m_device, meshComponent, D3D11_BIND_INDEX_BUFFER);
359 if (FAILED(hr)) {
360 ERROR("Main", "InitDevice",
361 ("Failed to initialize CyberGun index buffer. HRESULT: " + std::to_string(hr)).c_str());
362 return hr;
363 }
364
365 submesh.indexCount = meshComponent.m_numIndex;
366 submesh.materialSlot = 0;
367 m_cyberGunRenderMesh.getSubmeshes().push_back(std::move(submesh));
368 }
369
371 for (const MeshComponent& meshComponent : m_drakefireModel->GetMeshes()) {
372 Submesh submesh{};
373 hr = submesh.vertexBuffer.init(m_device, meshComponent, D3D11_BIND_VERTEX_BUFFER);
374 if (FAILED(hr)) {
375 ERROR("Main", "InitDevice",
376 ("Failed to initialize Drakefire vertex buffer. HRESULT: " + std::to_string(hr)).c_str());
377 return hr;
378 }
379
380 hr = submesh.indexBuffer.init(m_device, meshComponent, D3D11_BIND_INDEX_BUFFER);
381 if (FAILED(hr)) {
382 ERROR("Main", "InitDevice",
383 ("Failed to initialize Drakefire index buffer. HRESULT: " + std::to_string(hr)).c_str());
384 return hr;
385 }
386
387 submesh.indexCount = meshComponent.m_numIndex;
388 submesh.materialSlot = 0;
389 m_drakefireRenderMesh.getSubmeshes().push_back(std::move(submesh));
390 }
391
393 if (!meshRenderer) {
394 meshRenderer = EU::MakeShared<MeshRendererComponent>();
395 m_cyberGun->addComponent(meshRenderer);
396 }
397 meshRenderer->setMesh(&m_cyberGunRenderMesh);
398 meshRenderer->setMaterialInstance(&m_cyberGunMaterial);
399 meshRenderer->setVisible(true);
400 meshRenderer->setCastShadow(true);
401
403 if (!drakefireMeshRenderer) {
404 drakefireMeshRenderer = EU::MakeShared<MeshRendererComponent>();
405 m_drakefirePistol->addComponent(drakefireMeshRenderer);
406 }
407 drakefireMeshRenderer->setMesh(&m_drakefireRenderMesh);
408 drakefireMeshRenderer->setMaterialInstance(&m_drakefireMaterial);
409 drakefireMeshRenderer->setVisible(true);
410 drakefireMeshRenderer->setCastShadow(true);
411
412 m_directionalLightActor = EU::MakeShared<Actor>(m_device);
414 m_directionalLightActor->setName("DirectionalLight");
416 if (!lightComponent) {
417 lightComponent = EU::MakeShared<LightComponent>();
418 m_directionalLightActor->addComponent(lightComponent);
419 }
420
421 lightComponent->getLightData().type = LightType::Directional;
422 lightComponent->getLightData().direction = m_constantBufferStruct.LightDir;
423 lightComponent->getLightData().color = m_constantBufferStruct.LightColor;
424 lightComponent->getLightData().intensity = 1.0f;
425 lightComponent->setCastShadow(false);
426
428 }
429
431
432 hr = m_editorViewportPass.init(m_device, 1280, 720);
433 if (FAILED(hr)) {
434 ERROR("Main", "InitDevice",
435 ("Failed to initialize EditorViewportPass. HRESULT: " + std::to_string(hr)).c_str());
436 return hr;
437 }
438
440 if (FAILED(hr)) {
441 ERROR("Main", "InitDevice",
442 ("Failed to initialize ForwardRenderer. HRESULT: " + std::to_string(hr)).c_str());
443 return hr;
444 }
445
446 return S_OK;
447}
448
449void
450BaseApp::update(float deltaTime) {
451 // Update our time
452 static float t = 0.0f;
453 if (m_swapChain.m_driverType == D3D_DRIVER_TYPE_REFERENCE)
454 {
455 t += (float)XM_PI * 0.0125f;
456 }
457 else
458 {
459 static DWORD dwTimeStart = 0;
460 DWORD dwTimeCur = GetTickCount();
461 if (dwTimeStart == 0)
462 dwTimeStart = dwTimeCur;
463 t = (dwTimeCur - dwTimeStart) / 1000.0f;
464 }
465 // Update User Interface
467 bool show_demo_window = true;
468 //ImGui::ShowDemoWindow(&show_demo_window);
472 EU::TSharedPointer<Actor> selectedActor;
473 if (m_gui.selectedActorIndex >= 0 &&
474 m_gui.selectedActorIndex < static_cast<int>(m_actors.size())) {
475 selectedActor = m_actors[m_gui.selectedActorIndex];
476 }
477 m_gui.inspectorGeneral(selectedActor);
478 m_gui.editTransform(m_camera, m_window, selectedActor);
481 }
482
483 unsigned int desiredW = static_cast<unsigned int>(m_gui.m_viewportSize.x);
484 unsigned int desiredH = static_cast<unsigned int>(m_gui.m_viewportSize.y);
485
486 const unsigned int kMinViewportSize = 64;
487
488 if (desiredW < kMinViewportSize) desiredW = kMinViewportSize;
489 if (desiredH < kMinViewportSize) desiredH = kMinViewportSize;
490
491 // Si cambio el tamano solicitado, reinicia estabilidad
492 if (desiredW != m_lastRequestedViewportWidth || desiredH != m_lastRequestedViewportHeight)
493 {
497 }
498 else
499 {
500 // El tamano ya no cambio este frame
502 }
503
504 // Solo marcar resize cuando el tamano se haya mantenido estable
505 const int kStableFramesRequired = 2;
506
507 if (m_viewportResizeStableFrames >= kStableFramesRequired)
508 {
509 if (desiredW != m_editorViewportPass.getWidth() ||
510 desiredH != m_editorViewportPass.getHeight())
511 {
513 m_pendingViewportWidth = desiredW;
514 m_pendingViewportHeight = desiredH;
515 }
516 }
517
518 // Actualizar la matriz de proyeccion y vista
520
521 XMStoreFloat4x4(&m_constantBufferStruct.View, XMMatrixTranspose(m_camera.getView()));
522 XMStoreFloat4x4(&m_constantBufferStruct.Projection, XMMatrixTranspose(m_camera.getProj()));
524
525 // Luz blanca fuerte
526 m_gui.vec3Control("Light Direction", &m_constantBufferStruct.LightDir.x, 0.1f);
527 m_gui.vec3Control("Light Color", &m_constantBufferStruct.LightColor.x, 0.1f);
530 if (lightComponent) {
531 lightComponent->getLightData().direction = m_constantBufferStruct.LightDir;
532 lightComponent->getLightData().color = m_constantBufferStruct.LightColor;
533 }
534 }
535
536 // Update Skybox Pass -> Solo necesita la vista sin traslacion + proyeccion para funcionar correctamente (ver metodo update de Skybox)
538
539 // Update Actors
541
542}
543
544void
547
548 float ClearColor[4] = { 0.1f, 0.1f, 0.1f, 1.0f };
549
555 m_camera,
558 );
559
560 // 2) Volver al backbuffer principal
564
565 // 4) GUI
566 m_gui.render();
567
569}
570
571void
612
613LRESULT
614BaseApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
615 if (ImGui_ImplWin32_WndProcHandler(hWnd, message, wParam, lParam)) {
616 return true;
617 }
618
619 switch (message) {
620 case WM_CREATE: {
621 CREATESTRUCT* pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
622 SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pCreate->lpCreateParams);
623 }
624 return 0;
625 case WM_PAINT: {
626 PAINTSTRUCT ps;
627 BeginPaint(hWnd, &ps);
628 EndPaint(hWnd, &ps);
629 }
630 return 0;
631 case WM_SIZE:
632 {
633 // Evita recrear cuando esta minimizada
634 if (wParam == SIZE_MINIMIZED) return 0;
635
636 unsigned int newW = LOWORD(lParam);
637 unsigned int newH = HIWORD(lParam);
638 if (newW == 0 || newH == 0) return 0;
639
640 // Recupera tu instancia BaseApp (lo mas comun es guardarla en GWLP_USERDATA en WM_CREATE)
641 BaseApp* app = reinterpret_cast<BaseApp*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
642 if (app) app->onResize(newW, newH);
643 return 0;
644 }
645 case WM_DESTROY:
646 PostQuitMessage(0);
647 return 0;
648 }
649 return DefWindowProc(hWnd, message, wParam, lParam);
650}
651
652void BaseApp::onResize(unsigned int newW, unsigned int newH)
653{
654 // 1) Actualiza window size (tu init lo calcula con GetClientRect solo una vez) :contentReference[oaicite:6]{index=6}
655 if (!m_d3dReady) {
656 // Aun asi puedes actualizar el tamano logico de la ventana
657 m_window.m_width = (int)newW;
658 m_window.m_height = (int)newH;
659 return;
660 }
661
663 if (newW == 0 || newH == 0) return;
664
665 m_window.m_width = (int)newW;
666 m_window.m_height = (int)newH;
667 // 2) Desbindea targets actuales (clave antes de destruir)
668 ID3D11RenderTargetView* nullRTV = nullptr;
669 m_deviceContext.m_deviceContext->OMSetRenderTargets(1, &nullRTV, nullptr);
670
671 // 3) Libera recursos dependientes del tamano (RTV/DSV/Depth/BackBuffer)
676
677 // 4) Resize swapchain
678 HRESULT hr = m_swapChain.resizeBuffers(newW, newH);
679 if (FAILED(hr)) return;
680
681 // 5) Re-obten backbuffer
683 if (FAILED(hr)) return;
684
685 // 6) Re-crea RTV
686 hr = m_renderTargetView.init(m_device, m_backBuffer, DXGI_FORMAT_R8G8B8A8_UNORM);
687 if (FAILED(hr)) return;
688
689 // 7) Re-crea Depth/DSV (tu init actual lo hace con m_window.m_width/m_height)
690 hr = m_depthStencil.init(m_device, newW, newH, DXGI_FORMAT_D24_UNORM_S8_UINT, D3D11_BIND_DEPTH_STENCIL, 4, 0);
691 if (FAILED(hr)) return;
692
693 hr = m_depthStencilView.init(m_device, m_depthStencil, DXGI_FORMAT_D24_UNORM_S8_UINT);
694 if (FAILED(hr)) return;
695
696 // 8) Viewport
698
699 // 9) Camara (aspect ratio) (tu camara lo calcula a partir de m_window)
700 m_camera.setLens(XM_PIDIV4, newW / (float)newH, 0.01f, 100.0f);
701}
702
704{
706 return;
707
708 // Desbindear antes de tocar recursos
709 m_deviceContext.m_deviceContext->OMSetRenderTargets(0, nullptr, nullptr);
710
711 ID3D11ShaderResourceView* nullSRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {};
712 m_deviceContext.m_deviceContext->PSSetShaderResources(
713 0,
714 D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT,
715 nullSRVs
716 );
717
718 // Crear pass temporal nuevo
719 EditorViewportPass newPass;
721 if (FAILED(hr))
722 {
723 // Si falla, conserva el pass actual
725 return;
726 }
727
728 // Intercambio seguro: el pass viejo queda en newPass y se destruye al salir
729 m_editorViewportPass.swap(newPass);
731
733}
734
736{
737 CreateDirectoryA("Saved", nullptr);
738 return "Saved/DefaultScene.wvscene";
739}
740
741bool BaseApp::saveScene(const std::string& path)
742{
743 std::ofstream stream(path, std::ios::trunc);
744 if (!stream.is_open()) {
745 ERROR("Main", "saveScene", ("Failed to open scene file for writing: " + path).c_str());
746 return false;
747 }
748
749 stream << "WVSCENE 1\n";
750 stream << "ACTOR_COUNT " << m_actors.size() << "\n";
751
752 for (size_t actorIndex = 0; actorIndex < m_actors.size(); ++actorIndex) {
753 const EU::TSharedPointer<Actor>& actor = m_actors[actorIndex];
754 if (actor.isNull()) {
755 continue;
756 }
757
758 stream << "ACTOR " << actorIndex << " " << std::quoted(actor->getName()) << "\n";
759
760 EU::TSharedPointer<Transform> transform = actor->getComponent<Transform>();
761 if (transform) {
762 const EU::Vector3& position = transform->getPosition();
763 const EU::Vector3& rotation = transform->getRotation();
764 const EU::Vector3& scale = transform->getScale();
765 stream << "POSITION " << position.x << " " << position.y << " " << position.z << "\n";
766 stream << "ROTATION " << rotation.x << " " << rotation.y << " " << rotation.z << "\n";
767 stream << "SCALE " << scale.x << " " << scale.y << " " << scale.z << "\n";
768 }
769
770 EU::TSharedPointer<MeshRendererComponent> meshRenderer = actor->getComponent<MeshRendererComponent>();
771 if (meshRenderer) {
772 stream << "VISIBLE " << (meshRenderer->isVisible() ? 1 : 0) << "\n";
773 stream << "CAST_SHADOW " << (meshRenderer->canCastShadow() ? 1 : 0) << "\n";
774
775 const std::vector<MaterialInstance*>& materials = meshRenderer->getMaterialInstances();
776 stream << "MATERIAL_COUNT " << materials.size() << "\n";
777 for (size_t i = 0; i < materials.size(); ++i) {
778 MaterialInstance* materialInstance = materials[i];
779 if (!materialInstance) {
780 stream << "MATERIAL " << i << " 0 0 1 1 1 1 0 1 1 1 0.5\n";
781 continue;
782 }
783
784 Material* material = materialInstance->getMaterial();
785 const MaterialParams& params = materialInstance->getParams();
786 const int domain = material ? static_cast<int>(material->getDomain()) : 0;
787 const int blendMode = material ? static_cast<int>(material->getBlendMode()) : 0;
788
789 stream << "MATERIAL " << i << " "
790 << domain << " "
791 << blendMode << " "
792 << params.baseColor.x << " "
793 << params.baseColor.y << " "
794 << params.baseColor.z << " "
795 << params.baseColor.w << " "
796 << params.metallic << " "
797 << params.roughness << " "
798 << params.ao << " "
799 << params.normalScale << " "
800 << params.alphaCutoff << "\n";
801 }
802 }
803
804 stream << "END_ACTOR\n";
805 }
806
807 stream << "LIGHT "
814
815 stream << "END_SCENE\n";
816 const std::wstring pathW(path.begin(), path.end());
817 MESSAGE("Main", "saveScene", L"Saved scene to '" << pathW << L"'")
818 return true;
819}
820
821bool BaseApp::loadScene(const std::string& path)
822{
823 std::ifstream stream(path);
824 if (!stream.is_open()) {
825 return false;
826 }
827
828 std::string token;
829 stream >> token;
830 if (token != "WVSCENE") {
831 return false;
832 }
833
834 int version = 0;
835 stream >> version;
836 if (version != 1) {
837 return false;
838 }
839
840 EU::TSharedPointer<Actor> currentActor;
841 while (stream >> token) {
842 if (token == "ACTOR_COUNT") {
843 size_t ignoredCount = 0;
844 stream >> ignoredCount;
845 }
846 else if (token == "ACTOR") {
847 size_t actorIndex = 0;
848 std::string actorName;
849 stream >> actorIndex >> std::quoted(actorName);
850 currentActor = EU::TSharedPointer<Actor>();
851 if (actorIndex < m_actors.size()) {
852 currentActor = m_actors[actorIndex];
853 }
854 if (!currentActor.isNull()) {
855 currentActor->setName(actorName);
856 }
857 }
858 else if (token == "POSITION" && !currentActor.isNull()) {
859 float x = 0.0f, y = 0.0f, z = 0.0f;
860 stream >> x >> y >> z;
861 EU::TSharedPointer<Transform> transform = currentActor->getComponent<Transform>();
862 if (transform) {
863 transform->setPosition(EU::Vector3(x, y, z));
864 }
865 }
866 else if (token == "ROTATION" && !currentActor.isNull()) {
867 float x = 0.0f, y = 0.0f, z = 0.0f;
868 stream >> x >> y >> z;
869 EU::TSharedPointer<Transform> transform = currentActor->getComponent<Transform>();
870 if (transform) {
871 transform->setRotation(EU::Vector3(x, y, z));
872 }
873 }
874 else if (token == "SCALE" && !currentActor.isNull()) {
875 float x = 1.0f, y = 1.0f, z = 1.0f;
876 stream >> x >> y >> z;
877 EU::TSharedPointer<Transform> transform = currentActor->getComponent<Transform>();
878 if (transform) {
879 transform->setScale(EU::Vector3(x, y, z));
880 }
881 }
882 else if (token == "VISIBLE" && !currentActor.isNull()) {
883 int value = 1;
884 stream >> value;
885 EU::TSharedPointer<MeshRendererComponent> meshRenderer = currentActor->getComponent<MeshRendererComponent>();
886 if (meshRenderer) {
887 meshRenderer->setVisible(value != 0);
888 }
889 }
890 else if (token == "CAST_SHADOW" && !currentActor.isNull()) {
891 int value = 1;
892 stream >> value;
893 EU::TSharedPointer<MeshRendererComponent> meshRenderer = currentActor->getComponent<MeshRendererComponent>();
894 if (meshRenderer) {
895 meshRenderer->setCastShadow(value != 0);
896 }
897 }
898 else if (token == "MATERIAL_COUNT") {
899 size_t ignoredCount = 0;
900 stream >> ignoredCount;
901 }
902 else if (token == "MATERIAL" && !currentActor.isNull()) {
903 size_t materialIndex = 0;
904 int domain = 0;
905 int blendMode = 0;
906 MaterialParams params{};
907 stream >> materialIndex
908 >> domain
909 >> blendMode
910 >> params.baseColor.x
911 >> params.baseColor.y
912 >> params.baseColor.z
913 >> params.baseColor.w
914 >> params.metallic
915 >> params.roughness
916 >> params.ao
917 >> params.normalScale
918 >> params.alphaCutoff;
919
920 EU::TSharedPointer<MeshRendererComponent> meshRenderer = currentActor->getComponent<MeshRendererComponent>();
921 if (meshRenderer) {
922 const std::vector<MaterialInstance*>& materials = meshRenderer->getMaterialInstances();
923 if (materialIndex < materials.size() && materials[materialIndex]) {
924 materials[materialIndex]->getParams() = params;
925 Material* material = materials[materialIndex]->getMaterial();
926 if (material) {
927 material->setDomain(static_cast<MaterialDomain>(domain));
928 material->setBlendMode(static_cast<BlendMode>(blendMode));
929 }
930 }
931 }
932 }
933 else if (token == "LIGHT") {
940
943 if (lightComponent) {
944 lightComponent->getLightData().direction = m_constantBufferStruct.LightDir;
945 lightComponent->getLightData().color = m_constantBufferStruct.LightColor;
946 }
947 }
948 }
949 else if (token == "END_ACTOR") {
950 currentActor = EU::TSharedPointer<Actor>();
951 }
952 else if (token == "END_SCENE") {
953 break;
954 }
955 }
956
957 const std::wstring pathW(path.begin(), path.end());
958 MESSAGE("Main", "loadScene", L"Loaded scene from '" << pathW << L"'")
959 return true;
960}
961
962
963
964
Declara la API de BaseApp dentro del subsistema Core.
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
@ OBJ
Definition Model3D.h:14
@ FBX
Definition Model3D.h:15
#define MESSAGE(classObj, method, state)
#define ERROR(classObj, method, errorMSG)
@ JPG
@ PNG
BlendMode
Definition RenderTypes.h:20
MaterialDomain
Definition RenderTypes.h:13
Declara la API de ResourceManager dentro del subsistema Core.
void setName(const std::string &name)
Establece el nombre del actor.
Definition Actor.h:118
Coordina el ciclo de vida principal de Wildvine Engine.
Definition BaseApp.h:48
Skybox m_skybox
Definition BaseApp.h:179
bool m_d3dReady
Definition BaseApp.h:144
MaterialInstance m_drakefireMaterial
Definition BaseApp.h:189
bool loadScene(const std::string &path)
Carga una escena serializada previamente.
Definition BaseApp.cpp:821
Texture m_skyboxTex
Definition BaseApp.h:180
Texture m_drakefireAOSRV
Definition BaseApp.h:159
DeviceContext m_deviceContext
Definition BaseApp.h:134
Texture m_NormalSRV
Definition BaseApp.h:153
unsigned int m_lastRequestedViewportWidth
Definition BaseApp.h:198
Viewport m_viewport
Definition BaseApp.h:140
Texture m_drakefireAlbedoSRV
Definition BaseApp.h:155
Texture m_drakefireMetallicSRV
Definition BaseApp.h:157
SamplerState m_defaultSampler
Definition BaseApp.h:183
HRESULT init()
Inicializa recursos graficos, escena, materiales y renderer.
Definition BaseApp.cpp:72
Texture m_depthStencil
Definition BaseApp.h:138
void handleEditorViewportResize()
Atiende cambios diferidos del viewport interno del editor.
Definition BaseApp.cpp:703
DepthStencilView m_depthStencilView
Definition BaseApp.h:139
int run(HINSTANCE hInst, int nCmdShow)
Ejecuta el bucle principal de la aplicacion.
Definition BaseApp.cpp:26
void render()
Emite el frame actual en el viewport del editor y en el back buffer final.
Definition BaseApp.cpp:545
void destroy()
Libera recursos del motor en orden seguro de destruccion.
Definition BaseApp.cpp:572
bool saveScene(const std::string &path)
Serializa la escena actual a disco.
Definition BaseApp.cpp:741
Texture m_MetallicSRV
Definition BaseApp.h:150
Model3D * m_model
Definition BaseApp.h:170
MaterialInstance m_cyberGunMaterial
Definition BaseApp.h:188
Mesh m_cyberGunRenderMesh
Definition BaseApp.h:184
Texture m_AOSRV
Definition BaseApp.h:152
std::string getDefaultScenePath() const
Devuelve la ruta por defecto usada por el editor para persistencia rapida.
Definition BaseApp.cpp:735
int m_viewportResizeStableFrames
Definition BaseApp.h:200
unsigned int m_pendingViewportHeight
Definition BaseApp.h:196
RenderTargetView m_renderTargetView
Definition BaseApp.h:137
Material m_transparentPbrMaterial
Definition BaseApp.h:187
ForwardRenderer m_forwardRenderer
Definition BaseApp.h:192
DepthStencilState m_defaultDepthStencil
Definition BaseApp.h:182
Texture m_backBuffer
Definition BaseApp.h:136
EU::TSharedPointer< Actor > m_cyberGun
Definition BaseApp.h:165
RasterizerState m_defaultRasterizer
Definition BaseApp.h:181
Texture m_AlbedoSRV
Definition BaseApp.h:149
RenderScene m_renderScene
Definition BaseApp.h:193
Texture m_EmissiveSRV
Definition BaseApp.h:154
Window m_window
Definition BaseApp.h:132
bool m_guiInitialized
Definition BaseApp.h:176
EU::TSharedPointer< Actor > m_directionalLightActor
Definition BaseApp.h:167
void onResize(unsigned int newW, unsigned int newH)
Reconstuye recursos dependientes de la resolucion principal.
Definition BaseApp.cpp:652
unsigned int m_pendingViewportWidth
Definition BaseApp.h:195
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition BaseApp.cpp:614
GUI m_gui
Definition BaseApp.h:175
bool m_editorViewportResizePending
Definition BaseApp.h:194
CBMain m_constantBufferStruct
Definition BaseApp.h:146
SwapChain m_swapChain
Definition BaseApp.h:135
Material m_pbrMaterial
Definition BaseApp.h:186
SceneGraph m_sceneGraph
Definition BaseApp.h:163
Model3D * m_drakefireModel
Definition BaseApp.h:171
EU::TSharedPointer< Actor > m_drakefirePistol
Definition BaseApp.h:166
ShaderProgram m_shaderProgram
Definition BaseApp.h:141
unsigned int m_lastRequestedViewportHeight
Definition BaseApp.h:199
Device m_device
Definition BaseApp.h:133
Texture m_drakefireNormalSRV
Definition BaseApp.h:156
void update(float deltaTime)
Ejecuta la logica por frame y sincroniza GUI, camara y escena.
Definition BaseApp.cpp:450
Texture m_drakefireRoughnessSRV
Definition BaseApp.h:158
Mesh m_drakefireRenderMesh
Definition BaseApp.h:185
Buffer m_constantBuffer
Definition BaseApp.h:145
HRESULT awake()
Prepara subsistemas previos al render.
Definition BaseApp.cpp:14
EditorViewportPass m_editorViewportPass
Definition BaseApp.h:191
Texture m_RoughnessSRV
Definition BaseApp.h:151
Camera m_camera
Definition BaseApp.h:161
std::vector< EU::TSharedPointer< Actor > > m_actors
Definition BaseApp.h:164
HRESULT init(Device &device, const MeshComponent &mesh, unsigned int bindFlag)
Inicializa el buffer como Vertex o Index Buffer usando un MeshComponent.
Definition Buffer.cpp:11
XMMATRIX getView() const
Matriz View (mundo->vista).
Definition Camera.h:113
EU::Vector3 getPosition() const
Obtiene la posición en mundo.
Definition Camera.h:45
XMMATRIX getProj() const
Matriz Projection (vista->clip).
Definition Camera.h:119
void setPosition(float x, float y, float z)
Define posición en mundo.
Definition Camera.cpp:28
void updateViewMatrix()
Recalcula la matriz View si es necesario.
Definition Camera.cpp:114
void setLens(float fovYRadians, float aspectRatio, float nearPlane, float farPlane)
Configura la proyección en perspectiva (LH).
Definition Camera.cpp:14
HRESULT init(Device &device, bool depthEnable, D3D11_DEPTH_WRITE_MASK writeMask, D3D11_COMPARISON_FUNC depthFunc)
Crea el objeto ID3D11DepthStencilState a partir de flags comunes.
void destroy()
Libera el recurso ID3D11DepthStencilState y deja la instancia en estado no inicializado.
void destroy()
Libera el recurso asociado al ID3D11DepthStencilView.
HRESULT init(Device &device, Texture &depthStencil, DXGI_FORMAT format)
Inicializa el ID3D11DepthStencilView a partir de una textura de profundidad.
void render(DeviceContext &deviceContext)
Asigna la vista de profundidad/esténcil al pipeline de render.
void destroy()
Libera el recurso ID3D11DeviceContext.
ID3D11DeviceContext * m_deviceContext
Puntero al contexto inmediato de Direct3D 11.
void destroy()
Definition Device.cpp:8
Clase TSharedPointer para manejar la gestión de memoria compartida.
bool isNull() const
Comprobar si el puntero es nulo.
T * get() const
Obtener el puntero crudo.
A 3D vector class.
Definition Vector3.h:45
float x
The x-coordinate of the vector.
Definition Vector3.h:47
float z
The z-coordinate of the vector.
Definition Vector3.h:49
float y
The y-coordinate of the vector.
Definition Vector3.h:48
ID3D11ShaderResourceView * getSRV() const
HRESULT init(Device &device, unsigned int width, unsigned int height)
unsigned int getHeight() const
void swap(EditorViewportPass &other)
unsigned int getWidth() const
void addComponent(EU::TSharedPointer< T > component)
Agrega un componente a la entidad.
Definition Entity.h:61
EU::TSharedPointer< T > getComponent()
Obtiene un componente de la entidad por su tipo.
Definition Entity.h:73
void resize(Device &device, unsigned int width, unsigned int height)
Reconstuye los recursos dependientes del tamano del viewport.
ID3D11ShaderResourceView * getPreShadowSRV() const
void destroy()
Libera los recursos internos del renderer.
HRESULT init(Device &device)
Inicializa buffers, shaders y estados del renderer.
ID3D11ShaderResourceView * getShadowMapSRV() const
void render(DeviceContext &deviceContext, const Camera &camera, RenderScene &scene, EditorViewportPass &viewportPass)
Renderiza la escena completa sobre el EditorViewportPass.
void editTransform(Camera &cam, Window &window, EU::TSharedPointer< Actor > actor)
Definition GUI.cpp:800
void inspectorGeneral(EU::TSharedPointer< Actor > actor)
Definition GUI.cpp:541
void destroy()
Definition GUI.cpp:259
int selectedActorIndex
Indice del actor seleccionado en el outliner.
Definition GUI.h:139
bool consumeSaveSceneRequest()
Consume de forma atomica la solicitud de guardado emitida desde la UI.
Definition GUI.h:119
void init(Window &window, Device &device, DeviceContext &deviceContext)
Configura los backends de ImGui para Win32 y Direct3D 11.
Definition GUI.cpp:193
void drawRenderDebugPanel(ID3D11ShaderResourceView *preShadowSRV, ID3D11ShaderResourceView *finalViewportSRV, ID3D11ShaderResourceView *shadowMapSRV)
Definition GUI.cpp:1257
void update(Viewport &viewport, Window &window)
Actualiza el frame de ImGui y el estado de la ventana del editor.
Definition GUI.cpp:224
void drawViewportPanel(ID3D11ShaderResourceView *viewportSRV)
Definition GUI.cpp:1203
void vec3Control(const std::string &label, float *values, float resetValues=0.0f, float columnWidth=100.0f, bool displayAsDegrees=false)
Definition GUI.cpp:267
ImVec2 m_viewportSize
Tamano actual del viewport del editor.
Definition GUI.h:141
void outliner(const std::vector< EU::TSharedPointer< Actor > > &actors)
Definition GUI.cpp:733
void render()
Renderiza todos los paneles activos del editor.
Definition GUI.cpp:246
LayoutBuilder & Add(const char *semantic, DXGI_FORMAT format, UINT semanticIndex=0, UINT inputSlot=0, UINT alignedByteOffset=D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_CLASSIFICATION slotClass=D3D11_INPUT_PER_VERTEX_DATA, UINT instanceStepRate=0)
Agrupa un material base con sus texturas y parametros concretos.
void setNormal(Texture *texture)
void setMaterial(Material *material)
void setEmissive(Texture *texture)
Material * getMaterial() const
void setRoughness(Texture *texture)
void setAlbedo(Texture *texture)
void setAO(Texture *texture)
void setMetallic(Texture *texture)
MaterialParams & getParams()
Describe el estado fijo compartido por una o mas instancias de material.
Definition Material.h:23
void setSamplerState(SamplerState *state)
Definition Material.h:28
void setDomain(MaterialDomain domain)
Definition Material.h:29
void setShader(ShaderProgram *shader)
Definition Material.h:25
BlendMode getBlendMode() const
Definition Material.h:37
void setBlendMode(BlendMode blendMode)
Definition Material.h:30
void setRasterizerState(RasterizerState *state)
Definition Material.h:26
MaterialDomain getDomain() const
Definition Material.h:36
void setDepthStencilState(DepthStencilState *state)
Definition Material.h:27
Componente ECS que almacena la información de geometría (malla) de un actor.
void destroy()
Libera todos los buffers asociados a las submallas.
Definition Mesh.h:37
std::vector< Submesh > & getSubmeshes()
Definition Mesh.h:30
const std::vector< MeshComponent > & GetMeshes() const
Definition Model3D.h:52
bool load(const std::string &path) override
Definition Model3D.cpp:67
void destroy()
Libera el recurso ID3D11RasterizerState.
HRESULT init(Device device)
Inicializa el Rasterizer State.
Skybox * skybox
Skybox activo para el frame actual.
Definition RenderScene.h:31
void clear()
Limpia todas las colecciones para preparar un nuevo frame.
void destroy()
Libera el recurso ID3D11RenderTargetView.
HRESULT init(Device &device, Texture &backBuffer, DXGI_FORMAT Format)
Inicializa el Render Target View desde el back buffer.
void render(DeviceContext &deviceContext, DepthStencilView &depthStencilView, unsigned int numViews, const float ClearColor[4])
Limpia y asigna el RTV junto con un Depth Stencil View.
HRESULT init(Device &device)
Inicializa el Sampler State con una configuración predeterminada.
void destroy()
Libera el recurso ID3D11SamplerState.
void gatherRenderScene(RenderScene &outScene, const Camera &camera)
void destroy()
void init()
void addEntity(Entity *e)
Registra una entidad dentro del grafo.
void update(float deltaTime, DeviceContext &deviceContext)
HRESULT init(Device &device, const std::string &fileName, LayoutBuilder layoutBuilder)
Inicializa el programa de shaders desde un archivo HLSL.
void destroy()
Libera todos los recursos asociados (shaders, blobs e input layout).
HRESULT init(Device &device, DeviceContext *deviceContext, Texture &cubemap)
Definition Skybox.cpp:13
void update(DeviceContext &deviceContext, Camera &camera)
Definition Skybox.cpp:107
HRESULT init(Device &device, DeviceContext &deviceContext, Texture &backBuffer, Window window)
Inicializa el Swap Chain y obtiene el back buffer.
Definition SwapChain.cpp:13
void present()
Presenta el back buffer en pantalla.
IDXGISwapChain * m_swapChain
Objeto principal del Swap Chain en Direct3D 11.
Definition SwapChain.h:111
void destroy()
Libera todos los recursos asociados al Swap Chain.
D3D_DRIVER_TYPE m_driverType
Tipo de driver utilizado (hardware, referencia, software, etc.).
Definition SwapChain.h:116
HRESULT resizeBuffers(unsigned int width, unsigned int height)
HRESULT getBackBuffer(Texture &backBuffer)
HRESULT init(Device &device, const std::string &textureName, ExtensionType extensionType)
Inicializa una textura cargada desde archivo.
Definition Texture.cpp:182
void destroy()
Libera los recursos de la textura.
Definition Texture.cpp:327
HRESULT CreateCubemap(Device &device, DeviceContext &deviceContext, const std::array< std::string, 6 > &facePaths, bool generateMips)
Definition Texture.cpp:337
ID3D11ShaderResourceView * m_textureFromImg
Vista de la textura como recurso de shader.
Definition Texture.h:170
void render(DeviceContext &deviceContext)
Aplica el viewport al contexto de dispositivo.
Definition Viewport.cpp:48
HRESULT init(const Window &window)
Inicializa el viewport a partir de una ventana.
Definition Viewport.cpp:11
HRESULT init(HINSTANCE hInstance, int nCmdShow, WNDPROC wndproc, BaseApp *app)
Crea y muestra la ventana principal del motor.
Definition Window.cpp:11
unsigned int m_width
Ancho actual del area cliente.
Definition Window.h:47
unsigned int m_height
Alto actual del area cliente.
Definition Window.h:48
EU::Vector3 LightDir
XMFLOAT4X4 View
EU::Vector3 LightColor
EU::Vector3 CameraPos
XMFLOAT4X4 Projection
float emissiveStrength
Definition RenderTypes.h:63
XMFLOAT4 baseColor
Definition RenderTypes.h:58
Describe una porcion renderizable de una malla con sus buffers asociados.
Definition Mesh.h:15
Buffer vertexBuffer
Buffer de vertices de la submalla.
Definition Mesh.h:16