diff --git a/.gitignore b/.gitignore index 920b172..0e9297b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -cmake-build-debug/ -cmake-build-release/ +cmake-build-*/ +build/ .DS_Store .idea/ node_modules/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 02b20b3..31c8478 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,9 @@ add_subdirectory("examples/raylib-sidebar-scrolling-container") # add_subdirectory("examples/cairo-pdf-rendering") Some issue with github actions populating cairo, disable for now if(NOT MSVC) add_subdirectory("examples/clay-official-website") + add_subdirectory("examples/introducing-clay-video-demo") + add_subdirectory("examples/SDL2-video-demo") + add_subdirectory("examples/minimal-imgui") add_subdirectory("examples/SDL3-simple-demo") endif() add_subdirectory("examples/introducing-clay-video-demo") diff --git a/examples/minimal-imgui/CMakeLists.txt b/examples/minimal-imgui/CMakeLists.txt new file mode 100644 index 0000000..c20bd55 --- /dev/null +++ b/examples/minimal-imgui/CMakeLists.txt @@ -0,0 +1,50 @@ +cmake_minimum_required(VERSION 3.27) +project(minimal_imgui) +set(CMAKE_C_STANDARD 99) + +set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) + +#add_subdirectory(3rd_party) + +include(FetchContent) + +FetchContent_Declare( + sokol + GIT_REPOSITORY "https://github.com/floooh/sokol.git" + GIT_COMMIT "789d97071d17cbab4e3835a0b0b8b379e98c114f" + GIT_PROGRESS TRUE + GIT_SHALLOW TRUE +) + +FetchContent_Declare( + imgui + GIT_REPOSITORY "https://github.com/ocornut/imgui.git" + GIT_TAG "v1.91.6" + GIT_PROGRESS TRUE + GIT_SHALLOW TRUE +) + +FetchContent_MakeAvailable(sokol imgui) + +add_executable(minimal_imgui + main.cpp + ${imgui_SOURCE_DIR}/imgui.cpp + ${imgui_SOURCE_DIR}/imgui_demo.cpp + ${imgui_SOURCE_DIR}/imgui_draw.cpp + ${imgui_SOURCE_DIR}/imgui_tables.cpp + ${imgui_SOURCE_DIR}/imgui_widgets.cpp +) + +target_compile_options(minimal_imgui PUBLIC) +target_include_directories(minimal_imgui PUBLIC .) + +#set(CMAKE_CXX_FLAGS_DEBUG "-DCLAY_DEBUG") +set(CMAKE_CXX_FLAGS_RELEASE "-O3") +target_include_directories(minimal_imgui PUBLIC ${sokol_SOURCE_DIR} ${imgui_SOURCE_DIR}) +if(WIN32) + target_link_libraries(minimal_imgui PUBLIC kernel32 user32 shell32 gdi32) +elseif(APPLE) + target_link_libraries(minimal_imgui PUBLIC "-framework Cocoa" "-framework QuartzCore" "-framework OpenGL") +elseif(UNIX AND NOT APPLE) + target_link_libraries(minimal_imgui PUBLIC X11 Xi Xcursor GL dl pthread m) +endif() diff --git a/examples/minimal-imgui/main.cpp b/examples/minimal-imgui/main.cpp new file mode 100644 index 0000000..d42cde6 --- /dev/null +++ b/examples/minimal-imgui/main.cpp @@ -0,0 +1,196 @@ +#define CLAY_IMPLEMENTATION +#include "../../clay.h" + +#define SOKOL_IMPL +#define SOKOL_NO_ENTRY +#define SOKOL_GLCORE +#include "sokol_app.h" +#include "sokol_gfx.h" +#include "sokol_glue.h" +#include "sokol_log.h" + +#define IMGUI_DEFINE_MATH_OPERATORS +#include "imgui.h" +#define SOKOL_IMGUI_IMPL +#include "util/sokol_imgui.h" + +#include + +#define SCREEN_WIDTH 800 +#define SCREEN_HEIGHT 600 + +sg_pass_action pass_action = {}; + +static const uint32_t FONT_ID_BODY_24 = 0; +static const Clay_Color COLOR_ORANGE = (Clay_Color) {225, 138, 50, 255}; +static const Clay_Color COLOR_BLUE = (Clay_Color) {111, 173, 162, 255}; +static const Clay_Color COLOR_LIGHT = (Clay_Color) {224, 215, 210, 255}; + +void init(); +void frame(); +void cleanup(); +void input(const sapp_event* event); + +static void Label(Clay_String text) { + CLAY(CLAY_LAYOUT({ .padding = {16, 8} }), + CLAY_RECTANGLE({ .color = Clay_Hovered() ? COLOR_BLUE : COLOR_ORANGE }) + ) { + CLAY_TEXT(text, CLAY_TEXT_CONFIG({ + .textColor = { 255, 255, 255, 255 }, + .fontId = FONT_ID_BODY_24, + .fontSize = 24, + })); + } +} + +static Clay_RenderCommandArray CreateLayout() { + Clay_BeginLayout(); + CLAY(CLAY_ID("MainContent"), + CLAY_LAYOUT({ + .sizing = { + .width = CLAY_SIZING_GROW(), + .height = CLAY_SIZING_GROW(), + }, + .childAlignment = { + .x = CLAY_ALIGN_X_CENTER, + .y = CLAY_ALIGN_Y_CENTER, + } + }), + CLAY_RECTANGLE({ + .color = COLOR_LIGHT, + }) + ) { + Label(CLAY_STRING("Hello, World!")); + } + return Clay_EndLayout(); +} + +Clay_Dimensions measureText(Clay_String *text, Clay_TextElementConfig *config); +void render(Clay_RenderCommandArray renderCommands); + +int main(int argc, char** args) { + //----------------------------------------------------------------------- + // Setup Clay + //----------------------------------------------------------------------- + uint64_t totalMemorySize = Clay_MinMemorySize(); + Clay_Arena clayMemory = (Clay_Arena) { + .label = CLAY_STRING("Clay Memory Arena"), + .capacity = totalMemorySize, + .memory = (char*)malloc(totalMemorySize), + }; + + Clay_SetMeasureTextFunction(measureText); + + Clay_Initialize(clayMemory, (Clay_Dimensions) { SCREEN_WIDTH, SCREEN_HEIGHT }); + + //----------------------------------------------------------------------- + // Setup Sokol + //----------------------------------------------------------------------- + sapp_desc desc = {0}; + desc.init_cb = init; + desc.frame_cb = frame; + desc.cleanup_cb = cleanup, + desc.event_cb = input, + desc.width = SCREEN_WIDTH, + desc.height = SCREEN_HEIGHT, + desc.window_title = "sokol + puredoom", + desc.icon.sokol_default = true, + desc.logger.func = slog_func; + sapp_run(&desc); + + return 0; +} + +void init() { + sg_desc desc = {0}; + desc.environment = sglue_environment(); + desc.logger.func = slog_func; + sg_setup(&desc); + + pass_action.colors[0] = (sg_color_attachment_action){ .load_action=SG_LOADACTION_CLEAR, .clear_value={0.2f, 0.1f, 0.3f, 1.0f} }; + + simgui_desc_t simgui_desc = {0}; + simgui_setup(&simgui_desc); +} + +void frame() { + // const double dt = sapp_frame_duration(); + + const int width = sapp_width(); + const int height = sapp_height(); + simgui_new_frame({ width, height, sapp_frame_duration(), sapp_dpi_scale() }); + + // imgui + { + // ImGui::ShowDemoWindow(); + ImGui::SetNextWindowSize(ImVec2{SCREEN_WIDTH, SCREEN_HEIGHT}); + ImGui::SetNextWindowPos(ImVec2{0, 0}); + ImGui::Begin("Text rendering", NULL, ImGuiWindowFlags_NoBackground|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoSavedSettings); + + Clay_RenderCommandArray renderCommands = CreateLayout(); + render(renderCommands); + + ImGui::End(); + } + + sg_begin_pass({ .action = pass_action, .swapchain = sglue_swapchain() }); + simgui_render(); + sg_end_pass(); + sg_commit(); +} + +void cleanup() { + simgui_shutdown(); + sg_shutdown(); +} + +void input(const sapp_event* event) { + simgui_handle_event(event); +} + +Clay_Dimensions measureText(Clay_String *text, Clay_TextElementConfig *config) +{ + ImVec2 size = ImGui::CalcTextSize(text->chars, nullptr); + return (Clay_Dimensions) { + .width = size.x, + .height = size.y, + }; +} + + +void render(Clay_RenderCommandArray renderCommands) +{ + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + ImVec2 p = ImGui::GetCursorScreenPos(); + + for (uint32_t i = 0; i < renderCommands.length; i++) + { + Clay_RenderCommand *renderCommand = Clay_RenderCommandArray_Get(&renderCommands, i); + Clay_BoundingBox boundingBox = renderCommand->boundingBox; + switch (renderCommand->commandType) + { + case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: { + Clay_RectangleElementConfig *config = renderCommand->config.rectangleElementConfig; + Clay_Color color = config->color; + + draw_list->AddRectFilled(p+ImVec2(boundingBox.x, boundingBox.y), p+ImVec2(boundingBox.x+boundingBox.width, boundingBox.y+boundingBox.height), ImColor(color.r/255.0f, color.g/255.0f, color.b/255.0f, color.a/255.0f)); + + break; + } + case CLAY_RENDER_COMMAND_TYPE_TEXT: { + Clay_TextElementConfig *config = renderCommand->config.textElementConfig; + + draw_list->AddText(p+ImVec2(boundingBox.x, boundingBox.y), ImColor(config->textColor.r/255.0f, config->textColor.g/255.0f, config->textColor.b/255.0f, config->textColor.a/255.0f), renderCommand->text.chars); + + break; + } + default: { + fprintf(stderr, "Error: unhandled render command: %d\n", renderCommand->commandType); + #ifdef CLAY_OVERFLOW_TRAP + raise(SIGTRAP); + #endif + exit(1); + } + } + } +}