diff --git a/CMakeLists.txt b/CMakeLists.txt
index b825769..7ddea29 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,6 +10,7 @@ option(CLAY_INCLUDE_RAYLIB_EXAMPLES "Build raylib examples" OFF)
 option(CLAY_INCLUDE_SDL2_EXAMPLES "Build SDL 2 examples" OFF)
 option(CLAY_INCLUDE_SDL3_EXAMPLES "Build SDL 3 examples" OFF)
 option(CLAY_INCLUDE_WIN32_GDI_EXAMPLES "Build Win32 GDI examples" OFF)
+option(CLAY_INCLUDE_SOKOL_EXAMPLES "Build Sokol examples" OFF)
 
 message(STATUS "CLAY_INCLUDE_DEMOS: ${CLAY_INCLUDE_DEMOS}")
 
@@ -37,6 +38,10 @@ endif ()
 if(NOT MSVC AND (CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_SDL3_EXAMPLES))
     add_subdirectory("examples/SDL3-simple-demo")
 endif()
+if(CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_SOKOL_EXAMPLES)
+  add_subdirectory("examples/sokol-video-demo")
+  add_subdirectory("examples/sokol-corner-radius")
+endif()
 
 if(WIN32)   # Build only for Win or Wine
     if(CLAY_INCLUDE_ALL_EXAMPLES OR CLAY_INCLUDE_WIN32_GDI_EXAMPLES)
