Skip to content

vaxp/marduk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Marduk Toolkit 🌌

Marduk is a high-performance, low-level Retained Mode OOP Toolkit written in Modern C++ (C++20). It is designed to be the foundational engine for building custom Desktop Environments, UI Frameworks, and graphics-intensive native applications.

Unlike traditional UI frameworks that force you to use pre-built components (like Buttons or TextFields), Marduk provides the raw, unopinionated primitives: Hardware-Accelerated Rendering, Flexbox Layout, and Event Routing. It acts as a "Framework Factory," giving developers absolute control over every pixel while eliminating the boilerplate of setting up graphics contexts.


🚀 Key Features

  • Raw Skia Power (GPU Accelerated): Direct, zero-overhead access to the Skia Graphics Engine. You can extract the raw SkCanvas* to draw complex paths, GLSL Shaders (SkRuntimeEffect), gradients, and particles at 60+ FPS.
  • Integrated Anu Flexbox Layout: Forget manual x, y coordinate math. Marduk integrates the Anu Flexbox engine directly into its RenderObject tree. Build responsive, complex layouts that automatically adapt to window resizing.
  • Zero-Boilerplate Setup: Say goodbye to the headache of initializing SDL, setting up OpenGL/Vulkan contexts, and managing OS event loops. Marduk handles the windowing and context lifecycle out of the box.
  • Retained Mode Efficiency: Utilizes a persistent RenderObject scene graph. State mutations (like changing a color or size) use targeted markNeedsLayout() and markNeedsPaint() signals, ensuring the CPU/GPU only recalculates what actually changed, rather than rebuilding the entire tree.
  • Precise Event Routing: Built-in Hit Testing traversing the scene graph, delivering precise mouse, scroll, and pointer events exactly to the affected low-level RenderObject.

🎯 Primary Use Cases

  1. Desktop Environments (DEs): Perfect for building components like custom Taskbars, Docks, or interactive Live Wallpapers (e.g., AetherDesktop), where you need bare-metal graphics performance and low memory footprint.
  2. Building New UI Frameworks: Want to build the next React Native, Flutter, or Qt? Use Marduk as your foundation. Build your "Virtual DOM" or "Widget Tree" in C++, Rust, or Python, and let Marduk handle the heavy lifting of Layout and Rendering.
  3. High-Performance Custom Apps: Ideal for software that demands custom UI paradigms, such as Video Editors, Audio Workstations (DAWs), or 2D Game Editors, where standard OS controls are too restrictive or too slow.

⚡ What Makes Marduk Unique?

It's a "Toolkit", not a "Framework"

Marduk does not ship with Button, Checkbox, or TextField. If it did, it would be imposing a specific design language and architecture on you. Instead, Marduk gives you RenderBox and RenderFlex. You inherit from them, grab the SkCanvas, and draw your own completely unique components.

100% Control, 0% Overhead

Because there is no intermediate "Declarative Widget" layer diffing in the background, you are communicating almost directly with the GPU. When you build with Marduk, you are writing code that is as close to the metal as a graphics engine, but with the convenience of Flexbox and structured event handling.


🛠️ Quick Example: Raw Skia Integration

#include "marduk/app/app.hpp"
#include "marduk/tree/render_object.hpp"
#include "marduk/rendering/canvas.hpp"

// Raw Skia includes
#include <include/core/SkCanvas.h>
#include <include/core/SkPaint.h>
#include <include/core/SkShader.h>
#include <include/effects/SkGradientShader.h>
#include <include/core/SkPath.h>

using namespace marduk;

// A custom RenderObject that uses raw Skia for advanced drawing
class RenderSkiaBox : public RenderBox {
public:
    void paint(PaintContext& ctx) override {
        // 1. Get raw Skia canvas
        SkCanvas* sk_canvas = static_cast<SkCanvas*>(ctx.canvas.getNativeHandle());

        // 2. Define the bounds based on the layout computed by Anu
        SkRect rect = SkRect::MakeXYWH(ctx.offset.x, ctx.offset.y, size().width, size().height);
        
        // 3. Create a beautiful gradient shader
        SkColor colors[] = { 0xFFFF0055, 0xFF5500FF }; // Pink to Purple
        SkPoint points[] = { 
            SkPoint::Make(rect.left(), rect.top()), 
            SkPoint::Make(rect.right(), rect.bottom()) 
        };

        SkPaint sk_paint;
        sk_paint.setShader(SkGradientShader::MakeLinear(
            points, colors, nullptr, 2, SkTileMode::kClamp
        ));

        // Draw the background with the gradient
        sk_canvas->drawRect(rect, sk_paint);

        // 4. Draw a custom shape (a star) using SkPath
        SkPath star_path;
        float center_x = rect.centerX();
        float center_y = rect.centerY();
        float R = std::min(rect.width(), rect.height()) * 0.4f; // outer radius
        float r = R * 0.4f; // inner radius
        
        star_path.moveTo(center_x, center_y - R);
        for (int i = 1; i < 10; ++i) {
            float angle = i * (3.14159265f / 5.0f);
            float radius = (i % 2 == 0) ? R : r;
            star_path.lineTo(
                center_x + radius * std::sin(angle),
                center_y - radius * std::cos(angle)
            );
        }
        star_path.close();

        SkPaint star_paint;
        star_paint.setColor(SK_ColorWHITE);
        star_paint.setAntiAlias(true);
        star_paint.setStyle(SkPaint::kFill_Style);

        // Draw the star!
        sk_canvas->drawPath(star_path, star_paint);
    }
};

int main(int argc, char** argv) {
    AppConfig config{
        .title = "Marduk - Raw Skia Integration",
        .width = 800,
        .height = 600,
        .clear_color = 0xFF121212 // Very dark gray
    };

    // Use Anu Flexbox for layout
    auto root = std::make_shared<RenderFlex>();
    root->setFlexDirection(FlexDirection::Column);
    root->setMainAxisAlignment(MainAxisAlign::Center);
    root->setCrossAxisAlignment(CrossAxisAlign::Center);

    // Create our custom Skia box
    auto skia_box = new RenderSkiaBox();
    
    // Set layout constraints directly on the Anu node
    ANUNodeStyleSetWidth(skia_box->anuNode(), 300);
    ANUNodeStyleSetHeight(skia_box->anuNode(), 300);
    
    // You can even add margins via Anu!
    ANUNodeStyleSetMargin(skia_box->anuNode(), ANUEdgeAll, 50);

    root->addChild(skia_box);

    return marduk::runApp(root, config);
}

📦 Building

meson setup build
meson compile -C build

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages