2d orientation
This commit is contained in:
parent
f48edc2210
commit
7cee41de2a
16
Makefile
16
Makefile
@ -1,14 +1,20 @@
|
|||||||
|
.SUFFIXES:
|
||||||
|
.INTERMEDIATE:
|
||||||
|
.SECONDARY:
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
SDL ?= ../SDL
|
SDL ?= ../SDL
|
||||||
|
|
||||||
DEBUG = -g -gdwarf-5
|
DEBUG = -g -gdwarf-5
|
||||||
|
|
||||||
CFLAGS += -Wall -Werror -Wfatal-errors
|
CFLAGS += -Wall -Werror -Wfatal-errors
|
||||||
CFLAGS += -Wno-error=unused-function
|
CFLAGS += -Wno-error=unused-function
|
||||||
CFLAGS += -std=c23
|
CFLAGS += -std=c++23
|
||||||
CFLAGS += -I$(SDL)/include -D_REENTRANT
|
CFLAGS += -I$(SDL)/include -D_REENTRANT
|
||||||
CFLAGS += $(shell pkg-config --cflags freetype2)
|
CFLAGS += $(shell pkg-config --cflags freetype2)
|
||||||
LDFLAGS += -L$(SDL)/build -lSDL3 -Wl,-rpath=$(SDL)/build
|
LDFLAGS += -L$(SDL)/build -lSDL3 -Wl,-rpath=$(SDL)/build
|
||||||
LDFLAGS += $(shell pkg-config --libs freetype2)
|
LDFLAGS += $(shell pkg-config --libs freetype2)
|
||||||
|
LDFLAGS += -lm
|
||||||
|
|
||||||
DEPFLAGS = -MMD -MP
|
DEPFLAGS = -MMD -MP
|
||||||
|
|
||||||
@ -23,13 +29,13 @@ clean:
|
|||||||
rm -f *.o *.d *.gch
|
rm -f *.o *.d *.gch
|
||||||
rm -f main
|
rm -f main
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.cpp
|
||||||
$(CC) $(CARCH) $(CFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -MF ${<}.d -c $< -o $@
|
$(CXX) $(CARCH) $(CFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -MF ${<}.d -c $< -o $@
|
||||||
|
|
||||||
main: $(MAIN_OBJS)
|
main: $(MAIN_OBJS)
|
||||||
$(CC) $^ -o $@ $(LDFLAGS)
|
$(CXX) $^ -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
-include $(shell find -type f -name '*.d')
|
#-include $(shell find -type f -name '*.d')
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.INTERMEDIATE:
|
.INTERMEDIATE:
|
||||||
|
@ -6,12 +6,16 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include "math/vec2.hpp"
|
||||||
|
#include "math/mat2x2.hpp"
|
||||||
|
|
||||||
struct glyph {
|
struct glyph {
|
||||||
int32_t width;
|
int32_t width;
|
||||||
int32_t height;
|
int32_t height;
|
||||||
@ -63,8 +67,8 @@ load_outline_char(SDL_Renderer * renderer,
|
|||||||
|
|
||||||
SDL_LockSurface(surface);
|
SDL_LockSurface(surface);
|
||||||
|
|
||||||
for (int y = 0; y < face->glyph->bitmap.rows; y++) {
|
for (unsigned int y = 0; y < face->glyph->bitmap.rows; y++) {
|
||||||
for (int x = 0; x < face->glyph->bitmap.width; x++) {
|
for (unsigned int x = 0; x < face->glyph->bitmap.width; x++) {
|
||||||
int s_ix = y * face->glyph->bitmap.pitch + x;
|
int s_ix = y * face->glyph->bitmap.pitch + x;
|
||||||
int d_ix = y * surface->pitch + x * 4;
|
int d_ix = y * surface->pitch + x * 4;
|
||||||
uint8_t gray = face->glyph->bitmap.buffer[s_ix];
|
uint8_t gray = face->glyph->bitmap.buffer[s_ix];
|
||||||
@ -125,49 +129,156 @@ int load_font(SDL_Renderer * renderer, int font_size)
|
|||||||
return 0;
|
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;
|
int32_t x_advance = x;
|
||||||
for (int i = (length - 1); i >= 0; i--) {
|
int32_t y_advance = y;
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
char c = s[i];
|
char c = s[i];
|
||||||
struct glyph * glyph = &glyphs[c - 0x20];
|
struct glyph * glyph = &glyphs[c - 0x20];
|
||||||
advance -= glyph->horiAdvance;
|
x_advance += glyph->horiAdvance;
|
||||||
if (glyph->texture != NULL) {
|
if (glyph->texture != NULL) {
|
||||||
double x = (double)(advance + glyph->horiBearingX) / 64.f;
|
float x = (float)(x_advance + glyph->horiBearingX) / 64.f;
|
||||||
double y = (window_height / 2) + (face_height >> 6) / 3 + ((double)glyph->horiBearingY / -64.f);
|
float y = (float)(y_advance - glyph->horiBearingY) / 64.f;
|
||||||
SDL_FRect srect = {
|
SDL_FRect srect = {
|
||||||
.x = 0.f,
|
.x = 0.f,
|
||||||
.y = 0.f,
|
.y = 0.f,
|
||||||
.w = glyph->width,
|
.w = (float)glyph->width,
|
||||||
.h = glyph->height
|
.h = (float)glyph->height
|
||||||
};
|
};
|
||||||
SDL_FRect drect = {
|
SDL_FRect drect = {
|
||||||
.x = x,
|
.x = x,
|
||||||
.y = y,
|
.y = y,
|
||||||
.w = glyph->width,
|
.w = (float)glyph->width,
|
||||||
.h = glyph->height
|
.h = (float)glyph->height
|
||||||
};
|
};
|
||||||
SDL_RenderTexture(renderer, glyph->texture, &srect, &drect);
|
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>;
|
||||||
static int table[10] = {
|
|
||||||
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
|
struct line {
|
||||||
|
vec2 a;
|
||||||
|
vec2 b;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (digits <= 0)
|
struct state {
|
||||||
return buf;
|
struct line line;
|
||||||
|
vec2 normal;
|
||||||
|
vec2 mouse_position;
|
||||||
|
};
|
||||||
|
|
||||||
int power = table[digits - 1];
|
struct state state = {
|
||||||
for (int i = 0; i < digits; i++) {
|
.line = {
|
||||||
buf[i] = '0' + ((value / power) % 10);
|
{ 0, -0.5 },
|
||||||
power /= 10;
|
{ 0, 0.5 },
|
||||||
|
},
|
||||||
|
.normal = { -1, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static int window_width = 1;
|
||||||
|
static int window_height = 1;
|
||||||
|
|
||||||
|
static inline int min(int a, int b)
|
||||||
|
{
|
||||||
|
return (a > b) ? b : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf + digits;
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
int main()
|
||||||
@ -190,7 +301,7 @@ int main()
|
|||||||
const char * s = SDL_GetRenderDriver(i);
|
const char * s = SDL_GetRenderDriver(i);
|
||||||
printf(" %s\n", s);
|
printf(" %s\n", s);
|
||||||
}
|
}
|
||||||
renderer = SDL_CreateRenderer(window, "opengles2");
|
renderer = SDL_CreateRenderer(window, "software");
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||||
|
|
||||||
SDL_PropertiesID props = SDL_GetRendererProperties(renderer);
|
SDL_PropertiesID props = SDL_GetRendererProperties(renderer);
|
||||||
@ -198,7 +309,7 @@ int main()
|
|||||||
const char * name = SDL_GetRendererName(renderer);
|
const char * name = SDL_GetRendererName(renderer);
|
||||||
assert(name != NULL);
|
assert(name != NULL);
|
||||||
printf("renderer: %s\n", name);
|
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);
|
assert(formats != NULL);
|
||||||
while (*formats != SDL_PIXELFORMAT_UNKNOWN) {
|
while (*formats != SDL_PIXELFORMAT_UNKNOWN) {
|
||||||
printf("%s\n", SDL_GetPixelFormatName(*formats++));
|
printf("%s\n", SDL_GetPixelFormatName(*formats++));
|
||||||
@ -206,17 +317,17 @@ int main()
|
|||||||
|
|
||||||
uint64_t ticks = SDL_GetTicks();
|
uint64_t ticks = SDL_GetTicks();
|
||||||
|
|
||||||
int font_size = 30;
|
int font_size = 25;
|
||||||
load_font(renderer, font_size);
|
load_font(renderer, font_size);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||||
SDL_RenderClear(renderer);
|
SDL_RenderClear(renderer);
|
||||||
int window_width;
|
|
||||||
int window_height;
|
|
||||||
bool success = SDL_GetWindowSizeInPixels(window, &window_width, &window_height);
|
bool success = SDL_GetWindowSizeInPixels(window, &window_width, &window_height);
|
||||||
assert(success == true);
|
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); }
|
while (SDL_GetTicks() - ticks < (1000 / 60)) { SDL_Delay(1); }
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
@ -231,6 +342,13 @@ int main()
|
|||||||
if (event.key.key == SDLK_ESCAPE)
|
if (event.key.key == SDLK_ESCAPE)
|
||||||
goto exit;
|
goto exit;
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user