diff --git a/examples/sokol-corner-radius/CMakeLists.txt b/examples/sokol-corner-radius/CMakeLists.txt
new file mode 100644
index 0000000..cf8997b
--- /dev/null
+++ b/examples/sokol-corner-radius/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.27)
+project(sokol_corner_radius C)
+
+if(CMAKE_SYSTEM_NAME STREQUAL Windows)
+    add_executable(sokol_corner_radius WIN32 main.c)
+    set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT sokol_corner_radius)
+else()
+    add_executable(sokol_corner_radius main.c)
+endif()
+target_link_libraries(sokol_corner_radius PUBLIC sokol)
\ No newline at end of file
diff --git a/examples/sokol-corner-radius/main.c b/examples/sokol-corner-radius/main.c
new file mode 100644
index 0000000..05453b9
--- /dev/null
+++ b/examples/sokol-corner-radius/main.c
@@ -0,0 +1,110 @@
+#include "sokol_app.h"
+#include "sokol_gfx.h"
+#include "sokol_glue.h"
+#include "sokol_log.h"
+
+#define CLAY_IMPLEMENTATION
+#include "../../clay.h"
+
+#include "util/sokol_gl.h"
+#include "fontstash.h"
+#include "util/sokol_fontstash.h"
+#define SOKOL_CLAY_IMPL
+#include "../../renderers/sokol/sokol_clay.h"
+
+static void init() {
+    sg_setup(&(sg_desc){
+        .environment = sglue_environment(),
+        .logger.func = slog_func,
+    });
+    sgl_setup(&(sgl_desc_t){
+        .logger.func = slog_func,
+    });
+    sclay_setup();
+    uint64_t totalMemorySize = Clay_MinMemorySize();
+    Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));
+    Clay_Initialize(clayMemory, (Clay_Dimensions){ (float)sapp_width(), (float)sapp_height() }, (Clay_ErrorHandler){0});
+    Clay_SetMeasureTextFunction(sclay_measure_text, NULL);
+}
+
+Clay_RenderCommandArray CornerRadiusTest(){
+    Clay_BeginLayout();
+    Clay_Sizing layoutExpand = {
+        .width = CLAY_SIZING_GROW(0),
+        .height = CLAY_SIZING_GROW(0)
+    };
+    CLAY({ .id = CLAY_ID("OuterContainer"),
+        .backgroundColor = {43, 41, 51, 255},
+        .layout = {
+            .layoutDirection = CLAY_TOP_TO_BOTTOM,
+            .sizing = layoutExpand,
+            .padding = {0, 0, 20, 20},
+            .childGap = 20
+        }
+    }) {
+        for(int i = 0; i < 6; ++i){
+            CLAY({ .id = CLAY_IDI("Row", i),
+                .layout = {
+                    .layoutDirection = CLAY_LEFT_TO_RIGHT,
+                    .sizing = layoutExpand,
+                    .padding = {20, 20, 0, 0},
+                    .childGap = 20
+                }
+            }) {
+                for(int j = 0; j < 6; ++j){
+                    CLAY({ .id = CLAY_IDI("Tile", i*6+j),
+                        .backgroundColor = {120, 140, 255, 128},
+                        .cornerRadius = {(i%3)*15, (j%3)*15, (i/2)*15, (j/2)*15},
+                        .border = {
+                            .color = {120, 140, 255, 255},
+                            .width = {3, 9, 6, 12, 0},
+                        },
+                        .layout = { .sizing = layoutExpand }
+                    });
+                }
+            }
+        }
+    }
+    return Clay_EndLayout();
+}
+
+static void frame() {
+    sclay_new_frame();
+    Clay_RenderCommandArray renderCommands = CornerRadiusTest();
+
+    sg_begin_pass(&(sg_pass){ .swapchain = sglue_swapchain() });
+    sgl_matrix_mode_modelview();
+    sgl_load_identity();
+    sclay_render(renderCommands, NULL);
+    sgl_draw();
+    sg_end_pass();
+    sg_commit();
+}
+
+static void event(const sapp_event *ev) {
+    if(ev->type == SAPP_EVENTTYPE_KEY_DOWN && ev->key_code == SAPP_KEYCODE_D){
+        Clay_SetDebugModeEnabled(true);
+    } else {
+        sclay_handle_event(ev);
+    }
+}
+
+static void cleanup() {
+    sclay_shutdown();
+    sgl_shutdown();
+    sg_shutdown();
+}
+
+sapp_desc sokol_main(int argc, char **argv) {
+    return (sapp_desc){
+        .init_cb = init,
+        .frame_cb = frame,
+        .event_cb = event,
+        .cleanup_cb = cleanup,
+        .window_title = "Clay - Corner Radius Test",
+        .width = 800,
+        .height = 600,
+        .icon.sokol_default = true,
+        .logger.func = slog_func,
+    };
+}
diff --git a/examples/sokol-video-demo/CMakeLists.txt b/examples/sokol-video-demo/CMakeLists.txt
new file mode 100644
index 0000000..6ce8bd9
--- /dev/null
+++ b/examples/sokol-video-demo/CMakeLists.txt
@@ -0,0 +1,71 @@
+cmake_minimum_required(VERSION 3.27)
+project(sokol_video_demo C)
+
+include(FetchContent)
+set(FETCHCONTENT_QUIET FALSE)
+
+# Linux -pthread shenanigans
+if (CMAKE_SYSTEM_NAME STREQUAL Linux)
+    set(THREADS_PREFER_PTHREAD_FLAG ON)
+    find_package(Threads REQUIRED)
+endif()
+
+FetchContent_Declare(
+    fontstash
+    GIT_REPOSITORY "https://github.com/memononen/fontstash.git"
+    GIT_TAG "b5ddc9741061343740d85d636d782ed3e07cf7be"
+    GIT_PROGRESS TRUE
+    GIT_SHALLOW TRUE
+)
+FetchContent_MakeAvailable(fontstash)
+
+FetchContent_Declare(
+    sokol
+    GIT_REPOSITORY "https://github.com/floooh/sokol.git"
+    GIT_TAG "da9de496f938b7575eff7f01ab774d77469bd390"
+    GIT_PROGRESS TRUE
+    GIT_SHALLOW TRUE
+)
+FetchContent_MakeAvailable(sokol)
+set(sokol_HEADERS
+    ${sokol_SOURCE_DIR}/sokol_app.h
+    ${sokol_SOURCE_DIR}/sokol_gfx.h
+    ${sokol_SOURCE_DIR}/sokol_glue.h
+    ${sokol_SOURCE_DIR}/sokol_log.h
+    ${sokol_SOURCE_DIR}/util/sokol_gl.h
+    ${fontstash_SOURCE_DIR}/src/fontstash.h
+    ${sokol_SOURCE_DIR}/util/sokol_fontstash.h)
+if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+    add_library(sokol STATIC sokol.c ${sokol_HEADERS})
+    target_compile_options(sokol PRIVATE -x objective-c)
+    target_link_libraries(sokol PUBLIC
+        "-framework QuartzCore"
+        "-framework Cocoa"
+        "-framework MetalKit"
+        "-framework Metal")
+else()
+    add_library(sokol STATIC sokol.c ${sokol_HEADERS})
+    if (CMAKE_SYSTEM_NAME STREQUAL Linux)
+        target_compile_definitions(sokol PRIVATE SOKOL_GLCORE=1)
+        target_link_libraries(sokol INTERFACE X11 Xi Xcursor GL dl m)
+        target_link_libraries(sokol PUBLIC Threads::Threads)
+    endif()
+endif()
+target_include_directories(sokol INTERFACE ${sokol_SOURCE_DIR} ${fontstash_SOURCE_DIR}/src
+                                 PRIVATE ${sokol_SOURCE_DIR} ${fontstash_SOURCE_DIR}/src)
+
+
+
+if(CMAKE_SYSTEM_NAME STREQUAL Windows)
+    add_executable(sokol_video_demo WIN32 main.c)
+    set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT sokol_video_demo)
+else()
+    add_executable(sokol_video_demo main.c)
+endif()
+target_link_libraries(sokol_video_demo PUBLIC sokol)
+
+add_custom_command(
+        TARGET sokol_video_demo POST_BUILD
+        COMMAND ${CMAKE_COMMAND} -E copy_directory
+        ${CMAKE_CURRENT_SOURCE_DIR}/resources
+        ${CMAKE_CURRENT_BINARY_DIR}/resources)
diff --git a/examples/sokol-video-demo/main.c b/examples/sokol-video-demo/main.c
new file mode 100644
index 0000000..ba39b87
--- /dev/null
+++ b/examples/sokol-video-demo/main.c
@@ -0,0 +1,77 @@
+#include "sokol_app.h"
+#include "sokol_gfx.h"
+#include "sokol_glue.h"
+#include "sokol_log.h"
+
+#define CLAY_IMPLEMENTATION
+#include "../../clay.h"
+
+#include "util/sokol_gl.h"
+#include "fontstash.h"
+#include "util/sokol_fontstash.h"
+#define SOKOL_CLAY_IMPL
+#include "../../renderers/sokol/sokol_clay.h"
+
+#include "../shared-layouts/clay-video-demo.c"
+
+static ClayVideoDemo_Data demoData;
+static sclay_font_t fonts[1];
+
+static void init() {
+    sg_setup(&(sg_desc){
+        .environment = sglue_environment(),
+        .logger.func = slog_func,
+    });
+    sgl_setup(&(sgl_desc_t){
+        .logger.func = slog_func,
+    });
+    sclay_setup();
+    uint64_t totalMemorySize = Clay_MinMemorySize();
+    Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));
+    Clay_Initialize(clayMemory, (Clay_Dimensions){ (float)sapp_width(), (float)sapp_height() }, (Clay_ErrorHandler){0});
+    fonts[FONT_ID_BODY_16] = sclay_add_font("resources/Roboto-Regular.ttf");
+    Clay_SetMeasureTextFunction(sclay_measure_text, &fonts);
+    demoData = ClayVideoDemo_Initialize();
+}
+
+static void frame() {
+    sclay_new_frame();
+    Clay_RenderCommandArray renderCommands = ClayVideoDemo_CreateLayout(&demoData);
+
+    sg_begin_pass(&(sg_pass){ .swapchain = sglue_swapchain() });
+    sgl_matrix_mode_modelview();
+    sgl_load_identity();
+    sclay_render(renderCommands, fonts);
+    sgl_draw();
+    sg_end_pass();
+    sg_commit();
+}
+
+static void event(const sapp_event *ev) {
+    if(ev->type == SAPP_EVENTTYPE_KEY_DOWN && ev->key_code == SAPP_KEYCODE_D){
+        Clay_SetDebugModeEnabled(true);
+    } else {
+        sclay_handle_event(ev);
+    }
+}
+
+static void cleanup() {
+    sclay_shutdown();
+    sgl_shutdown();
+    sg_shutdown();
+}
+
+sapp_desc sokol_main(int argc, char **argv) {
+    return (sapp_desc){
+        .init_cb = init,
+        .frame_cb = frame,
+        .event_cb = event,
+        .cleanup_cb = cleanup,
+        .window_title = "Clay - Sokol Renderer Example",
+        .width = 800,
+        .height = 600,
+        .high_dpi = true,
+        .icon.sokol_default = true,
+        .logger.func = slog_func,
+    };
+}
diff --git a/examples/sokol-video-demo/resources/Roboto-Regular.ttf b/examples/sokol-video-demo/resources/Roboto-Regular.ttf
new file mode 100644
index 0000000..ddf4bfa
Binary files /dev/null and b/examples/sokol-video-demo/resources/Roboto-Regular.ttf differ
diff --git a/examples/sokol-video-demo/sokol.c b/examples/sokol-video-demo/sokol.c
new file mode 100644
index 0000000..ed43e9c
--- /dev/null
+++ b/examples/sokol-video-demo/sokol.c
@@ -0,0 +1,24 @@
+#define SOKOL_IMPL
+#if defined(_WIN32)
+#define SOKOL_D3D11
+#elif defined(__EMSCRIPTEN__)
+#define SOKOL_GLES2
+#elif defined(__APPLE__)
+#define SOKOL_METAL
+#else
+#define SOKOL_GLCORE33
+#endif
+#include "sokol_app.h"
+#include "sokol_gfx.h"
+#include "sokol_time.h"
+#include "sokol_fetch.h"
+#include "sokol_glue.h"
+#include "sokol_log.h"
+
+#include "util/sokol_gl.h"
+#include <stdio.h> // fontstash requires this
+#include <stdlib.h> // fontstash requires this
+#define FONTSTASH_IMPLEMENTATION
+#include "fontstash.h"
+#define SOKOL_FONTSTASH_IMPL
+#include "util/sokol_fontstash.h"
diff --git a/renderers/sokol/sokol_clay.h b/renderers/sokol/sokol_clay.h
new file mode 100644
index 0000000..0436a50
--- /dev/null
+++ b/renderers/sokol/sokol_clay.h
@@ -0,0 +1,450 @@
+#ifndef SOKOL_CLAY_INCLUDED
+#define SOKOL_CLAY_INCLUDED (1)
+/*
+    sokol_clay.h -- drop-in Clay renderer for sokol_gfx.h
+
+    Do this:
+        #define SOKOL_CLAY_IMPL
+
+    before you include this file in *one* C file to create the
+    implementation.
+
+    Optionally provide the following configuration define both before including the
+    the declaration and implementation:
+
+    SOKOL_CLAY_NO_SOKOL_APP    - don't depend on sokol_app.h (see below for details)
+
+    Include the following headers before sokol_clay.h (both before including
+    the declaration and implementation):
+
+        sokol_gl.h
+        sokol_fontstash.h
+        sokol_app.h         (except SOKOL_CLAY_NO_SOKOL_APP)
+        clay.h
+
+    FEATURE OVERVIEW:
+    =================
+    sokol_clay.h implements the rendering and event-handling code for Clay
+    (https://github.com/nicbarker/clay) on top of sokol_gl.h and (optionally)
+    sokol_app.h.
+
+    Since sokol_fontstash.h already depends on sokol_gl.h, the rendering is
+    implemented using sokol_gl calls. (TODO: make fontstash optional?)
+
+    The sokol_app.h dependency is optional and used for input event handling.
+    If you only use sokol_gfx.h but not sokol_app.h in your application,
+    define SOKOL_CLAY_NO_SOKOL_APP before including the implementation
+    of sokol_clay.h, this will remove any dependency to sokol_app.h, but
+    you must call sclay_set_layout_dimensions and handle input yourself.
+
+    sokol_clay.h is not thread-safe, all calls must be made from the
+    same thread where sokol_gfx.h is running.
+
+    HOWTO:
+    ======
+
+    --- To initialize sokol-clay, call sclay_setup(). This can be done
+        before or after Clay_Initialize.
+
+    --- Create an array of sclay_font_t and fill it by calling one of:
+
+            sclay_font_t sclay_add_font(const char *filename);
+            sclay_font_t sclay_add_font_mem(unsigned char *data, int dataLen);
+
+        The fontId value in Clay corresponds to indices in this array. After calling
+        Clay_Initialize but before calling any layout code, do this:
+
+            Clay_SetMeasureTextFunction(sclay_measure_text, &fonts);
+
+        where `fonts` is the abovementioned array.
+
+    --- At the start of a frame, call sclay_new_frame() if you're using sokol_app.h.
+        If you're not using sokol_app.h, call:
+ 
+            void sclay_set_layout_dimensions(Clay_Dimensions size, float dpi_scale);
+
+        at the start of the frame (or just when the window is resized.)
+
+        Either way, do some layout, then at the end of the frame call sclay_render:
+
+            sg_begin_pass(...)
+            // other rendering...
+            sclay_render(renderCommands, &fonts);
+            // other rendering...
+            sgl_draw();
+            sg_end_pass();
+            sg_commit();
+
+        One caveat: sclay_render assumes the default gl view matrix, and handles scaling
+        automatically. If you've adjusted the view matrix, remember to first call:
+
+            sgl_matrix_mode_modelview();
+            sgl_load_identity();
+
+        before calling sclay_render.
+
+    --- if you're using sokol_app.h, from inside the sokol_app.h event callback,
+        call:
+
+            void sclay_handle_event(const sapp_event* ev);
+
+        Unfortunately Clay does not currently provide feedback on whether a mouse
+        click was handled or not.
+
+    --- finally, on application shutdown, call
+
+            sclay_shutdown()
+ */
+#if !defined(SOKOL_CLAY_NO_SOKOL_APP) && !defined(SOKOL_APP_INCLUDED)
+#error "Please include sokol_app.h before sokol_clay.h (or define SOKOL_CLAY_NO_SOKOL_APP)"
+#endif
+
+typedef int sclay_font_t;
+
+void sclay_setup();
+void sclay_shutdown();
+
+sclay_font_t sclay_add_font(const char *filename);
+sclay_font_t sclay_add_font_mem(unsigned char *data, int dataLen);
+Clay_Dimensions sclay_measure_text(Clay_StringSlice text, Clay_TextElementConfig *config, void *userData);
+
+#ifndef SOKOL_CLAY_NO_SOKOL_APP
+void sclay_new_frame();
+void sclay_handle_event(const sapp_event *ev);
+#endif  /* SOKOL_CLAY_NO_SOKOL_APP */
+
+/* Use this if you don't call sclay_new_frame. `size` is the "virtual" size which
+ * your layout is relative to (ie. the actual framebuffer size divided by dpi_scale.)
+ * Set dpi_scale to 1 if you're not using high-dpi support. */
+void sclay_set_layout_dimensions(Clay_Dimensions size, float dpi_scale);
+
+void sclay_render(Clay_RenderCommandArray renderCommands, sclay_font_t *fonts);
+
+#endif /* SOKOL_CLAY_INCLUDED */
+
+#ifdef SOKOL_CLAY_IMPL
+#define SOKOL_CLAY_IMPL_INCLUDED (1)
+#ifndef SOKOL_GL_INCLUDED
+#error "Please include sokol_gl.h before sokol_clay.h"
+#endif
+#ifndef SOKOL_FONTSTASH_INCLUDED
+#error "Please include sokol_fontstash.h before sokol_clay.h"
+#endif
+#ifndef CLAY_HEADER
+#error "Please include clay.h before sokol_clay.h"
+#endif
+
+typedef struct {
+    sgl_pipeline pip;
+#ifndef SOKOL_CLAY_NO_SOKOL_APP
+    Clay_Vector2 mouse_pos, scroll;
+    bool mouse_down;
+#endif
+    Clay_Dimensions size;
+    float dpi_scale;
+    FONScontext *fonts;
+} _sclay_state_t;
+static _sclay_state_t _sclay;
+
+void sclay_setup() {
+    _sclay.pip = sgl_make_pipeline(&(sg_pipeline_desc){
+        .colors[0] = {
+            .blend = {
+                .enabled = true,
+                .src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
+                .dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
+            },
+        }
+    });
+#ifndef SOKOL_CLAY_NO_SOKOL_APP
+    _sclay.mouse_pos = (Clay_Vector2){0, 0};
+    _sclay.scroll = (Clay_Vector2){0, 0};
+    _sclay.mouse_down = false;
+#endif
+    _sclay.size = (Clay_Dimensions){1, 1};
+    _sclay.dpi_scale = 1;
+    _sclay.fonts = sfons_create(&(sfons_desc_t){ 0 });
+    //TODO clay error handler?
+}
+
+void sclay_shutdown() {
+    sgl_destroy_pipeline(_sclay.pip);
+    sfons_destroy(_sclay.fonts);
+}
+
+#ifndef SOKOL_CLAY_NO_SOKOL_APP
+void sclay_handle_event(const sapp_event* ev) {
+    switch(ev->type){
+    case SAPP_EVENTTYPE_MOUSE_MOVE:
+        _sclay.mouse_pos.x = ev->mouse_x / _sclay.dpi_scale;
+        _sclay.mouse_pos.y = ev->mouse_y / _sclay.dpi_scale;
+        break;
+    case SAPP_EVENTTYPE_MOUSE_DOWN:
+        _sclay.mouse_down = true;
+        break;
+    case SAPP_EVENTTYPE_MOUSE_UP:
+        _sclay.mouse_down = false;
+        break;
+    case SAPP_EVENTTYPE_MOUSE_SCROLL:
+        _sclay.scroll.x += ev->scroll_x;
+        _sclay.scroll.y += ev->scroll_y;
+        break;
+    default: break;
+    }
+}
+
+void sclay_new_frame() {
+    sclay_set_layout_dimensions((Clay_Dimensions){ (float)sapp_width(), (float)sapp_height() },
+                                sapp_dpi_scale());
+    Clay_SetPointerState(_sclay.mouse_pos, _sclay.mouse_down);
+    Clay_UpdateScrollContainers(true, _sclay.scroll, sapp_frame_duration());
+    _sclay.scroll = (Clay_Vector2){0, 0};
+}
+#endif  /* SOKOL_CLAY_NO_SOKOL_APP */
+
+void sclay_set_layout_dimensions(Clay_Dimensions size, float dpi_scale) {
+    size.width /= dpi_scale;
+    size.height /= dpi_scale;
+    _sclay.size = size;
+    if(_sclay.dpi_scale != dpi_scale){
+        _sclay.dpi_scale = dpi_scale;
+        Clay_ResetMeasureTextCache();
+    }
+    Clay_SetLayoutDimensions(size);
+}
+
+sclay_font_t sclay_add_font(const char *filename) {
+    //TODO log something if we get FONS_INVALID
+    return fonsAddFont(_sclay.fonts, "", filename);
+}
+
+sclay_font_t sclay_add_font_mem(unsigned char *data, int dataLen) {
+    //TODO log something if we get FONS_INVALID
+    return fonsAddFontMem(_sclay.fonts, "", data, dataLen, false);
+}
+
+Clay_Dimensions sclay_measure_text(Clay_StringSlice text, Clay_TextElementConfig *config, void *userData) {
+    sclay_font_t *fonts = (sclay_font_t *)userData;
+    if(!fonts) return (Clay_Dimensions){ 0 };
+    fonsSetFont(_sclay.fonts, fonts[config->fontId]);
+    fonsSetSize(_sclay.fonts, config->fontSize);
+    fonsSetSpacing(_sclay.fonts, config->letterSpacing);
+    float ascent, descent, lineh;
+    fonsVertMetrics(_sclay.fonts, &ascent, &descent, &lineh);
+    return (Clay_Dimensions) {
+        .width = fonsTextBounds(_sclay.fonts, 0, 0, text.chars, text.chars + text.length, NULL),
+        .height = ascent - descent
+    };
+}
+
+static void _draw_rect(float x, float y, float w, float h){
+    sgl_v2f(x, y);
+    sgl_v2f(x, y);
+    sgl_v2f(x+w, y);
+    sgl_v2f(x, y+h);
+    sgl_v2f(x+w, y+h);
+    sgl_v2f(x+w, y+h);
+}
+
+static float _SIN[16] = {
+    0.000000f, 0.104528f, 0.207912f, 0.309017f,
+    0.406737f, 0.500000f, 0.587785f, 0.669131f,
+    0.743145f, 0.809017f, 0.866025f, 0.913545f,
+    0.951057f, 0.978148f, 0.994522f, 1.000000f,
+};
+
+/* rx,ry = radius */
+static void _draw_corner(float x, float y, float rx, float ry){
+    x -= rx;
+    y -= ry;
+    sgl_v2f(x, y);
+    for(int i = 0; i < 16; ++i){
+        sgl_v2f(x, y);
+        sgl_v2f(x+(rx*_SIN[15-i]), y+(ry*_SIN[i]));
+    }
+    sgl_v2f(x+(rx*_SIN[0]), y+(ry*_SIN[15]));
+}
+
+/* rx,ry = radius   ix,iy = inner radius */
+static void _draw_corner_border(float x, float y, float rx, float ry, float ix, float iy){
+    x -= rx;
+    y -= ry;
+    sgl_v2f(x+(ix*_SIN[15]), y+(iy*_SIN[0]));
+    for(int i = 0; i < 16; ++i){
+        sgl_v2f(x+(ix*_SIN[15-i]), y+(iy*_SIN[i]));
+        sgl_v2f(x+(rx*_SIN[15-i]), y+(ry*_SIN[i]));
+    }
+    sgl_v2f(x+(rx*_SIN[0]), y+(ry*_SIN[15]));
+}
+
+void sclay_render(Clay_RenderCommandArray renderCommands, sclay_font_t *fonts) {
+    sgl_matrix_mode_modelview();
+    sgl_translate(-1.0f, 1.0f, 0.0f);
+    sgl_scale(2.0f/_sclay.size.width, -2.0f/_sclay.size.height, 1.0f);
+    sgl_disable_texture();
+    sgl_push_pipeline();
+    sgl_load_pipeline(_sclay.pip);
+    for (uint32_t i = 0; i < renderCommands.length; i++) {
+        Clay_RenderCommand *renderCommand = Clay_RenderCommandArray_Get(&renderCommands, i);
+        Clay_BoundingBox bbox = renderCommand->boundingBox;
+        switch (renderCommand->commandType) {
+            case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
+                Clay_RectangleRenderData *config = &renderCommand->renderData.rectangle;
+                sgl_c4f(config->backgroundColor.r / 255.0f,
+                        config->backgroundColor.g / 255.0f,
+                        config->backgroundColor.b / 255.0f,
+                        config->backgroundColor.a / 255.0f);
+                Clay_CornerRadius r = config->cornerRadius;
+                sgl_begin_triangle_strip();
+                if(r.topLeft > 0 || r.topRight > 0){
+                    _draw_corner(bbox.x, bbox.y, -r.topLeft, -r.topLeft);
+                    _draw_corner(bbox.x+bbox.width, bbox.y, r.topRight, -r.topRight);
+                    _draw_rect(bbox.x+r.topLeft, bbox.y,
+                               bbox.width-r.topLeft-r.topRight, CLAY__MAX(r.topLeft, r.topRight));
+                }
+                if(r.bottomLeft > 0 || r.bottomRight > 0){
+                    _draw_corner(bbox.x, bbox.y+bbox.height, -r.bottomLeft, r.bottomLeft);
+                    _draw_corner(bbox.x+bbox.width, bbox.y+bbox.height, r.bottomRight, r.bottomRight);
+                    _draw_rect(bbox.x+r.bottomLeft,
+                               bbox.y+bbox.height-CLAY__MAX(r.bottomLeft, r.bottomRight),
+                               bbox.width-r.bottomLeft-r.bottomRight, CLAY__MAX(r.bottomLeft, r.bottomRight));
+                }
+                if(r.topLeft < r.bottomLeft){
+                    if(r.topLeft < r.topRight){
+                        _draw_rect(bbox.x, bbox.y+r.topLeft, r.topLeft, bbox.height-r.topLeft-r.bottomLeft);
+                        _draw_rect(bbox.x+r.topLeft, bbox.y+r.topRight,
+                                   r.bottomLeft-r.topLeft, bbox.height-r.topRight-r.bottomLeft);
+                    } else {
+                        _draw_rect(bbox.x, bbox.y+r.topLeft, r.bottomLeft, bbox.height-r.topLeft-r.bottomLeft);
+                    }
+                } else {
+                    if(r.bottomLeft < r.bottomRight){
+                        _draw_rect(bbox.x, bbox.y+r.topLeft, r.bottomLeft, bbox.height-r.topLeft-r.bottomLeft);
+                        _draw_rect(bbox.x+r.bottomLeft, bbox.y+r.topLeft,
+                                   r.topLeft-r.bottomLeft, bbox.height-r.topLeft-r.bottomRight);
+                    } else {
+                        _draw_rect(bbox.x, bbox.y+r.topLeft, r.topLeft, bbox.height-r.topLeft-r.bottomLeft);
+                    }
+                }
+                if(r.topRight < r.bottomRight){
+                    if(r.topRight < r.topLeft){
+                        _draw_rect(bbox.x+bbox.width-r.bottomRight, bbox.y+r.topLeft,
+                                   r.bottomRight-r.topRight, bbox.height-r.topLeft-r.bottomRight);
+                        _draw_rect(bbox.x+bbox.width-r.topRight, bbox.y+r.topRight,
+                                   r.topRight, bbox.height-r.topRight-r.bottomRight);
+                    } else {
+                        _draw_rect(bbox.x+bbox.width-r.bottomRight, bbox.y+r.topRight,
+                                   r.bottomRight, bbox.height-r.topRight-r.bottomRight);
+                    }
+                } else {
+                    if(r.bottomRight < r.bottomLeft){
+                        _draw_rect(bbox.x+bbox.width-r.topRight, bbox.y+r.topRight,
+                                   r.topRight-r.bottomRight, bbox.height-r.topRight-r.bottomLeft);
+                        _draw_rect(bbox.x+bbox.width-r.bottomRight, bbox.y+r.topRight,
+                                   r.bottomRight, bbox.height-r.topRight-r.bottomRight);
+                    } else {
+                        _draw_rect(bbox.x+bbox.width-r.topRight, bbox.y+r.topRight,
+                                   r.topRight, bbox.height-r.topRight-r.bottomRight);
+                    }
+                }
+                _draw_rect(bbox.x+CLAY__MAX(r.topLeft, r.bottomLeft),
+                           bbox.y+CLAY__MAX(r.topLeft, r.topRight),
+                           bbox.width-CLAY__MAX(r.topLeft, r.bottomLeft)-CLAY__MAX(r.topRight, r.bottomRight),
+                           bbox.height-CLAY__MAX(r.topLeft, r.topRight)-CLAY__MAX(r.bottomLeft, r.bottomRight));
+                sgl_end();
+                break;
+            }
+            case CLAY_RENDER_COMMAND_TYPE_TEXT: {
+                if(!fonts) break;
+                Clay_TextRenderData *config = &renderCommand->renderData.text;
+                Clay_StringSlice text = config->stringContents;
+                fonsSetFont(_sclay.fonts, fonts[config->fontId]);
+                uint32_t color = sfons_rgba(
+                        config->textColor.r,
+                        config->textColor.g,
+                        config->textColor.b,
+                        config->textColor.a);
+                fonsSetColor(_sclay.fonts, color);
+                fonsSetSpacing(_sclay.fonts, config->letterSpacing * _sclay.dpi_scale);
+                fonsSetAlign(_sclay.fonts, FONS_ALIGN_LEFT | FONS_ALIGN_TOP);
+                fonsSetSize(_sclay.fonts, config->fontSize * _sclay.dpi_scale);
+                sgl_matrix_mode_modelview();
+                sgl_push_matrix();
+                sgl_scale(1.0f/_sclay.dpi_scale, 1.0f/_sclay.dpi_scale, 1.0f);
+                fonsDrawText(_sclay.fonts, bbox.x*_sclay.dpi_scale, bbox.y*_sclay.dpi_scale,
+                             text.chars, text.chars + text.length);
+                sgl_pop_matrix();
+                break;
+            }
+            case CLAY_RENDER_COMMAND_TYPE_SCISSOR_START: {
+                sgl_scissor_rectf(bbox.x*_sclay.dpi_scale, bbox.y*_sclay.dpi_scale,
+                                  bbox.width*_sclay.dpi_scale, bbox.height*_sclay.dpi_scale,
+                                  true);
+                break;
+            }
+            case CLAY_RENDER_COMMAND_TYPE_SCISSOR_END: {
+                sgl_scissor_rectf(0, 0,
+                                  _sclay.size.width*_sclay.dpi_scale, _sclay.size.height*_sclay.dpi_scale,
+                                  true);
+                break;
+            }
+            case CLAY_RENDER_COMMAND_TYPE_IMAGE: {
+                //TODO
+                break;
+            }
+            case CLAY_RENDER_COMMAND_TYPE_BORDER: {
+                Clay_BorderRenderData *config = &renderCommand->renderData.border;
+                sgl_c4f(config->color.r / 255.0f,
+                        config->color.g / 255.0f,
+                        config->color.b / 255.0f,
+                        config->color.a / 255.0f);
+                Clay_BorderWidth w = config->width;
+                Clay_CornerRadius r = config->cornerRadius;
+                sgl_begin_triangle_strip();
+                if(w.left > 0){
+                    _draw_rect(bbox.x, bbox.y + r.topLeft,
+                               w.left, bbox.height - r.topLeft - r.bottomLeft);
+                }
+                if(w.right > 0){
+                    _draw_rect(bbox.x + bbox.width - w.right, bbox.y + r.topRight,
+                               w.right, bbox.height - r.topRight - r.bottomRight);
+                }
+                if(w.top > 0){
+                    _draw_rect(bbox.x + r.topLeft, bbox.y,
+                               bbox.width - r.topLeft - r.topRight, w.top);
+                }
+                if(w.bottom > 0){
+                    _draw_rect(bbox.x + r.bottomLeft, bbox.y + bbox.height - w.bottom,
+                               bbox.width - r.bottomLeft - r.bottomRight, w.bottom);
+                }
+                if(r.topLeft > 0 && (w.top > 0 || w.left > 0)){
+                    _draw_corner_border(bbox.x, bbox.y,
+                                        -r.topLeft, -r.topLeft,
+                                        -r.topLeft+w.left, -r.topLeft+w.top);
+                }
+                if(r.topRight > 0 && (w.top > 0 || w.right > 0)){
+                    _draw_corner_border(bbox.x+bbox.width, bbox.y,
+                                        r.topRight, -r.topRight,
+                                        r.topRight-w.right, -r.topRight+w.top);
+                }
+                if(r.bottomLeft > 0 && (w.bottom > 0 || w.left > 0)){
+                    _draw_corner_border(bbox.x, bbox.y+bbox.height,
+                                        -r.bottomLeft, r.bottomLeft,
+                                        -r.bottomLeft+w.left, r.bottomLeft-w.bottom);
+                }
+                if(r.bottomRight > 0 && (w.bottom > 0 || w.right > 0)){
+                    _draw_corner_border(bbox.x+bbox.width, bbox.y+bbox.height,
+                                        r.bottomRight, r.bottomRight,
+                                        r.bottomRight-w.right, r.bottomRight-w.bottom);
+                }
+                sgl_end();
+                break;
+            }
+            default:
+                break;
+        }
+    }
+    sgl_pop_pipeline();
+    sfons_flush(_sclay.fonts);
+}
+#endif /* SOKOL_CLAY_IMPL */