commit 4c129482be98fe54516eff50bb117872ef96a033
parent 949276287319d0559604f299a9029ed3c44a833a
Author: root <root@lunarcry>
Date: Sat, 19 Oct 2024 20:56:53 +0000
SR: Added triangle function:
triangle(vertex 1, vertex 2, vertex3, color) -- draws the triangle
Diffstat:
| M | src/sr/sr.c | | | 316 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
1 file changed, 164 insertions(+), 152 deletions(-)
diff --git a/src/sr/sr.c b/src/sr/sr.c
@@ -7,111 +7,120 @@
#include <math.h>
#include <SDL2/SDL.h>
-#define W 512
-#define H 512
+#define W 1024
+#define H 1024
#define WIN_W 1024
#define WIN_H 1024
#define VEC2I_SWAP(x, y) { ivec2 temp = x; x = y; y = temp; }
+#define I_SWAP(x, y) { int temp = x; x = y; y = temp; }
typedef void v; typedef uint8_t u8;typedef uint16_t u16;typedef uint32_t u32;typedef uint64_t u64;typedef int8_t i8;typedef int16_t i16;typedef int32_t i32;typedef int64_t i64;typedef uint8_t Bool;
typedef struct { u32 *data; } FB;
typedef struct {u8 b;u8 g;u8 r; u8 a;} C;
-
-typedef struct {
- double x, y, z;
-} point;
-
-typedef struct {
- int x, y;
-} ivec2;
-
-typedef struct {
- double x, y, z;
-} vec3f;
-
-typedef struct {
-
-} scene;
-
+typedef struct { double x, y, z; } point;
+typedef struct { int x, y; } ivec2;
+typedef struct { double x, y, z; } vec3f;
enum mop {ADD, SUB, MUL, DIV};
FB fb;
SDL_Window* win;
SDL_Renderer* ren;
vec3f **vertices;
-int **faces;
+i32 **faces;
+
+void
+FB_flip_vert(u32 *data)
+{
+ u64 bytes_per_line; u32 *line; i32 half, j;
+
+ bytes_per_line = W;
+ line = (u32 *)malloc(bytes_per_line * sizeof(u32));
+ half = H>>1;
+
+ for (i32 j=0; j<half; j++) {
+ u64 l1 = j*bytes_per_line;
+ u64 l2 = (H-1-j)*bytes_per_line;
+ memmove((void *)line, (void *)(data+l1), bytes_per_line* sizeof(u32));
+ memmove((void *)(data+l1), (void *)(data+l2), bytes_per_line* sizeof(u32));
+ memmove((void *)(data+l2), (void *)line, bytes_per_line* sizeof(u32));
+ }
+ free(line);
+}
ivec2
IVEC2_op(ivec2 a, ivec2 b, enum mop mop)
{
-
- ivec2 c;
- switch(mop) {
- case ADD:
- c.x = a.x + b.x;
- c.y = a.y + b.y;
- break;
- case SUB:
- c.x = a.x - b.x;
- c.y = a.y - b.y;
- break;
- case MUL:
- c.x = a.x * b.x;
- c.y = a.y * b.y;
- break;
- default:
- break;
- }
- return c;
+ ivec2 c;
+ switch(mop) {
+ case ADD:
+ c.x = a.x + b.x;
+ c.y = a.y + b.y;
+ break;
+ case SUB:
+ c.x = a.x - b.x;
+ c.y = a.y - b.y;
+ break;
+ case MUL:
+ c.x = a.x * b.x;
+ c.y = a.y * b.y;
+ break;
+ default:
+ break;
+ }
+ return c;
}
+
ivec2
-IVEC2_ops(ivec2 a, int b, enum mop mop)
+IVEC2_ops(ivec2 a, i32 b, enum mop mop)
{
- ivec2 c;
- switch(mop) {
- case ADD:
- c.x = a.x + b;
- c.y = a.y + b;
- break;
- case SUB:
- c.x = a.x - b;
- c.y = a.y - b;
- break;
- case MUL:
- c.x = a.x * b;
- c.y = a.y * b;
- break;
- default:
- break;
- }
- return c;
+ ivec2 c;
+ switch(mop) {
+ case ADD:
+ c.x = a.x + b;
+ c.y = a.y + b;
+ break;
+ case SUB:
+ c.x = a.x - b;
+ c.y = a.y - b;
+ break;
+ case MUL:
+ c.x = a.x * b;
+ c.y = a.y * b;
+ break;
+ default:
+ break;
+ }
+ return c;
}
-C*
-new_C(u32 b)
+C
+C_new(u32 b)
{
- C* c = malloc(sizeof(C));
- c->r = (u8)(b & 0xff);
- c->g = (u8)((b >> 8) & 0xff);
- c->b = (u8)((b >> 16) & 0xff);
- c->a = (u8)((b >> 24) & 0xff);
+ C c;
+ c.r = (u8)(b & 0xff);
+ c.g = (u8)((b >> 8) & 0xff);
+ c.b = (u8)((b >> 16) & 0xff);
+ c.a = (u8)((b >> 24) & 0xff);
return c;
};
v new_fb() { fb.data = malloc(W*H*sizeof(u32));}
-void FB_set(int x, int y, C c) { (!fb.data || x<0 || y<0 || x>=W || y>=H) ? 0 : memcpy(fb.data + ((x + y * W)), &c, 4); }
-C* FB_get(int x, int y)
-{
- void* c = (!fb.data || x<0 || y<0 || x>=W || y>=H) ? (void*)0 : (void*)(new_C(fb.data[(x+y*W)]));
- return (C*)c;
-}
+void FB_set(i32 x, i32 y, C c) { (!fb.data || x<0 || y<0 || x>=W || y>=H) ? 0 : memcpy(fb.data + ((x + y * W)), &c, 4); }
+
+//C*
+//FB_get(i32 x, i32 y)
+//{
+// void* c = (!fb.data || x<0 || y<0 || x>=W || y>=H) ? (void*)0 : (void*)(C_new(fb.data[(x+y*W)]));
+// return (C*)c;
+//}
-void line(ivec2 v, ivec2 v1, C color)
+void
+line(ivec2 v, ivec2 v1, C color)
{
- int x,y,x0,x1,y0,y1,dx,dy,sx,sy,e,e2,p;
+ i32 x,y,x0,x1,y0,y1,dx,dy,sx,sy,e,e2,p;
x0 = v.x;
y0 = v.y;
x1 = v1.x;
@@ -145,16 +154,8 @@ init_sdl() {
ren = SDL_CreateRenderer(win, -1, 0);
}
-//void
-//drw_ls()
-//{
-// line(0, 0, 256, 256, (C){0xff, 0xff, 0xff, 0xff});
-// line(23, 30,90, 50, (C){0xff, 0x0, 0x0, 255});
-// line(127,0, 0, 127, (C){0, 255, 0, 255});
-//}
-
-int
-parse_obj(int *fcount, int *ecount)
+i32
+parse_obj(i32 *fcount, i32 *ecount)
{
FILE *f;
char *line;
@@ -162,7 +163,7 @@ parse_obj(int *fcount, int *ecount)
size_t len;
ssize_t read;
long pos;
- int edge_count, face_count;
+ i32 edge_count, face_count;
f = fopen("african.obj", "rb");
@@ -175,7 +176,7 @@ parse_obj(int *fcount, int *ecount)
face_count = 0;
while ((read = getline(&line, &len, f)) != -1) {
- int i;
+ i32 i;
i = 0;
if (strstr(line, "v ") != NULL) {
for ((p = strtok(line, " ")); p; (p = strtok(NULL, " ")))
@@ -193,8 +194,8 @@ parse_obj(int *fcount, int *ecount)
for ((p = strtok(line, " ")); p; (p = strtok(NULL, " ")))
tokens[i++] = p;
- faces = realloc(faces, (face_count + 1) * sizeof(int*));
- faces[face_count] = malloc(sizeof(int)*3);
+ faces = realloc(faces, (face_count + 1) * sizeof(i32*));
+ faces[face_count] = malloc(sizeof(i32)*3);
faces[face_count][0] = atoi(tokens[1]) - 1;
faces[face_count][1] = atoi(tokens[2]) - 1;
@@ -212,60 +213,66 @@ parse_obj(int *fcount, int *ecount)
return 1;
}
+
void
-draw_obj(int fcount)
+draw_obj(i32 fcount)
{
- for (int i=0; i<fcount-1; i++) {
- int *face = faces[i];
+ for (i32 i=0; i<fcount-1; i++) {
+ i32 *face = faces[i];
- for (int j=0; j<3; j++) {
+ for (i32 j=0; j<3; j++) {
vec3f *v0 = vertices[face[j]];
vec3f *v1 = vertices[face[(j+1)%3]];
- int x0 = (v0->x+1.)*W/2.;
- int y0 = W - ((v0->y+1.)*W/2.);
- int x1 = (v1->x+1.)*W/2.;
- int y1 = W - ((v1->y+1.)*W/2.);
- line((ivec2){x0, y0}, (ivec2){x1, y1}, (C){0xff, 0xff, 0xff, 0xff});
+ i32 x0 = (v0->x+1.)*W/2.;
+ i32 y0 = W - ((v0->y+1.)*W/2.);
+ i32 x1 = (v1->x+1.)*W/2.;
+ i32 y1 = W - ((v1->y+1.)*W/2.);
+ line((ivec2){x0, y0}, (ivec2){x1, y1}, C_new(0x3333ffff));
}
}
}
-void triangle(ivec2 t0, ivec2 t1, ivec2 t2, C color) {
- // sort the vertices, t0, t1, t2 lower−to−upper (bubblesort yay!)
- ivec2 temp;
-
- if (t0.y>t1.y) VEC2I_SWAP(t0, t1);
- if (t0.y>t2.y) VEC2I_SWAP(t0, t2);
- if (t1.y>t2.y) VEC2I_SWAP(t1, t2);
- int total_height = t2.y-t0.y;
- for (int y=t0.y; y<=t1.y; y++) {
- int segment_height = t1.y-t0.y+1;
- int alpha = (y-t0.y)/total_height;
- int beta = (y-t0.y)/segment_height; // be careful with divisions by zero
- ivec2 A = IVEC2_op(t0,IVEC2_ops(IVEC2_op(t2,t0,SUB), alpha, MUL), ADD);
- ivec2 B = IVEC2_op(t0,IVEC2_ops(IVEC2_op(t1,t0,SUB), beta, MUL), ADD);
- if (A.x>B.x) VEC2I_SWAP(A, B);
- for (int j=A.x; j<=B.x; j++) {
- FB_set(j, y, color); // attention, due to int casts t0.y+i != A.y
- }
- }
-
- for (int y=t1.y; y<=t2.y; y++) {
- int segment_height = t2.y-t1.y+1;
- int alpha = (y-t0.y)/total_height;
- int beta = (y-t1.y)/segment_height; // be careful with divisions by zero
- ivec2 A = IVEC2_op(t0,IVEC2_ops(IVEC2_op(t2,t0,SUB), alpha, MUL), ADD);
- ivec2 B = IVEC2_op(t1,IVEC2_ops(IVEC2_op(t1,t0,SUB), beta, MUL), ADD);
- //ivec2 A = t0 + (t2-t0)*alpha;
- //ivec2 B = t1 + (t2-t1)*beta;
- if (A.x>B.x) VEC2I_SWAP(A, B);
- for (int j=A.x; j<=B.x; j++) {
- FB_set(j, y, color); // attention, due to int casts t0.y+i != A.y
- }
- }
+void
+triangle(ivec2 t0, ivec2 t1, ivec2 t2, C color) {
+ // sort the vertices, t0, t1, t2 lower−to−upper (bubblesort yay!)
+ ivec2 temp;
+
+ if (t0.y>t1.y) VEC2I_SWAP(t0, t1);
+ if (t0.y>t2.y) VEC2I_SWAP(t0, t2);
+ if (t1.y>t2.y) VEC2I_SWAP(t1, t2);
+
+ i32 total_height = t2.y - t0.y;
+
+ for (i32 i = 0; i < total_height; i++) {
+ i32 second_half = i > (t1.y - t0.y) || t1.y == t0.y;
+ i32 segment_height = second_half ? t2.y - t1.y : t1.y - t0.y;
+ float alpha = (float)i / total_height;
+ float beta = (float)(i - (second_half ? t1.y - t0.y : 0)) / segment_height; // how far down are we
+
+ ivec2 A = {
+ t0.x + (t2.x - t0.x) * alpha,
+ t0.y + i
+ };
+
+ ivec2 B = second_half ?
+ (ivec2){
+ t1.x + (t2.x - t1.x) * beta,
+ t1.y + (i - (t1.y - t0.y))
+ } :
+ (ivec2){
+ t0.x + (t1.x - t0.x) * beta,
+ t0.y + i
+ };
+
+ if (A.x > B.x) VEC2I_SWAP(A, B);
+ // Draw horizontal span between A and B
+ for (i32 x = A.x; x <= B.x; x++) {
+ FB_set(x, A.y, color);
+ }
+ }
}
-int
+i32
main()
{
init_sdl();
@@ -278,36 +285,41 @@ main()
SDL_RenderClear(ren);
- //int fcount, ecount;
- //int ho = parse_obj(&fcount, &ecount);
+ //i32 fcount, ecount;
+ //i32 ho = parse_obj(&fcount, &ecount);
//draw_obj(fcount);
ivec2 t0[3] = {{10, 70}, {50, 160}, {70, 80}};
ivec2 t1[3] = {{180, 50}, {150, 1}, {70, 180}};
ivec2 t2[3] = {{180, 150}, {120, 160}, {130, 180}};
- triangle(t0[0], t0[1], t0[2], (C){0xff, 0x00, 0x00, 0xff});
- triangle(t1[0], t1[1], t1[2], (C){0xff, 0xff, 0xff, 0xff});
- triangle(t2[0], t2[1], t2[2], (C){0x00, 0xff, 0x00, 0xff});
+ triangle(t0[0], t0[1], t0[2],C_new(0xff000000));
+ triangle(t1[0], t1[1], t1[2],C_new(0xffff0000));
+ triangle(t2[0], t2[1], t2[2],C_new(0x000ff000));
+ //ivec2 v0 = {0, 0};
+ //ivec2 v1 = {W, 0};
+ //ivec2 v2 = {W/2, H};
+ //triangle(v0, v1, v2,C_new(0xff000000));
- SDL_UpdateTexture(texture, NULL, fb.data, W * sizeof(Uint32));
+ FB_flip_vert(fb.data);
+
+ SDL_UpdateTexture(texture, NULL, fb.data, W * sizeof(u32));
SDL_RenderCopy(ren, texture, NULL, NULL);
SDL_RenderPresent(ren);
- while(1) {
- SDL_Delay(33);
- while(SDL_PollEvent(&ev) != 0) {
- switch(ev.type) {
- case SDL_QUIT:
- SDL_Quit();
- exit(1);
- }
- switch(ev.key.keysym.sym) {
- case SDLK_q:
- SDL_Quit();
- exit(1);
- }
- }
- }
- return 0;
+ while(1) {
+ while(SDL_PollEvent(&ev) != 0) {
+ switch(ev.type) {
+ case SDL_QUIT:
+ SDL_Quit();
+ exit(1);
+ }
+ switch(ev.key.keysym.sym) {
+ case SDLK_q:
+ SDL_Quit();
+ exit(1);
+ }
+ }
+ }
+ return 0;
}