1134 lines
35 KiB
C++
1134 lines
35 KiB
C++
#include "imguiManager.h"
|
|
#include "application_class.h"
|
|
#include "stats.h"
|
|
|
|
static fps_limiter fpsLimiter(60.0f);
|
|
|
|
imguiManager::imguiManager()
|
|
{
|
|
io = nullptr;
|
|
m_frameTimeHistoryIndex = 0;
|
|
|
|
current_fps_ = 0;
|
|
min_fps_ = 0;
|
|
max_fps_ = 0;
|
|
draw_calls_ = 0;
|
|
total_vertex_count_ = 0;
|
|
total_triangle_count_ = 0;
|
|
visible_triangle_count_ = 0;
|
|
current_frame_time_ = 0;
|
|
|
|
showObjectWindow = false;
|
|
showTerrainWindow = false;
|
|
showLightWindow = false;
|
|
showOldSceneWindow = false;
|
|
showEngineSettingsWindow = false;
|
|
showLogWindow = false;
|
|
showStatsWindow = false;
|
|
|
|
// Initialiser l'historique des frametimes à zéro
|
|
for (int i = 0; i < FRAME_HISTORY_COUNT; i++)
|
|
{
|
|
m_frameTimeHistory[i] = 0.0f;
|
|
}
|
|
|
|
widgets_ = {
|
|
{&showObjectWindow, [&](){WidgetObjectWindow();}},
|
|
{&showEngineSettingsWindow, [&](){WidgetEngineSettingsWindow();}},
|
|
{&showTerrainWindow, [&](){WidgetTerrainWindow();}},
|
|
{&showLightWindow, [&](){WidgetLightWindow();}},
|
|
{&showLogWindow, [&](){WidgetLogWindow();}},
|
|
{&showOldSceneWindow, [&](){WidgetRenderWindow(ImVec2(800, 600));}},
|
|
{&showStatsWindow, [&](){WidgetRenderStats();}}
|
|
};
|
|
}
|
|
|
|
imguiManager::~imguiManager()
|
|
{
|
|
}
|
|
|
|
bool imguiManager::Initialize(HWND hwnd, ID3D11Device* device, ID3D11DeviceContext* deviceContext)
|
|
{
|
|
Logger::Get().Log("Initializing imgui", __FILE__, __LINE__, Logger::LogLevel::Initialize);
|
|
|
|
m_device = device;
|
|
m_deviceContext = deviceContext;
|
|
|
|
IMGUI_CHECKVERSION();
|
|
ImGui::CreateContext();
|
|
io = &ImGui::GetIO();
|
|
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
|
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
|
io->FontGlobalScale = 1.0f;
|
|
|
|
ImGui_ImplWin32_Init(hwnd);
|
|
ImGui_ImplDX11_Init(m_device, m_deviceContext);
|
|
|
|
// Appliquer un thème sombre de base
|
|
ImGui::StyleColorsDark();
|
|
|
|
// Définir les couleurs pour une interface de type éditeur sobre
|
|
ImGuiStyle& style = ImGui::GetStyle();
|
|
|
|
// Palette de couleurs sobres inspirée des éditeurs modernes
|
|
ImVec4 background_dark = ImVec4(0.10f, 0.10f, 0.10f, 1.00f); // Fond foncé
|
|
ImVec4 background = ImVec4(0.15f, 0.15f, 0.15f, 1.00f); // Fond principal
|
|
ImVec4 background_light = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); // Fond clair
|
|
ImVec4 accent = ImVec4(0.14f, 0.44f, 0.80f, 0.50f); // Accent bleu
|
|
ImVec4 accent_light = ImVec4(0.14f, 0.44f, 0.80f, 1.00f); // Accent bleu vif
|
|
ImVec4 text = ImVec4(1.0f, 1.0f, 1.0f, 1.00f); // Texte plus blanc
|
|
ImVec4 text_dim = ImVec4(0.70f, 0.70f, 0.70f, 1.00f);
|
|
|
|
// Ajustements de style généraux
|
|
style.WindowPadding = ImVec2(4.0f, 4.0f); // Moins de padding dans les fenêtres
|
|
style.FramePadding = ImVec2(4.0f, 3.0f); // Moins de padding dans les cadres
|
|
style.ItemSpacing = ImVec2(4.0f, 3.0f); // Moins d'espace entre les widgets
|
|
style.ItemInnerSpacing = ImVec2(3.0f, 3.0f); // Moins d'espace interne
|
|
style.DisplayWindowPadding = ImVec2(0.0f, 0.0f); // Pas de padding pour l'affichage
|
|
style.DisplaySafeAreaPadding = ImVec2(0.0f, 0.0f);
|
|
style.TouchExtraPadding = ImVec2(0.0f, 0.0f);
|
|
style.IndentSpacing = 20.0f;
|
|
style.ScrollbarSize = 14.0f;
|
|
style.GrabMinSize = 10.0f;
|
|
|
|
// Arrondis
|
|
style.WindowRounding = 4.0f;
|
|
style.ChildRounding = 4.0f;
|
|
style.FrameRounding = 3.0f;
|
|
style.PopupRounding = 4.0f;
|
|
style.ScrollbarRounding = 9.0f;
|
|
style.GrabRounding = 3.0f;
|
|
style.TabRounding = 4.0f;
|
|
|
|
// Couleurs principales
|
|
style.Colors[ImGuiCol_Text] = text;
|
|
style.Colors[ImGuiCol_TextDisabled] = text_dim;
|
|
style.Colors[ImGuiCol_WindowBg] = background;
|
|
style.Colors[ImGuiCol_ChildBg] = background_dark;
|
|
style.Colors[ImGuiCol_PopupBg] = background_dark;
|
|
style.Colors[ImGuiCol_Border] = ImVec4(0.25f, 0.25f, 0.27f, 1.00f);
|
|
style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
|
|
|
// Encadrements
|
|
style.Colors[ImGuiCol_FrameBg] = background_light;
|
|
style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f);
|
|
style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.30f, 0.30f, 0.30f, 1.00f);
|
|
|
|
// Titres
|
|
style.Colors[ImGuiCol_TitleBg] = background_dark;
|
|
style.Colors[ImGuiCol_TitleBgActive] = accent;
|
|
style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.12f, 0.12f, 0.12f, 0.90f);
|
|
|
|
// Éléments de menu
|
|
style.Colors[ImGuiCol_MenuBarBg] = background_dark;
|
|
style.Colors[ImGuiCol_ScrollbarBg] = background_dark;
|
|
style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.40f, 1.00f);
|
|
style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
|
|
style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
|
|
|
|
// Boutons et interactions
|
|
style.Colors[ImGuiCol_CheckMark] = accent_light;
|
|
style.Colors[ImGuiCol_SliderGrab] = accent;
|
|
style.Colors[ImGuiCol_SliderGrabActive] = accent_light;
|
|
style.Colors[ImGuiCol_Button] = background_light;
|
|
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.30f, 0.30f, 0.30f, 1.00f);
|
|
style.Colors[ImGuiCol_ButtonActive] = accent;
|
|
|
|
// En-têtes et onglets
|
|
style.Colors[ImGuiCol_Header] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
|
|
style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.25f, 0.25f, 0.25f, 1.00f);
|
|
style.Colors[ImGuiCol_HeaderActive] = accent;
|
|
|
|
style.Colors[ImGuiCol_Separator] = ImVec4(0.28f, 0.28f, 0.28f, 1.00f);
|
|
style.Colors[ImGuiCol_SeparatorHovered] = ImVec4(0.45f, 0.45f, 0.45f, 1.00f);
|
|
style.Colors[ImGuiCol_SeparatorActive] = accent;
|
|
|
|
style.Colors[ImGuiCol_Tab] = background_dark;
|
|
style.Colors[ImGuiCol_TabHovered] = accent;
|
|
style.Colors[ImGuiCol_TabActive] = accent;
|
|
style.Colors[ImGuiCol_TabUnfocused] = background_dark;
|
|
style.Colors[ImGuiCol_TabUnfocusedActive] = background;
|
|
|
|
// Autres éléments
|
|
style.Colors[ImGuiCol_DockingPreview] = accent;
|
|
style.Colors[ImGuiCol_DockingEmptyBg] = background_light;
|
|
|
|
// Charger une police avec une meilleure netteté
|
|
ImFontConfig fontConfig;
|
|
fontConfig.OversampleH = 2; // Suréchantillonnage horizontal
|
|
fontConfig.OversampleV = 2; // Suréchantillonnage vertical
|
|
fontConfig.PixelSnapH = true; // Alignement sur la grille de pixels
|
|
fontConfig.RasterizerMultiply = 1.2f; // Légère augmentation de l'épaisseur
|
|
io->Fonts->AddFontDefault(&fontConfig);
|
|
|
|
io->Fonts->Build();
|
|
|
|
// OU charger une police personnalisée (décommenter si vous avez la police)
|
|
// io->Fonts->AddFontFromFileTTF("assets/fonts/roboto.ttf", 16.0f, &fontConfig);
|
|
|
|
|
|
unsigned char* pixels;
|
|
int width, height;
|
|
io->Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
|
|
|
// initialize the scene manager
|
|
scene_manager_ = new scene_manager;
|
|
if (!scene_manager_->initialize(app_.get())) {
|
|
Logger::Get().Log("Failed to initialize scene manager", __FILE__, __LINE__, Logger::LogLevel::Error);
|
|
return false;
|
|
}
|
|
|
|
stats_ = app_->get_stats();
|
|
|
|
total_triangle_count_ = stats_->get_triangle_count_ptr();
|
|
total_vertex_count_ = stats_->get_vertex_count_ptr();
|
|
|
|
Logger::Get().Log("imgui initialized", __FILE__, __LINE__, Logger::LogLevel::Initialize);
|
|
|
|
return true;
|
|
}
|
|
|
|
void imguiManager::Shutdown()
|
|
{
|
|
Logger::Get().Log("Shutting down imgui", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
|
|
ImGui_ImplDX11_Shutdown();
|
|
ImGui_ImplWin32_Shutdown();
|
|
ImGui::DestroyContext();
|
|
Logger::Get().Log("imgui shutdown", __FILE__, __LINE__, Logger::LogLevel::Shutdown);
|
|
}
|
|
|
|
void imguiManager::Render()
|
|
{
|
|
ImGui::Render();
|
|
|
|
//app->get_direct_3d()->turn_z_buffer_off();
|
|
//app->get_direct_3d()->enable_alpha_blending();
|
|
|
|
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
|
|
|
//app->get_direct_3d()->disable_alpha_blending();
|
|
//app->get_direct_3d()->turn_z_buffer_on();
|
|
}
|
|
|
|
void imguiManager::NewFrame()
|
|
{
|
|
ImGui_ImplDX11_NewFrame();
|
|
ImGui_ImplWin32_NewFrame();
|
|
ImGui::NewFrame();
|
|
}
|
|
|
|
void imguiManager::SetupDockspace() {
|
|
// Configuration du style pour supprimer l'espace autour des fenêtres dockées
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
|
|
|
// Configuration du style pour les nœuds de dock
|
|
ImGui::PushStyleVar(ImGuiStyleVar_DockingSeparatorSize, 1.0f); // Réduit l'épaisseur des séparateurs
|
|
|
|
// Configuration de la fenêtre principale
|
|
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
|
ImGuiViewport* viewport = ImGui::GetMainViewport();
|
|
ImGui::SetNextWindowPos(viewport->Pos);
|
|
ImGui::SetNextWindowSize(viewport->Size);
|
|
ImGui::SetNextWindowViewport(viewport->ID);
|
|
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
|
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0));
|
|
|
|
ImGui::Begin("DockSpace", nullptr, window_flags);
|
|
|
|
// Pop des styles après avoir créé la fenêtre principale
|
|
ImGui::PopStyleVar(4); // 4 car nous avons poussé 4 variables de style
|
|
ImGui::PopStyleColor();
|
|
|
|
// Configuration du DockSpace
|
|
ImGuiID dockspace_id = ImGui::GetID("MainDockSpace");
|
|
ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
|
|
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
|
|
|
if (ImGui::BeginMenuBar()) {
|
|
if (ImGui::BeginMenu("Windows")) {
|
|
ImGui::MenuItem("Object Window", NULL, &showObjectWindow);
|
|
ImGui::MenuItem("Terrain Window", NULL, &showTerrainWindow);
|
|
ImGui::MenuItem("Light Window", NULL, &showLightWindow);
|
|
ImGui::MenuItem("Engine Settings Window", NULL, &showEngineSettingsWindow);
|
|
ImGui::MenuItem("Log Window", NULL, &showLogWindow);
|
|
ImGui::MenuItem("render Stats", NULL, &showStatsWindow);
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
if (ImGui::BeginMenu("Scene")) {
|
|
if (ImGui::MenuItem("Save Scene")) {
|
|
scene_manager_->save_scene();
|
|
}
|
|
if (ImGui::MenuItem("Save Scene As...")) {
|
|
scene_manager_->save_scene_as();
|
|
}
|
|
if (ImGui::MenuItem("Load Scene")) {
|
|
scene_manager_->load_scene();
|
|
}
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
ImGui::EndMenuBar();
|
|
}
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
void imguiManager::WidgetSpeedSlider(float* speed)
|
|
{
|
|
ImGui::SliderFloat("Speed", speed, 0.0f, 100.0f);
|
|
}
|
|
|
|
void imguiManager::WidgetButton()
|
|
{
|
|
static int counter = 0;
|
|
|
|
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
|
|
counter++;
|
|
ImGui::SameLine();
|
|
ImGui::Text("counter = %d", counter);
|
|
}
|
|
|
|
void imguiManager::WidgetAddObject()
|
|
{
|
|
if (ImGui::CollapsingHeader("Objects"))
|
|
{
|
|
if (ImGui::Button("Add Cube"))
|
|
{
|
|
app_->add_cube();
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::Button("Import Object"))
|
|
{
|
|
// Open file dialog
|
|
OPENFILENAME ofn;
|
|
WCHAR szFile[260];
|
|
ZeroMemory(&ofn, sizeof(ofn));
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = NULL;
|
|
ofn.lpstrFile = szFile;
|
|
ofn.lpstrFile[0] = '\0';
|
|
ofn.nMaxFile = sizeof(szFile);
|
|
ofn.lpstrFilter = L"OBJ\0*.obj\0KOBJ\0*.kobj\0TXT\0*.txt";
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFileTitle = NULL;
|
|
ofn.nMaxFileTitle = 0;
|
|
ofn.lpstrInitialDir = NULL;
|
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
|
|
|
if (GetOpenFileName(&ofn))
|
|
{
|
|
std::wstring filepath = ofn.lpstrFile;
|
|
|
|
WCHAR exePath[MAX_PATH];
|
|
GetModuleFileName(NULL,exePath,MAX_PATH);
|
|
std::wstring exeDir = exePath;
|
|
size_t pos = exeDir.find_last_of(L"\\/");
|
|
if(pos != std::wstring::npos)
|
|
{
|
|
exeDir = exeDir.substr(0, pos);
|
|
}
|
|
|
|
std::wstring targetDir = exeDir + L"\\Content\\Assets\\Kobject";
|
|
|
|
|
|
DWORD ftyp = GetFileAttributesW(targetDir.c_str());
|
|
if( ftyp == INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
std::wstring contentDir = exeDir + L"\\Content";
|
|
if (GetFileAttributes(contentDir.c_str()) == INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
CreateDirectory(contentDir.c_str(), NULL);
|
|
}
|
|
std::wstring assetsDir = contentDir + L"\\Assets";
|
|
if (GetFileAttributes(assetsDir.c_str()) == INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
CreateDirectory(assetsDir.c_str(), NULL);
|
|
}
|
|
std::wstring kobjectDir = assetsDir + L"\\Kobject";
|
|
if (GetFileAttributes(kobjectDir.c_str()) == INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
CreateDirectory(kobjectDir.c_str(), NULL);
|
|
}
|
|
}
|
|
|
|
size_t posFile = filepath.find_last_of(L"\\/");
|
|
std::wstring filename = (posFile != std::wstring::npos) ? filepath.substr(posFile + 1) : filepath;
|
|
|
|
std::wstring targetPath = targetDir + L"\\" + filename;
|
|
|
|
if (!CopyFile(filepath.c_str(), targetPath.c_str(), FALSE))
|
|
{
|
|
// En cas d'erreur, vous pouvez gérer ici l'erreur (par exemple afficher un message)
|
|
MessageBox(NULL, L"Erreur lors de la copie du fichier.", L"Erreur", MB_OK);
|
|
}
|
|
else
|
|
{
|
|
// On récupère le chemin relatif par rapport à exeDir
|
|
std::wstring relativePath = targetPath.substr(exeDir.size());
|
|
|
|
// Suppression du premier caractère s'il s'agit d'un antislash
|
|
if (!relativePath.empty() && (relativePath[0] == L'\\' || relativePath[0] == L'/'))
|
|
{
|
|
relativePath.erase(0, 1);
|
|
}
|
|
|
|
// Remplacer les antislashs par des slashs
|
|
std::replace(relativePath.begin(), relativePath.end(), L'\\', L'/');
|
|
app_->add_kobject(relativePath);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
ImGui::SameLine();
|
|
ImGui::Text("Number of cubes: %d", 1);
|
|
}
|
|
}
|
|
|
|
void imguiManager::WidgetObjectWindow()
|
|
{
|
|
ImGui::Begin("Objects", &showObjectWindow);
|
|
|
|
// Obtenir toutes les entités avec un composant d'identité et de transformation
|
|
auto entities = app_->get_entity_manager()->GetEntitiesWithComponent<ecs::IdentityComponent>();
|
|
|
|
int index = 0;
|
|
for (auto& entity : entities)
|
|
{
|
|
auto identity = entity->GetComponent<ecs::IdentityComponent>();
|
|
auto transform = entity->GetComponent<ecs::TransformComponent>();
|
|
auto render = entity->GetComponent<ecs::RenderComponent>();
|
|
auto shader = entity->GetComponent<ecs::ShaderComponent>();
|
|
auto physics = entity->GetComponent<ecs::PhysicsComponent>();
|
|
|
|
if (identity && transform)
|
|
{
|
|
std::string headerName = identity->GetName() + " " + std::to_string(identity->GetId());
|
|
if (ImGui::CollapsingHeader(headerName.c_str()))
|
|
{
|
|
// Position, Rotation, Scale
|
|
XMVECTOR position = transform->GetPosition();
|
|
XMVECTOR rotation = transform->GetRotation();
|
|
XMVECTOR scale = transform->GetScale();
|
|
|
|
float pos[3] = { XMVectorGetX(position), XMVectorGetY(position), XMVectorGetZ(position) };
|
|
std::string posLabel = "Position##" + std::to_string(identity->GetId());
|
|
if (ImGui::DragFloat3(posLabel.c_str(), pos))
|
|
{
|
|
transform->SetPosition(XMVectorSet(pos[0], pos[1], pos[2], 0.0f));
|
|
transform->UpdateWorldMatrix();
|
|
}
|
|
|
|
float rot[3] = { XMVectorGetX(rotation), XMVectorGetY(rotation), XMVectorGetZ(rotation) };
|
|
std::string rotLabel = "Rotation##" + std::to_string(identity->GetId());
|
|
if (ImGui::DragFloat3(rotLabel.c_str(), rot))
|
|
{
|
|
transform->SetRotation(XMVectorSet(rot[0], rot[1], rot[2], 0.0f));
|
|
transform->UpdateWorldMatrix();
|
|
}
|
|
|
|
float scl[3] = { XMVectorGetX(scale), XMVectorGetY(scale), XMVectorGetZ(scale) };
|
|
std::string sclLabel = "Scale##" + std::to_string(identity->GetId());
|
|
if (ImGui::DragFloat3(sclLabel.c_str(), scl))
|
|
{
|
|
transform->SetScale(XMVectorSet(scl[0], scl[1], scl[2], 0.0f));
|
|
transform->UpdateWorldMatrix();
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
// Textures - Seulement si le composant de rendu existe
|
|
if (render && render->GetModel())
|
|
{
|
|
// Définir les types de textures_
|
|
std::vector<std::string> textureCategories = {
|
|
"Diffuse", "Normal", "Specular", "Alpha"
|
|
};
|
|
|
|
std::vector<TextureType> textureTypes = {
|
|
TextureType::Diffuse, TextureType::Normal,
|
|
TextureType::Specular, TextureType::Alpha
|
|
};
|
|
|
|
// Créer un espace pour afficher les textures_ avec défilement
|
|
std::string textureChildId = "TextureChild##" + std::to_string(identity->GetId());
|
|
ImGui::BeginChild(textureChildId.c_str(), ImVec2(0, 200), true, ImGuiWindowFlags_HorizontalScrollbar);
|
|
|
|
// Pour chaque type de texture
|
|
for (int typeIndex = 0; typeIndex < textureCategories.size(); typeIndex++)
|
|
{
|
|
TextureType type = textureTypes[typeIndex];
|
|
std::string typeName = textureCategories[typeIndex];
|
|
|
|
// Afficher le titre de la catégorie
|
|
std::string categoryLabel = typeName + "##" + std::to_string(identity->GetId());
|
|
ImGui::Text("%s:", typeName.c_str());
|
|
ImGui::SameLine();
|
|
|
|
// Compter combien de textures_ de ce type existent
|
|
int textureCount = 0;
|
|
while (render->GetModel()->GetTexture(type, textureCount) != nullptr)
|
|
{
|
|
textureCount++;
|
|
}
|
|
|
|
// Afficher toutes les textures_ existantes
|
|
std::string groupId = "TextureGroup_" + std::to_string(identity->GetId()) + "_" + std::to_string(typeIndex);
|
|
ImGui::BeginGroup();
|
|
for (int texIndex = 0; texIndex < textureCount; texIndex++)
|
|
{
|
|
ID3D11ShaderResourceView* texture = render->GetModel()->GetTexture(type, texIndex);
|
|
if (texture)
|
|
{
|
|
// ID unique pour chaque bouton de texture
|
|
std::string buttonId = "tex##" + std::to_string(identity->GetId()) + "_" +
|
|
std::to_string(typeIndex) + "_" +
|
|
std::to_string(texIndex);
|
|
|
|
if (ImGui::ImageButton(buttonId.c_str(), (ImTextureID)texture, ImVec2(48, 48)))
|
|
{
|
|
// Ouvrir une boîte de dialogue pour changer la texture
|
|
OPENFILENAME ofn;
|
|
WCHAR szFile[260] = {0};
|
|
ZeroMemory(&ofn, sizeof(ofn));
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = NULL;
|
|
ofn.lpstrFile = szFile;
|
|
ofn.nMaxFile = sizeof(szFile);
|
|
ofn.lpstrFilter = L"Texture\0*.png;*.jpg;*.dds\0";
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrInitialDir = NULL;
|
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
|
|
|
if (GetOpenFileName(&ofn))
|
|
{
|
|
// Changer la texture existante
|
|
render->GetModel()->ChangeTexture(m_device, m_deviceContext, ofn.lpstrFile, type, texIndex);
|
|
}
|
|
}
|
|
|
|
// Afficher l'indice de texture et prévisualisation au survol
|
|
if (ImGui::IsItemHovered())
|
|
{
|
|
ImGui::BeginTooltip();
|
|
ImGui::Text("%s %d", typeName.c_str(), texIndex);
|
|
ImGui::Image((ImTextureID)texture, ImVec2(192, 192));
|
|
ImGui::EndTooltip();
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
}
|
|
}
|
|
|
|
// Bouton pour ajouter une nouvelle texture
|
|
std::string addButtonLabel = "+##" + std::to_string(identity->GetId()) + "_" + std::to_string(typeIndex);
|
|
if (ImGui::Button(addButtonLabel.c_str(), ImVec2(48, 48)))
|
|
{
|
|
// Ouvrir une boîte de dialogue pour ajouter une texture
|
|
OPENFILENAME ofn;
|
|
WCHAR szFile[260] = {0};
|
|
ZeroMemory(&ofn, sizeof(ofn));
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = NULL;
|
|
ofn.lpstrFile = szFile;
|
|
ofn.nMaxFile = sizeof(szFile);
|
|
ofn.lpstrFilter = L"Texture\0*.png;*.jpg;*.dds\0";
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrInitialDir = NULL;
|
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
|
|
|
if (GetOpenFileName(&ofn))
|
|
{
|
|
// Ajouter une nouvelle texture
|
|
render->GetModel()->AddTexture(m_device, m_deviceContext, ofn.lpstrFile, type);
|
|
}
|
|
}
|
|
|
|
ImGui::EndGroup();
|
|
ImGui::Separator();
|
|
}
|
|
|
|
ImGui::EndChild();
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
// Delete button
|
|
std::string deleteLabel = "Delete##" + std::to_string(identity->GetId());
|
|
if (ImGui::Button(deleteLabel.c_str()))
|
|
{
|
|
app_->delete_entity_by_id(identity->GetId());
|
|
// Sortir du boucle après suppression pour éviter des accès invalides
|
|
break;
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
// Shader options
|
|
if (shader)
|
|
{
|
|
// Liste des options de shader
|
|
const char* shaderOptions[] = {
|
|
"Enable Global Lighting",
|
|
"Enable Lighting",
|
|
"Enable Cel Shading",
|
|
"Enable Normal Mapping",
|
|
"Enable Specular Mapping",
|
|
"Enable Alpha Mapping"
|
|
};
|
|
|
|
std::vector<ecs::ShaderType> shaderTypes = {
|
|
ecs::ShaderType::SUNLIGHT,
|
|
ecs::ShaderType::LIGHTING,
|
|
ecs::ShaderType::CEL_SHADING,
|
|
ecs::ShaderType::NORMAL_MAPPING,
|
|
ecs::ShaderType::SPECULAR_MAPPING,
|
|
ecs::ShaderType::ALPHA_MAPPING
|
|
};
|
|
|
|
// Trouver l'index actuel du shader pour cette entité spécifique
|
|
int currentShader = 0;
|
|
ecs::ShaderType activeShader = shader->GetActiveShader();
|
|
for (size_t i = 0; i < shaderTypes.size(); i++)
|
|
{
|
|
if (shaderTypes[i] == activeShader)
|
|
{
|
|
currentShader = static_cast<int>(i);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Création du menu déroulant avec un ID unique pour chaque entité
|
|
std::string shaderComboId = "Shader Options##" + std::to_string(identity->GetId());
|
|
if (ImGui::BeginCombo(shaderComboId.c_str(), shaderOptions[currentShader]))
|
|
{
|
|
for (int i = 0; i < IM_ARRAYSIZE(shaderOptions); i++)
|
|
{
|
|
// Crée une option sélectionnable pour chaque shader avec ID unique
|
|
std::string shaderSelectableId = std::to_string(i) + "##shader_" + std::to_string(identity->GetId());
|
|
bool isSelected = (currentShader == i);
|
|
if (ImGui::Selectable(shaderOptions[i], isSelected))
|
|
{
|
|
// Met à jour l'option sélectionnée uniquement pour cette entité
|
|
currentShader = i;
|
|
shader->SetActiveShader(shaderTypes[i]);
|
|
}
|
|
|
|
// Si l'option sélectionnée est active, nous mettons en surbrillance
|
|
if (isSelected)
|
|
ImGui::SetItemDefaultFocus();
|
|
}
|
|
ImGui::EndCombo();
|
|
}
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
// Physics
|
|
bool isPhysicsEnabled = (physics != nullptr);
|
|
std::string physicsLabel = "Physics##" + std::to_string(identity->GetId());
|
|
|
|
if (ImGui::Checkbox(physicsLabel.c_str(), &isPhysicsEnabled))
|
|
{
|
|
if (isPhysicsEnabled && !physics)
|
|
{
|
|
// Ajouter un composant de physique
|
|
physics = entity->AddComponent<ecs::PhysicsComponent>();
|
|
physics->Initialize();
|
|
}
|
|
else if (!isPhysicsEnabled && physics)
|
|
{
|
|
// Retirer le composant de physique
|
|
entity->RemoveComponent<ecs::PhysicsComponent>();
|
|
physics = nullptr;
|
|
}
|
|
}
|
|
|
|
if (physics)
|
|
{
|
|
// Gravity Enabled checkbox
|
|
bool gravityEnabled = physics->IsGravityEnabled();
|
|
std::string gravityLabel = "Gravity##" + std::to_string(identity->GetId());
|
|
if (ImGui::Checkbox(gravityLabel.c_str(), &gravityEnabled))
|
|
{
|
|
physics->SetGravityEnabled(gravityEnabled);
|
|
}
|
|
|
|
// 3 radio buttons pour le type d'objet physique avec IDs uniques
|
|
std::string typeLabel = "Type##" + std::to_string(identity->GetId());
|
|
ecs::ObjectType type = identity->GetType();
|
|
|
|
if (ImGui::RadioButton(("None##" + std::to_string(identity->GetId())).c_str(),
|
|
type == ecs::ObjectType::Unknown))
|
|
{
|
|
identity->SetType(ecs::ObjectType::Unknown);
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::RadioButton(("Cube##" + std::to_string(identity->GetId())).c_str(),
|
|
type == ecs::ObjectType::Cube))
|
|
{
|
|
identity->SetType(ecs::ObjectType::Cube);
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::RadioButton(("Sphere##" + std::to_string(identity->GetId())).c_str(),
|
|
type == ecs::ObjectType::Sphere))
|
|
{
|
|
identity->SetType(ecs::ObjectType::Sphere);
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::RadioButton(("Terrain##" + std::to_string(identity->GetId())).c_str(),
|
|
type == ecs::ObjectType::Terrain))
|
|
{
|
|
identity->SetType(ecs::ObjectType::Terrain);
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::Separator();
|
|
}
|
|
index++;
|
|
}
|
|
}
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
void imguiManager::WidgetTerrainWindow()
|
|
{
|
|
ImGui::Begin("Terrain", &showTerrainWindow);
|
|
|
|
ImGui::Text("Number of terrain cubes: %d", 1);
|
|
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::Button("Generate Flat Terrain"))
|
|
{
|
|
app_->generate_terrain();
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
// Input for the number of cubes on each side
|
|
ImGui::Text("Number of cubes on each side: ");
|
|
ImGui::SameLine();
|
|
ImGui::InputInt("##SideCount", &m_SideCount);
|
|
if (m_SideCount < 1)
|
|
{
|
|
m_SideCount = 1;
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::Button("Generate BigCube Terrain"))
|
|
{
|
|
app_->create_big_cube(m_SideCount);
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::Button("Delete All Terrain Cubes"))
|
|
{
|
|
app_->delete_terrain();
|
|
}
|
|
|
|
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
bool imguiManager::ImGuiWidgetRenderer()
|
|
{
|
|
// Start the Dear ImGui frame
|
|
NewFrame();
|
|
|
|
// Setup the dockspace
|
|
SetupDockspace();
|
|
|
|
//ImGui Widget
|
|
ImGui::Begin("Khaotic Engine", NULL);
|
|
|
|
float speed = app_->get_speed();
|
|
|
|
WidgetSpeedSlider(&speed);
|
|
app_->set_speed(speed);
|
|
WidgetButton();
|
|
WidgetAddObject();
|
|
|
|
ImGui::End();
|
|
|
|
// Read the widget list and call the function if the show variable is true
|
|
for (const auto& entry : widgets_)
|
|
{
|
|
if (*entry.show == true) {entry.func();}
|
|
}
|
|
|
|
//render imgui
|
|
Render();
|
|
|
|
return true;
|
|
}
|
|
|
|
void imguiManager::WidgetLightWindow()
|
|
{
|
|
ImGui::Begin("Light", &showLightWindow);
|
|
|
|
|
|
// Sun light settings
|
|
light_class* sunLight = app_->get_sun_light();
|
|
// Direction input
|
|
XMFLOAT3 direction = sunLight->GetDirection();
|
|
float dir[3] = { direction.x, direction.y, direction.z };
|
|
if (ImGui::DragFloat3("Sun Direction", dir))
|
|
{
|
|
sunLight->SetDirection(dir[0], dir[1], dir[2]);
|
|
}
|
|
// Color input
|
|
XMFLOAT4 color = sunLight->GetDiffuseColor();
|
|
float col[3] = { color.x, color.y, color.z };
|
|
if (ImGui::ColorEdit3("Sun Color", col))
|
|
{
|
|
sunLight->SetDiffuseColor(col[0], col[1], col[2], 1.0f);
|
|
}
|
|
// Intensity input
|
|
float intensity = sunLight->GetIntensity();
|
|
if (ImGui::DragFloat("Sun Intensity", &intensity, 0.1f, 0.0f, 100.0f))
|
|
{
|
|
sunLight->SetIntensity(intensity);
|
|
}
|
|
|
|
|
|
ImGui::Separator();
|
|
|
|
int index = 0;
|
|
|
|
// Area light settings
|
|
|
|
for(auto& light : app_->get_lights())
|
|
{
|
|
std::string headerName = "Light " + std::to_string(index);
|
|
if (ImGui::CollapsingHeader(headerName.c_str()))
|
|
{
|
|
XMVECTOR position = app_->get_light_position(index);
|
|
XMVECTOR color = app_->get_light_color(index);
|
|
float pos[3] = { XMVectorGetX(position), XMVectorGetY(position), XMVectorGetZ(position) };
|
|
float col[3] = { XMVectorGetX(color), XMVectorGetY(color), XMVectorGetZ(color) };
|
|
|
|
std::string posLabel = "Position##" + std::to_string(index);
|
|
std::string colLabel = "Color##" + std::to_string(index);
|
|
|
|
if (ImGui::DragFloat3(posLabel.c_str(), pos))
|
|
{
|
|
app_->set_light_position(index, XMVectorSet(pos[0], pos[1], pos[2], 0.0f));
|
|
}
|
|
|
|
if (ImGui::ColorEdit3(colLabel.c_str(), col))
|
|
{
|
|
app_->set_light_color(index, XMVectorSet(col[0], col[1], col[2], 0.0f));
|
|
}
|
|
|
|
}
|
|
index++;
|
|
};
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
void imguiManager::WidgetEngineSettingsWindow()
|
|
{
|
|
ImGui::Begin("Engine Settings", &showEngineSettingsWindow);
|
|
|
|
// Begining Of General Setting
|
|
ImGui::Text("General");
|
|
|
|
// Checkbox for toggling vsync globally in the application class by calling the set_vsync function in the application class when the checkbox state changes
|
|
bool vsync = app_->get_vsync();
|
|
if (ImGui::Checkbox("Vsync", &vsync))
|
|
{
|
|
app_->set_vsync(vsync);
|
|
}
|
|
|
|
// End Of General Setting
|
|
ImGui::Separator();
|
|
// culling section
|
|
ImGui::Text("Culling");
|
|
|
|
// float input for frustum tolerance
|
|
float frustumTolerance = app_->get_frustum_tolerance();
|
|
if (ImGui::DragFloat("Frustum Tolerance", &frustumTolerance, 0.1f, 0.0f, 100.0f))
|
|
{
|
|
app_->set_frustum_tolerance(frustumTolerance);
|
|
}
|
|
|
|
// End Of Culling Setting
|
|
ImGui::Separator();
|
|
|
|
// physics section
|
|
ImGui::Text("physics");
|
|
|
|
// Input To set the Fixed Update Interval
|
|
int physicsInterval = app_->get_physics_tick_rate();
|
|
if (ImGui::InputInt("physics Tick Rate", &physicsInterval))
|
|
{
|
|
app_->set_physics_tick_rate(physicsInterval);
|
|
}
|
|
|
|
// Input to change the gravity on same line
|
|
XMVECTOR gravity = app_->get_physics()->GetGravity();
|
|
float gravityValues[3] = { XMVectorGetX(gravity), XMVectorGetY(gravity), XMVectorGetZ(gravity) };
|
|
if (ImGui::DragFloat3("Gravity", gravityValues))
|
|
{
|
|
app_->get_physics()->SetGravity(XMVectorSet(gravityValues[0], gravityValues[1], gravityValues[2], 0.0f));
|
|
}
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
void imguiManager::WidgetLogWindow()
|
|
{
|
|
ImGui::Begin("Log Window" , &showLogWindow);
|
|
|
|
// Filtre de recherche
|
|
static ImGuiTextFilter filter;
|
|
filter.Draw("Filter ", 180);
|
|
|
|
ImGui::SameLine();
|
|
|
|
// Bouton pour ouvrir le fichier de log
|
|
if (ImGui::Button("Open Log File"))
|
|
{
|
|
ShellExecuteA(NULL, "open", Logger::Get().m_logFilePath.c_str(), NULL, NULL, SW_SHOWNORMAL);
|
|
}
|
|
|
|
// Place the menu on the same line as the filter
|
|
ImGui::SameLine();
|
|
|
|
// Menu déroulant pour les niveaux de log
|
|
if (ImGui::BeginMenu("Log Levels"))
|
|
{
|
|
for (size_t i = 0; i < Logger::LogLevelCount; ++i)
|
|
{
|
|
bool isVisible = !Logger::Get().m_disabledLogLevels[i];
|
|
if (ImGui::Checkbox(Logger::Get().GetLogLevelInfo(static_cast<Logger::LogLevel>(i)).name, &isVisible))
|
|
{
|
|
Logger::Get().m_disabledLogLevels[i] = !isVisible;
|
|
}
|
|
}
|
|
ImGui::EndMenu();
|
|
}
|
|
|
|
const auto& logBuffer = Logger::Get().GetLogBuffer();
|
|
std::vector<Logger::LogEntry> logfiltered;
|
|
int logCount = logBuffer.size();
|
|
|
|
// Affichage des logs filtrés
|
|
ImGui::BeginChild("Log");
|
|
|
|
for (const auto& log : logBuffer)
|
|
{
|
|
if (filter.PassFilter(log.message.c_str()) && !Logger::Get().m_disabledLogLevels[static_cast<size_t>(log.level)])
|
|
{
|
|
logfiltered.push_back(log);
|
|
}
|
|
}
|
|
|
|
if (logfiltered.size() == 0)
|
|
{
|
|
ImGui::Text("No logs to display.");
|
|
}
|
|
else
|
|
{
|
|
ImGuiListClipper clipper;
|
|
clipper.Begin(logCount);
|
|
while (clipper.Step())
|
|
{
|
|
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
|
{
|
|
if (i < logfiltered.size()) {
|
|
const auto& log = logfiltered[i];
|
|
ImGui::TextColored(Logger::Get().GetLogLevelInfo(log.level).color, log.message.c_str());
|
|
}
|
|
|
|
}
|
|
}
|
|
clipper.End();
|
|
}
|
|
|
|
// Scroll to the bottom
|
|
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
|
|
{
|
|
ImGui::SetScrollHereY(1.0f);
|
|
}
|
|
|
|
ImGui::EndChild();
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
void imguiManager::WidgetRenderWindow(ImVec2 availableSize)
|
|
{
|
|
ImGui::Begin("render Window");
|
|
|
|
ImVec2 oldWindowSize = windowSize;
|
|
windowSize = ImGui::GetContentRegionAvail();
|
|
|
|
// Si la taille de la fenêtre a changé, ajustez la taille de la fenêtre de l'application
|
|
if (oldWindowSize.x != windowSize.x || oldWindowSize.y != windowSize.y)
|
|
{
|
|
app_->set_window_size(windowSize);
|
|
}
|
|
|
|
|
|
// Get the aspect ratio of the scene in app
|
|
float aspectRatio = app_->get_aspect_ratio();
|
|
// calculate the size of the window
|
|
if (windowSize.x / windowSize.y > aspectRatio)
|
|
{
|
|
windowSize.x = windowSize.y * aspectRatio;
|
|
}
|
|
else
|
|
{
|
|
windowSize.y = windowSize.x / aspectRatio;
|
|
}
|
|
|
|
ID3D11ShaderResourceView* texture = app_->get_scene_texture()->GetShaderResourceView();
|
|
if (texture)
|
|
{
|
|
|
|
// Affichez la scenne projeté sur texture dans une fenêtre ImGui
|
|
// alpha blend is not enable to render the texture
|
|
|
|
app_->get_direct_3d()->turn_z_buffer_off();
|
|
app_->get_direct_3d()->enable_alpha_blending();
|
|
|
|
ImGui::Image((ImTextureID)texture, windowSize, ImVec2(0, 0), ImVec2(1, 1), ImVec4(1, 1, 1, 1));
|
|
}
|
|
else
|
|
{
|
|
ImGui::Text("render texture is not available.");
|
|
}
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
void imguiManager::WidgetRenderStats()
|
|
{
|
|
ImGui::Begin("render Stats");
|
|
|
|
current_fps_ = stats_->get_current_fps();
|
|
min_fps_ = stats_->get_min_fps();
|
|
max_fps_ = stats_->get_max_fps();
|
|
draw_calls_ = stats_->get_draw_calls();
|
|
|
|
|
|
// total_vertex_count_ = stats_->get_total_vertex_count();
|
|
// total_triangle_count_ = stats_->get_total_triangle_count();
|
|
|
|
visible_triangle_count_ = stats_->get_visible_triangle_count();
|
|
current_frame_time_ = stats_->get_frame_time();
|
|
|
|
m_frameTimeHistory[m_frameTimeHistoryIndex] = current_frame_time_;
|
|
m_frameTimeHistoryIndex = (m_frameTimeHistoryIndex + 1) % FRAME_HISTORY_COUNT;
|
|
|
|
ImGui::Text("FPS: %d", current_fps_);
|
|
ImGui::SameLine();
|
|
ImGui::Text("Min Fps: %d", min_fps_);
|
|
ImGui::SameLine();
|
|
ImGui::Text("Max Fps: %d", max_fps_);
|
|
|
|
ImGui::Separator();
|
|
|
|
// Trouver les valeurs min/max pour l'échelle du graphique
|
|
float frameTimeMin = FLT_MAX;
|
|
float frameTimeMax = 0.0f;
|
|
for (int i = 0; i < FRAME_HISTORY_COUNT; i++) {
|
|
if (m_frameTimeHistory[i] > 0.0f) {
|
|
frameTimeMin = min(frameTimeMin, m_frameTimeHistory[i]);
|
|
frameTimeMax = max(frameTimeMax, m_frameTimeHistory[i]);
|
|
}
|
|
}
|
|
// S'assurer d'avoir au moins une petite plage
|
|
if (frameTimeMax == 0.0f) frameTimeMax = 0.033f; // ~30 FPS
|
|
if (frameTimeMin == FLT_MAX) frameTimeMin = 0.0f;
|
|
|
|
// Ajouter 10% de marge pour la lisibilité
|
|
float margin = (frameTimeMax - frameTimeMin) * 0.1f;
|
|
frameTimeMin = max(0.0f, frameTimeMin - margin);
|
|
frameTimeMax += margin;
|
|
|
|
// Afficher le graphique
|
|
ImGui::Text("Frame Time: %.3f ms", current_frame_time_ * 1000.0f);
|
|
ImGui::PlotLines("FrameTimeGraph", // Au lieu de chaîne vide ""
|
|
m_frameTimeHistory,
|
|
FRAME_HISTORY_COUNT,
|
|
m_frameTimeHistoryIndex,
|
|
"",
|
|
frameTimeMin,
|
|
frameTimeMax,
|
|
ImVec2(0, 80));
|
|
|
|
ImGui::Text("Draw Calls: %d", draw_calls_);
|
|
|
|
ImGui::Separator();
|
|
|
|
ImGui::Text("Statistiques de rendu:");
|
|
ImGui::Text("Vertices total: %d", *total_vertex_count_);
|
|
|
|
ImGui::Text("Triangles total: %d", *total_triangle_count_);
|
|
ImGui::SameLine();
|
|
ImGui::Text("Triangles visibles: %d", visible_triangle_count_);
|
|
|
|
app_->get_direct_3d()->get_video_card_info(card_name_, video_memory_);
|
|
cpu_name_ = stats_->get_cpu_name();
|
|
version_driver_ = stats_->get_gpu_driver_version(app_->get_direct_3d()->get_device());
|
|
|
|
ImGui::Columns(3, "GPUCPURAMColumns", false);
|
|
ImGui::SetColumnWidth(0, ImGui::GetWindowWidth() * 0.33f);
|
|
ImGui::SetColumnWidth(1, ImGui::GetWindowWidth() * 0.33f);
|
|
|
|
// Premier collapsing header pour les informations GPU
|
|
if (ImGui::CollapsingHeader("Informations GPU"))
|
|
{
|
|
ImGui::Text("Carte graphique: %s", card_name_);
|
|
ImGui::Text("Memoire video: %d Mo", video_memory_);
|
|
ImGui::Text("Pilote: %s", version_driver_.c_str());
|
|
}
|
|
|
|
ImGui::NextColumn();
|
|
|
|
// Second collapsing header pour les informations CPU
|
|
if (ImGui::CollapsingHeader("Informations CPU"))
|
|
{
|
|
SYSTEM_INFO sysInfo;
|
|
GetSystemInfo(&sysInfo);
|
|
ImGui::Text("Processeur: %s", cpu_name_.c_str());
|
|
ImGui::Text("Nombre de coeurs: %u", sysInfo.dwNumberOfProcessors);
|
|
ImGui::Text("Architecture: %s", (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ? "x64" : "x86");
|
|
ImGui::Text("Taille de la page: %u octets", sysInfo.dwPageSize);
|
|
ImGui::Text("Taille du cache: %u octets", sysInfo.dwAllocationGranularity);
|
|
ImGui::Text("Type de processeur: %u", sysInfo.wProcessorLevel);
|
|
ImGui::Text("Version du processeur: %u", sysInfo.wProcessorRevision);
|
|
}
|
|
|
|
ImGui::NextColumn();
|
|
|
|
if (ImGui::CollapsingHeader("Informations RAM"))
|
|
{
|
|
MEMORYSTATUSEX mem_info;
|
|
mem_info.dwLength = sizeof(MEMORYSTATUSEX);
|
|
GlobalMemoryStatusEx(&mem_info);
|
|
ImGui::Text("Memoire totale: %llu Mo", mem_info.ullTotalPhys / (1024 * 1024));
|
|
ImGui::Text("Memoire disponible: %llu Mo", mem_info.ullAvailPhys / (1024 * 1024));
|
|
ImGui::Text("Memoire utilisee: %llu Mo", (mem_info.ullTotalPhys - mem_info.ullAvailPhys) / (1024 * 1024));
|
|
}
|
|
|
|
ImGui::Columns(1);
|
|
|
|
ImGui::End();
|
|
}
|
|
|