diff options
Diffstat (limited to 'robsonGL.h')
| -rw-r--r-- | robsonGL.h | 323 |
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; -} |