vokegpu / ekg-ui-library

High-performance multi-platform modular GUI library with GPU API modular support: OpenGL/Vulkan accelerated
MIT License
74 stars 3 forks source link
cpp17 glew glfw glfw3 gui hacktoberfest librar native opengl sdl2 ui

πŸ„ EKG 🐈

EKG is a retained UI-toolkit/UI library to create fancy high-perfmance GUIs, always looking for low-specs hardware.

Documentation: here
Development updates: here

Please before cloning EKG, insert --depth 1 flag, or you will clone almost 1gb (yeah this is bizzare, soon EKG MUST fix it filtering the repository).

Image Text

EKG is recognised as an open-source project by JetBrains πŸ–€
JetBrains Black Box Logo logo.

This project also is a tribute for Astah πŸˆβ€β¬›, an amazing lovely cat.

Rendering & Platform Support

The graphics engine is implemented over a RHI-like (Rendering Hardware-Interface-like); supporting multi-API(s) (OpenGL, OpenGL ES3, Vulkan, etc). EKG implements some object-state based concepts, like in the initialization process and sampler creation, due the Khronos API high-performance Vulkan support.

Name Support
OpenGL Stable, minimum version required 3.3 with GLEW, example project
OpenGL ES Stable, minimum version required ES 3 with NDK, example project
Vulkan Not implemented
Metal Not implemented, maybe implemented with MoltenVK
DirectX 12 Not implemented, perharps not even be implemented
DirectX 11 Not implemented, perharps not even be implemented

The OS (Android, Windows and Linux) platform (SDL, GLFW, Win32, Wayland, etc) support also used an interface.

Name Support OS
SDL Stable example code Linux, Windows & Android
GLFW Stable example code Linux & Windows
Win32 Not implemented ?
Wayland Not implemented ?

I can not implement everything alone, so, if you want contribute writing these APIs and platform, be welcome.
Check the code of conduct and πŸ–€ !

See more about EKG-demos.

Getting Started πŸˆβ€β¬›

Initializing EKG for SDL and OpenGL is simple.

#include <ekg/ekg.hpp>
#include <ekg/os/ekg_opengl.hpp>
#include <ekg/os/ekg_sdl.hpp>

int32_t main(int32_t, char**) {
  // initialize SDL window
  // initialize OpenGL context and GLEW

  /**
   * Runtime property is object-state based,
   * because of Vulkan support, but it does not require a large configutarion template.
   * 
   * The font rendering requires some explains:
   * - EKG font rendering is "maximum" optimized to fast rendering, so Kanjis or any char
   * far from 256 unicode value does not have a decent implementation (still).
   * - Only Emojis chars are implemented on font rendering.
   * 
   * Soon EKG should add Kanji and some chars support, but for now, only emoji and text is ok.
   * You can read more about how EKG font rendering works here: <yet no link> 
   **/
  ekg::runtime_property ekg_runtime_property {
    .p_font_path = "./local_font.ttf.otf",
    .p_font_path_emoji = "./local_optional_emoji_support.ttf.otf",
    .p_gpu_api = new ekg::os::opengl(), // check documentation for Vulkan initialization (not done yet :c)
    .p_os_platform = new ekg::os::sdl(p_sdl_win)
  };

  ekg::runtime ekg_runtime {};
  ekg::init(&ekg_runtime, ekg_runtime_property);

  // now EKG is initialized and done to be used.

  while (running_loop) {
    while (SDL_PollEvent(&sdl_event)) {
      /**
       * The EKG for SDL is different from other(s) platform implementations.
       * Each platform may perform with some "overheads", as in the case of GLFW.
       * GLFW does not have a loop-statement place like SDL to poll events.
       **/
      ekg::os::sdl_poll_event(&sdl_event);
    }

    /**
     * Note: These next functions are aside from platform interface implementation,
     * only events poll is necessary an interface.
     **/

    // The delta time (framerate interval time between new and old frame loop).
    ekg::ui::dt = 0.016f; // you need to calculate by yourself.

    /**
     * You are able to add multi-thread support to EKG
     * invoking this function on a different thread.
     * But I do not recommend it.
     **/
    ekg::update();

    // Now on rendering loop section you must invoke EKG render function.
    ekg::render();
  }
}

UI Elements Creation and Configuration

The EKG is not an immediate UI library, then you need to build once widgets and tasks,
you can create widgets on the application initialization or any other place at once.

Building widgets support builder-concept, so you have free to customize a lot the widget.


ekg::frame("meow", ekg::vec2(200, 200), ekg::vec2(200, 200))
  ->set_drag(ekg::dock::top)
  ->set_resize(ekg::dock::left | ekg::dock::bottom | ekg::dock::right);

ekg::label("ekg sampler gui?", ekg::dock::fill);
ekg::button("click here bu", ekg::dock::fill | ekg::dock::next);

ekg::textbox("meow", "πŸ„ EKG 🐈", ekg::dock::fill | ekg::dock::next)
  ->set_scaled_height(3);

ekg::label("meow", ekg::dock::next);
ekg::slider("dragging the life", 0.0f, 0.0f, 666.0f, ekg::dock::fill)
  ->set_text_align(ekg::dock::center);

ekg::checkbox("checkbox like a πŸˆβ€β¬›", true, ekg::dock::fill | ekg::dock::next);
ekg::scrollbar("scrollbar omg");

// not necessary unless you create a second frame that you do not want to dockenize on it.
ekg::pop_group(); 

showcase-sampler-gui

Action Inputs and Tasks

The EKG is task-event-based then any widget-activity (activity here means activating the purpose of a widget, like a button press or a slider bar etc). You can link tasks to these activities using the set_task method in widget.

ekg::button("inputs example meow", ekg::dock::fill)
  ->set_task(
    new ekg::task {
      .info = {
        .tag = "inputs example meow",
        .p_data = nullptr // you can pass any address ptr
      },
      .function = [](ekg::info &info) {
        auto p_void = info.p_data;
        auto p_ui = info.p_ui; // a `void *ptr` pointing to widget ui.

        std::cout << info.tag << std::endl;
      }
    },
    ekg::action::activity
  );

This example print outputs the name of task in terminal.

Linking

First download the latest release and FreeType2.
Let see for SDL2 and OpenGL with GLEW, note: the order link is important, be sure you are linking EKG first.

# cmake
add_executable(your-project-name ekg SDL2main SDL2 freetype glew32)

# make
cxx ... -lekg -lSDL2main -lSDL2 -lfreetype -lglew32

Building

Toolchain Support OS
GCC Stable Arch & Ubuntu
MinGW Stable Windows
Clang Untested ?

EKG used some std 17 features, so the minimum std version is 17, note: you must use CMake with Ninja to generate makefiles.

If you can not compile because of freetype not found, insert flag -DEKG_LINUX_NOT_FOUND_FREETYPE=1; the CMake build file will force an include.

cmake -S . -B ./cmake-build-debug -G Ninja
cmake --build ./cmake-build-debug

Build output folder tree:


@copyright 2024 - Rina Wilk - VokeGpu