diff options
author | Krow Savcik <krow@savcik.xyz> | 2023-12-25 12:20:59 +0200 |
---|---|---|
committer | Krow Savcik <krow@savcik.xyz> | 2023-12-25 12:20:59 +0200 |
commit | fb26949fe3c1b6145f1c77af2198d999a856cd37 (patch) | |
tree | 4c73c35d0fa4d6083373a0369c47bd5a3be0d885 |
initial commit
-rw-r--r-- | Makefile | 17 | ||||
-rw-r--r-- | README.md | 41 | ||||
-rw-r--r-- | config.mk | 4 | ||||
-rw-r--r-- | draw.c | 340 | ||||
-rw-r--r-- | draw.h | 6 | ||||
-rw-r--r-- | obj/car.obj | 108 | ||||
-rw-r--r-- | obj/cube.obj | 25 | ||||
-rw-r--r-- | obj/smth.obj | 22 | ||||
-rw-r--r-- | sim.c | 199 | ||||
-rw-r--r-- | sim.h | 25 | ||||
-rw-r--r-- | types.h | 4 |
11 files changed, 791 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2553325 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +include config.mk + +OBJ = draw.o + +all: build run + +build: ${OBJ} sim.c + ${CC} ${CFLAGS} ${LIBS} ${OBJ} sim.c -o sim + +run: + ./sim + +%.o: %.c + ${CC} ${CFLAGS} $< -c + +clean: + rm *.o sim diff --git a/README.md b/README.md new file mode 100644 index 0000000..0c5108a --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# 3D triangle renderer + +Short interactive C program for rendering 3D triangles. + +## Compiling + +The only requirement are the SDL2 devel files. + +```sh +make +``` + +## Controls + +- **W,A,S,D** for moving. +- **M** for toggling mouse-lock. +- **arrows** for rotating camera. +- **J,K** for moving vertically. +- **I** for object importing. +- **=/-** for increasing/decreasing speed. + +## Object files + +Object files are a modified/simplified version of standard .obj files. +Available potions are the following: + +1. **M** *factor* - multiply factor. Vertices added will have their coordinates multiplied. +2. **v** *x* *y* *z* - add vertex. +3. **f** *v1* *v2* *v3* - add triangle face with following vertices. +4. **F** *v1* *v2* *v3* *color* - add triangle face with color and following vertices. + +Lines that start with any other character will be ignored. + +## TO-DO List + +- use matrix math instead of trigonometric formulas. +- crop triangles close to screen. +- fix Z depth. +- faster drawing. +- config file with controls and defines. +- organize functions in files properly. diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..1b416d4 --- /dev/null +++ b/config.mk @@ -0,0 +1,4 @@ +CFLAGS = -std=c89 -DSDL_DISABLE_IMMINTRIN_H -w -I. +LIBS = -lm -lSDL2 + +CC = cc @@ -0,0 +1,340 @@ +#include <SDL2/SDL.h> +#include <math.h> +/* #include <SDL2/SDL_render.h> */ + +#include "draw.h" +#include "sim.h" + +/*#define SHADOW*/ +#define TRIANGLELINES +#define MAXTRIANGLE 2048 +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define INTTOCOL(C) (C>>16), ((C>>8)%256), (C%256) +#define P(a,b,c) ((Point){a, b, c}) + +const int shadowcol = 0x191919ff; + +int w, h; +SDL_Point *pts_queue; +int pts_queue_cnt; +float *pts_depth; + +Triangle tgs[MAXTRIANGLE]; +int tgs_cnt; + +typedef struct { + int x, y; +} Point2d; + +void add_triangle(Point, Point, Point, unsigned int); + +void +add_obj(const char *path, Point off) +{ + char s[1024]; + FILE *f; + /* CAP of 1024 vertecies */ + Point v[1024]; + Point t[3]; + int pc = 0; + int a, b, c; + float mult = 1; + unsigned int col; + + if ((f = fopen(path, "r")) == NULL) { + printf("%s:%d add_obj(...): Error opening file %s\n", __FILE__, __LINE__, path); + return; + } + + while (fgets(s, 1024, f) != NULL) { + switch (s[0]) { + case 'M': + sscanf(s, "%*c %f", &mult); + break; + case 'v': + sscanf(s, "%*c %f%f%f", &v[pc].x, &v[pc].y, &v[pc].z); + v[pc].x = v[pc].x * mult + off.x; + v[pc].y = v[pc].y * mult + off.y; + v[pc].z = v[pc].z * mult + off.z; + ++pc; + break; + case 'f': + sscanf(s, "%*c %d%d%d", &a, &b, &c); + add_triangle(v[a-1], v[b-1], v[c-1], 0x808080ff); + t[0] = v[a-1]; t[0].y = 0; + t[1] = v[b-1]; t[1].y = 0; + t[2] = v[c-1]; t[2].y = 0; +#ifdef SHADOW + add_triangle(t[0], t[1], t[2], shadowcol); +#endif + break; + case 'F': + sscanf(s, "%*c %d%d%d%x", &a, &b, &c, &col); + add_triangle(v[a-1], v[b-1], v[c-1], col); + t[0] = v[a-1]; t[0].y = 0; + t[1] = v[b-1]; t[1].y = 0; + t[2] = v[c-1]; t[2].y = 0; +#ifdef SHADOW + add_triangle(t[0], t[1], t[2], shadowcol); +#endif + break; + } + } + + fclose(f); +} + +void +add_obj_interactive() +{ + char path[1024]; + int i; + Point offset; + printf("PATH: "); + fflush(stdout); + + do + fgets(path, 1024, stdin); + while (path[0] == '\n'); + printf("OFFSET X Y Z: "); + fflush(stdout); + scanf("%f%f%f", &offset.x, &offset.y, &offset.z); + + for (i = 0; i < 1024; ++i) + if (path[i] == '\n') + path[i] = '\0'; + + add_obj(path, offset); +} + +void +redo_obj() +{ + tgs_cnt = 0; + add_obj("obj/car.obj", P(0,0,0)); +} + +void +make_point_relative(Point *a) +{ + double x, y, z; + double b, c; + x = a->x - cam.pos.x; + y = a->y - cam.pos.y; + z = a->z - cam.pos.z; + + b = cos(cam.rad) * x + sin(cam.rad) * z; + c = cos(cam.rad) * z - sin(cam.rad) * x; + + x = b; + z = c; + + + b = cos(cam.azim) * x + sin(cam.azim) * y; + c = cos(cam.azim) * y - sin(cam.azim) * x; + + x = b; + y = c; + + a->x = x; + a->y = y; + a->z = z; +} + +Point2d +get_point(Point a) +{ + Point2d r; + + if (a.x > 0) { + if (a.x < 0.01) + a.x = 0.01; + } else if (a.x > -0.01) + a.x = -0.01; + r.x = ((float) w) * a.z / (a.x * 2.0 * hfov); + r.x += w/2; + r.y = ((float) h) * a.y / (a.x * 2.0 * vfov); + r.y = h/2 - r.y; + return r; +} + +int +det(Point2d a, Point2d b, Point2d c) +{ + /* TODO Better */ + int d = 0; + int L = 3200; + + d = MAX(-L, MIN(L, a.x)) * MAX(-L, MIN(L, b.y - c.y)); + d += MAX(-L, MIN(L, a.y)) * MAX(-L, MIN(L, c.x - b.x)); + d += MAX(-L, MIN(L, b.x)) * MAX(-L, MIN(L, c.y)); + d -= MAX(-L, MIN(L, b.y)) * MAX(-L, MIN(L, c.x)); + return a.x * (b.y - c.y) - a.y * (b.x - c.x) + b.x * c.y - b.y * c.x; +} + +void +draw_point2d(Point2d a, int d) +{ + SDL_Rect r; + + if (a.x < 0 || a.x > w) return; + if (a.y < 0 || a.y > h) return; + + r.x = a.x - d; + r.y = a.y - d; + r.w = 2 * d + 1; + r.h = 2 * d + 1; +/* SDL_RenderDrawPoint(ren, a.x, a.y);*/ + SDL_RenderFillRect(ren, &r); +} + +float +getdep(Point a, Point b, Point c, Point d) +{ + Point cp; + float r; + b.x -= a.x; c.x -= a.x; + b.y -= a.y; c.y -= a.y; + b.z -= a.z; c.z -= a.z; + + b.z = -b.z; + a.z = -a.z; + c.z = -c.z; + d.z = -d.z; + + cp.x = - ( - b.y * c.z + b.z * c.y ); + cp.y = - ( - b.z * c.x + b.x * c.z ); + cp.z = - ( - b.x * c.y + b.y * c.x ); + r = cp.x * a.x + cp.y * a.y + cp.z * a.z; + r = r / (cp.x * d.x + cp.y * d.y + cp.z * d.z); + + return r; +} + +void +draw_triangle(Point x, Point y, Point z) +{ + int i, j; + int mnx, mny, mxx, mxy; + float d; + + Point2d a, b, c; + a = get_point(x); + b = get_point(y); + c = get_point(z); + + if (det(a, b, c) >= 0) return; + mnx = MIN(a.x, MIN(b.x, c.x)); + mxx = MAX(a.x, MAX(b.x, c.x)); + mny = MIN(a.y, MIN(b.y, c.y)); + mxy = MAX(a.y, MAX(b.y, c.y)); + + /* Fake depth :> */ + + for(i = MAX(mnx, 0); i <= MIN(mxx, w-1); ++i) { + for (j = MAX(mny, 0); j <= MIN(mxy, h-1); ++j) { + if (det(a, b, (Point2d){i, j}) <= 0 && + det(b, c, (Point2d){i, j}) <= 0 && + det(c, a, (Point2d){i, j}) <= 0) { + d = getdep(x, y, z, P(((float)w)/(2.0*hfov), h/2 - j, i - w/2)); + if (d < pts_depth[j*w+i]) { + pts_queue[pts_queue_cnt++] = (SDL_Point){i, j}; + pts_depth[j*w+i] = d; + } + } + } + } + + SDL_RenderDrawPoints(ren, pts_queue, pts_queue_cnt); +#ifdef TRIANGLELINES + SDL_SetRenderDrawColor(ren, 0xff, 0xff, 0xff, 0xff); + SDL_SetRenderDrawColor(ren, 0x00, 0x00, 0x00, 0xff); + SDL_RenderDrawLine(ren, a.x, a.y, b.x, b.y); + SDL_RenderDrawLine(ren, c.x, c.y, b.x, b.y); + SDL_RenderDrawLine(ren, a.x, a.y, c.x, c.y); +#endif +} + +void +draw_triangle3d(Point a, Point b, Point c) +{ + int x, y, z; + int i, j; + pts_queue_cnt = 0; + Point2d m, n, o; + make_point_relative(&a); + make_point_relative(&b); + make_point_relative(&c); + + if (a.x < 0 && b.x < 0 && c.x < 0) return; + if (a.x >= 0 && b.x >= 0 && c.x >= 0) return draw_triangle(a, b, c); + return; + + x = (a.x >= 0) ? 1 : -1; m = get_point(a); + y = (b.x >= 0) ? 1 : -1; n = get_point(b); + z = (c.x >= 0) ? 1 : -1; o = get_point(c); + + /* TODO: Better, not entire screen */ + if (x * y * z * det(m,n,o) >= 0) return; + + for(i = 0; i <= w; ++i) { + for (j = 0; j <= h; ++j) { + if ((x * y * det(m, n, (Point2d){i, j}) <= 0) && + (z * y * det(n, o, (Point2d){i, j}) <= 0) && + (z * x * det(o, m, (Point2d){i, j}) <= 0)) + SDL_RenderDrawPoint(ren, i, j); + } + } +} + +void +add_triangle(Point a, Point b, Point c, unsigned int col) +{ + tgs[tgs_cnt].p[0] = a; + tgs[tgs_cnt].p[1] = b; + tgs[tgs_cnt].p[2] = c; + tgs[tgs_cnt].col = col; + tgs_cnt++; +} + +int +draw_init() +{ + /* TODO: error handling */ + pts_queue = malloc(w * h * (sizeof *pts_queue)); + pts_depth = malloc(w * h * (sizeof *pts_depth)); + + tgs_cnt = 0; + add_triangle((Point){3,16,2}, (Point){10,8,-5}, (Point){10,6,6}, 0xff0040ff); + add_triangle((Point){10,8,-5}, (Point){5,4,2}, (Point){10,6,6}, 0xff0040ff); + add_triangle((Point){10,0,-5}, (Point){5,0,2}, (Point){10,0,6}, shadowcol); + + int u = 7; + + return 0; +} + +int +draw_screen() +{ + int i; + for (i = 0; i < w*h; ++i) { + pts_depth[i] = 250000.0; + } + /* Background */ + SDL_SetRenderDrawColor(ren, INTTOCOL(0x404040), 255); + SDL_RenderClear(ren); + + /* SDL_SetRenderDrawColor(ren, 25, 25, 25, 255); + draw_triangle3d((Point){cam.pos.x-1.5,0,cam.pos.z-1.5}, (Point){cam.pos.x-1.5,0,cam.pos.z+1.5}, (Point){cam.pos.x+2.0,0,cam.pos.z}); */ + + for (i = 0; i < tgs_cnt; ++i) { + SDL_SetRenderDrawColor(ren, INTTOCOL((tgs[i].col)>>8), tgs[i].col%256); + draw_triangle3d(tgs[i].p[0], tgs[i].p[1], tgs[i].p[2]); + } + + SDL_RenderPresent(ren); + + return 0; +} @@ -0,0 +1,6 @@ +int draw_screen(); +int draw_init(); +void add_obj_interactive(); +void redo_obj(); + +extern int w, h; diff --git a/obj/car.obj b/obj/car.obj new file mode 100644 index 0000000..97a8235 --- /dev/null +++ b/obj/car.obj @@ -0,0 +1,108 @@ +M 3.0 + +v 0.2 0.6 1.1 +v 0 0.9 1.4 +v 0 1.4 1.4 +v 2 1.6 1.4 +v 6.8 0.7 1.1 +v 7.2 1.1 1.4 +v 7.2 1.6 1.4 +v 6.1 1.8 1.4 +v 0.2 0.6 -1.1 +v 0 0.9 -1.4 +v 0 1.4 -1.4 +v 2 1.6 -1.4 +v 6.8 0.7 -1.1 +v 7.2 1.1 -1.4 +v 7.2 1.6 -1.4 +v 6.1 1.8 -1.4 +v 3.0 2.5 1 +v 5.1 2.5 1 +v 3.0 2.5 -1 +v 5.1 2.5 -1 +v 2.1 1.8 1.4 +v 3.1 2.4 1 +v 3.7 2.4 1 +v 3.6 1.8 1.4 + +# Front Lights 25-32 +v -0.01 0.95 0.95 +v -0.01 0.95 1.35 +v -0.01 1.35 1.35 +v -0.01 1.35 0.95 +v -0.01 0.95 -0.95 +v -0.01 0.95 -1.35 +v -0.01 1.35 -1.35 +v -0.01 1.35 -0.95 + +# License Plate 33- +v -0.01 0.95 -0.4 +v -0.01 0.95 0.4 +v -0.01 1.25 0.4 +v -0.01 1.25 -0.4 +v -0.02 1.00 -0.3 +v -0.02 1.00 0.3 +v -0.02 1.07 0.3 +v -0.02 1.07 -0.3 +v -0.02 1.13 -0.3 +v -0.02 1.13 0.3 +v -0.02 1.20 0.3 +v -0.02 1.20 -0.3 + + +# X Y Z +# Left side +F 2 1 6 0x424c6eff +F 1 5 6 0x424c6eff +F 2 6 7 0x657392ff +F 2 7 3 0x657392ff +F 3 7 8 0x657392ff +F 3 8 4 0x657392ff +F 4 8 18 0x0e071bff +F 4 18 17 0x0e071bff + +# Right side +F 10 14 9 0x424c6eff +F 9 14 13 0x424c6eff +F 10 15 14 0x657392ff +F 10 11 15 0x657392ff +F 11 16 15 0x657392ff +F 11 12 16 0x657392ff +F 12 20 16 0x0e071bff +F 12 19 20 0x0e071bff + +# Front +F 1 2 10 0x424c6eff +F 1 10 9 0x424c6eff +F 2 3 11 0x657392ff +F 2 11 10 0x657392ff +F 3 4 12 0x728199ff +F 3 12 11 0x728199ff +F 4 17 19 0x0e071bff +F 4 19 12 0x0e071bff +F 17 18 20 0x728199ff +F 17 20 19 0x728199ff + +# Back +F 6 5 13 0x424c6eff +F 6 13 14 0x424c6eff +F 7 6 14 0x657392ff +F 7 14 15 0x657392ff +F 8 7 15 0x728199ff +F 8 15 16 0x728199ff +F 8 16 20 0x0e071bff +F 8 20 18 0x0e071bff + +# Front Lights +F 25 26 27 0xf0c674ff +F 25 27 28 0xf0c674ff +F 29 31 30 0xf0c674ff +F 29 32 31 0xf0c674ff + +# License Plate Front +F 33 34 35 0xc5c8c6ff +F 33 35 36 0xc5c8c6ff +# F 37 38 39 0x1d1f21ff +# F 37 39 40 0x1f1f21ff +# F 41 42 43 0x1d1f21ff +# F 41 43 44 0x1f1f21ff diff --git a/obj/cube.obj b/obj/cube.obj new file mode 100644 index 0000000..7faca9b --- /dev/null +++ b/obj/cube.obj @@ -0,0 +1,25 @@ +v 0 0 0 +v 0 0 8 +v 0 8 0 +v 0 8 8 +v 8 0 0 +v 8 0 8 +v 8 8 0 +v 8 8 8 +F 1 4 3 0xd75f5fff +F 1 2 4 0xd75f5fff + +F 4 2 8 0x87af5fff +F 2 6 8 0x87af5fff + +F 5 7 8 0xffaf5fff +F 6 5 8 0xffaf5fff + +F 1 3 7 0x87afd7ff +F 1 7 5 0x87afd7ff + +F 1 6 2 0x69b2b2ff +F 1 5 6 0x69b2b2ff + +F 4 8 3 0x8787afff +F 3 8 7 0x8787afff diff --git a/obj/smth.obj b/obj/smth.obj new file mode 100644 index 0000000..9a12225 --- /dev/null +++ b/obj/smth.obj @@ -0,0 +1,22 @@ +v 0 0 0 +v 0 0 5 +v 0 4.33 2.5 +v 20 0 0 +v 20 0 5 +v 20 4.33 2.5 +F 1 2 3 0xd75f5f88 +F 1 3 2 0xd75f5f88 +F 6 4 5 0xd75f5f88 +F 6 5 4 0xd75f5f88 +F 1 2 4 0xd75f5f88 +F 1 4 2 0xd75f5f88 +F 2 5 4 0xd75f5f88 +F 2 4 5 0xd75f5f88 +F 2 5 6 0xd75f5f88 +F 2 6 5 0xd75f5f88 +F 3 2 6 0xd75f5f88 +F 3 6 2 0xd75f5f88 +F 3 1 6 0xd75f5f88 +F 3 6 1 0xd75f5f88 +F 4 1 6 0xd75f5f88 +F 4 6 1 0xd75f5f88 @@ -0,0 +1,199 @@ +/* #include <stdio.h> */ +#include <math.h> +#include <SDL2/SDL.h> + +#include "sim.h" +#include "draw.h" +#include "types.h" + +#define MOUSE_LOCK 1 + +float hfov, vfov; +float PI; +Camera cam; +uint fps = 30; + +SDL_Window *win; +void *ren; + +typedef struct{ + SDL_Keymod mod; + SDL_Keycode sym; + void (*func)(const Arg *); + const Arg arg; +} Key; + +int +main_init() +{ + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "%s:%d:main_init() error %s", __FILE__, __LINE__, SDL_GetError()); + return 1; + } + + win = SDL_CreateWindow("3D Sim", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + 2*w, 2*h, SDL_WINDOW_RESIZABLE); + if (win == NULL) { + fprintf(stderr, "%s:%d:main_init() error %s", __FILE__, __LINE__, SDL_GetError()); + return 1; + } + + ren = SDL_CreateRenderer(win, -1, 0); + if (ren == NULL) { + fprintf(stderr, "%s:%d:main_init() error %s", __FILE__, __LINE__, SDL_GetError()); + return 1; + } + SDL_RenderSetLogicalSize(ren, w, h); + /* SDL_RenderSetScale(ren, 2, 2); */ + + if (draw_init()) + return 1; + + return 0; +} + +int +main_quit() +{ + SDL_DestroyWindow(win); + SDL_Quit(); + return 1; +} + +int +main_event() +{ + static SDL_Event event; + static uint inp = MOUSE_LOCK * 1024; + static double s = 0.5; + uint8 q; + + while(SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + q = 1; + break; + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_q) + q = 1; + switch (event.key.keysym.sym) { + case SDLK_w: inp |= 1; break; + case SDLK_s: inp |= 2; break; + case SDLK_a: inp |= 4; break; + case SDLK_d: inp |= 8; break; + case SDLK_RIGHT: inp |= 16; break; + case SDLK_LEFT: inp |= 32; break; + case SDLK_UP: inp |= 64; break; + case SDLK_DOWN: inp |= 128; break; + case SDLK_j: inp |= 256; break; + case SDLK_k: inp |= 512; break; + case SDLK_m: inp ^= 1024; break; + case SDLK_i: add_obj_interactive(); break; + case SDLK_r: redo_obj(); break; + case SDLK_EQUALS: s += 0.1; break; + case SDLK_MINUS: s -= 0.1; break; + } + break; + case SDL_KEYUP: + switch (event.key.keysym.sym) { + case SDLK_w: inp &= (inp^1); break; + case SDLK_s: inp &= (inp^2); break; + case SDLK_a: inp &= (inp^4); break; + case SDLK_d: inp &= (inp^8); break; + case SDLK_RIGHT: inp &= (inp^16); break; + case SDLK_LEFT: inp &= (inp^32); break; + case SDLK_UP: inp &= (inp^64); break; + case SDLK_DOWN: inp &= (inp^128); break; + case SDLK_j: inp &= (inp^256); break; + case SDLK_k: inp &= (inp^512); break; + } + break; + case SDL_MOUSEMOTION: + if (~inp & 1024) break; + cam.azim -= ((float)event.motion.yrel)/25.0; + cam.rad += ((float)event.motion.xrel)/25.0; + break; + } + } + + if (inp&1024) + SDL_SetRelativeMouseMode(SDL_TRUE); + else + SDL_SetRelativeMouseMode(SDL_FALSE); + + if (inp&1) { + cam.pos.x += cos(cam.rad) * s; + cam.pos.z += sin(cam.rad) * s; + } + if (inp&2) { + cam.pos.x -= cos(cam.rad) * s; + cam.pos.z -= sin(cam.rad) * s; + } + if (inp&4) { + cam.pos.x += sin(cam.rad) * s; + cam.pos.z -= cos(cam.rad) * s; + } + if (inp&8) { + cam.pos.x -= sin(cam.rad) * s; + cam.pos.z += cos(cam.rad) * s; + } + + if (inp&256) cam.pos.y -= s; + if (inp&512) cam.pos.y += s; + if (inp&16) + cam.rad += 0.05; + if (inp&32) + cam.rad -= 0.05; + + if (inp&64) + cam.azim += 0.05; + if (inp&128) + cam.azim -= 0.05; + + if (cam.azim < 0) + cam.azim += 2.0 * PI; + if (cam.azim > 2.0 * PI) + cam.azim -= 2.0 * PI; + + if (cam.rad < 0) + cam.rad += 2.0 * PI; + if (cam.rad > 2.0 * PI) + cam.rad -= 2.0 * PI; + + if (q) + return main_quit(); + + if (draw_screen()) + return 1; + + return 0; +} + +int main() +{ + Uint32 ltick, fdif; + cam.pos.x = cam.pos.z = 0; + cam.pos.y = 10; + cam.rad = cam.azim = 0; + PI = 4.0 * atan(1); + h = 288; + w = 384; + hfov = 1; + + if (main_init()) + return 1; + + vfov = 0.75; + + fdif = 1000 / fps; + while (1) { + ltick = SDL_GetTicks(); + if (main_event()) + break; + ltick = SDL_GetTicks() - ltick; + + if (ltick < fdif) + SDL_Delay(fdif - ltick); + } +} @@ -0,0 +1,25 @@ +typedef union { + int i; + unsigned int u; + float f; + const void *v; + const char *s; +} Arg; + +typedef struct { + float x, y, z; +} Point; + +typedef struct { + Point pos; + float azim, rad; +} Camera; + +typedef struct { + Point p[3]; + unsigned int col; +} Triangle; + +extern Camera cam; +extern float hfov, vfov; +extern void *ren; @@ -0,0 +1,4 @@ +#define uint unsigned int +#define uint8 unsigned char +#define uint16 uint16_t +#define uint32 unsigned int |