sdl and opengl contexts

This commit is contained in:
2025-11-23 10:10:57 +00:00
parent bed8e5e363
commit d5ac791a1a
6 changed files with 218 additions and 12 deletions

28
inc/engine/opengl.hpp Normal file
View File

@@ -0,0 +1,28 @@
#ifndef OPENGL_HPP
#define OPENGL_HPP
// Includes
#include <SDL3/SDL_opengl.h>
#include "engine/sdl.hpp"
// OpenGL Context Class
class OpenGLContext {
public:
OpenGLContext(SDLWindow& window);
~OpenGLContext();
bool isInitialized() const;
void makeCurrent();
void swapBuffers();
float getFrameTime();
private:
SDLWindow& window;
SDL_GLContext glContext;
Uint32 lastTime;
float frameTime;
};
#endif

28
inc/engine/sdl.hpp Normal file
View File

@@ -0,0 +1,28 @@
#ifndef SDL_HPP
#define SDL_HPP
// Includes
#include <SDL3/SDL.h>
// Classes
class SDLWindow {
public:
SDLWindow(const char* title, int width, int height, SDL_WindowFlags flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_HIDDEN);
~SDLWindow();
void setEventCallback(void (*callback)(const SDL_Event&));
void pollEvents();
bool isRunning() const;
void showWindow();
void hideWindow();
void setPosition(int x, int y);
SDL_Window* getSDLWindow() const;
private:
SDL_Window* window;
SDL_Event event;
bool running;
void (*eventCallback)(const SDL_Event&) = nullptr;
};
#endif

View File

