-
Notifications
You must be signed in to change notification settings - Fork 152
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0602565
commit b5b47b2
Showing
3 changed files
with
261 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
cmake_minimum_required(VERSION 3.27) | ||
project(minimal_sdl2 C) | ||
set(CMAKE_C_STANDARD 99) | ||
|
||
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) | ||
|
||
include(FetchContent) | ||
set(FETCHCONTENT_QUIET FALSE) | ||
|
||
FetchContent_Declare( | ||
SDL2 | ||
GIT_REPOSITORY "https://github.com/libsdl-org/SDL.git" | ||
GIT_TAG "release-2.30.10" | ||
GIT_PROGRESS TRUE | ||
GIT_SHALLOW TRUE | ||
) | ||
FetchContent_MakeAvailable(SDL2) | ||
|
||
FetchContent_Declare( | ||
SDL2_ttf | ||
GIT_REPOSITORY "https://github.com/libsdl-org/SDL_ttf.git" | ||
GIT_TAG "release-2.22.0" | ||
GIT_PROGRESS TRUE | ||
GIT_SHALLOW TRUE | ||
) | ||
FetchContent_MakeAvailable(SDL2_ttf) | ||
|
||
add_executable(minimal_sdl2 main.c) | ||
|
||
target_compile_options(minimal_sdl2 PUBLIC) | ||
target_include_directories(minimal_sdl2 PUBLIC .) | ||
|
||
target_link_libraries(minimal_sdl2 PUBLIC SDL2 SDL2_ttf) | ||
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Werror -DCLAY_DEBUG") | ||
set(CMAKE_CXX_FLAGS_RELEASE "-O3") | ||
|
||
add_custom_command( | ||
TARGET minimal_sdl2 POST_BUILD | ||
COMMAND ${CMAKE_COMMAND} -E copy_directory | ||
${CMAKE_CURRENT_SOURCE_DIR}/resources | ||
${CMAKE_CURRENT_BINARY_DIR}/resources) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
#define CLAY_IMPLEMENTATION | ||
#include "../../clay.h" | ||
|
||
#include <SDL.h> | ||
#include <SDL_ttf.h> | ||
|
||
#include <stdio.h> | ||
#include <stdbool.h> | ||
#include <stdint.h> | ||
#include <stdlib.h> | ||
|
||
|
||
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}; | ||
|
||
|
||
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({ | ||
.fontId = FONT_ID_BODY_24, | ||
.fontSize = 24, | ||
.textColor = { 255, 255, 255, 255 }, | ||
})); | ||
} | ||
} | ||
|
||
|
||
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(); | ||
} | ||
|
||
|
||
typedef struct | ||
{ | ||
uint32_t fontId; | ||
TTF_Font *font; | ||
} Font; | ||
static Font fonts[1]; | ||
|
||
|
||
static Clay_Dimensions measureText(Clay_String *text, Clay_TextElementConfig *config); | ||
static void render(SDL_Renderer *renderer, Clay_RenderCommandArray renderCommands); | ||
|
||
|
||
int main(void) { | ||
if (SDL_Init(SDL_INIT_VIDEO) < 0) { | ||
fprintf(stderr, "Error: could not initialize SDL: %s\n", SDL_GetError()); | ||
return 1; | ||
} | ||
if (TTF_Init() < 0) { | ||
fprintf(stderr, "Error: could not initialize TTF: %s\n", TTF_GetError()); | ||
return 1; | ||
} | ||
|
||
TTF_Font *font = TTF_OpenFont("resources/Roboto-Regular.ttf", 24); | ||
if (!font) { | ||
fprintf(stderr, "Error: could not load font: %s\n", TTF_GetError()); | ||
return 1; | ||
} | ||
fonts[FONT_ID_BODY_24] = (Font) { | ||
.font = font, | ||
.fontId = FONT_ID_BODY_24, | ||
}; | ||
|
||
SDL_Window *window = NULL; | ||
SDL_Renderer *renderer = NULL; | ||
if (SDL_CreateWindowAndRenderer(800, 600, SDL_WINDOW_RESIZABLE, &window, &renderer) < 0) { | ||
fprintf(stderr, "Error: could not create window and renderer: %s", SDL_GetError()); | ||
} | ||
|
||
uint64_t totalMemorySize = Clay_MinMemorySize(); | ||
Clay_Arena clayMemory = (Clay_Arena) { | ||
.label = CLAY_STRING("Clay Memory Arena"), | ||
.memory = malloc(totalMemorySize), | ||
.capacity = totalMemorySize, | ||
}; | ||
|
||
Clay_SetMeasureTextFunction(measureText); | ||
|
||
int windowWidth = 0; | ||
int windowHeight = 0; | ||
SDL_GetWindowSize(window, &windowWidth, &windowHeight); | ||
Clay_Initialize(clayMemory, (Clay_Dimensions) { windowWidth, windowHeight }); | ||
|
||
while (true) { | ||
SDL_Event event; | ||
while (SDL_PollEvent(&event)) { | ||
switch (event.type) { | ||
case SDL_QUIT: goto quit; | ||
} | ||
} | ||
int mouseX = 0; | ||
int mouseY = 0; | ||
Uint32 mouseState = SDL_GetMouseState(&mouseX, &mouseY); | ||
Clay_Vector2 mousePosition = (Clay_Vector2){ mouseX, mouseY }; | ||
Clay_SetPointerState((Clay_Vector2){ mouseX, mouseY }, mouseState & SDL_BUTTON(1)); | ||
|
||
SDL_GetWindowSize(window, &windowWidth, &windowHeight); | ||
Clay_SetLayoutDimensions((Clay_Dimensions) { windowWidth, windowHeight }); | ||
|
||
Clay_RenderCommandArray renderCommands = CreateLayout(); | ||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); | ||
SDL_RenderClear(renderer); | ||
|
||
render(renderer, renderCommands); | ||
|
||
SDL_RenderPresent(renderer); | ||
} | ||
quit: | ||
|
||
SDL_DestroyRenderer(renderer); | ||
SDL_DestroyWindow(window); | ||
TTF_Quit(); | ||
SDL_Quit(); | ||
return 0; | ||
} | ||
|
||
|
||
static Clay_Dimensions measureText(Clay_String *text, Clay_TextElementConfig *config) | ||
{ | ||
TTF_Font *font = fonts[config->fontId].font; | ||
char *chars = (char *)calloc(text->length + 1, 1); | ||
memcpy(chars, text->chars, text->length); | ||
int width = 0; | ||
int height = 0; | ||
if (TTF_SizeUTF8(font, chars, &width, &height) < 0) { | ||
fprintf(stderr, "Error: could not measure text: %s\n", TTF_GetError()); | ||
#ifdef CLAY_OVERFLOW_TRAP | ||
raise(SIGTRAP); | ||
#endif | ||
exit(1); | ||
} | ||
free(chars); | ||
return (Clay_Dimensions) { | ||
.width = width, | ||
.height = height, | ||
}; | ||
} | ||
|
||
|
||
static void render(SDL_Renderer *renderer, Clay_RenderCommandArray renderCommands) | ||
{ | ||
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; | ||
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a); | ||
SDL_FRect rect = (SDL_FRect) { | ||
.x = boundingBox.x, | ||
.y = boundingBox.y, | ||
.w = boundingBox.width, | ||
.h = boundingBox.height, | ||
}; | ||
SDL_RenderFillRectF(renderer, &rect); | ||
break; | ||
} | ||
case CLAY_RENDER_COMMAND_TYPE_TEXT: { | ||
Clay_TextElementConfig *config = renderCommand->config.textElementConfig; | ||
Clay_String text = renderCommand->text; | ||
char *cloned = (char *)calloc(text.length + 1, 1); | ||
memcpy(cloned, text.chars, text.length); | ||
TTF_Font* font = fonts[config->fontId].font; | ||
SDL_Surface *surface = TTF_RenderUTF8_Blended(font, cloned, (SDL_Color) { | ||
.r = config->textColor.r, | ||
.g = config->textColor.g, | ||
.b = config->textColor.b, | ||
.a = config->textColor.a, | ||
}); | ||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface); | ||
|
||
SDL_Rect destination = (SDL_Rect){ | ||
.x = boundingBox.x, | ||
.y = boundingBox.y, | ||
.w = boundingBox.width, | ||
.h = boundingBox.height, | ||
}; | ||
SDL_RenderCopy(renderer, texture, NULL, &destination); | ||
|
||
SDL_DestroyTexture(texture); | ||
SDL_FreeSurface(surface); | ||
free(cloned); | ||
break; | ||
} | ||
default: { | ||
fprintf(stderr, "Error: unhandled render command: %d\n", renderCommand->commandType); | ||
#ifdef CLAY_OVERFLOW_TRAP | ||
raise(SIGTRAP); | ||
#endif | ||
exit(1); | ||
} | ||
} | ||
} | ||
} |
Binary file not shown.