diff --git a/imgui_sdl_simple_example/imgui_sdl_simple_example/imgui_sdl_simple_example.vcxproj b/imgui_sdl_simple_example/imgui_sdl_simple_example/imgui_sdl_simple_example.vcxproj
index b4102e4..d710420 100644
--- a/imgui_sdl_simple_example/imgui_sdl_simple_example/imgui_sdl_simple_example.vcxproj
+++ b/imgui_sdl_simple_example/imgui_sdl_simple_example/imgui_sdl_simple_example.vcxproj
@@ -107,6 +107,7 @@
_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
..\..\sdl2_simple_example\sdl2_simple_example\
+ stdcpp20
Console
diff --git a/sdl2_simple_example/sdl2_simple_example/Config.cpp b/sdl2_simple_example/sdl2_simple_example/Config.cpp
new file mode 100644
index 0000000..b605b48
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Config.cpp
@@ -0,0 +1,103 @@
+#include "Config.h"
+
+
+Config::Config(MyWindow* window) : _myWindow(window) {}
+Config::~Config() {}
+
+void Config::draw(SDL_Window* _window, Renderer renderer, float fps) {
+ ImGui::Begin("Config");
+ ImGui::Text("Configuracion general del sistema");
+
+ // Sección de resolución de pantalla
+ ImGui::Text("Resolución de pantalla:");
+
+ struct ResolutionItem {
+ ivec2 resolution;
+ std::string name;
+ };
+
+ std::vector resolutions = {
+ { {800, 600}, "800 x 600" },
+ { {1024, 768}, "1024 x 768" },
+ { {1280, 720}, "1280 x 720" },
+ { {1360, 768}, "1360 x 768" },
+ { {1366, 768}, "1366 x 768" },
+ { {1440, 900}, "1440 x 900" },
+ { {1600, 900}, "1600 x 900" },
+ { {1920, 1080}, "1920 x 1080" }
+ };
+
+ static int selectedResolutionIndex = 0;
+ if (ImGui::Combo("Resolucion", &selectedResolutionIndex, [](void* data, int idx, const char** out_text) {
+ const std::vector* resolutions = static_cast*>(data);
+ *out_text = resolutions->at(idx).name.c_str(); // Return resolution name
+ return true;
+ }, (void*)&resolutions, resolutions.size())) {
+ selectedResolution = resolutions[selectedResolutionIndex].resolution;
+
+ // Update window size
+ SDL_SetWindowSize(_window, selectedResolution.x, selectedResolution.y);
+
+ // Ensure we apply the new projection and viewport
+ if (!isFullscreen) {
+ renderer.applyProjectionAndViewport(selectedResolution); // Aplica la resolución seleccionada
+ }
+ }
+
+ // Sección de pantalla completa
+ if (ImGui::Checkbox("Pantalla completa", &isFullscreen)) {
+ if (isFullscreen) {
+ SDL_SetWindowFullscreen(_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
+ _myWindow->logMessage("Pantalla completa activada.");
+ }
+ else {
+ SDL_SetWindowFullscreen(_window, 0); // 0 means windowed mode
+ _myWindow->logMessage("Pantalla completa desactivada.");
+ }
+
+ // Get the current window size dynamically after changing fullscreen mode
+ int windowWidth, windowHeight;
+ SDL_GetWindowSize(_window, &windowWidth, &windowHeight);
+
+ // Apply the new window size for projection and viewport
+ renderer.applyProjectionAndViewport(ivec2(windowWidth, windowHeight));
+ }
+
+ ImGui::Text("Grafico FPS");
+ static float values[90] = {};
+ static int values_offset = 0;
+ values[values_offset] = fps; // Ejemplo fijo de FPS
+ values_offset = (values_offset + 1) % 90;
+ char fpsText[16];
+ sprintf_s(fpsText, "%d fps", static_cast(fps));
+ ImGui::PlotLines("FPS", values, IM_ARRAYSIZE(values), values_offset, fpsText, 0.0f, 100.0f, ImVec2(0, 80));
+
+ ImGui::Text("Consumo de Memoria: ");
+ try {
+ MemoryInfo memInfo = MemoryUsage::getMemoryInfo();
+ ImGui::Separator();
+ ImGui::Text("Consumo de Memoria:");
+ ImGui::Text("Memoria Total: %llu MB", memInfo.totalMemory);
+ ImGui::Text("Memoria Libre: %llu MB", memInfo.freeMemory);
+ ImGui::Text("Memoria Usada: %llu MB", memInfo.usedMemory);
+ static float totalMemoryValues[90];
+ static float freeMemoryValues[90];
+ static float usedMemoryValues[90];
+ static int memValuesOffset = 0;
+
+ totalMemoryValues[memValuesOffset] = memInfo.totalMemory;
+ freeMemoryValues[memValuesOffset] = memInfo.freeMemory;
+ usedMemoryValues[memValuesOffset] = memInfo.usedMemory;
+ memValuesOffset = (values_offset + 1) % 90;
+
+ ImGui::PlotLines("TotalMem", totalMemoryValues, IM_ARRAYSIZE(totalMemoryValues), memValuesOffset, "TotalMem", 0.0f, 100.0f, ImVec2(0, 80));
+ ImGui::PlotLines("freeMem", freeMemoryValues, IM_ARRAYSIZE(freeMemoryValues), memValuesOffset, "FreeMem", 0.0f, 100.0f, ImVec2(0, 80));
+ ImGui::PlotLines("UsedMem", usedMemoryValues, IM_ARRAYSIZE(usedMemoryValues), memValuesOffset, "UsedMem", 0.0f, 100.0f, ImVec2(0, 80));
+ }
+ catch (const std::exception& e) {
+ ImGui::Text("Error obteniendo memoria: %s", e.what());
+ }
+ ImGui::Text("Deteccion de maquinaria i versions de programario:");
+ ImGui::Text("SDL, OpenGL, DevIL");
+ ImGui::End();
+}
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Config.h b/sdl2_simple_example/sdl2_simple_example/Config.h
new file mode 100644
index 0000000..f7d3d01
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Config.h
@@ -0,0 +1,25 @@
+#pragma once
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include
+#include
+#include
+#include "MyWindow.h"
+#include "MemoryUsage.h"
+
+
+class Config {
+public:
+ Config(MyWindow* window);
+ ~Config();
+
+ void draw(SDL_Window* _window, Renderer renderer, float fps);
+private:
+ MyWindow* _myWindow;
+ glm::ivec2 selectedResolution;
+ bool isFullscreen = false;
+};
+
+
+#endif // CONFIG_H
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Consola.cpp b/sdl2_simple_example/sdl2_simple_example/Consola.cpp
new file mode 100644
index 0000000..ff96704
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Consola.cpp
@@ -0,0 +1,12 @@
+#include "Consola.h"
+
+Consola::Consola(){}
+Consola::~Consola(){}
+
+void Consola::draw(std::vector logMessage) {
+ ImGui::Begin("Consola");
+ for (const auto& msg : logMessage) {
+ ImGui::Text("%s", msg.c_str());
+ }
+ ImGui::End();
+}
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Consola.h b/sdl2_simple_example/sdl2_simple_example/Consola.h
new file mode 100644
index 0000000..73f490c
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Consola.h
@@ -0,0 +1,19 @@
+#pragma once
+#ifndef CONSOLA_H
+#define CONSOLA_H
+
+#include
+#include
+#include
+
+class Consola {
+public:
+ Consola();
+ ~Consola();
+
+ static void draw(std::vector logMessage);
+private:
+
+};
+
+#endif // CONSOLA_H
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/CustomFormatUtils.h b/sdl2_simple_example/sdl2_simple_example/CustomFormatUtils.h
new file mode 100644
index 0000000..1c4c78a
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/CustomFormatUtils.h
@@ -0,0 +1,42 @@
+#pragma once
+#include
+#include
+#include
+
+void saveCustomFormat(const std::string& path, const std::vector& vertices, const std::vector& uvs, const std::vector& indices) {
+ std::ofstream file(path, std::ios::binary);
+
+ size_t vertexCount = vertices.size();
+ size_t uvCount = uvs.size();
+ size_t indexCount = indices.size();
+
+ file.write(reinterpret_cast(&vertexCount), sizeof(size_t));
+ file.write(reinterpret_cast(vertices.data()), vertices.size() * sizeof(float));
+
+ file.write(reinterpret_cast(&uvCount), sizeof(size_t));
+ file.write(reinterpret_cast(uvs.data()), uvs.size() * sizeof(float));
+
+ file.write(reinterpret_cast(&indexCount), sizeof(size_t));
+ file.write(reinterpret_cast(indices.data()), indices.size() * sizeof(unsigned int));
+
+ file.close();
+}
+
+void loadCustomFormat(const std::string& path, std::vector& vertices, std::vector& uvs, std::vector& indices) {
+ std::ifstream file(path, std::ios::binary);
+
+ size_t vertexCount, uvCount, indexCount;
+ file.read(reinterpret_cast(&vertexCount), sizeof(size_t));
+ vertices.resize(vertexCount);
+ file.read(reinterpret_cast(vertices.data()), vertexCount * sizeof(float));
+
+ file.read(reinterpret_cast(&uvCount), sizeof(size_t));
+ uvs.resize(uvCount);
+ file.read(reinterpret_cast(uvs.data()), uvCount * sizeof(float));
+
+ file.read(reinterpret_cast(&indexCount), sizeof(size_t));
+ indices.resize(indexCount);
+ file.read(reinterpret_cast(indices.data()), indexCount * sizeof(unsigned int));
+
+ file.close();
+}
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Escena.cpp b/sdl2_simple_example/sdl2_simple_example/Escena.cpp
new file mode 100644
index 0000000..4bbccc4
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Escena.cpp
@@ -0,0 +1,24 @@
+#include "Escena.h"
+
+extern Renderer renderer;
+
+Escena::Escena(){}
+Escena::~Escena(){}
+
+void Escena::draw(GLuint textureColorbuffer) {
+ ImGui::Begin("Scene");
+ if (textureColorbuffer) {
+
+ ImGui::Image((void*)(intptr_t)textureColorbuffer, ImVec2(renderer._WINDOW_SIZE.x, renderer._WINDOW_SIZE.y));
+
+ if (ImGui::BeginDragDropTarget()) {
+ if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("FILE_PATH")) {
+ const char* filePath = (const char*)payload->Data;
+
+ handleFileDrop(filePath); // Procesar archivo arrastrado
+ }
+ ImGui::EndDragDropTarget();
+ }
+ }
+ ImGui::End();
+}
diff --git a/sdl2_simple_example/sdl2_simple_example/Escena.h b/sdl2_simple_example/sdl2_simple_example/Escena.h
new file mode 100644
index 0000000..0f4fd72
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Escena.h
@@ -0,0 +1,18 @@
+#pragma once
+#ifndef ESCENA_H
+#define ESCENA_H
+
+#include
+#include "MyWindow.h"
+
+
+class Escena {
+public:
+ Escena();
+ ~Escena();
+ static void draw(GLuint texturecolorbuffer);
+private:
+
+};
+
+#endif // ESCENA_H
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/FileExplorer.cpp b/sdl2_simple_example/sdl2_simple_example/FileExplorer.cpp
new file mode 100644
index 0000000..022bbd9
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/FileExplorer.cpp
@@ -0,0 +1,111 @@
+#include "FileExplorer.h"
+
+Explorer::Explorer(){}
+Explorer::~Explorer(){}
+
+
+void Explorer::UpdateDirectoryContents() {
+ try {
+ directoryContents.clear();
+
+ if (fs::exists(currentDirectory) && fs::is_directory(currentDirectory)) {
+ for (const auto& entry : fs::directory_iterator(currentDirectory)) {
+ directoryContents.push_back(entry.path().string());
+ }
+ // Asegurarnos de que el índice seleccionado sea válido
+ if (selectedFileIndex >= directoryContents.size()) {
+ selectedFileIndex = -1;
+ }
+ }
+ }
+ catch (const fs::filesystem_error& e) {
+ std::cerr << "Error listing directory: " << e.what() << std::endl;
+ selectedFileIndex = -1;
+ }
+}
+void Explorer::deleteSelectedFile() {
+ if (selectedFileIndex < 0 || selectedFileIndex >= directoryContents.size()) {
+ return;
+ }
+
+ try {
+ std::string filePath = directoryContents[selectedFileIndex];
+ if (!fs::is_directory(filePath) && fs::exists(filePath)) {
+ if (fs::remove(filePath)) {
+ selectedFileIndex = -1;
+ UpdateDirectoryContents();
+ }
+ }
+ }
+ catch (const fs::filesystem_error& e) {
+ std::cerr << "Error deleting file: " << e.what() << std::endl;
+ }
+}
+void Explorer::draw() {
+ ImGui::Begin("File Explorer");
+
+ // Mostrar directorio actual
+ ImGui::Text("Current Directory: %s", currentDirectory.c_str());
+
+ // Botón para subir un nivel
+ if (ImGui::Button(".. (Go Up)")) {
+ try {
+ fs::path parent = fs::path(currentDirectory).parent_path();
+ if (fs::exists(parent)) {
+ currentDirectory = parent.string();
+ selectedFileIndex = -1; // Reset selection when changing directory
+ UpdateDirectoryContents();
+ }
+ }
+ catch (const fs::filesystem_error& e) {
+ std::cerr << "Error accessing parent directory: " << e.what() << std::endl;
+ }
+ }
+
+ // Lista de archivos y directorios
+ ImGui::BeginChild("Files", ImVec2(0, -30), true);
+ for (size_t i = 0; i < directoryContents.size(); ++i) {
+ try {
+ fs::path entry(directoryContents[i]);
+ if (!fs::exists(entry)) continue; // Skip if file no longer exists
+
+ std::string displayName = FileSystemUtils::getFileName(entry.string());
+ bool isSelected = (i == selectedFileIndex);
+
+ if (fs::is_directory(entry)) {
+ // Directorios como botones
+ if (ImGui::Button(displayName.c_str())) {
+ currentDirectory = entry.string();
+ selectedFileIndex = -1;
+ UpdateDirectoryContents();
+ }
+ }
+ else {
+ // Archivos como seleccionables
+ if (ImGui::Selectable(displayName.c_str(), isSelected)) {
+ selectedFileIndex = i;
+ }
+
+ // Drag & Drop solo para archivos
+ if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
+ const char* filePath = entry.string().c_str();
+ ImGui::SetDragDropPayload("FILE_PATH", filePath, strlen(filePath) + 1);
+ ImGui::Text("Dragging: %s", displayName.c_str());
+ ImGui::EndDragDropSource();
+ }
+ }
+ }
+ catch (const fs::filesystem_error& e) {
+ std::cerr << "Error processing file: " << e.what() << std::endl;
+ }
+ }
+ ImGui::EndChild();
+
+ // Manejar borrado con tecla Delete
+ if (ImGui::IsKeyPressed(ImGuiKey_Delete) && selectedFileIndex >= 0) {
+ deleteSelectedFile();
+ }
+
+ ImGui::End();
+}
+
diff --git a/sdl2_simple_example/sdl2_simple_example/FileExplorer.h b/sdl2_simple_example/sdl2_simple_example/FileExplorer.h
new file mode 100644
index 0000000..46dcc92
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/FileExplorer.h
@@ -0,0 +1,40 @@
+#pragma once
+#ifndef FILEEXPLORER_H
+#define FILEEXPLORER_H
+
+#include
+#include "MyWindow.h"
+#include "FilesystemUtils.h"
+#include
+#include
+
+class Explorer {
+public:
+ //MyWindow* window
+ Explorer();
+ ~Explorer();
+
+ void draw();
+ void UpdateDirectoryContents();
+
+
+ int getSelectedFileIndex() const { return selectedFileIndex; }
+ std::string getSelectedFilePath() const {
+ return selectedFileIndex >= 0 && selectedFileIndex < directoryContents.size()
+ ? directoryContents[selectedFileIndex]
+ : "";
+ }
+private:
+ //MyWindow* _myWindow;
+ glm::ivec2 selectedResolution;
+ bool isFullscreen = false;
+
+ std::string currentDirectory = "Library/Meshes";
+ std::vector directoryContents;
+ int selectedFileIndex = -1;
+
+ void deleteSelectedFile();
+};
+
+
+#endif // FILEEXPLORER_H
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/FilesystemUtils.h b/sdl2_simple_example/sdl2_simple_example/FilesystemUtils.h
new file mode 100644
index 0000000..56a9cef
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/FilesystemUtils.h
@@ -0,0 +1,69 @@
+#pragma once
+
+#include
+#include
+
+namespace fs = std::filesystem;
+
+class FileSystemUtils {
+public:
+ // Crear directorios necesarios
+ static void GenerateRequiredDirectories() {
+ const std::vector dirs = {
+ "Assets",
+ "Library/Meshes",
+ "Library/Materials",
+ "Library/Models",
+ "Library/Textures"
+ };
+
+ for (const auto& dir : dirs) {
+ try {
+ if (!fs::exists(dir)) {
+ fs::create_directories(dir);
+ }
+ }
+ catch (const fs::filesystem_error& e) {
+ std::cerr << "Error al crear directorio " << dir << ": " << e.what() << std::endl;
+ }
+ }
+ }
+
+ // Obtener nombre del archivo a partir de su ruta
+ static std::string getFileName(const std::string& filePath) {
+ try {
+ return fs::path(filePath).filename().string();
+ }
+ catch (const fs::filesystem_error& e) {
+ std::cerr << "Error al obtener el nombre del archivo: " << e.what() << std::endl;
+ return "";
+ }
+ }
+
+ // Listar todos los archivos y carpetas dentro de un directorio
+ static std::vector ListDirectory(const std::string& directoryPath) {
+ std::vector entries;
+ try {
+ if (fs::exists(directoryPath) && fs::is_directory(directoryPath)) {
+ for (const auto& entry : fs::directory_iterator(directoryPath)) {
+ entries.push_back(entry.path().generic_string());
+ }
+ }
+ }
+ catch (const fs::filesystem_error& e) {
+ std::cerr << "Error al listar el directorio " << directoryPath << ": " << e.what() << std::endl;
+ }
+ return entries;
+ }
+
+ // Verificar si un archivo existe
+ static bool FileExists(const std::string& filePath) {
+ try {
+ return fs::exists(filePath);
+ }
+ catch (const fs::filesystem_error& e) {
+ std::cerr << "Error al verificar existencia de archivo: " << e.what() << std::endl;
+ return false;
+ }
+ }
+};
diff --git a/sdl2_simple_example/sdl2_simple_example/GameObject.cpp b/sdl2_simple_example/sdl2_simple_example/GameObject.cpp
new file mode 100644
index 0000000..fae217b
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/GameObject.cpp
@@ -0,0 +1,152 @@
+#include "GameObject.h"
+#include
+#include
+#include
+
+GameObject::GameObject(Mesh* mesh, TextureData* texture)
+ : mesh(mesh), texture(texture), parent(nullptr) {}
+
+GameObject::~GameObject() {
+ // Desvinculamos todos los hijos antes de destruir el objeto
+ for (auto* child : children) {
+ child->parent = nullptr;
+ }
+
+ // Si tenemos un padre, nos removemos de su lista de hijos
+ if (parent) {
+ parent->removeChild(this);
+ }
+ delete mesh;
+ if (texture) delete texture;
+}
+
+void GameObject::setTexture(TextureData* newTexture) {
+ texture = newTexture;
+}
+
+
+void GameObject::setTransform(const Transform& newTransform) {
+ transform = newTransform;
+}
+bool GameObject::isChildOf(GameObject* potentialParent) const {
+ if (!potentialParent) return false;
+
+ GameObject* current = parent;
+ while (current) {
+ if (current == potentialParent) return true;
+ current = current->getParent();
+ }
+ return false;
+}
+void GameObject::setParent(GameObject* newParent) {
+ // Si ya teníamos un padre, nos removemos de su lista de hijos
+ if (parent) {
+ parent->removeChild(this);
+ }
+
+ parent = newParent;
+
+ // Nos agregamos a la lista de hijos del nuevo padre
+ if (parent) {
+ parent->addChild(this);
+ }
+}
+
+void GameObject::addChild(GameObject* child) {
+ if (child && std::find(children.begin(), children.end(), child) == children.end()) {
+ children.push_back(child);
+ if (child->parent != this) {
+ child->setParent(this);
+ }
+ }
+}
+
+void GameObject::removeChild(GameObject* child) {
+ auto it = std::find(children.begin(), children.end(), child);
+ if (it != children.end()) {
+ children.erase(it);
+ if (child->parent == this) {
+ child->parent = nullptr;
+ }
+ }
+}
+
+Transform GameObject::getGlobalTransform() const {
+ glm::mat4 localMatrix = glm::mat4(1.0f);
+ localMatrix = glm::translate(localMatrix, glm::vec3(transform.position.x, transform.position.y, transform.position.z));
+ localMatrix = glm::rotate(localMatrix, glm::radians(transform.rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
+ localMatrix = glm::rotate(localMatrix, glm::radians(transform.rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
+ localMatrix = glm::rotate(localMatrix, glm::radians(transform.rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
+ localMatrix = glm::scale(localMatrix, glm::vec3(transform.scale.x, transform.scale.y, transform.scale.z));
+
+ // Multiply with parent's matrix if exists
+ if (parent) {
+ glm::mat4 parentMatrix = glm::mat4(1.0f);
+ Transform parentTransform = parent->getGlobalTransform();
+ parentMatrix = glm::translate(parentMatrix, glm::vec3(parentTransform.position.x, parentTransform.position.y, parentTransform.position.z));
+ parentMatrix = glm::rotate(parentMatrix, glm::radians(parentTransform.rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
+ parentMatrix = glm::rotate(parentMatrix, glm::radians(parentTransform.rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
+ parentMatrix = glm::rotate(parentMatrix, glm::radians(parentTransform.rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
+ parentMatrix = glm::scale(parentMatrix, glm::vec3(parentTransform.scale.x, parentTransform.scale.y, parentTransform.scale.z));
+
+ localMatrix = parentMatrix * localMatrix;
+ }
+
+ Transform globalTransform;
+
+ // Extract position
+ glm::vec3 position = glm::vec3(localMatrix[3]);
+ globalTransform.position.x = position.x;
+ globalTransform.position.y = position.y;
+ globalTransform.position.z = position.z;
+
+ // Extract rotation
+ glm::vec3 rotation;
+ rotation.x = glm::degrees(atan2(localMatrix[1][2], localMatrix[2][2]));
+ rotation.y = glm::degrees(asin(-localMatrix[0][2]));
+ rotation.z = glm::degrees(atan2(localMatrix[0][1], localMatrix[0][0]));
+ globalTransform.rotation.x = rotation.x;
+ globalTransform.rotation.y = rotation.y;
+ globalTransform.rotation.z = rotation.z;
+
+ // Extract scale
+ globalTransform.scale.x = glm::length(glm::vec3(localMatrix[0]));
+ globalTransform.scale.y = glm::length(glm::vec3(localMatrix[1]));
+ globalTransform.scale.z = glm::length(glm::vec3(localMatrix[2]));
+
+ return globalTransform;
+}
+
+void GameObject::draw() const {
+ glPushMatrix(); // Save the current matrix
+
+ Transform globalTransform = getGlobalTransform();
+ // Apply transformations based on the GameObject's transform
+ glTranslatef(globalTransform.position.x, globalTransform.position.y, globalTransform.position.z);
+ glRotatef(globalTransform.rotation.x, 1.0f, 0.0f, 0.0f);
+ glRotatef(globalTransform.rotation.y, 0.0f, 1.0f, 0.0f);
+ glRotatef(globalTransform.rotation.z, 0.0f, 0.0f, 1.0f);
+ glScalef(globalTransform.scale.x, globalTransform.scale.y, globalTransform.scale.z);
+
+ // Enable textures if there is a texture bound
+ if (texture) {
+ glEnable(GL_TEXTURE_2D);
+ texture->bind(); // Bind the object's texture
+ }
+ else {
+ glDisable(GL_TEXTURE_2D); // Disable if no texture
+ }
+
+ if (mesh) mesh->render(); // Render the mesh
+
+ // Unbind and disable texture after rendering to prevent interference with other objects
+ if (texture) {
+ texture->unbind();
+ glDisable(GL_TEXTURE_2D);
+ }
+ // Dibujar todos los hijos
+ for (const auto* child : children) {
+ child->draw();
+ }
+ glPopMatrix(); // Restore the previous matrix
+}
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/GameObject.h b/sdl2_simple_example/sdl2_simple_example/GameObject.h
new file mode 100644
index 0000000..e0af0fb
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/GameObject.h
@@ -0,0 +1,32 @@
+#pragma once
+#include "Mesh.h"
+#include "Texture.h"
+#include "Transform.h"
+#include
+
+class GameObject {
+public:
+ GameObject(Mesh* mesh, TextureData* texture);
+ ~GameObject();
+
+ void draw() const;
+ void setTexture(TextureData* texture);
+ void setParent(GameObject* newParent);
+ void addChild(GameObject* child);
+ void removeChild(GameObject* child);
+
+ Transform getGlobalTransform() const;
+ void setTransform(const Transform& newTransform);
+ bool isChildOf(GameObject* potentialParent) const;
+
+ TextureData* getTexture() const { return texture; }
+ Mesh* getMesh() const { return mesh; }
+ GameObject* getParent() const { return parent; }
+ const std::vector& getChildren() const { return children; }
+
+ Mesh* mesh;
+ TextureData* texture;
+ Transform transform;
+ GameObject* parent;
+ std::vector children;
+};
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Importer.cpp b/sdl2_simple_example/sdl2_simple_example/Importer.cpp
new file mode 100644
index 0000000..00eb440
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Importer.cpp
@@ -0,0 +1,182 @@
+#include "Importer.h"
+#include "Texture.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using vec3 = glm::dvec3;
+
+float modelScale = 1.0f; // Global scaling factor for the model
+vec3 modelCenter(0.0f); // Model center for positioning
+
+Importer::Importer() {
+ ilInit();
+ iluInit();
+ ilutRenderer(ILUT_OPENGL);
+}
+
+Importer::~Importer() {
+ if (textureID) {
+ glDeleteTextures(1, &textureID);
+ }
+}
+
+void Importer::setWindow(MyWindow* window) {
+ _window = window;
+}
+
+void centerModel(const aiScene* scene) {
+ if (scene->mNumMeshes == 0) return;
+
+ aiVector3D minimo(FLT_MAX, FLT_MAX, FLT_MAX);
+ aiVector3D maximo(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+
+ for (unsigned int i = 0; i < scene->mNumMeshes; i++) {
+ for (unsigned int v = 0; v < scene->mMeshes[i]->mNumVertices; v++) {
+ aiVector3D vertex = scene->mMeshes[i]->mVertices[v];
+ minimo.x = min(minimo.x, vertex.x);
+ minimo.y = min(minimo.y, vertex.y);
+ minimo.z = min(minimo.z, vertex.z);
+ maximo.x = max(maximo.x, vertex.x);
+ maximo.y = max(maximo.y, vertex.y);
+ maximo.z = max(maximo.z, vertex.z);
+ }
+ }
+
+ modelCenter = vec3((minimo.x + maximo.x) / 2, (minimo.y + maximo.y) / 2, (minimo.z + maximo.z) / 2);
+ modelScale = 2.0f / glm::length(vec3(maximo.x - minimo.x, maximo.y - minimo.y, maximo.z - minimo.z));
+}
+
+// Dentro de la clase Importer, agrega un método para crear una textura checker
+GLuint Importer::GenerateCheckerTexture() {
+ const int width = 64;
+ const int height = 64;
+ std::vector checkerImage(width * height * 4);
+
+ // Generar el patrón checker
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ int c = ((x / 8) % 2) == ((y / 8) % 2) ? 255 : 0;
+ checkerImage[(y * width + x) * 4 + 0] = (GLubyte)c;
+ checkerImage[(y * width + x) * 4 + 1] = (GLubyte)c;
+ checkerImage[(y * width + x) * 4 + 2] = (GLubyte)c;
+ checkerImage[(y * width + x) * 4 + 3] = 255; // Alpha
+ }
+ }
+
+ static GLuint checkerTexture = 2;
+ glBindTexture(GL_TEXTURE_2D, checkerTexture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkerImage.data());
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ return checkerTexture;
+}
+
+bool Importer::loadFBX(const std::string& filePath) {
+ _window->logMessage("Attempting to load FBX file: " + filePath); // Log de carga
+
+ Assimp::Importer importer;
+ const aiScene* scene = importer.ReadFile(filePath, aiProcess_Triangulate | aiProcess_GenUVCoords | aiProcess_CalcTangentSpace);
+
+ if (!scene) {
+ _window->logMessage("Error loading FBX: " + std::string(importer.GetErrorString()));
+ return false;
+ }
+
+ _window->logMessage("Successfully loaded FBX file: " + filePath);
+ _window->logMessage("Total meshes in scene: " + std::to_string(scene->mNumMeshes));
+
+ // Centrado y escalado del modelo
+ centerModel(scene);
+
+ // Limpiar los contenedores para evitar que se mezclen datos de diferentes cargas
+ vertices.clear();
+ uvs.clear();
+ indices.clear();
+
+ // Procesar cada malla en el archivo FBX
+ for (unsigned int i = 0; i < scene->mNumMeshes; i++) {
+ aiMesh* mesh = scene->mMeshes[i];
+ _window->logMessage("Processing mesh: " + std::to_string(i) + " with " +
+ std::to_string(mesh->mNumVertices) + " vertices and " +
+ std::to_string(mesh->mNumFaces) + " faces.");
+
+ unsigned int baseVertex = vertices.size() / 3; // Offset para los índices de cada malla
+
+ // Añadir vértices y coordenadas UV de la malla actual
+ for (unsigned int v = 0; v < mesh->mNumVertices; v++) {
+ aiVector3D vertex = mesh->mVertices[v];
+ vertices.push_back(vertex.x);
+ vertices.push_back(vertex.y);
+ vertices.push_back(vertex.z);
+
+ if (mesh->HasTextureCoords(0)) {
+ aiVector3D texCoord = mesh->mTextureCoords[0][v];
+ uvs.push_back(texCoord.x);
+ uvs.push_back(1.0f - texCoord.y);
+ }
+ else {
+ uvs.push_back(0.0f);
+ uvs.push_back(0.0f);
+ }
+ }
+
+ // Añadir índices de la malla actual
+ for (unsigned int f = 0; f < mesh->mNumFaces; f++) {
+ aiFace face = mesh->mFaces[f];
+ for (unsigned int j = 0; j < face.mNumIndices; j++) {
+ indices.push_back(baseVertex + face.mIndices[j]); // Ajuste para índice base
+ }
+ }
+ }
+
+ return true;
+}
+
+TextureData* Importer::loadTexture(const std::string& texturePath) {
+ ILuint imageID;
+ ilGenImages(1, &imageID);
+ ilBindImage(imageID);
+
+ if (!ilLoadImage((const wchar_t*)texturePath.c_str())) { // Cambia a ilLoadImage((const wchar_t*)texturePath.c_str()) en Windows si necesitas soporte para rutas UTF-16
+ ilDeleteImages(1, &imageID);
+ std::cerr << "Failed to load texture from: " << texturePath << std::endl;
+ return 0; // Retorna 0 si falla la carga
+ }
+
+ // Convertir la imagen a formato RGBA para OpenGL
+ ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
+
+ // Obtener dimensiones
+ int width = ilGetInteger(IL_IMAGE_WIDTH);
+ int height = ilGetInteger(IL_IMAGE_HEIGHT);
+
+ GLuint textureID;
+ glGenTextures(1, &textureID);
+ glBindTexture(GL_TEXTURE_2D, textureID);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ilGetData());
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ ilDeleteImages(1, &imageID); // Limpia la imagen DevIL
+
+ // Retorna la textura cargada con ID, path, ancho y alto
+ TextureData* texture = new TextureData(textureID, texturePath, width, height);
+ return texture;
+}
+
+// Método para obtener la textura cargada o checker
+GLuint Importer::getTextureID() const {
+ return textureID;
+}
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Importer.h b/sdl2_simple_example/sdl2_simple_example/Importer.h
new file mode 100644
index 0000000..ae249d0
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Importer.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include
+#include
+#include
+#include "glm/glm.hpp"
+#include "MyWindow.h"
+#include "Texture.h"
+
+class Importer {
+public:
+ Importer();
+ ~Importer();
+
+ bool loadFBX(const std::string& filePath);
+ TextureData* loadTexture(const std::string& texturePath);
+ const std::vector& getVertices() const { return vertices; }
+ const std::vector& getUVs() const { return uvs; }
+ const std::vector& getIndices() const { return indices; }
+ GLuint getTextureID() { return textureID; }
+
+ GLuint GenerateCheckerTexture();
+ GLuint getTextureID() const;
+
+ void setWindow(MyWindow* window);
+
+private:
+ std::vector vertices;
+ std::vector uvs;
+ std::vector indices;
+ GLuint textureID = 0;
+
+ MyWindow* _window = nullptr;
+};
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Inspector.cpp b/sdl2_simple_example/sdl2_simple_example/Inspector.cpp
new file mode 100644
index 0000000..e401541
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Inspector.cpp
@@ -0,0 +1,112 @@
+#include "Inspector.h"
+
+extern Scene scene;
+
+Inspector::Inspector() {}
+Inspector::~Inspector() {}
+
+static TextureData* originalTexture = nullptr;
+
+void Inspector::draw() {
+ ImGui::Begin("Inspector");
+
+ if (scene.selectedGameObjectIndex >= 0 && scene.selectedGameObjectIndex < scene.gameObjects.size()) {
+ GameObject* selectedObject = scene.gameObjects[scene.selectedGameObjectIndex];
+ if (!selectedObject) {
+ ImGui::End();
+ return;
+ }
+
+ ImGui::Text("Texture");
+
+ // Safe texture handling
+ if (selectedObject->texture) {
+ if (selectedObject->texture->id != 2 && !originalTexture) {
+ originalTexture = selectedObject->texture;
+ }
+
+ if (ImGui::Button("Off")) {
+ if (!chekerOn && scene.checkerTextureID != 0) {
+ selectedObject->setTexture(new TextureData(scene.checkerTextureID));
+ chekerOn = true;
+ }
+ }
+ ImGui::SameLine();
+ if (ImGui::Button("On")) {
+ if (chekerOn && originalTexture) {
+ selectedObject->setTexture(originalTexture);
+ chekerOn = false;
+ }
+ }
+
+ // Display texture information
+ GLuint textureID = selectedObject->texture->getTextureID();
+ ImGui::Text("Texture ID: %u", textureID);
+
+ if (selectedObject->texture->getHeight() && selectedObject->texture->getWidth()) {
+ GLuint GetHeight = selectedObject->texture->getHeight();
+ GLuint GetWidth = selectedObject->texture->getWidth();
+ ImGui::Text("Texture Shape: %u x %u", GetHeight, GetWidth);
+ }
+ else {
+ ImGui::Text("Texture Shape: None");
+ }
+ ImGui::Text("Texture path: %s", selectedObject->texture->getPath().c_str());
+ }
+ else {
+ ImGui::Text("No texture assigned");
+ }
+
+ // Transform controls
+ float position[3] = { selectedObject->transform.position.x, selectedObject->transform.position.y, selectedObject->transform.position.z };
+ if (ImGui::InputFloat3("Posicion", position)) {
+ selectedObject->transform.position = { position[0], position[1], position[2] };
+ }
+
+ float rotation[3] = { selectedObject->transform.rotation.x, selectedObject->transform.rotation.y, selectedObject->transform.rotation.z };
+ if (ImGui::InputFloat3("Rotacion", rotation)) {
+ selectedObject->transform.rotation = { rotation[0], rotation[1], rotation[2] };
+ }
+
+ float scale[3] = { selectedObject->transform.scale.x, selectedObject->transform.scale.y, selectedObject->transform.scale.z };
+ if (ImGui::InputFloat3("Escala", scale)) {
+ selectedObject->transform.scale = { scale[0], scale[1], scale[2] };
+ }
+
+ // Mesh information
+ if (Mesh* mesh = selectedObject->getMesh()) {
+ const std::vector& vertices = mesh->getVertices();
+ const std::vector& uvs = mesh->getUVs();
+ const std::vector& indices = mesh->getIndices();
+
+ ImGui::Text("Informacion de la Malla:");
+ ImGui::Text("Vertices: %zu", vertices.size());
+ ImGui::Text("UVs: %zu", uvs.size());
+ ImGui::Text("Indices: %zu", indices.size());
+
+ ImGui::Separator();
+ ImGui::Text("Vista previa de vertices:");
+ for (size_t i = 0; i < std::min(vertices.size(), 9); i += 3) {
+ ImGui::Text("(%f, %f, %f)", vertices[i], vertices[i + 1], vertices[i + 2]);
+ }
+
+ ImGui::Text("Vista previa de UVs:");
+ for (size_t i = 0; i < std::min(uvs.size(), 6); i += 2) {
+ ImGui::Text("(%f, %f)", uvs[i], uvs[i + 1]);
+ }
+
+ ImGui::Text("Vista previa de indices:");
+ for (size_t i = 0; i < std::min(indices.size(), 9); i += 3) {
+ ImGui::Text("(%u, %u, %u)", indices[i], indices[i + 1], indices[i + 2]);
+ }
+ }
+ else {
+ ImGui::Text("Malla: Ninguna");
+ }
+ }
+ else {
+ ImGui::Text("Seleccione un GameObject de la jerarquia para ver sus propiedades.");
+ }
+
+ ImGui::End();
+}
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Inspector.h b/sdl2_simple_example/sdl2_simple_example/Inspector.h
new file mode 100644
index 0000000..e6c9c54
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Inspector.h
@@ -0,0 +1,19 @@
+#pragma once
+#ifndef INSPECTOR_H
+#define INSPECTOR_H
+
+#include "MyWindow.h"
+#include "imgui.h"
+
+class Inspector {
+public:
+ Inspector();
+ ~Inspector();
+ void draw();
+private:
+ bool chekerOn = false;
+ bool saved = false;
+
+};
+
+#endif // INSPECTOR_H
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Jerarquia.cpp b/sdl2_simple_example/sdl2_simple_example/Jerarquia.cpp
new file mode 100644
index 0000000..043b6e0
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Jerarquia.cpp
@@ -0,0 +1,106 @@
+#include "Jerarquia.h"
+
+extern Scene scene;
+
+Jerarquia::Jerarquia() {}
+Jerarquia::~Jerarquia() {}
+
+void Jerarquia::drawGameObjectNode(GameObject* obj, const std::string& name, int index) {
+ if (!obj) return;
+
+ ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
+
+ if (scene.selectedGameObjectIndex == index) {
+ flags |= ImGuiTreeNodeFlags_Selected;
+ }
+
+ if (obj->getChildren().empty()) {
+ flags |= ImGuiTreeNodeFlags_Leaf;
+ }
+
+ bool nodeOpen = ImGui::TreeNodeEx((name + "###" + std::to_string(index)).c_str(), flags);
+
+ if (ImGui::IsItemClicked()) {
+ scene.selectedGameObjectIndex = index;
+ }
+
+ // Handle delete with Delete key
+ if (scene.selectedGameObjectIndex == index && ImGui::IsKeyPressed(ImGuiKey_Delete)) {
+ scene.deleteGameObjectHierarchy(obj);
+ if (nodeOpen) ImGui::TreePop();
+ return;
+ }
+
+ if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
+ int draggedIndex = index;
+ ImGui::SetDragDropPayload("GAMEOBJECT_DND", &draggedIndex, sizeof(int));
+ ImGui::Text("Arrastrando: %s", name.c_str());
+ ImGui::EndDragDropSource();
+ }
+
+ if (ImGui::BeginDragDropTarget()) {
+ if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("GAMEOBJECT_DND")) {
+ int droppedIndex = *(const int*)payload->Data;
+ if (droppedIndex != index) {
+ if (scene.setParentChild(droppedIndex, index)) {
+ printf("Objeto %s ahora es hijo de %s\n",
+ scene.gameObjectNames[droppedIndex].c_str(),
+ scene.gameObjectNames[index].c_str());
+ }
+ }
+ }
+ ImGui::EndDragDropTarget();
+ }
+
+ if (nodeOpen) {
+ auto& children = obj->getChildren();
+ for (GameObject* child : children) {
+ auto it = std::find(scene.gameObjects.begin(), scene.gameObjects.end(), child);
+ if (it != scene.gameObjects.end()) {
+ int childIndex = std::distance(scene.gameObjects.begin(), it);
+ drawGameObjectNode(child, scene.gameObjectNames[childIndex], childIndex);
+ }
+ }
+ ImGui::TreePop();
+ }
+}
+
+void Jerarquia::draw() {
+ ImGui::Begin("Jerarquía");
+
+ // Add "Create Empty" button
+ if (ImGui::Button("Create Empty")) {
+ GameObject* emptyObj = new GameObject(nullptr, nullptr);
+ scene.gameObjects.push_back(emptyObj);
+ scene.gameObjectNames.push_back("Empty Object " + std::to_string(scene.gameObjects.size()));
+ }
+
+ ImGui::Text("Lista de GameObjects:");
+
+ ImGui::BeginChild("GameObjectList", ImVec2(0, -30), true);
+
+ for (size_t i = 0; i < scene.gameObjects.size(); ++i) {
+ GameObject* obj = scene.gameObjects[i];
+ if (!obj->getParent()) {
+ drawGameObjectNode(obj, scene.gameObjectNames[i], i);
+ }
+ }
+ ImGui::EndChild();
+
+ ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.15f, 0.15f, 0.15f, 1.0f));
+ ImGui::BeginChild("DropZone", ImVec2(0, 25), true);
+ ImGui::Text("Desvincular padre");
+
+ if (ImGui::BeginDragDropTarget()) {
+ if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("GAMEOBJECT_DND")) {
+ int droppedIndex = *(const int*)payload->Data;
+ scene.removeFromParent(droppedIndex);
+ }
+ ImGui::EndDragDropTarget();
+ }
+
+ ImGui::EndChild();
+ ImGui::PopStyleColor();
+
+ ImGui::End();
+}
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Jerarquia.h b/sdl2_simple_example/sdl2_simple_example/Jerarquia.h
new file mode 100644
index 0000000..4bfb01f
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Jerarquia.h
@@ -0,0 +1,17 @@
+#pragma once
+#ifndef JERARQUIA_H
+#define JERARQUIA_H
+
+#include
+#include "MyWindow.h"
+#include "Scene.h"
+class Jerarquia {
+public:
+ Jerarquia();
+ ~Jerarquia();
+ static void draw();
+private:
+ static void drawGameObjectNode(GameObject* obj, const std::string& name, int index);
+};
+
+#endif // JERARQUIA_H
diff --git a/sdl2_simple_example/sdl2_simple_example/Library/Meshes/BakerHouse.fbx b/sdl2_simple_example/sdl2_simple_example/Library/Meshes/BakerHouse.fbx
new file mode 100644
index 0000000..b6e6721
Binary files /dev/null and b/sdl2_simple_example/sdl2_simple_example/Library/Meshes/BakerHouse.fbx differ
diff --git a/sdl2_simple_example/sdl2_simple_example/Library/Meshes/cube.fbx b/sdl2_simple_example/sdl2_simple_example/Library/Meshes/cube.fbx
new file mode 100644
index 0000000..3de70b0
Binary files /dev/null and b/sdl2_simple_example/sdl2_simple_example/Library/Meshes/cube.fbx differ
diff --git a/sdl2_simple_example/sdl2_simple_example/Library/Models/model_data.bin b/sdl2_simple_example/sdl2_simple_example/Library/Models/model_data.bin
new file mode 100644
index 0000000..ae89332
Binary files /dev/null and b/sdl2_simple_example/sdl2_simple_example/Library/Models/model_data.bin differ
diff --git a/sdl2_simple_example/sdl2_simple_example/Library/Textures/Baker_house.png b/sdl2_simple_example/sdl2_simple_example/Library/Textures/Baker_house.png
new file mode 100644
index 0000000..415732b
Binary files /dev/null and b/sdl2_simple_example/sdl2_simple_example/Library/Textures/Baker_house.png differ
diff --git a/sdl2_simple_example/sdl2_simple_example/MemoryUsage.h b/sdl2_simple_example/sdl2_simple_example/MemoryUsage.h
new file mode 100644
index 0000000..399719d
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/MemoryUsage.h
@@ -0,0 +1,25 @@
+#pragma once
+#include
+#include
+
+struct MemoryInfo {
+ unsigned long long totalMemory;
+ unsigned long long freeMemory;
+ unsigned long long usedMemory;
+};
+
+class MemoryUsage {
+public:
+ static MemoryInfo getMemoryInfo() {
+ MEMORYSTATUSEX memInfo;
+ memInfo.dwLength = sizeof(MEMORYSTATUSEX);
+
+ if (GlobalMemoryStatusEx(&memInfo)) {
+ MemoryInfo info;
+ info.totalMemory = memInfo.ullTotalPhys / (1024 * 1024); // Convertir a MB
+ info.freeMemory = memInfo.ullAvailPhys / (1024 * 1024); // Convertir a MB
+ info.usedMemory = info.totalMemory - info.freeMemory; // Calcular memoria usada
+ return info;
+ }
+ }
+};
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Mesh.cpp b/sdl2_simple_example/sdl2_simple_example/Mesh.cpp
new file mode 100644
index 0000000..d1662ec
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Mesh.cpp
@@ -0,0 +1,61 @@
+#include "Mesh.h"
+
+Mesh::Mesh(const std::vector& vertices, const std::vector& uvs, const std::vector& indices)
+ : vertices(vertices), uvs(uvs), indices(indices) {
+ setupMesh();
+}
+
+Mesh::~Mesh() {
+ glDeleteVertexArrays(1, &vao);
+ glDeleteBuffers(1, &vboVertices);
+ glDeleteBuffers(1, &vboUVs);
+ glDeleteBuffers(1, &ebo);
+}
+
+void Mesh::setupMesh() {
+ glGenVertexArrays(1, &vao);
+ glGenBuffers(1, &vboVertices);
+ glGenBuffers(1, &vboUVs);
+ glGenBuffers(1, &ebo);
+
+ glBindVertexArray(vao);
+
+ glBindBuffer(GL_ARRAY_BUFFER, vboVertices);
+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, vboUVs);
+ glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(float), uvs.data(), GL_STATIC_DRAW);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
+ glEnableVertexAttribArray(1);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
+
+ glBindVertexArray(0);
+}
+
+void Mesh::render() const {
+ glBindVertexArray(vao);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glBindBuffer(GL_ARRAY_BUFFER, vboVertices);
+ glVertexPointer(3, GL_FLOAT, 0, nullptr);
+
+ if (!uvs.empty()) {
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glBindBuffer(GL_ARRAY_BUFFER, vboUVs);
+ glTexCoordPointer(2, GL_FLOAT, 0, nullptr);
+ }
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
+ glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, nullptr);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ if (!uvs.empty()) {
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+
+ glBindVertexArray(0);
+}
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Mesh.h b/sdl2_simple_example/sdl2_simple_example/Mesh.h
new file mode 100644
index 0000000..03c8d65
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Mesh.h
@@ -0,0 +1,22 @@
+#pragma once
+#include
+#include
+
+class Mesh {
+public:
+ std::vector vertices;
+ std::vector uvs;
+ std::vector indices;
+ GLuint vao, vboVertices, vboUVs, ebo;
+
+ Mesh(const std::vector& vertices, const std::vector& uvs, const std::vector& indices);
+ ~Mesh();
+
+ void setupMesh();
+ void render() const;
+
+ // Getter methods for mesh information
+ const std::vector& getVertices() const { return vertices; }
+ const std::vector& getUVs() const { return uvs; }
+ const std::vector& getIndices() const { return indices; }
+};
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/MyWindow.cpp b/sdl2_simple_example/sdl2_simple_example/MyWindow.cpp
index 917af88..a45d9ac 100644
--- a/sdl2_simple_example/sdl2_simple_example/MyWindow.cpp
+++ b/sdl2_simple_example/sdl2_simple_example/MyWindow.cpp
@@ -1,16 +1,84 @@
-#include
-#include
-#include
-#include
+
#include "MyWindow.h"
+#include
+
+#include "imgui.h"
+#include "imgui_impl_sdl2.h"
+#include "imgui_impl_opengl3.h"
+#include
+
+#include "Consola.h"
+#include "Config.h"
+#include "Jerarquia.h"
+#include "Escena.h"
+#include "Inspector.h"
+#include "FileExplorer.h"
+
using namespace std;
+extern Scene scene;
+Renderer renderer;
+ImGuiIO* g_io = nullptr;
+Inspector inspector;
+Explorer explorer;
+
+float x = Renderer::eyeX;
+float y = Renderer::eyeY;
+float z = Renderer::eyeZ;
+bool chekerOn = false;
+
+MyWindow::MyWindow(const char* title, unsigned short width, unsigned short height) : fps(0.0f), frameCount(0), lastTime(SDL_GetTicks()) {
+ SDL_Init(SDL_INIT_VIDEO); // Mueve esta l�nea al principio del constructor
+ open(title, width, height);
+
+ ImGui::CreateContext();
+
+ g_io = &ImGui::GetIO();
+ g_io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable keyboard
+ g_io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable docking
+ g_io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable multiple viewports
-MyWindow::MyWindow(const char* title, unsigned short width, unsigned short height){
- open(title, width, height);
+ ImGui_ImplSDL2_InitForOpenGL(_window, _ctx);
+ ImGui_ImplOpenGL3_Init("#version 130");
+
+ // Tema de colores a un estilo lila oscuro cercano al negro
+ ImGuiStyle& style = ImGui::GetStyle();
+ ImVec4* colors = style.Colors;
+
+ colors[ImGuiCol_WindowBg] = ImVec4(0.08f, 0.02f, 0.1f, 0.9f); // Fondo de la ventana
+ colors[ImGuiCol_TitleBg] = ImVec4(0.18f, 0.05f, 0.2f, 1.0f); // TÃtulo de la ventana (sin focus)
+ colors[ImGuiCol_TitleBgActive] = ImVec4(0.22f, 0.05f, 0.25f, 1.0f); // TÃtulo de la ventana (con focus)
+ colors[ImGuiCol_Border] = ImVec4(0.2f, 0.1f, 0.25f, 1.0f); // Bordes
+ colors[ImGuiCol_FrameBg] = ImVec4(0.12f, 0.02f, 0.15f, 1.0f); // Fondo de widgets como InputFloat3
+ colors[ImGuiCol_FrameBgHovered] = ImVec4(0.2f, 0.1f, 0.25f, 1.0f); // Fondo de widgets cuando están en hover
+ colors[ImGuiCol_FrameBgActive] = ImVec4(0.25f, 0.1f, 0.3f, 1.0f); // Fondo de widgets cuando están activos
+ colors[ImGuiCol_Button] = ImVec4(0.15f, 0.05f, 0.2f, 1.0f); // Botones
+ colors[ImGuiCol_ButtonHovered] = ImVec4(0.2f, 0.1f, 0.25f, 1.0f); // Botones cuando están en hover
+ colors[ImGuiCol_ButtonActive] = ImVec4(0.25f, 0.1f, 0.3f, 1.0f); // Botones cuando están activos
+ colors[ImGuiCol_Header] = ImVec4(0.2f, 0.1f, 0.25f, 1.0f); // Cabecera de listas desplegables
+ colors[ImGuiCol_HeaderHovered] = ImVec4(0.25f, 0.1f, 0.3f, 1.0f); // Cabecera de listas desplegables en hover
+ colors[ImGuiCol_HeaderActive] = ImVec4(0.3f, 0.15f, 0.35f, 1.0f); // Cabecera de listas desplegables activas
+
+ SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
}
MyWindow::~MyWindow() {
+ // Limpieza de ImGui
+ ImGui_ImplSDL2_Shutdown();
+ ImGui_ImplOpenGL3_Shutdown();
+ ImGui::DestroyContext();
+
+ // Liberar recursos OpenGL
+ glDeleteFramebuffers(1, &framebuffer);
+ glDeleteTextures(1, &textureColorbuffer);
+ glDeleteRenderbuffers(1, &rbo);
+
+ // Cerrar ventana y SDL
close();
+ SDL_Quit();
+}
+
+void MyWindow::logMessage(const std::string& message) {
+ logMessages.push_back(message);
}
void MyWindow::open(const char* title, unsigned short width, unsigned short height) {
@@ -20,13 +88,18 @@ void MyWindow::open(const char* title, unsigned short width, unsigned short heig
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
- _window = SDL_CreateWindow( title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
- if (!_window) throw exception(SDL_GetError());
+ _window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
+ if (!_window) {
+ logMessage("Error al crear ventana SDL."); // Mensaje en caso de error
+ throw exception(SDL_GetError());
+ }
_ctx = SDL_GL_CreateContext(_window);
- if (!_ctx) throw exception(SDL_GetError());
- if (SDL_GL_MakeCurrent(_window, _ctx) != 0) throw exception(SDL_GetError());
- if (SDL_GL_SetSwapInterval(1) != 0) throw exception(SDL_GetError());
+ if (!_ctx) {
+ logMessage("Error al crear contexto OpenGL."); // Mensaje en caso de error
+ throw exception(SDL_GetError());
+ }
+ logMessage("Ventana y contexto creados con exito.");
}
void MyWindow::close() {
@@ -36,7 +109,174 @@ void MyWindow::close() {
_ctx = nullptr;
SDL_DestroyWindow(static_cast(_window));
- _window = nullptr;
+ _window = nullptr;
+
+ logMessage("Ventana cerrada.");
+}
+
+void MyWindow::setupFramebuffer() {
+ glGenFramebuffers(1, &framebuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+
+ glGenTextures(1, &textureColorbuffer);
+ glBindTexture(GL_TEXTURE_2D, textureColorbuffer);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, renderer._WINDOW_SIZE.x, renderer._WINDOW_SIZE.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);
+
+ glGenRenderbuffers(1, &rbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbo);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, renderer._WINDOW_SIZE.x, renderer._WINDOW_SIZE.y);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ logMessage("Framebuffer no está completo.");
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void MyWindow::renderToFramebuffer() {
+ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ logMessage("Framebuffer no está completo.");
+ return;
+ }
+
+ renderer.setupView(cameraDistance, cameraAngleX, cameraAngleY, panX, panY);
+
+ renderer.deployGrid(10.0f); // Draw grid first
+
+ scene.drawScene();
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void MyWindow::draw() {
+ Config config(this);
+
+ Uint32 currentTime = SDL_GetTicks();
+ frameCount++;
+
+ // Calcular FPS cada segundo
+ if (currentTime - lastTime >= 1000) {
+ fps = frameCount / ((currentTime - lastTime) / 1000.0f);
+ frameCount = 0;
+ lastTime = currentTime;
+ }
+ ImGui_ImplOpenGL3_NewFrame();
+ ImGui_ImplSDL2_NewFrame();
+ ImGui::NewFrame();
+
+ // Barra de men� principal
+ if (ImGui::BeginMainMenuBar()) {
+ if (ImGui::BeginMenu("Menu")) {
+ if (ImGui::MenuItem("Salir")) {
+ SDL_Event quit_event;
+ quit_event.type = SDL_QUIT;
+ SDL_PushEvent(&quit_event);
+ }
+ if (ImGui::MenuItem("GitHub")) {
+ SDL_OpenURL("https://github.com/didacpema/Oyuki_Engine.git");
+ // Aqu� podr�amos abrir el enlace de GitHub
+ }
+ if (ImGui::MenuItem("Sobre el motor")) {
+ ImGui::OpenPopup("AboutPopup");
+ ImGui::Text("Este motor grafico es propiedad de los estudiantes de la UPC");
+ }
+ ImGui::EndMenu();
+ }
+
+ if (ImGui::BeginMenu("Editor")) {
+ if (ImGui::MenuItem("Consola", NULL, isConsolaOn, true))
+ {
+ isConsolaOn = !isConsolaOn;
+ }
+ if (ImGui::MenuItem("Config", NULL, isConfigOn, true))
+ {
+ isConfigOn = !isConfigOn;
+ }
+ if (ImGui::MenuItem("Jerarquia", NULL, isJerarquiaOn, true))
+ {
+ isJerarquiaOn = !isJerarquiaOn;
+ }
+ if (ImGui::MenuItem("Inspector", NULL, isInspectorOn, true))
+ {
+ isInspectorOn = !isInspectorOn;
+ }
+ ImGui::EndMenu();
+ }
+
+ if (ImGui::BeginMenu("GameObject")) {
+ if (ImGui::MenuItem("Cube")) {
+ scene.createCube("Library/Meshes/cube.fbx");
+ }
+ if (ImGui::MenuItem("Sphere")) {
+ scene.createSphere("Sphere");
+ }
+ ImGui::EndMenu();
+ }
+ ImGui::EndMainMenuBar();
+ }
+ //COMENTA ESTA LINEA PARA SER FELIZ
+ ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()->ID);
+
+ if (isConsolaOn)
+ {
+ Consola::draw(logMessages);
+ }
+
+ if (isConfigOn)
+ {
+ config.draw(_window, renderer, fps);
+ }
+
+ if (isJerarquiaOn) {
+ Jerarquia::draw();
+ }
+
+ // Si el usuario pulsa 'F', movemos la cámara al objeto seleccionado
+ if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_F)) && scene.selectedGameObjectIndex != -1) {
+ GameObject* selectedObject = scene.gameObjects[scene.selectedGameObjectIndex];
+ panX = selectedObject->transform.position.x;
+ panY = selectedObject->transform.position.y;
+ cameraDistance = glm::distance(glm::vec3(x, y, z), selectedObject->transform.position); // Ajuste de distancia
+ logMessage("Cámara ajustada al objeto seleccionado.");
+ }
+
+ if (isSceneOn) {
+ renderToFramebuffer(); // Renderiza la escena al framebuffer
+ Escena::draw(textureColorbuffer);
+ }
+
+ if (isInspectorOn)
+ {
+ inspector.draw();
+ }
+
+
+ // Popup "About"
+ if (ImGui::BeginPopup("AboutPopup")) {
+ ImGui::Text("Informacion sobre el motor:");
+ ImGui::Text("Version: 1.0");
+ ImGui::Text("Desarrollado con SDL, OpenGL, ImGui, Assimp, DevIL");
+ ImGui::EndPopup();
+ }
+
+ explorer.draw();
+
+ ImGui::Render();
+ ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
+
+ if (g_io->ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
+ ImGui::UpdatePlatformWindows();
+ ImGui::RenderPlatformWindowsDefault();
+ SDL_GL_MakeCurrent(_window, _ctx);
+ }
+
}
void MyWindow::swapBuffers() const {
@@ -44,12 +284,88 @@ void MyWindow::swapBuffers() const {
}
bool MyWindow::processEvents(IEventProcessor* event_processor) {
- SDL_Event e;
- while (SDL_PollEvent(&e)) {
- if (event_processor) event_processor->processEvent(e);
- switch (e.type) {
- case SDL_QUIT: close(); return false;
- }
+ SDL_Event e;
+ static int lastMouseX, lastMouseY;
+
+ while (SDL_PollEvent(&e)) {
+ // Enviar el evento a ImGui primero
+ ImGui_ImplSDL2_ProcessEvent(&e);
+
+ if (event_processor) {
+ event_processor->processEvent(e); // Procesar eventos personalizados
+ }
+
+ switch (e.type)
+ {
+ case SDL_DROPFILE: {
+ char* droppedFile = e.drop.file;
+ logMessage("Archivo arrastrado: " + string(droppedFile));
+ handleFileDrop(droppedFile); // Tu función para manejar archivos
+ SDL_free(droppedFile);
+ break;
+ }
+ case SDL_QUIT:
+ logMessage("Evento de salida recibido.");
+ close();
+ return false;
+ case SDL_MOUSEMOTION:
+ if (e.motion.state & SDL_BUTTON_RMASK) {
+ if (SDL_GetModState() & KMOD_ALT) {
+ cameraAngleY += e.motion.xrel * 0.005f;
+ cameraAngleX -= e.motion.yrel * 0.005f;
+ }
+ }
+ break;
+ case SDL_KEYDOWN:
+ // Movimiento de cámara existente
+ if (e.key.keysym.sym == SDLK_w) {
+ if (e.key.keysym.mod & KMOD_SHIFT)
+ panY += camSpeed * 2;
+ else
+ panY += camSpeed;
+ }
+ if (e.key.keysym.sym == SDLK_s) {
+ if (e.key.keysym.mod & KMOD_SHIFT)
+ panY -= camSpeed * 2;
+ else
+ panY -= camSpeed;
+ }
+ if (e.key.keysym.sym == SDLK_a) {
+ if (e.key.keysym.mod & KMOD_SHIFT)
+ panX -= camSpeed * 2;
+ else
+ panX -= camSpeed;
+ }
+ if (e.key.keysym.sym == SDLK_d) {
+ if (e.key.keysym.mod & KMOD_SHIFT)
+ panX += camSpeed * 2;
+ else
+ panX += camSpeed;
+ }
+
+ // Nueva funcionalidad para enfocar el objeto seleccionado con tecla 'F'
+ if (e.key.keysym.sym == SDLK_f) {
+ // Verifica que haya un objeto seleccionado
+ if (scene.selectedGameObjectIndex >= 0 && scene.selectedGameObjectIndex < scene.gameObjects.size()) {
+ GameObject* selectedObject = scene.gameObjects[scene.selectedGameObjectIndex];
+
+ // Cambia el pivote de la cámara a la posición del objeto seleccionado
+ panX = selectedObject->transform.position.x;
+ panY = selectedObject->transform.position.y;
+ cameraDistance = glm::distance(glm::vec3(x, y, z), selectedObject->transform.position); // Ajuste de distancia
+
+ logMessage("Cámara centrada en el objeto seleccionado.");
+ }
+ else {
+ logMessage("No hay objeto seleccionado.");
+ }
+ }
+ break;
+ case SDL_MOUSEWHEEL:
+ cameraDistance += e.wheel.y > 0 ? -0.5f : 0.5f;
+ cameraDistance = max(1.0f, cameraDistance);
+ break;
+ }
}
return true;
}
diff --git a/sdl2_simple_example/sdl2_simple_example/MyWindow.h b/sdl2_simple_example/sdl2_simple_example/MyWindow.h
index 6d0c010..d174ea5 100644
--- a/sdl2_simple_example/sdl2_simple_example/MyWindow.h
+++ b/sdl2_simple_example/sdl2_simple_example/MyWindow.h
@@ -1,41 +1,77 @@
#pragma once
+
+#include "Renderer.h"
+#include "Scene.h"
+
+#include
+#include
#include
#include
+#include
+
+#include
+#include
+
class IEventProcessor {
public:
- virtual void processEvent(const SDL_Event& event) = 0;
+ virtual void processEvent(const SDL_Event& event) = 0;
};
class MyWindow {
+ SDL_Window* _window = nullptr;
+ void* _ctx = nullptr;
- SDL_Window* _window = nullptr;
- void* _ctx = nullptr;
-
- unsigned short _width = 800;
- unsigned short _height = 600;
+ unsigned short _width = 800;
+ unsigned short _height = 600;
public:
- int width() const { return _width; }
- int height() const { return _height; }
- double aspect() const { return static_cast(_width) / _height; }
+ int width() const { return _width; }
+ int height() const { return _height; }
+ double aspect() const { return static_cast(_width) / _height; }
- auto* windowPtr() const { return _window; }
- auto* contextPtr() const { return _ctx; }
+ float cameraDistance = 5.0f; // Distancia inicial de la cámara (zoom)
+ float cameraAngleX = 0.0f; // Ángulo de rotación en el eje X
+ float cameraAngleY = 0.0f; // Ángulo de rotación en el eje Y
+ float panX = 0.0f, panY = 0.0f; // Desplazamiento de la cámara (pan)
+ bool isSceneOn = true;
+ bool isConsolaOn = true;
+ bool isConfigOn = true;
+ bool isJerarquiaOn = true;
+ bool isInspectorOn = true;
+ float camSpeed = 0.1;
+ //FPS
+ float fps = 0.0f;
+ int frameCount = 0;
+ Uint32 lastTime = 0;
+ SDL_Window* windowPtr() const { return _window; }
+ void* contextPtr() const { return _ctx; }
- MyWindow(const char* title, unsigned short width, unsigned short height);
- MyWindow(MyWindow&&) noexcept = delete;
- MyWindow(const MyWindow&) = delete;
- MyWindow& operator=(const MyWindow&) = delete;
- ~MyWindow();
+ MyWindow(const char* title, unsigned short width, unsigned short height);
+ MyWindow(MyWindow&&) noexcept = delete;
+ MyWindow(const MyWindow&) = delete;
+ MyWindow& operator=(const MyWindow&) = delete;
+ ~MyWindow();
- void open(const char* title, unsigned short width, unsigned short height);
- void close();
- bool isOpen() const { return _window; }
+ void open(const char* title, unsigned short width, unsigned short height);
+ void close();
+ bool isOpen() const { return _window; }
- bool processEvents(IEventProcessor* event_processor = nullptr);
- void swapBuffers() const;
+ bool processEvents(IEventProcessor* event_processor = nullptr);
+ void draw();
+ void swapBuffers() const;
+
+ void setupFramebuffer();
+ void renderToFramebuffer();
+
+ GLuint getFramebufferTexture() const { return textureColorbuffer; }
+
+ void logMessage(const std::string& message); // Método para agregar mensajes al LOG
+ std::vector logMessages; // Vector de mensajes de LOG
+
+ GLuint framebuffer, textureColorbuffer, rbo;
+};
-};
\ No newline at end of file
+extern void handleFileDrop(const char* filePath);
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Renderer.cpp b/sdl2_simple_example/sdl2_simple_example/Renderer.cpp
new file mode 100644
index 0000000..f4aecce
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Renderer.cpp
@@ -0,0 +1,74 @@
+#include "Renderer.h"
+#include
+#include
+#include
+
+// Define the static member variable
+ivec2 Renderer::_WINDOW_SIZE;
+
+float Renderer::eyeX = 0.0f; // Asignar un valor inicial
+float Renderer::eyeY = 0.0f; // Asignar un valor inicial
+float Renderer::eyeZ = 0.0f; // Asignar un valor inicial
+
+void Renderer::initOpenGL(ivec2 WINDOW_SIZE) {
+ glewInit();
+ if (!GLEW_VERSION_3_0) throw std::exception("OpenGL 3.0 API is not available.");
+
+ glEnable(GL_DEPTH_TEST);
+
+ glDepthFunc(GL_LEQUAL); // Set depth function to less or equal
+ glClearDepth(1.0f); // Clear depth buffer with maximum depth value
+
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ // Store the window size
+ Renderer::_WINDOW_SIZE = WINDOW_SIZE;
+}
+
+void Renderer::deployGrid(float spacing) {
+ glDisable(GL_TEXTURE_2D); // Disable texture for the grid lines
+ float gridRange = 1000.0f;
+
+ glColor3f(1.0f, 1.0f, 1.0f); // Set grid color
+ glBegin(GL_LINES);
+
+ for (float i = -gridRange; i <= gridRange; i += spacing) {
+ glVertex3f(i, 0, -gridRange);
+ glVertex3f(i, 0, gridRange);
+ }
+
+ for (float i = -gridRange; i <= gridRange; i += spacing) {
+ glVertex3f(-gridRange, 0, i);
+ glVertex3f(gridRange, 0, i);
+ }
+
+ glEnd();
+}
+
+void Renderer::setupProjection(float fov, float aspectRatio, float nearPlane, float farPlane) {
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ float windowAspectRatio = static_cast(Renderer::_WINDOW_SIZE.x) / Renderer::_WINDOW_SIZE.y;
+ // Use the stored window size for the aspect ratio
+ gluPerspective(fov, static_cast(Renderer::_WINDOW_SIZE.x) / Renderer::_WINDOW_SIZE.y, nearPlane, farPlane);
+}
+
+void Renderer::setupView(float cameraDistance, float cameraAngleX, float cameraAngleY, float panX, float panY) {
+ glClearDepth(1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ // Actualiza las variables miembro con los valores calculados
+ eyeX = cameraDistance * sin(cameraAngleY) * cos(cameraAngleX) + panX;
+ eyeY = cameraDistance * sin(cameraAngleX) + panY;
+ eyeZ = cameraDistance * cos(cameraAngleY) * cos(cameraAngleX);
+
+ gluLookAt(eyeX, eyeY, eyeZ, panX, panY, 0.0, 0.0, -1.0, 0.0);
+}
+
+void Renderer::applyProjectionAndViewport(ivec2 selectedResolution) {
+ glViewport(0, 0, selectedResolution.x, selectedResolution.y); // Actualiza el viewport
+ // Asegúrate de usar selectedResolution para calcular el aspecto
+ setupProjection(45.0f, static_cast(selectedResolution.x) / selectedResolution.y, 0.1f, 1000.0f);
+}
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Renderer.h b/sdl2_simple_example/sdl2_simple_example/Renderer.h
new file mode 100644
index 0000000..7decd14
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Renderer.h
@@ -0,0 +1,21 @@
+#pragma once
+#include
+#include
+#include "MyWindow.h"
+#include
+
+using ivec2 = glm::ivec2;
+
+class Renderer {
+public:
+ static void initOpenGL(ivec2 WINDOW_SIZE);
+ static void setupProjection(float fov, float aspectRatio, float nearPlane, float farPlane);
+ static void setupView(float cameraDistance, float cameraAngleX, float cameraAngleY, float panX, float panY);
+ static void deployGrid(float spacing);
+ void applyProjectionAndViewport(ivec2 selectedResolution);
+
+ // Nuevas variables miembro
+ static float eyeX, eyeY, eyeZ;
+
+ static ivec2 _WINDOW_SIZE;
+};
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Scene.cpp b/sdl2_simple_example/sdl2_simple_example/Scene.cpp
new file mode 100644
index 0000000..41ff887
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Scene.cpp
@@ -0,0 +1,184 @@
+#include "Scene.h"
+#include "Importer.h"
+#include "FilesystemUtils.h"
+#include
+
+extern Importer importer;
+
+Scene::Scene() {}
+
+Scene::~Scene() {
+ // Solo eliminamos los objetos raíz, ya que eliminarán recursivamente a sus hijos
+ for (auto it = gameObjects.begin(); it != gameObjects.end();) {
+ GameObject* obj = *it;
+ if (!obj->getParent()) {
+ deleteGameObjectHierarchy(obj);
+ it = gameObjects.erase(it);
+ }
+ else {
+ ++it;
+ }
+ }
+ gameObjects.clear();
+ gameObjectNames.clear();
+}
+void Scene::deleteGameObjectHierarchy(GameObject* obj) {
+ if (!obj) return;
+
+ // Primero eliminamos los hijos recursivamente
+ auto children = obj->getChildren(); // Hacemos una copia porque se modificará durante la eliminación
+ for (auto* child : children) {
+ deleteGameObjectHierarchy(child);
+ }
+
+ // Eliminamos este objeto de la lista de gameObjects y gameObjectNames
+ auto it = std::find(gameObjects.begin(), gameObjects.end(), obj);
+ if (it != gameObjects.end()) {
+ int index = std::distance(gameObjects.begin(), it);
+ gameObjects.erase(it);
+ gameObjectNames.erase(gameObjectNames.begin() + index);
+ }
+
+ delete obj;
+}
+void Scene::loadModelData(const std::vector& vertices, const std::vector& uvs, const std::vector& indices, const std::string& name, const Transform& transform) {
+ Mesh* mesh = new Mesh(vertices, uvs, indices);
+ GameObject* gameObject = new GameObject(mesh, nullptr);
+
+ gameObject->setTransform(transform);
+
+ gameObjects.push_back(gameObject);
+ gameObjectNames.push_back(name);
+}
+
+void Scene::setTexture(TextureData* newTexture) {
+ if (!gameObjects.empty()) {
+ GameObject* lastObject = gameObjects.back();
+ if (lastObject->getTexture() != nullptr) {
+ delete lastObject->getTexture();
+ }
+ lastObject->setTexture(newTexture);
+ }
+}
+
+void Scene::setCheckerTexture(GLuint checkerTextureID) {
+ // Creamos una textura temporal con el checkerTextureID, un path vacío y tamaño predeterminado (0,0)
+ TextureData* checkerTexture = new TextureData(checkerTextureID, "checker_texture_path", 0, 0);
+
+ // Asignamos esta textura a través de setTexture
+ setTexture(checkerTexture);
+}
+
+bool Scene::setParentChild(int childIndex, int parentIndex) {
+ if (!isValidParenting(childIndex, parentIndex)) {
+ return false;
+ }
+
+ GameObject* child = gameObjects[childIndex];
+ GameObject* newParent = gameObjects[parentIndex];
+
+ child->setParent(newParent);
+ return true;
+}
+void Scene::removeFromParent(int childIndex) {
+ if (childIndex >= 0 && childIndex < gameObjects.size()) {
+ GameObject* child = gameObjects[childIndex];
+ GameObject* parent = child->getParent();
+ if (parent) {
+ parent->removeChild(child);
+ child->setParent(nullptr);
+ }
+ }
+}
+bool Scene::isValidParenting(int childIndex, int parentIndex) const {
+ if (childIndex < 0 || childIndex >= gameObjects.size() ||
+ parentIndex < 0 || parentIndex >= gameObjects.size() ||
+ childIndex == parentIndex) {
+ return false;
+ }
+
+ GameObject* child = gameObjects[childIndex];
+ GameObject* parent = gameObjects[parentIndex];
+
+ // Verificar que el padre no sea hijo del hijo (evitar ciclos)
+ return !parent->isChildOf(child);
+}
+void Scene::drawScene() {
+ // Solo dibujamos los objetos raíz, ellos dibujarán a sus hijos
+ for (auto* obj : gameObjects) {
+ if (!obj->getParent()) { // Si no tiene padre, es un objeto raíz
+ if (obj->getTexture() == nullptr && checkerTextureID != 2) {
+ TextureData* checkerTexture = new TextureData(checkerTextureID, "checker_texture_path", 0, 0);
+ obj->setTexture(checkerTexture);
+ }
+ obj->draw();
+ }
+ }
+}
+
+void Scene::createCube(const char* filePath) {
+
+ std::string fileName = "Cube";
+
+ std::string path(filePath);
+ std::string extension = path.substr(path.find_last_of('.') + 1);
+
+ if (importer.loadFBX(filePath)) {
+ loadModelData(importer.getVertices(), importer.getUVs(), importer.getIndices(), fileName);
+
+ setCheckerTexture(checkerTextureID);
+ }
+}
+
+void Scene::createSphere(const std::string& name, const Transform& transform) {
+
+ const int sectors = 36; // Divide la esfera en 36 partes (puedes cambiar este número para más resolución)
+ const int stacks = 18; // Divide la esfera en 18 partes (puedes cambiar este número)
+
+ // Vértices y UVs para la esfera
+ std::vector vertices;
+ std::vector uvs;
+ std::vector indices;
+
+ // Generar la malla esférica (esto se hace con un algoritmo para crear una esfera)
+ for (int i = 0; i <= stacks; ++i) {
+ float stackStep = angle / stacks;
+ float stackAngle = angle / 2 - i * stackStep;
+
+ for (int j = 0; j <= sectors; ++j) {
+ float sectorAngle = j * (2 * angle / sectors);
+
+ // Coordenadas esféricas convertidas a cartesianas
+ float x = cos(stackAngle) * cos(sectorAngle);
+ float y = cos(stackAngle) * sin(sectorAngle);
+ float z = sin(stackAngle);
+
+ // Añadir vértices
+ vertices.push_back(x);
+ vertices.push_back(y);
+ vertices.push_back(z);
+
+ // Generar coordenadas UV
+ uvs.push_back((float)j / sectors);
+ uvs.push_back((float)i / stacks);
+ }
+ }
+
+ // Generar índices para el dibujo de las caras
+ for (int i = 0; i < stacks; ++i) {
+ for (int j = 0; j < sectors; ++j) {
+ int first = (i * (sectors + 1)) + j;
+ int second = first + sectors + 1;
+
+ indices.push_back(first);
+ indices.push_back(second);
+ indices.push_back(first + 1);
+
+ indices.push_back(second);
+ indices.push_back(second + 1);
+ indices.push_back(first + 1);
+ }
+ }
+ loadModelData(vertices, uvs, indices, name, transform);
+ setCheckerTexture(checkerTextureID);
+}
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Scene.h b/sdl2_simple_example/sdl2_simple_example/Scene.h
new file mode 100644
index 0000000..7723b25
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Scene.h
@@ -0,0 +1,35 @@
+#pragma once
+#include
+#include
+#include "GameObject.h"
+#include
+#include
+
+
+class Scene {
+public:
+ Scene();
+ ~Scene();
+ void loadModelData(const std::vector& vertices, const std::vector& uvs, const std::vector& indices, const std::string& name, const Transform& transform = Transform());
+ void createSphere(const std::string& name, const Transform& transform = Transform());
+ void createCube(const char* filePath);
+ void setTexture(TextureData* newTexture);
+ void setCheckerTexture(GLuint checkerTextureID);
+ void drawScene();
+
+ // Nuevos métodos para manejar la jerarquía
+ bool setParentChild(int childIndex, int parentIndex);
+ void removeFromParent(int childIndex);
+ bool isValidParenting(int childIndex, int parentIndex) const;
+
+ std::vector gameObjects;
+ std::vector gameObjectNames;
+
+ // Índice del objeto seleccionado (-1 si no hay ninguno)
+ int selectedGameObjectIndex = -1;
+ float angle = 3.14159265359f;
+ GLuint checkerTextureID;
+
+ void deleteGameObjectHierarchy(GameObject* obj);
+
+};
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Texture.cpp b/sdl2_simple_example/sdl2_simple_example/Texture.cpp
new file mode 100644
index 0000000..768e55c
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Texture.cpp
@@ -0,0 +1,9 @@
+#include "Texture.h"
+
+void TextureData::bind() const {
+ glBindTexture(GL_TEXTURE_2D, id);
+}
+
+void TextureData::unbind() const {
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Texture.h b/sdl2_simple_example/sdl2_simple_example/Texture.h
new file mode 100644
index 0000000..de4e896
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Texture.h
@@ -0,0 +1,22 @@
+#pragma once
+#include
+#include
+
+class TextureData {
+public:
+ GLuint id;
+ std::string path;
+ int width;
+ int height;
+
+ TextureData(GLuint textureId = 0, const std::string& filePath = "", int texWidth = 0, int texHeight = 0)
+ : id(textureId), path(filePath), width(texWidth), height(texHeight) {}
+
+ void bind() const;
+ void unbind() const;
+
+ GLuint getTextureID() const { return id; }
+ std::string getPath() const { return path; }
+ int getWidth() const { return width; }
+ int getHeight() const { return height; }
+};
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/Transform.h b/sdl2_simple_example/sdl2_simple_example/Transform.h
new file mode 100644
index 0000000..71630d1
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/Transform.h
@@ -0,0 +1,11 @@
+#pragma once
+#include
+
+class Transform {
+public:
+ glm::vec3 position;
+ glm::vec3 rotation;
+ glm::vec3 scale;
+
+ Transform() : position(0.0f), rotation(0.0f), scale(1.0f) {}
+};
\ No newline at end of file
diff --git a/sdl2_simple_example/sdl2_simple_example/imgui.ini b/sdl2_simple_example/sdl2_simple_example/imgui.ini
new file mode 100644
index 0000000..24ba21c
--- /dev/null
+++ b/sdl2_simple_example/sdl2_simple_example/imgui.ini
@@ -0,0 +1,115 @@
+[Window][Debug##Default]
+Pos=60,60
+Size=400,400
+Collapsed=0
+
+[Window][Consola]
+ViewportPos=730,513
+ViewportId=0xAA02EECC
+Size=636,241
+Collapsed=0
+DockId=0x00000009,1
+
+[Window][Configuració]
+Pos=37,333
+Size=325,273
+Collapsed=0
+
+[Window][Jerarquia]
+Pos=0,394
+Size=186,113
+Collapsed=0
+
+[Window][Inspector]
+Pos=590,19
+Size=210,581
+Collapsed=0
+DockId=0x00000008,0
+
+[Window][Console]
+Pos=28,107
+Size=488,472
+Collapsed=0
+
+[Window][Config]
+ViewportPos=730,513
+ViewportId=0xAA02EECC
+Size=636,241
+Collapsed=0
+DockId=0x00000009,0
+
+[Window][Hierarchy]
+Pos=176,287
+Size=283,65
+Collapsed=0
+
+[Window][WindowOverViewport_11111111]
+Pos=0,19
+Size=800,581
+Collapsed=0
+
+[Window][Dockable Window 1]
+Pos=602,19
+Size=198,581
+Collapsed=0
+DockId=0x00000004,0
+
+[Window][Dockable Window 2]
+Pos=0,19
+Size=397,581
+Collapsed=0
+DockId=0x00000001,0
+
+[Window][Editor Docking Window]
+Pos=60,60
+Size=32,39
+Collapsed=0
+
+[Window][DockSpace]
+Size=800,600
+Collapsed=0
+
+[Window][Scene View]
+Pos=60,60
+Size=32,35
+Collapsed=0
+
+[Window][JerarquÃa]
+Pos=0,19
+Size=209,581
+Collapsed=0
+DockId=0x00000006,0
+
+[Window][Scene]
+Pos=164,19
+Size=424,581
+Collapsed=0
+DockId=0x00000005,0
+
+[Window][File Explorer]
+ViewportPos=730,513
+ViewportId=0xAA02EECC
+Size=636,241
+Collapsed=0
+DockId=0x00000009,2
+
+[Window][Jerarquía]
+Pos=0,19
+Size=162,581
+Collapsed=0
+DockId=0x0000000B,0
+
+[Docking][Data]
+DockNode ID=0x00000009 Pos=730,513 Size=636,241 Selected=0xCAC6E4C7
+DockSpace ID=0x11111111 Window=0xA87D555D Pos=560,259 Size=800,581 Split=X
+ DockNode ID=0x0000000B Parent=0x11111111 SizeRef=162,581 Selected=0x06C9255F
+ DockNode ID=0x0000000C Parent=0x11111111 SizeRef=636,581 Split=X
+ DockNode ID=0x00000006 Parent=0x0000000C SizeRef=209,581 Selected=0xADB1772B
+ DockNode ID=0x0000000A Parent=0x0000000C SizeRef=589,581 Split=X
+ DockNode ID=0x00000003 Parent=0x0000000A SizeRef=600,581 Split=X
+ DockNode ID=0x00000001 Parent=0x00000003 SizeRef=397,581 Selected=0x29384C3A
+ DockNode ID=0x00000002 Parent=0x00000003 SizeRef=0,0 Split=X Selected=0x83E87391
+ DockNode ID=0x00000005 Parent=0x00000002 SizeRef=424,559 CentralNode=1 Selected=0xE192E354
+ DockNode ID=0x00000008 Parent=0x00000002 SizeRef=210,559 Selected=0xE7039252
+ DockNode ID=0x00000004 Parent=0x0000000A SizeRef=198,581 Selected=0x6E9836EA
+
diff --git a/sdl2_simple_example/sdl2_simple_example/main.cpp b/sdl2_simple_example/sdl2_simple_example/main.cpp
index ff32d4b..968a0ab 100644
--- a/sdl2_simple_example/sdl2_simple_example/main.cpp
+++ b/sdl2_simple_example/sdl2_simple_example/main.cpp
@@ -1,54 +1,112 @@
+
+
+#define SDL_MAIN_HANDLED
+
#include
#include
#include
#include
#include
#include "MyWindow.h"
-using namespace std;
+#include "Importer.h"
+#include "customFormatUtils.h"
+#include "FilesystemUtils.h"
+#include
+#include
+#include
+#include "FileExplorer.h"
+using namespace std;
using hrclock = chrono::high_resolution_clock;
-using u8vec4 = glm::u8vec4;
using ivec2 = glm::ivec2;
-using vec3 = glm::dvec3;
-static const ivec2 WINDOW_SIZE(512, 512);
+static const ivec2 WINDOW_SIZE(800, 600);
static const unsigned int FPS = 60;
static const auto FRAME_DT = 1.0s / FPS;
-static void init_openGL() {
- glewInit();
- if (!GLEW_VERSION_3_0) throw exception("OpenGL 3.0 API is not available.");
- glEnable(GL_DEPTH_TEST);
- glClearColor(0.5, 0.5, 0.5, 1.0);
-}
+Importer importer;
+Scene scene;
+MyWindow myWindow("SDL2 Simple Example", WINDOW_SIZE.x, WINDOW_SIZE.y);
+extern Explorer explorer;
-static void draw_triangle(const u8vec4& color, const vec3& center, double size) {
- glColor4ub(color.r, color.g, color.b, color.a);
- glBegin(GL_TRIANGLES);
- glVertex3d(center.x, center.y + size, center.z);
- glVertex3d(center.x - size, center.y - size, center.z);
- glVertex3d(center.x + size, center.y - size, center.z);
- glEnd();
-}
+void handleFileDrop(const char* filePath) {
+ std::string fileName = FileSystemUtils::getFileName(filePath);
+
+ // Procesar extensiones
+ size_t dotPos = fileName.find_last_of(".");
+ if (dotPos != std::string::npos) {
+ fileName = fileName.substr(0, dotPos);
+ }
+ std::string path(filePath);
+ std::string extension = path.substr(path.find_last_of('.') + 1);
+
+ if (extension == "fbx") {
+ if (importer.loadFBX(filePath)) {
+ scene.loadModelData(importer.getVertices(), importer.getUVs(), importer.getIndices(), fileName);
-static void display_func() {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- draw_triangle(u8vec4(255, 0, 0, 255), vec3(0.0, 0.0, 0.0), 0.5);
+ // Configurar textura checker si no está asignada
+
+ scene.checkerTextureID = importer.GenerateCheckerTexture();
+
+ scene.setCheckerTexture(scene.checkerTextureID);
+ }
+ }
+ else if (extension == "png" || extension == "jpg") {
+ TextureData* texture = importer.loadTexture(filePath);
+ if (texture != nullptr) {
+ scene.setTexture(texture);
+ }
+ }
+
+ // Actualizar el contenido del directorio en la interfaz
+ explorer.UpdateDirectoryContents();
}
int main(int argc, char** argv) {
- MyWindow window("SDL2 Simple Example", WINDOW_SIZE.x, WINDOW_SIZE.y);
- init_openGL();
+ FileSystemUtils::GenerateRequiredDirectories();
+
+ explorer.UpdateDirectoryContents(); // Cargar contenido inicial
+ importer.setWindow(&myWindow);
+
+ myWindow.logMessage("Initializing SDL...");
+ if (SDL_Init(SDL_INIT_VIDEO) != 0) {
+ myWindow.logMessage("Error initializing SDL: " + std::string(SDL_GetError()));
+ return -1;
+ }
+ myWindow.logMessage("SDL initialized successfully.");
+
+ myWindow.logMessage("Initializing DevIL...");
+ ilInit();
+ iluInit();
+ ilutRenderer(ILUT_OPENGL);
+ myWindow.logMessage("DevIL initialized successfully.");
+
+ myWindow.logMessage("Initializing OpenGL context...");
+ Renderer::initOpenGL(WINDOW_SIZE);
+ Renderer::setupProjection(45.0f, 1.0f, 0.1f, 1000.0f);
+ myWindow.logMessage("OpenGL context initialized.");
+ myWindow.setupFramebuffer();
+ myWindow.renderToFramebuffer();
+
+ SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
+
+ handleFileDrop("Library/Meshes/BakerHouse.fbx");
+ handleFileDrop("Library/Textures/Baker_house.png");
+
+ while (myWindow.processEvents() && myWindow.isOpen()) {
+ auto start = hrclock::now();
+
+
+
+ myWindow.draw();
+ myWindow.swapBuffers();
- while(window.processEvents() && window.isOpen()) {
- const auto t0 = hrclock::now();
- display_func();
- window.swapBuffers();
- const auto t1 = hrclock::now();
- const auto dt = t1 - t0;
- if(dttrue
_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
+ stdcpp17
Console
@@ -127,11 +128,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sdl2_simple_example/sdl2_simple_example/sdl2_simple_example.vcxproj.filters b/sdl2_simple_example/sdl2_simple_example/sdl2_simple_example.vcxproj.filters
index 04a7e88..da064ea 100644
--- a/sdl2_simple_example/sdl2_simple_example/sdl2_simple_example.vcxproj.filters
+++ b/sdl2_simple_example/sdl2_simple_example/sdl2_simple_example.vcxproj.filters
@@ -13,6 +13,9 @@
{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+ {15a2393b-0452-4c45-af67-e7d5dde42e75}
+
@@ -21,10 +24,94 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Windows
+
+
+ Windows
+
+
+ Windows
+
+
+ Windows
+
+
+ Windows
+
+
+ Source Files
+
+
+ Windows
+
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Windows
+
+
+ Windows
+
+
+ Windows
+
+
+ Windows
+
+
+ Windows
+
+
+ Windows
+
\ No newline at end of file
diff --git a/vcpkg.json b/vcpkg.json
index a4d6f3d..61feba4 100644
--- a/vcpkg.json
+++ b/vcpkg.json
@@ -1,12 +1,4 @@
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
- "dependencies": [
- "glm",
- "glew",
- "sdl2",
- {
- "name": "imgui",
- "features": [ "sdl2-binding", "opengl3-binding", "docking-experimental" ]
- }
- ]
+ "dependencies": ["glm", "glew", "sdl2","assimp","devil", {"name": "imgui", "features": [ "sdl2-binding", "opengl3-binding", "docking-experimental"]}]
}
\ No newline at end of file