Emil S.D

Personal blog & portfolio

Project Esd.CppApp

Project Esd.CppApp

Tags
Project
C++
SDL
Dear ImGui
Published
August 16, 2023
Author
Emil S.D

Introduction

In this blog post, we’ll walk through the development of a library designed to simplify the startup of new desktop application projects. It is built using SDL (Simple DirectMedia Layer) for window creation and context handling, and ImGui for creating modern, interactive graphical user interfaces. This library serves as a foundation, helping to quickly prototype and develop applications without worrying about initial setup. The library is hosted on GitHub, so it's readily available for anyone to clone, fork, and contribute.
In this blog post, we’ll walk through the development of a library designed to simplify the startup of new desktop application projects. It is built using SDL (Simple DirectMedia Layer) for window creation and context handling, and ImGui for creating modern, interactive graphical user interfaces. This library serves as a foundation, helping to quickly prototype and develop applications without worrying about initial setup. The library is hosted on GitHub, so it's readily available for anyone to clone, fork, and contribute.

Utility of the Application

This library can be used as a starting point for any desktop application that requires:
  1. An invisible window and OpenGL context: Through the use of SDL.
  1. A modern, interactive GUI: Through the use of ImGui which serves as the main application window.
  1. An event handling system: Customizable through the EventHandler class.
  1. Cross-platform application.

Code Structure

The application library is structured into several classes, each with a specific role:
  1. EsdApp: The core application layer for managing the application.
  1. Window: Encapsulates the SDL_Window and associated SDL_GLContext for OpenGL rendering.
  1. ImGuiLayer: Handles ImGui rendering.
  1. EventHandler: Responsible for processing system events.

Step 1: Initializing

The EsdApp class is responsible for initializing and managing our application. We initialize the application by creating a new Window and ImGuiLayer instances.
void EsdCppApp::EsdApp::StartLayer(const char* title, const float width, const float height) { appWindow = new Window(); imguiLayer = new ImGuiLayer(title, width, height, appWindow->GetSDLWindow(), appWindow->GetGLContext()); }

Step 2: Window Creation

The Window class is responsible for creating an SDL window and an associated OpenGL context.
EsdWindow::EsdWindow() { // ... Initialization code ... }
When we are done with the window, its destructor ensures that the resources are properly released:
EsdWindow::~EsdWindow() { SDL_GL_DeleteContext(m_GLContext); SDL_DestroyWindow(m_Window); SDL_Quit(); }

Step 3: Handling ImGui

The ImGuiLayer class handles ImGui rendering. It initiates ImGui’s context and sets it up to render using SDL and OpenGL.
EsdImGuiLayer::EsdImGuiLayer(const char* title, const float w, const float h, SDL_Window* window, SDL_GLContext glContext) { // ... ImGui setup code ... }
It also has a RunFrame method that manages the entire lifecycle of an ImGui frame.
void EsdImGuiLayer::RunFrame(void(*userAppUI)(), bool& isActive) { // ... Code for ImGui frame rendering ... }

Step 4: Handling Events

The EventHandler class processes the system events and updates the application state accordingly.
void EventHandler::HandleEvent(bool& isActive) { SDL_Event event; while (SDL_PollEvent(&event)) { ImGui_ImplSDL2_ProcessEvent(&event); if (event.type == SDL_QUIT) isActive = false; } }

Step 5: Cleanup

The EsdApp class is also responsible for cleaning up resources when the application is about to exit:
void EsdCppApp::EsdApp::EndLayer() { delete imguiLayer; delete appWindow; }

Getting Started

First things first, we need to set the parameters for our application window:
#define WIDTH 1280 #define HEIGHT 720 #define TITLE "Esd.CppApp"
These preprocessor directives are simple: they define the width, height, and title of our application window.

StartLayer()

EsdCppApp::EsdApp::StartLayer(TITLE, WIDTH, HEIGHT);
StartLayer() initializes the application layer with a new Window and ImGuiLayer instance. The parameters (TITLE, WIDTH, HEIGHT) determine the initial state of the application window.

Crafting the Main Loop

The core of our application is the main loop:
bool running = true; auto myApp = []() { ImGui::ShowDemoWindow(); }; // Run the application layer, which handles events, updates the application state, and renders the application. EsdCppApp::EsdApp::RunLayer(myApp, running);
  • running is a boolean flag that keeps our application running until an event (like a user closing the window) sets it to false.
  • myApp is a lambda function that is designed to contain your application's ImGui user interface. In this example, it simply displays ImGui’s built-in demo window.
  • RunLayer takes care of handling events and running the app.
    • GetEventHandler()->HandleEvent(running) polls and handles system events, like user inputs. It will set running to false when a quit event is detected, gracefully ending the main loop.
    • GetImGuiLayer()->RunFrame(myApp, running) runs a single frame of our ImGui user interface by calling our myApp function.

EndLayer()

Before exiting our program, we want to make sure we clean up any resources that our application was using:
EsdCppApp::EsdApp::EndLayer();
This EndLayer() function cleans up the resources that were allocated during the application's start-up.

Usage

#include "../EsdCppApp.h" // Include the header file for the EsdApp class and related functionality. #define WIDTH 1280 // Define the width of the application window. #define HEIGHT 720 // Define the height of the application window. #define TITLE "Esd.CppApp" // Define the title of the application window. // Entry point for the application. int main(int, char**) { // Define a lambda function that contains the user interface elements for the application. // In this case, it simply displays ImGui's built-in demo window. auto myApp = []() { ImGui::ShowDemoWindow(); // Show the ImGui demo window to demonstrate ImGui's functionalities. }; // Declare a boolean flag to indicate whether the application is running or not. bool running = true; // Initialize the application with a title, width, and height. EsdCppApp::EsdApp::StartLayer(TITLE, WIDTH, HEIGHT); // Run the application layer, which handles events, updates the application state, and renders the application. EsdCppApp::EsdApp::RunLayer(myApp, running); // Perform cleanup operations for the application layer, such as deleting allocated resources. EsdCppApp::EsdApp::EndLayer(); // Return 0 to indicate successful termination of the application. return 0; }

Demo

notion image
And there we have it, a simple cross-platform desktop application using EsdCppApp, a Custom SDL+ImGui Application Library.

Another Demo App:

notion image

Conclusion

This SDL+ImGui application library is designed to fast-track the initial setup when developing new desktop applications. By using this library, developers can skip the boilerplate setup and jump directly into the core development of their application.
Happy coding!
 
View this on GitHub
View this on GitHub
You can access the complete code and contribute to this project on GitHub.