From 0f6e9fdebb905487ef5f09081d8cfa47eda906b8 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 8 Sep 2024 22:19:04 +0100 Subject: [PATCH] Implement basic ImGUI editor for a game --- .gitignore | 2 + compile | 4 +- src/main.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 113 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 6e47b57..2379ac8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .cache compile_commands.json main +extern +imgui.ini diff --git a/compile b/compile index 3cacbdd..1f8b6e7 100755 --- a/compile +++ b/compile @@ -1,8 +1,8 @@ #!/bin/bash CC=clang -CFLAGS="-g -Wall $(pkg-config --cflags sdl2)" -LIBS="$(pkg-config --libs sdl2)" +CFLAGS="-g -Wall $(pkg-config --cflags sdl2) -Wl,-rpath,\$ORIGIN/lib -Ivendor" +LIBS="$(pkg-config --libs sdl2) -Llib -lcimgui" SRC=src/*.c OUT=main diff --git a/src/main.c b/src/main.c index cbb5022..c9d8302 100644 --- a/src/main.c +++ b/src/main.c @@ -1,28 +1,77 @@ +#include "SDL_rect.h" #include #include #include #include +#include +#include +#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS +#include "cimgui/cimgui.h" +#define CIMGUI_USE_SDL2 +#include "cimgui/cimgui_impl.h" #include -#define WINDOW_WIDTH 800 -#define WINDOW_HEIGHT 600 +#define WINDOW_WIDTH 1280 +#define WINDOW_HEIGHT 720 + +#define PLAYER_SIZE 50 +#define MIN_SPEED 10 +#define MAX_SPEED 3000 + +static const float delta = 1.0f / 60.0f; + +typedef struct character Character; +struct character { + SDL_FRect position; + ImVec4 color; + int direction; + float speed; +}; + +void update_character(Character *player); +void render_character(SDL_Renderer *renderer, const Character *player); +void toggle_direction(Character *player); int main(void) { SDL_Init(SDL_INIT_EVERYTHING); - SDL_Window *window = - SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN); + SDL_Window *window = SDL_CreateWindow( + "Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, + WINDOW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); SDL_Renderer *renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + igCreateContext(NULL); + ImGuiIO *io = igGetIO(); + // Enable Keyboard Controls + io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + // Enable Gamepad Controls + io->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; + + igStyleColorsDark(NULL); + if (!ImGui_ImplSDL2_InitForSDLRenderer(window, renderer) || + !ImGui_ImplSDLRenderer2_Init(renderer)) { + goto IMGUI_FAILED; + } + bool running = true; + Character player = { + .position = {.x = WINDOW_WIDTH / 2.0f - PLAYER_SIZE / 2.0f, + .y = 0.0f, + .w = PLAYER_SIZE, + .h = PLAYER_SIZE}, + .direction = 1, + .speed = 10.0f, + .color = {.x = 0, .y = 0, .z = 0, .w = 255}, + }; + SDL_Event event = {0}; while (running) { while (SDL_PollEvent(&event)) { + ImGui_ImplSDL2_ProcessEvent(&event); switch (event.type) { case SDL_QUIT: running = false; @@ -30,13 +79,43 @@ int main(void) { } } + update_character(&player); + + ImGui_ImplSDLRenderer2_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + igNewFrame(); + + { + // Create a window and append into it. + igBegin("Player Properties", NULL, 0); + + // Edit 1 float using a slider + igSliderFloat("Speed", &(player.speed), MIN_SPEED, MAX_SPEED, "%.6f", 0); + + // Edit 3 floats representing a color + igColorEdit3("Color", (float *)&(player.color), 0); + + igEnd(); + } + + igRender(); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDL_RenderClear(renderer); + render_character(renderer, &player); + + ImGui_ImplSDLRenderer2_RenderDrawData(igGetDrawData(), renderer); + SDL_RenderPresent(renderer); } + ImGui_ImplSDLRenderer2_Shutdown(); + ImGui_ImplSDL2_Shutdown(); + igDestroyContext(NULL); + +IMGUI_FAILED: SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); @@ -45,3 +124,28 @@ int main(void) { return 0; } + +void update_character(Character *player) { + player->position.y += player->speed * player->direction * delta; + + if (player->position.y < 0 || + player->position.y + player->position.h > WINDOW_HEIGHT) { + toggle_direction(player); + + if (player->position.y < 0) { + player->position.y = 0; + } else { + player->position.y = WINDOW_HEIGHT - player->position.h; + } + } +} + +void render_character(SDL_Renderer *renderer, const Character *player) { + SDL_SetRenderDrawColor(renderer, (uint8_t)(player->color.x * 255), + (uint8_t)(player->color.y * 255), + (uint8_t)(player->color.z * 255), + (uint8_t)(player->color.w * 255)); + SDL_RenderFillRectF(renderer, &(player->position)); +} + +void toggle_direction(Character *player) { player->direction *= -1; }