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.
Utility of the Application
This library can be used as a starting point for any desktop application that requires:
- An invisible window and OpenGL context: Through the use of SDL.
- A modern, interactive GUI: Through the use of ImGui which serves as the main application window.
- An event handling system: Customizable through the
EventHandler
class.
- Cross-platform application.
Code Structure
The application library is structured into several classes, each with a specific role:
EsdApp
: The core application layer for managing the application.
Window
: Encapsulates the SDL_Window and associated SDL_GLContext for OpenGL rendering.
ImGuiLayer
: Handles ImGui rendering.
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 tofalse
.
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 setrunning
tofalse
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 ourmyApp
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
And there we have it, a simple cross-platform desktop application using
EsdCppApp
, a Custom SDL+ImGui Application Library.Another Demo App:
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
You can access the complete code and contribute to this project on GitHub.