@@ -3,26 +3,32 @@ INCLUDE_DIR = inc
SRC_DIR = src
BUILD_DIR = build
# imgui bs
# imgui
IMGUI_DIR = lib/imgui
INCLUDE_DIR += $(IMGUI_DIR) $(IMGUI_DIR)/backends
# Compiler, flags and libraries
CXX = g++
CXX = g++
CXXFLAGS = -std=c++17
LIBS = -lGL -lglm `pkg-config --libs sdl3 sdl3-image`
# =============================== Don't touch below pwease :3 ===============================
# Compiler and linker settings
# Include dirs in compiler flags
CXXFLAGS += $(addprefix -I, $(INCLUDE_DIR))
# Source files
SRC = $(wildcard $(SRC_DIR)/*.cpp)
# Source files (app + subdirs)
SRC := $(wildcard $(SRC_DIR)/*.cpp) $(wildcard $(SRC_DIR)/*/*.cpp)
# Imgui specific stuff
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
# ImGui specific sources (explicit list)
IMGUI_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 \
$(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp \
$(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp
SRC += $(IMGUI_SRC)
# Target executable
UNAME := $(shell uname -s)
@@ -30,8 +36,13 @@ BUILD_DIR := $(BUILD_DIR)/$(UNAME)
OBJ_DIR := $(BUILD_DIR)/objs
BIN = $(BUILD_DIR)/main
# Note: I have no clue how this works, copilot made it for me cus my usual makefile didn't like the directory structure :P
# Object files corresponding to the source files
OBJS = $(addprefix $(OBJ_DIR)/, $(addsuffix .o, $(basename $(notdir $(SRC)))))
# Map source paths to object paths so subdirectories are preserved.
# - Files under `$(SRC_DIR)` become `$(OBJ_DIR)/<subdirs>/name.o`
# - ImGui files (in `$(IMGUI_DIR)` and its `backends`) become `$(OBJ_DIR)/name.o`
OBJS := $(foreach f,$(SRC),$(if $(filter $(SRC_DIR)/%,$(f)),$(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(f)),$(if $(filter $(IMGUI_DIR)/backends/%,$(f)),$(patsubst $(IMGUI_DIR)/backends/%.cpp,$(OBJ_DIR)/%.o,$(f)),$(patsubst $(IMGUI_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(f)))) )
# black magic wizardry below this line (pwease don't touch i beg you)
dev: CXXFLAGS += -g -Wall -Wformat
@@ -43,6 +54,8 @@ release: all
dirs:
@mkdir -p $(BUILD_DIR)
@mkdir -p $(OBJ_DIR)
# create any required subdirectories for object files
@mkdir -p $(sort $(dir $(OBJS)))
# Even more imgui specific stuff >:(
$(OBJ_DIR)/%.o: $(IMGUI_DIR)/%.cpp
@@ -58,7 +71,9 @@ all: dirs $(BIN)
@echo Build complete
$(BIN): $(OBJS)
$(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS)
$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
.PHONY: all dev release clean dirs
clean:
rm -rf $(BUILD_DIR)

44
src/engine/opengl.cpp Normal file
View File

@@ -0,0 +1,44 @@
#include "engine/opengl.hpp"
// OpenGLContext Constructor
OpenGLContext::OpenGLContext(SDLWindow& window): window(window), lastTime(SDL_GetTicks()), frameTime(0.0f) {
glContext = SDL_GL_CreateContext(window.getSDLWindow());
if (!glContext) {
// Handle context creation error
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create OpenGL context: %s", SDL_GetError());
return;
}
SDL_GL_MakeCurrent(window.getSDLWindow(), glContext);
}
// OpenGLContext Destructor
OpenGLContext::~OpenGLContext() {
if (glContext) {
SDL_GL_DestroyContext(glContext);
}
}
// Check if Initialized
bool OpenGLContext::isInitialized() const {
return glContext != nullptr;
}
// Make Context Current
void OpenGLContext::makeCurrent() {
SDL_GL_MakeCurrent(window.getSDLWindow(), glContext);
}
// Swap Buffers
void OpenGLContext::swapBuffers() {
SDL_GL_SwapWindow(window.getSDLWindow());
// Update frame time
Uint32 currentTime = SDL_GetTicks();
frameTime = (currentTime - lastTime) / 1000.0f;
lastTime = currentTime;
}
// Get Frame Time
float OpenGLContext::getFrameTime() {
return frameTime;
}

72
src/engine/sdl.cpp Normal file
View File

@@ -0,0 +1,72 @@
#include "engine/sdl.hpp"
// SDLWindow Constructor
SDLWindow::SDLWindow(const char* title, int width, int height, SDL_WindowFlags flags): running(true) {
if (!SDL_Init(SDL_INIT_VIDEO)) {
// Handle initialization error
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize SDL: %s", SDL_GetError());
running = false;
return;
}
window = SDL_CreateWindow(title, width, height, flags);
if (!window) {
// Handle window creation error
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to create SDL window: %s", SDL_GetError());
SDL_Quit();
running = false;
}
return;
}
// SDLWindow Destructor
SDLWindow::~SDLWindow()
{
if (window) {
SDL_DestroyWindow(window);
}
SDL_Quit();
}
// Poll Events
void SDLWindow::pollEvents() {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_EVENT_QUIT) {
running = false;
}
if (eventCallback) {
eventCallback(event);
}
}
}
// Set Event Callback
void SDLWindow::setEventCallback(void (*callback)(const SDL_Event&)) {
eventCallback = callback;
}
// Check if Window is Running
bool SDLWindow::isRunning() const {
return running;
}
// Show Window
void SDLWindow::showWindow() {
SDL_ShowWindow(window);
}
// Hide Window
void SDLWindow::hideWindow() {
SDL_HideWindow(window);
}
// Set Window Position
void SDLWindow::setPosition(int x, int y) {
SDL_SetWindowPosition(window, x, y);
}
// Return raw SDL_Window pointer
SDL_Window* SDLWindow::getSDLWindow() const {
return window;
}

View File

@@ -0,0 +1,19 @@
#include "engine/sdl.hpp"
#include "engine/opengl.hpp"
int main(int argc, char* argv[]) {
SDLWindow window("My SDL Application", 800, 600);
if (!window.isRunning()) { return -1; }
OpenGLContext glContext(window);
if (!glContext.isInitialized()) { return -1; }
window.setPosition(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
window.showWindow();
while (window.isRunning()) {
window.pollEvents();
// Application logic and rendering would go here
glContext.swapBuffers();
}
return 0;
}