summaryrefslogtreecommitdiff
path: root/robsonGL.h
diff options
context:
space:
mode:
authorRoberto Esteves <contact@robertoesteves.dev>2026-01-05 14:11:50 +0000
committerRoberto Esteves <contact@robertoesteves.dev>2026-01-05 14:11:50 +0000
commit52c6a7635056ee78d282ba2a55eb26f2663bb577 (patch)
tree9d37d851e63e96e53ef3836321f03d4f2839edef /robsonGL.h
parentda12440cabe270584ff650703e90db540d2ec4c9 (diff)
refactor some stuff:HEADmaster
- add meson build system - refactor executable to be a test - remove stdlib from base library
Diffstat (limited to 'robsonGL.h')
-rw-r--r--robsonGL.h323
1 files changed, 0 insertions, 323 deletions
diff --git a/robsonGL.h b/robsonGL.h
deleted file mode 100644
index 59e0d6a..0000000
--- a/robsonGL.h
+++ /dev/null
@@ -1,323 +0,0 @@
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-typedef int32_t rglFixed;
-
-#define RGL_SUBPIXEL_SHIFT 8
-#define RGL_SUBPIXEL_SCALE 256
-#define RGL_SUBPIXEL_MASK 255
-
-#define crash(text) \
- do { \
- printf(text); \
- *((int *)0) = -1; \
- } while (0)
-
-static inline rglFixed rglGetFixedI(int x) {
- return (rglFixed)(x << RGL_SUBPIXEL_SHIFT);
-}
-
-static inline rglFixed rglGetFixedF(float x) {
- return (rglFixed)(x * RGL_SUBPIXEL_SCALE);
-}
-
-static inline rglFixed rglGetFixedD(double x) {
- return (rglFixed)(x * RGL_SUBPIXEL_SCALE);
-}
-
-static inline int rglFixedToInt(rglFixed x) { return x >> RGL_SUBPIXEL_SHIFT; }
-
-static inline rglFixed rglFixedMul(rglFixed a, rglFixed b) {
- return (rglFixed)(((int64_t)a * b) >> RGL_SUBPIXEL_SHIFT);
-}
-
-typedef struct {
- uint32_t width, height;
- uint32_t *data;
-} rglBuffer;
-
-typedef struct {
- uint32_t x, y, width, height;
-} rglRectangle;
-
-typedef uint32_t rglColor;
-
-typedef struct {
- rglFixed x, y;
-} rglPoint;
-
-typedef enum { PathStroke, PathFill } rglPathVerb;
-
-typedef struct {
- uint32_t listSize;
- uint32_t listCapacity;
- rglPathVerb verb;
-
- rglFixed *xList;
- rglFixed *yList;
-} rglPath;
-
-typedef enum { Rect, Path } rglCommandType;
-
-typedef struct {
- rglCommandType type;
- rglColor color;
- union {
- rglRectangle *rect;
- rglPath *path;
- };
-} rglCommand;
-
-typedef struct {
- uint32_t size;
- rglCommand *commands;
-} rglCommandQueue;
-
-typedef struct {
- rglColor color;
- rglBuffer buf;
- rglCommandQueue queue;
-
- // TODO: make this use rglCommand in the future
- void *current;
-} rglContext;
-
-void rglQueueCommand(rglCommandQueue *queue, rglCommand *cmd) {
- // FIXME: append correctly
- queue->size += 1;
- queue->commands = cmd;
-}
-
-// TODO: Use memory arena implementation from ruim
-void rglBeginPath(rglContext *ctx, rglPathVerb verb) {
- rglPath *path = malloc(sizeof(rglPath));
-
- path->listSize = 0;
- path->listCapacity = 16;
- path->verb = verb;
- path->xList = malloc(path->listCapacity * sizeof(uint32_t));
- path->yList = malloc(path->listCapacity * sizeof(uint32_t));
-
- ctx->current = (void *)path;
-}
-
-void rglPathMoveTo(rglContext *ctx, int32_t x, int32_t y) {
- rglPath *path = (rglPath *)ctx->current;
-
- uint32_t p = path->listSize;
- path->xList[p] = rglGetFixedI(x);
- path->yList[p] = rglGetFixedI(y);
-
- path->listSize += 1;
-}
-
-void rglEndPath(rglContext *ctx) {
- rglCommand *command = malloc(sizeof(rglCommand));
-
- command->type = Path;
- command->path = (rglPath *)ctx->current;
- command->color = ctx->color;
-
- rglQueueCommand(&ctx->queue, command);
- ctx->current = 0;
-}
-
-#define COLOR(a, r, g, b) ((a << 24) | (r << 16) | (g << 8) | b)
-
-// TODO: implement shared memory mechanism
-int rglBufferAlloc(rglBuffer *buf) {
- uint32_t size = buf->width * buf->height * 4;
- buf->data = malloc(size); // ARGB pixel format
-
- if (buf->data == NULL) {
- return -1;
- }
-
- memset(buf->data, 0, size);
-
- return 0;
-}
-
-void rglDrawRect(rglBuffer *buf, rglCommand *cmd) {
- if (cmd->type != Rect)
- crash("expected rectangle type");
-
- for (int y = 0; y < buf->height; ++y) {
- for (int x = 0; x < buf->width; ++x) {
- int insideX = x >= cmd->rect->x && x <= (cmd->rect->x + cmd->rect->width);
- int insideY =
- y >= cmd->rect->y && y <= (cmd->rect->y + cmd->rect->height);
-
- if (insideX && insideY) {
- buf->data[x + (y * buf->width)] = cmd->color;
- }
- }
- }
-}
-
-void rglDrawStroke(rglBuffer *buf, rglPath *path, rglColor color) {
- for (uint32_t i = 0; i < path->listSize; ++i) {
- rglPoint p1, p2;
-
- p1.x = path->xList[i];
- p1.y = path->yList[i];
-
- p2.x = path->xList[(i + 1) % path->listSize];
- p2.y = path->yList[(i + 1) % path->listSize];
-
- int x0 = rglFixedToInt(p1.x), y0 = rglFixedToInt(p1.y);
- int x1 = rglFixedToInt(p2.x), y1 = rglFixedToInt(p2.y);
-
- int dx = abs(x1 - x0);
- int dy = -abs(y1 - y0);
-
- int sx = x0 < x1 ? 1 : -1;
- int sy = y0 < y1 ? 1 : -1;
-
- int err = dx + dy, e2;
- for (;;) {
- int idx = x0 + (y0 * buf->width);
- if (idx < buf->width * buf->height) {
- buf->data[idx] = color;
- }
-
- if (x0 == x1 && y0 == y1)
- break;
- e2 = err * 2;
- if (e2 >= dy) {
- err += dy;
- x0 += sx;
- }
-
- if (e2 <= dx) {
- err += dx;
- y0 += sy;
- }
- }
- }
-}
-
-// TODO: maybe construct edge table on command creation
-void rglDrawFill(rglBuffer *buf, rglPath *path, rglColor col) {
- struct edge_node {
- int active;
- rglFixed yMax;
- rglFixed x;
- // FIXME: make this fixed point later
- float slope;
- struct edge_node *next;
- };
-
- unsigned int x0, y0, x1, y1, x, y, xMin, yMin, lineTest;
- unsigned int i, yMinIdx, yMaxIdx;
- int j;
- struct edge_node *table;
- struct edge_node *node;
-
- table = malloc(sizeof(struct edge_node) * buf->height);
- memset(table, 0, sizeof(struct edge_node) * buf->height);
-
- for (i = 0; i < path->listSize; ++i) {
- for (j = i; j < path->listSize; ++j) {
- if (path->yList[j] < path->yList[yMinIdx]) {
- yMinIdx = j;
- }
- }
-
- x0 = rglFixedToInt(path->xList[yMinIdx]);
- y0 = rglFixedToInt(path->yList[yMinIdx]);
-
- node = &(table[y0]);
- for (j = -1; j < 2; j += 2) {
- yMaxIdx = (i + j * 1) % path->listSize;
- if (y0 == path->yList[yMaxIdx]) {
- continue;
- } else if (y0 <= path->yList[yMaxIdx]) {
- yMaxIdx = yMinIdx;
- }
-
- x1 = rglFixedToInt(path->xList[yMaxIdx]);
- y1 = rglFixedToInt(path->yList[yMaxIdx]);
-
- node->active = 1;
- node->x = x1;
- node->yMax = y1;
- node->slope = (float)(x1 - x0) / (float)(y1 - y0);
-
- if (j != -1) {
- node->next = malloc(sizeof(struct edge_node));
- node = node->next;
- }
- }
- }
-
- for (y = 0; y < buf->height; ++y) {
- yMin = buf->height - 1;
- while (table[yMin].active) {
- yMin--;
- }
-
- // Draw polygon
- node = &table[yMin];
- xMin = node->x;
-
- for (x = 0; x < buf->width; ++x) {
- i = x + (y * buf->width);
- lineTest = (x * node->slope) -
- }
- }
-}
-
-void rglDrawPath(rglBuffer *buf, rglPath *path, rglColor col) {
- switch (path->verb) {
- case PathStroke: {
- rglDrawStroke(buf, path, col);
- } break;
- case PathFill: {
- rglDrawFill(buf, path, col);
- } break;
- }
-}
-
-void rglSetColor(rglContext *ctx, int a, int r, int g, int b) {
- ctx->color = COLOR(a, r, g, b);
-}
-
-void rglDraw(rglContext *ctx) {
- for (int i = 0; i < ctx->queue.size; ++i) {
- rglCommand cmd = ctx->queue.commands[i];
- switch (cmd.type) {
- case Rect: {
- rglDrawRect(&ctx->buf, &cmd);
- } break;
- case Path: {
- rglDrawPath(&ctx->buf, cmd.path, cmd.color);
- } break;
- }
- }
-}
-
-int rglWritePPM(rglContext *ctx, const char *filename) {
- FILE *f = fopen(filename, "wb");
- if (!f)
- return -1;
-
- fprintf(f, "P6\n%d %d\n255\n", ctx->buf.width, ctx->buf.height);
-
- for (int i = 0; i < ctx->buf.width * ctx->buf.height; ++i) {
- uint32_t pixel = ctx->buf.data[i];
-
- uint8_t r = (pixel >> 16) & 0xFF;
- uint8_t g = (pixel >> 8) & 0xFF;
- uint8_t b = pixel & 0xFF;
-
- fputc(r, f);
- fputc(g, f);
- fputc(b, f);
- }
-
- fclose(f);
- return 0;
-}