From b467feb01525562c3fcc84a3c4a7f7de586446c7 Mon Sep 17 00:00:00 2001 From: Alfie King Date: Thu, 10 Jul 2025 02:14:01 +0100 Subject: [PATCH] setup --- .gitignore | 3 + .gitmodules | 4 ++ imgui | 1 + include/main.hpp | 44 ++++++++++++ makefile | 74 +++++++++++++++++++++ src/main.cpp | 170 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 296 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 160000 imgui create mode 100644 include/main.hpp create mode 100644 makefile create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cefb221 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vscode +build +imgui.ini \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..6491ee4 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "imgui"] + path = imgui + url = https://github.com/ocornut/imgui.git + branch = docking diff --git a/imgui b/imgui new file mode 160000 index 0000000..44aa9a4 --- /dev/null +++ b/imgui @@ -0,0 +1 @@ +Subproject commit 44aa9a4b3a6f27d09a4eb5770d095cbd376dfc4b diff --git a/include/main.hpp b/include/main.hpp new file mode 100644 index 0000000..1709fd7 --- /dev/null +++ b/include/main.hpp @@ -0,0 +1,44 @@ +#ifndef MAIN_HPP +#define MAIN_HPP + +// ImGui +#include "imgui.h" +#include "imgui_impl_sdl3.h" +#include "imgui_impl_opengl3.h" + +// SDL3 and OpenGL +#include +#include + +// C++ Standard Library +#include +#include +#include + +// Structs + + + +// Variables +int window_width = 1920; +int window_height = 1080; + +float main_scale; +SDL_WindowFlags window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY; +SDL_Window* window; + +bool running; +SDL_Event event; + +Uint32 last_time; +Uint32 current_time; +float frame_time; +float fps; +float frame_time_graph[100] = {0.0f}; + +// Functions +int main(int argc, char* argv[]); +int initialize(); +void cleanup(); + +#endif \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..b389898 --- /dev/null +++ b/makefile @@ -0,0 +1,74 @@ +# Directories +INCLUDE_DIR = include +SRC_DIR = src +BUILD_DIR = build + +# ImGui directory (only set if ImGui is used) +IMGUI_DIR = imgui + +# Compiler +CXX = g++ + +# Libs +LIBS = -lGL `pkg-config --libs sdl3` + +# Compiler and linker settings +CXXFLAGS = `pkg-config --cflags sdl3` -std=c++17 -I $(INCLUDE_DIR) + +# If ImGui directory is set, include its source files +ifdef IMGUI_DIR +CXXFLAGS += -I $(IMGUI_DIR) -I $(IMGUI_DIR)/backends +endif + +# Source and object files +SRC = $(wildcard $(SRC_DIR)/*.cpp) + +# If ImGui is used, add its source files to the source list +ifdef IMGUI_DIR +SRC += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp +SRC += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp +endif + +# Target executable +UNAME := $(shell uname -s) +BUILD_DIR := $(BUILD_DIR)/$(UNAME) +OBJ_DIR := $(BUILD_DIR)/objs +BIN = $(BUILD_DIR)/main + +# Object files corresponding to the source files (now in obj directory) +OBJS = $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(basename $(notdir $(SRC))))) + +# development target with debugging +dev: CXXFLAGS += -g -Wall -Wformat +dev: all + +# Release target +release: CXXFLAGS += -O3 +release: all + +# Create directories for build output +dirs: + @mkdir -p $(BUILD_DIR) + @mkdir -p $(OBJ_DIR) + +# Pattern rule for source files in src directory +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +# Pattern rule for ImGui source files +ifdef IMGUI_DIR +$(OBJ_DIR)/%.o: $(IMGUI_DIR)/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +$(OBJ_DIR)/%.o: $(IMGUI_DIR)/backends/%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< +endif + +all: dirs $(BIN) + @echo Build complete + +$(BIN): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -rf $(BUILD_DIR) \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..85a5911 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,170 @@ +#include "main.hpp" + + +// Init +int initialize() { + // Initialize SDL + if (!SDL_Init(SDL_INIT_VIDEO)) { + std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl; + return 1; // Initialization failed + } + + // Create a window with OpenGL context + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + + main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); + window = SDL_CreateWindow("Untitled", (int)(window_width * main_scale), (int)(window_height * main_scale), window_flags); + if (!window) { + std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl; + SDL_Quit(); + return 1; // Window creation failed + } + + // Initialize OpenGL context + SDL_GLContext gl_context = SDL_GL_CreateContext(window); + if (!gl_context) { + std::cerr << "OpenGL context could not be created! SDL_Error: " << SDL_GetError() << std::endl; + SDL_DestroyWindow(window); + SDL_Quit(); + return 1; // OpenGL context creation failed + } + + SDL_GL_MakeCurrent(window, gl_context); + SDL_GL_SetSwapInterval(1); // Enable VSync + SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); + SDL_ShowWindow(window); + + // Initialize ImGui + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + + // Setup scale + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); + style.FontScaleDpi = main_scale; + + // Setup Platform/Renderer bindings + if (!ImGui_ImplSDL3_InitForOpenGL(window, gl_context)) { + std::cerr << "ImGui_ImplSDL3_InitForOpenGL failed!" << std::endl; + SDL_GL_DestroyContext(gl_context); + SDL_DestroyWindow(window); + SDL_Quit(); + return 1; // Initialization failed + } + + if (!ImGui_ImplOpenGL3_Init("#version 330")) { + std::cerr << "ImGui_ImplOpenGL3_Init failed!" << std::endl; + ImGui_ImplSDL3_Shutdown(); + SDL_GL_DestroyContext(gl_context); + SDL_DestroyWindow(window); + SDL_Quit(); + return 1; // Initialization failed + } + + return 0; // Initialization successful +} + + +// Cleanup +void cleanup() { + // Shutdown ImGui + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplSDL3_Shutdown(); + ImGui::DestroyContext(); + + // Destroy OpenGL context + SDL_GLContext gl_context = SDL_GL_GetCurrentContext(); + if (gl_context) { + SDL_GL_MakeCurrent(NULL, NULL); + SDL_GL_DestroyContext(gl_context); + } + + // Destroy window + if (window) { + SDL_DestroyWindow(window); + window = nullptr; + } + + // Quit SDL + SDL_Quit(); + std::cout << "Cleanup successful." << std::endl; +} + + +// Main +int main(int argc, char* argv[]) { + // Initialize + if (initialize() != 0) { + std::cerr << "Initialization failed." << std::endl; + return -1; // Initialization failed + } + + // Main loop + running = true; + last_time = SDL_GetTicks(); + while (running) { + + // Handle events + while (SDL_PollEvent(&event)) { + ImGui_ImplSDL3_ProcessEvent(&event); + if (event.type == SDL_EVENT_QUIT) { + running = false; // Exit loop on quit event + } + } + + // Start the ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplSDL3_NewFrame(); + ImGui::NewFrame(); + + // Show a simple ImGui window + ImGui::Begin("Hello, World!"); + ImGui::Text("This is a simple ImGui window."); + if (ImGui::Button("Close")) { + running = false; // Close button clicked + } + ImGui::End(); + + // Display FPS in the ImGui window + ImGui::Begin("FPS Counter"); + ImGui::Text("Current FPS: %.2f", fps); + // Frame time graph + ImGui::PlotLines("##FrameTime", frame_time_graph, 100, 0, "Frame Time (ms)", 0.0f, 0.1f, ImVec2(200, 80)); + ImGui::Text("Current Time: %u ms", current_time); + + ImGui::End(); + + // Render + ImGui::Render(); + glViewport(0, 0, (int)(window_width * main_scale), (int)(window_height * main_scale)); + glClearColor(0.45f, 0.55f, 0.60f, 1.00f); + glClear(GL_COLOR_BUFFER_BIT); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + SDL_GL_SwapWindow(window); + + // Calculate FPS + current_time = SDL_GetTicks(); + frame_time = (current_time - last_time) / 1000.0f; // Convert milliseconds to seconds + fps = 1.0f / frame_time; + last_time = current_time; + + // Update frame time graph + for (int i = 99; i > 0; --i) { + frame_time_graph[i] = frame_time_graph[i - 1]; // Shift old values + } + frame_time_graph[0] = frame_time; // Add new frame time + } + + // Cleanup + cleanup(); +} \ No newline at end of file