summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesper Jensen <jesper@jnsn.dev>2026-06-05 13:53:11 +0200
committerJesper Jensen <jesper@jnsn.dev>2026-06-05 13:53:11 +0200
commit1af2dfbde432af9f13e8fba09b7ca29f5de71863 (patch)
tree578304e26a1d34a3ed0adbb6ce854c761a203d6a
parent7bf056e5c652254c3a43e748b17cdbb7361a6a3c (diff)
Add imgui compilation
-rw-r--r--.gitignore2
-rw-r--r--Makefile27
-rw-r--r--src/main.c177
3 files changed, 200 insertions, 6 deletions
diff --git a/.gitignore b/.gitignore
index 9042904..5d4ccb4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@
obj/
/compile_commands.json
+
+imgui.ini
diff --git a/Makefile b/Makefile
index 98e6346..49823c8 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,5 @@
CC ?= gcc
+CC ?= g++
SRCDIR ?= src
INCDIR ?= inc
@@ -6,11 +7,13 @@ OBJDIR ?= obj
TSTDIR ?= test
EXMDIR ?= examples
-LIBS = -lm
-INCS = -Ithirdparty/cglm/include -Iinc/
+PKGS = sdl2 opengl
+LIBS = -lm $(shell pkg-config --libs $(PKGS))
+INCS = -Ithirdparty/cglm/include -Ithirdparty/ -Iinc/
CFLAGS ?= -D_FORTIFY_SOURCE=2 -Wall -Werror -Wno-error=unused-variable -g -Og
-CFLAGS += -std=gnu23 -fms-extensions -flto
+CFLAGS += -std=gnu23 -fms-extensions -flto $(shell pkg-config --cflags $(PKGS)) -DCIMGUI_USE_OPENGL3 -DCIMGUI_USE_SDL2
+CXXFLAGS += -flto $(shell pkg-config --cflags $(PKGS)) -DCIMGUI_USE_OPENGL3 -DCIMGUI_USE_SDL2 -DIMGUI_IMPL_API='extern "C"'
APP_MAIN_SOURCES = $(SRCDIR)/main.c
APP_MAIN_OBJS = $(APP_MAIN_SOURCES:%.c=$(OBJDIR)/%.o)
@@ -30,6 +33,8 @@ EXM_OBJS = $(EXM_SOURCES:%.c=$(OBJDIR)/%.o)
EXM_DEPS = $(EXM_OBJS:%.o=%.d)
EXM_APPS = $(EXM_SOURCES:%.c=$(OBJDIR)/%)
+IMGUI_OBJS = $(OBJDIR)/thirdparty/cimgui/imgui/backends/imgui_impl_sdl2.o $(OBJDIR)/thirdparty/cimgui/imgui/backends/imgui_impl_opengl3.o
+
-include $(APP_DEPS) $(APP_MAIN_DEPS) $(TST_DEPS) $(EXM_DEPS)
# We don't really need to run the tests for bear to record them
@@ -37,8 +42,14 @@ compile_commands.json: clean Makefile $(APP_SOURCES)
@rm -f "$@"
bear -- make main
-main: $(APP_MAIN_OBJS) $(APP_OBJS)
- $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(APP_MAIN_OBJS) $(APP_OBJS) $(LIBS)
+.PHONY: thirdparty/cimgui/cimgui.so
+thirdparty/cimgui/cimgui.so:
+ make -C thirdparty/cimgui
+
+LIBS += -Lthirdparty/cimgui -Wl,-rpath,'$$ORIGIN/thirdparty/cimgui' -lcimgui -lstdc++
+
+main: $(APP_MAIN_OBJS) $(APP_OBJS) thirdparty/cimgui/cimgui.so $(IMGUI_OBJS)
+ $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(APP_MAIN_OBJS) $(APP_OBJS) $(IMGUI_OBJS) $(LIBS)
$(OBJDIR)/%.o: %.c
@mkdir -p $(dir $@)
@@ -55,6 +66,7 @@ $(OBJDIR)/examples/%: $(OBJDIR)/examples/%.o $(APP_OBJS)
clean:
@rm -rf $(OBJDIR)
@rm -f main
+ @make -C thirdparty/cimgui clean
test: $(TST_APPS)
@echo "Running tests"
@@ -64,3 +76,8 @@ examples: $(EXM_APPS)
.DEFAULT_GOAL := all
all: main test examples
+
+# Imgui specific compile rules
+$(OBJDIR)/%.o: %.cpp
+ @mkdir -p $(dir $@)
+ $(CXX) $(CXXFLAGS) $(INCS) -Ithirdparty/cimgui/imgui/ -MMD -o $@ -c $<
diff --git a/src/main.c b/src/main.c
index 9f8d151..10cbbfc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,17 @@
#include "cad.h"
#include "cad/debug.h"
+#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
+#include "cimgui/cimgui.h"
+#include "cimgui/cimgui_impl.h"
+#include <SDL2/SDL.h>
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#define igGetIO igGetIO_Nil
+SDL_Window *window = NULL;
+
struct smooth_line {
struct component l1;
struct component l2;
@@ -151,7 +162,7 @@ void draw_from_constraints(struct constraints *c, struct topology *t, struct can
free_drawing(&drawing);
}
-int main(int argc, char *argv[]) {
+int main2(int argc, char *argv[]) {
struct constraints constraints = {};
struct topology topo = {};
@@ -280,4 +291,168 @@ int main(int argc, char *argv[]) {
free_constraints(&constraints);
free_topology(&topo);
+ return 0;
+}
+
+int main(int argc, char* argv[]) {
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+ SDL_Log("failed to init: %s", SDL_GetError());
+ return -1;
+ }
+
+ // GL 3.0 + GLSL 130
+ const char* glsl_version = "#version 130";
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
+
+ // and prepare OpenGL stuff
+ SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_DisplayMode current;
+ SDL_GetCurrentDisplayMode(0, &current);
+ float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
+ SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
+ window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
+
+ if (window == NULL) {
+ SDL_Log("Failed to create window: %s", SDL_GetError());
+ return -1;
+ }
+
+ SDL_GLContext gl_context = SDL_GL_CreateContext(window);
+ SDL_GL_SetSwapInterval(1); // enable vsync
+
+
+ // check opengl version sdl uses
+ SDL_Log("opengl version: %s", (char*)glGetString(GL_VERSION));
+
+ // setup imgui
+ igCreateContext(NULL);
+
+ //set docking
+ ImGuiIO* ioptr = igGetIO();
+ ioptr->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
+ ioptr->ConfigFlags |= ImGuiConfigFlags_DockingEnable;
+
+ // Setup scaling
+ ImGuiStyle* style = igGetStyle();
+ ImGuiStyle_ScaleAllSizes(style, main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
+ style->FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
+ ioptr->ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
+ ioptr->ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
+
+
+ ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
+ ImGui_ImplOpenGL3_Init(glsl_version);
+
+ igStyleColorsDark(NULL);
+ //ImFontAtlas_AddFontDefault(io.Fonts, NULL);
+
+
+ bool showDemoWindow = true;
+ bool showAnotherWindow = false;
+ ImVec4 clearColor;
+ clearColor.x = 0.45f;
+ clearColor.y = 0.55f;
+ clearColor.z = 0.60f;
+ clearColor.w = 1.00f;
+
+ bool quit = false;
+ while (!quit)
+ {
+ SDL_Event e;
+
+ // we need to call SDL_PollEvent to let window rendered, otherwise
+ // no window will be shown
+ while (SDL_PollEvent(&e) != 0)
+ {
+ ImGui_ImplSDL2_ProcessEvent(&e);
+ if (e.type == SDL_QUIT)
+ quit = true;
+ if (e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_CLOSE && e.window.windowID == SDL_GetWindowID(window))
+ quit = true;
+ }
+
+ // start imgui frame
+ ImGui_ImplOpenGL3_NewFrame();
+ ImGui_ImplSDL2_NewFrame();
+ igNewFrame();
+
+ if (showDemoWindow)
+ igShowDemoWindow(&showDemoWindow);
+
+ // show a simple window that we created ourselves.
+ {
+ static float f = 0.0f;
+ static int counter = 0;
+
+ igBegin("Hello, world!", NULL, 0);
+ igText("This is some useful text");
+ igCheckbox("Demo window", &showDemoWindow);
+ igCheckbox("Another window", &showAnotherWindow);
+
+ igSliderFloat("Float", &f, 0.0f, 1.0f, "%.3f", 0);
+ igColorEdit3("clear color", (float*)&clearColor, 0);
+
+ ImVec2 buttonSize;
+ buttonSize.x = 0;
+ buttonSize.y = 0;
+ if (igButton("Button", buttonSize))
+ counter++;
+ igSameLine(0.0f, -1.0f);
+ igText("counter = %d", counter);
+
+ igText("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / igGetIO()->Framerate, igGetIO()->Framerate);
+ igEnd();
+ }
+
+ if (showAnotherWindow)
+ {
+ igBegin("imgui Another Window", &showAnotherWindow, 0);
+ igText("Hello from imgui");
+ ImVec2 buttonSize;
+ buttonSize.x = 0; buttonSize.y = 0;
+ if (igButton("Close me", buttonSize))
+ {
+ showAnotherWindow = false;
+ }
+ igEnd();
+ }
+
+ // render
+ igRender();
+ SDL_GL_MakeCurrent(window, gl_context);
+ glViewport(0, 0, (int)ioptr->DisplaySize.x, (int)ioptr->DisplaySize.y);
+ glClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
+ glClear(GL_COLOR_BUFFER_BIT);
+ ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
+ if (ioptr->ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
+ SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow();
+ SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
+ igUpdatePlatformWindows();
+ igRenderPlatformWindowsDefault(NULL,NULL);
+ SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
+ }
+ SDL_GL_SwapWindow(window);
+ }
+
+ // clean up
+ ImGui_ImplOpenGL3_Shutdown();
+ ImGui_ImplSDL2_Shutdown();
+ igDestroyContext(NULL);
+
+ SDL_GL_DeleteContext(gl_context);
+ if (window != NULL)
+ {
+ SDL_DestroyWindow(window);
+ window = NULL;
+ }
+ SDL_Quit();
+
+ return 0;
}