From 7cee41de2a8f1a5fbf5334eadb928179b54ea87b Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Fri, 7 Feb 2025 15:26:32 -0600 Subject: [PATCH] 2d orientation --- Makefile | 16 +++-- main.c => main.cpp | 174 +++++++++++++++++++++++++++++++++++++-------- math | 1 + 3 files changed, 158 insertions(+), 33 deletions(-) rename main.c => main.cpp (55%) create mode 120000 math diff --git a/Makefile b/Makefile index 14d4831..f4f3d87 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,20 @@ +.SUFFIXES: +.INTERMEDIATE: +.SECONDARY: +.PHONY: all clean + SDL ?= ../SDL DEBUG = -g -gdwarf-5 CFLAGS += -Wall -Werror -Wfatal-errors CFLAGS += -Wno-error=unused-function -CFLAGS += -std=c23 +CFLAGS += -std=c++23 CFLAGS += -I$(SDL)/include -D_REENTRANT CFLAGS += $(shell pkg-config --cflags freetype2) LDFLAGS += -L$(SDL)/build -lSDL3 -Wl,-rpath=$(SDL)/build LDFLAGS += $(shell pkg-config --libs freetype2) +LDFLAGS += -lm DEPFLAGS = -MMD -MP @@ -23,13 +29,13 @@ clean: rm -f *.o *.d *.gch rm -f main -%.o: %.c - $(CC) $(CARCH) $(CFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -MF ${<}.d -c $< -o $@ +%.o: %.cpp + $(CXX) $(CARCH) $(CFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -MF ${<}.d -c $< -o $@ main: $(MAIN_OBJS) - $(CC) $^ -o $@ $(LDFLAGS) + $(CXX) $^ -o $@ $(LDFLAGS) --include $(shell find -type f -name '*.d') +#-include $(shell find -type f -name '*.d') .SUFFIXES: .INTERMEDIATE: diff --git a/main.c b/main.cpp similarity index 55% rename from main.c rename to main.cpp index d3f5ceb..7f2a630 100644 --- a/main.c +++ b/main.cpp @@ -6,12 +6,16 @@ #include #include #include +#include #include #include FT_FREETYPE_H #include +#include "math/vec2.hpp" +#include "math/mat2x2.hpp" + struct glyph { int32_t width; int32_t height; @@ -63,8 +67,8 @@ load_outline_char(SDL_Renderer * renderer, SDL_LockSurface(surface); - for (int y = 0; y < face->glyph->bitmap.rows; y++) { - for (int x = 0; x < face->glyph->bitmap.width; x++) { + for (unsigned int y = 0; y < face->glyph->bitmap.rows; y++) { + for (unsigned int x = 0; x < face->glyph->bitmap.width; x++) { int s_ix = y * face->glyph->bitmap.pitch + x; int d_ix = y * surface->pitch + x * 4; uint8_t gray = face->glyph->bitmap.buffer[s_ix]; @@ -125,49 +129,156 @@ int load_font(SDL_Renderer * renderer, int font_size) return 0; } -void render(SDL_Renderer * renderer, int window_width, int window_height, const char * s, int length) +int32_t render_text(SDL_Renderer * renderer, int32_t x, int32_t y, const char * s, int length) { - int32_t advance = (window_width - (window_width * 5 / 100)) << 6; - for (int i = (length - 1); i >= 0; i--) { + int32_t x_advance = x; + int32_t y_advance = y; + for (int i = 0; i < length; i++) { char c = s[i]; struct glyph * glyph = &glyphs[c - 0x20]; - advance -= glyph->horiAdvance; + x_advance += glyph->horiAdvance; if (glyph->texture != NULL) { - double x = (double)(advance + glyph->horiBearingX) / 64.f; - double y = (window_height / 2) + (face_height >> 6) / 3 + ((double)glyph->horiBearingY / -64.f); + float x = (float)(x_advance + glyph->horiBearingX) / 64.f; + float y = (float)(y_advance - glyph->horiBearingY) / 64.f; SDL_FRect srect = { .x = 0.f, .y = 0.f, - .w = glyph->width, - .h = glyph->height + .w = (float)glyph->width, + .h = (float)glyph->height }; SDL_FRect drect = { .x = x, .y = y, - .w = glyph->width, - .h = glyph->height + .w = (float)glyph->width, + .h = (float)glyph->height }; SDL_RenderTexture(renderer, glyph->texture, &srect, &drect); } } + return x_advance; } -char * format_base10(char * buf, int value, int digits) +using vec2 = vec<2, float>; +using mat2x2 = mat<2, 2, float>; + +struct line { + vec2 a; + vec2 b; +}; + +struct state { + struct line line; + vec2 normal; + vec2 mouse_position; +}; + +struct state state = { + .line = { + { 0, -0.5 }, + { 0, 0.5 }, + }, + .normal = { -1, 0 }, +}; + +static int window_width = 1; +static int window_height = 1; + +static inline int min(int a, int b) { - static int table[10] = { - 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 + return (a > b) ? b : a; +} + +vec2 transform_vertex(vec2 v, float scale) +{ + float dim = ((float)min(window_height, window_width)) / 2.0f; + + float x = v.x; + float y = v.y; + + x *= scale; + y *= scale; + + return { + x * dim + window_width / 2.0f, + y * dim + window_height / 2.0f, + }; +} + +vec2 inverse_transform(float x, float y) +{ + float dim = ((float)min(window_height, window_width)) / 2.0f; + assert(dim != 0); + + return { + -(window_width - 2 * x) / (2 * dim), + -(window_height - 2 * y) / (2 * dim), + }; +} + +struct line transform_line(struct line line, float scale) +{ + return { + transform_vertex(line.a, scale), + transform_vertex(line.b, scale), + }; +} + +static inline void render_line(SDL_Renderer * renderer, struct line line) +{ + assert(SDL_RenderLine(renderer, line.a.x, line.a.y, line.b.x, line.b.y)); +} + +void render_lines(SDL_Renderer * renderer) +{ + // line + assert(SDL_SetRenderDrawColorFloat(renderer, 1, 0.5, 0.5, 1)); + struct line tl = transform_line(state.line, 1.0f); + render_line(renderer, tl); + + // normal + assert(SDL_SetRenderDrawColorFloat(renderer, 1, 0, 0, 1)); + struct line normal_line = {{0, 0}, state.normal}; + render_line(renderer, transform_line(normal_line, 0.5f)); + + // mouse + assert(SDL_SetRenderDrawColorFloat(renderer, 0, 0, 1, 1)); + struct line mouse_line = {{0, 0}, state.mouse_position}; + render_line(renderer, transform_line(mouse_line, 0.5f)); + + // foo + float s = cross(state.normal, -state.mouse_position); + float c = dot(state.normal, -state.mouse_position); + mat2x2 r = { + c, -s, + s, c, }; - if (digits <= 0) - return buf; + vec2 nr = r * state.normal; + assert(SDL_SetRenderDrawColorFloat(renderer, 0, 1, 0, 1)); + struct line nr_line = {{0, 0}, nr}; + render_line(renderer, transform_line(nr_line, 0.5f)); - int power = table[digits - 1]; - for (int i = 0; i < digits; i++) { - buf[i] = '0' + ((value / power) % 10); - power /= 10; + { + assert(SDL_SetRenderDrawColorFloat(renderer, 0.5, 1, 0.5, 1)); + vec2 ar = r * state.line.a; + vec2 br = r * state.line.b; + struct line tl = transform_line({ar, br}, 1.0f); + render_line(renderer, tl); } +} - return buf + digits; +void render_text_state(SDL_Renderer * renderer) +{ + int32_t x_advance = 10 << 6; + int32_t y_advance = face_height; + x_advance = render_text(renderer, x_advance, y_advance, "dot: ", 5); + + + //float d = dot(state.normal, state.mouse_position); + float d = dot({0, 1}, state.mouse_position); + char buf[64]; + int len = snprintf(buf, 64, "%.03f", d); + x_advance = render_text(renderer, x_advance, y_advance, buf, len); } int main() @@ -190,7 +301,7 @@ int main() const char * s = SDL_GetRenderDriver(i); printf(" %s\n", s); } - renderer = SDL_CreateRenderer(window, "opengles2"); + renderer = SDL_CreateRenderer(window, "software"); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_PropertiesID props = SDL_GetRendererProperties(renderer); @@ -198,7 +309,7 @@ int main() const char * name = SDL_GetRendererName(renderer); assert(name != NULL); printf("renderer: %s\n", name); - const SDL_PixelFormat * formats = SDL_GetPointerProperty(props, SDL_PROP_RENDERER_TEXTURE_FORMATS_POINTER, NULL); + const SDL_PixelFormat * formats = (const SDL_PixelFormat *)SDL_GetPointerProperty(props, SDL_PROP_RENDERER_TEXTURE_FORMATS_POINTER, NULL); assert(formats != NULL); while (*formats != SDL_PIXELFORMAT_UNKNOWN) { printf("%s\n", SDL_GetPixelFormatName(*formats++)); @@ -206,17 +317,17 @@ int main() uint64_t ticks = SDL_GetTicks(); - int font_size = 30; + int font_size = 25; load_font(renderer, font_size); while (1) { SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); - int window_width; - int window_height; bool success = SDL_GetWindowSizeInPixels(window, &window_width, &window_height); assert(success == true); - render(renderer, window_width, window_height, "test", 4); + + render_text_state(renderer); + render_lines(renderer); while (SDL_GetTicks() - ticks < (1000 / 60)) { SDL_Delay(1); } SDL_RenderPresent(renderer); @@ -231,6 +342,13 @@ int main() if (event.key.key == SDLK_ESCAPE) goto exit; break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + if (event.button.button == 1) { + vec2 mv = inverse_transform(event.button.x, event.button.y); + float m = magnitude(mv); + state.mouse_position = mv / m; + } + break; default: break; } diff --git a/math b/math new file mode 120000 index 0000000..3b488e0 --- /dev/null +++ b/math @@ -0,0 +1 @@ +../dreamcast/math \ No newline at end of file