commit 3d325d0ec55fbe4c90f1c3af682b57d87cec76f9
parent 84a31fb7042db237390325e6d3b33ea02ed491ce
Author: Edea Kramer <edea@lunarcry.home>
Date: Sat, 2 Nov 2024 20:26:37 +0200
- Changes default SDL_PIXELFORMAT to RGB888 to represent true color of ps1
(we don't need alpha).
- Implemented color implementation on REN_triangle.
- Probably we need backbuffering
Diffstat:
4 files changed, 143 insertions(+), 68 deletions(-)
diff --git a/src/gpu.c b/src/gpu.c
@@ -368,7 +368,6 @@ GPU_gp0_triangle_shaded_opaque(GPU* gpu)
colors[2] = COLOR_from_gp0(gpu->gp0_command.buffer[4]);
REN_push_triangle(gpu->ren, positions, colors);
- //REN_display(gpu->ren);
fprintf(stdout, "Draw triangle shaded\n");
}
diff --git a/src/main.c b/src/main.c
@@ -57,6 +57,7 @@ main(int argc, char **argv)
free(inter->ram->data);
free(inter->ram);
free(inter->dma);
+ free(inter->gpu);
free(inter);
free(cpu);
diff --git a/src/sr.c b/src/sr.c
@@ -28,7 +28,6 @@ COLOR_from_gp0(u32 val)
c.r = (u8)val;
c.g = (u8)(val >> 8);
c.b = (u8)(val >> 16);
- c.a = (u8)((val >> 24) & 0xff);
return c;
}
@@ -105,11 +104,10 @@ C_new(u32 b)
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;
};
-void REN_FB_set(REN* ren, i32 x, i32 y, C c) { (!ren->fb || x<0 || y<0 || x>=W || y>=H) ? 0 : memcpy(ren->fb + ((x + y * W)), &c, 4); }
+void REN_FB_set(REN* ren, i32 x, i32 y, C c) { (!ren->fb || x<0 || y<0 || x>=W || y>=H) ? 0 : memcpy(ren->fb + ((x + y * W)), &c, 3); }
//C*
//FB_get(i32 x, i32 y)
@@ -121,79 +119,157 @@ void REN_FB_set(REN* ren, i32 x, i32 y, C c) { (!ren->fb || x<0 || y<0 || x>=W |
REN*
REN_new()
{
- REN* ren;
- ren = (REN*)malloc(sizeof(REN));
- ren->window = SDL_CreateWindow("Ultimecia", 400, 400, WIN_W, WIN_H, SDL_WINDOW_SHOWN);
- ren->renderer = SDL_CreateRenderer(ren->window, -1, 0);
- ren->tex = SDL_CreateTexture(ren->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, W, H);
- ren->verts = NULL;
- ren->colors = NULL;
- ren->fb = malloc(W*H*sizeof(u32));
- memset(ren->fb, 0, (u32)(W*H)*sizeof(u32));
- ren->nvertices = 0;
- printf("FFFFFFFFFFFFFFFFUCK");
- return ren;
+ REN* ren;
+ ren = (REN*)malloc(sizeof(REN));
+ ren->window = SDL_CreateWindow("Ultimecia", 400, 750, WIN_W, WIN_H, SDL_WINDOW_SHOWN);
+ ren->renderer = SDL_CreateRenderer(ren->window, -1, 0);
+ ren->tex = SDL_CreateTexture(ren->renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_STREAMING, W, H);
+ ren->verts = NULL;
+ ren->colors = NULL;
+ ren->fb = malloc(W*H*sizeof(u32));
+ memset(ren->fb, 0, (u32)(W*H)*sizeof(u32));
+ ren->nvertices = 0;
+ return ren;
}
+
+
void
REN_triangle(REN* ren, ivec2 verts[3], C colors[3]) {
- // SORT the vertices, t0, t1, t2 lower−to−upper (bubblesort yay!)
- ivec2 temp, t0, t1, t2;
+ ivec2 temp, t0, t1, t2;
+ C c0 = colors[0], c1 = colors[1], c2 = colors[2];
t0 = verts[0]; t1 = verts[1]; t2 = verts[2];
- 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++) {
- REN_FB_set(ren, x, A.y, colors[0]);
- }
- }
+ if (t0.y > t1.y) { VEC2I_SWAP(t0, t1); C_SWAP(c0, c1); }
+ if (t0.y > t2.y) { VEC2I_SWAP(t0, t2); C_SWAP(c0, c2); }
+ if (t1.y > t2.y) { VEC2I_SWAP(t1, t2); C_SWAP(c1, c2); }
+
+ i32 total_height = t2.y - t0.y;
+ i32 height_first_half = t1.y - t0.y;
+ i32 height_second_half = t2.y - t1.y;
+ float alpha_step = 1.0f / total_height;
+ float alpha = 0.0f;
+
+ for (i32 i = 0; i < total_height; i++, alpha += alpha_step) {
+ i32 second_half = (i > height_first_half) || (t1.y == t0.y);
+ i32 segment_height = second_half ? height_second_half : height_first_half;
+ float beta = (float)(i - (second_half ? height_first_half : 0)) / segment_height;
+
+ // Interpolated points for this scanline
+ 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 - height_first_half) }
+ : (ivec2){ t0.x + (t1.x - t0.x) * beta, t0.y + i };
+
+ // Interpolated colors for this scanline
+ C color_a = {
+ c0.r + (c2.r - c0.r) * alpha,
+ c0.g + (c2.g - c0.g) * alpha,
+ c0.b + (c2.b - c0.b) * alpha
+ };
+
+ C color_b = second_half
+ ? (C){
+ c1.r + (c2.r - c1.r) * beta,
+ c1.g + (c2.g - c1.g) * beta,
+ c1.b + (c2.b - c1.b) * beta
+ }
+ : (C){
+ c0.r + (c1.r - c0.r) * beta,
+ c0.g + (c1.g - c0.g) * beta,
+ c0.b + (c1.b - c0.b) * beta
+ };
+
+ // Sort A and B for left-to-right filling
+ if (A.x > B.x) {
+ VEC2I_SWAP(A, B);
+ C_SWAP(color_a, color_b);
+ }
+
+ // Fill the horizontal span between A and B, interpolating color
+ for (i32 x = A.x; x <= B.x; x++) {
+ float t = (float)(x - A.x) / (B.x - A.x);
+
+ // Linearly interpolate color across the span
+ C color = {
+ color_a.r + (color_b.r - color_a.r) * t,
+ color_a.g + (color_b.g - color_a.g) * t,
+ color_a.b + (color_b.b - color_a.b) * t
+ };
+
+ REN_FB_set(ren, x, A.y, color);
+ }
+ }
}
+//void
+//REN_triangle(REN* ren, ivec2 verts[3], C colors[3]) {
+// // SORT the vertices, t0, t1, t2 lower−to−upper (bubblesort yay!)
+// ivec2 temp, t0, t1, t2;
+// i32 first_half, second_half;
+// t0 = verts[0]; t1 = verts[1]; t2 = verts[2];
+//
+// 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;
+// i32 height_first_half = t1.y - t0.y;
+// i32 height_second_half = t2.y - t1.y;
+// float alpha_step = 1.0f / total_height;
+// float alpha = 0.0f;
+//
+// for (i32 i = 0; i < total_height; i++, alpha += alpha_step) {
+// i32 second_half = (i > height_first_half) || (t1.y == t0.y);
+// i32 segment_height = second_half ? height_second_half : height_first_half;
+// float beta = (float)(i - (second_half ? height_first_half : 0)) / segment_height;
+//
+// 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 - height_first_half) }
+// : (ivec2){ t0.x + (t1.x - t0.x) * beta, t0.y + i };
+//
+// if (A.x > B.x) VEC2I_SWAP(A, B);
+//
+// i32 row_buffer[W*4];
+// i32 row_index = 0;
+// for (i32 x = A.x; x <= B.x; x++) {
+// row_buffer[row_index++] = x;
+// }
+//
+// for (i32 j = 0; j < row_index; j++) {
+// REN_FB_set(ren, row_buffer[j], A.y, colors[j%3]);
+// }
+// }
+//
+//}
+
void
REN_push_triangle(REN* ren, ivec2 verts[3], C colors[3])
{
u8 i;
- long VERTEX_BUFFER_LEN = 64*1024;
ivec2 tmp[3];
- if (ren->nvertices + 3 > 1000) {
+ if (ren->nvertices + 3 > 10) {
printf("Vertex attribute buffer full, forcing draw... and NVERTICES IS %d\n", ren->nvertices);
- for(int i = 0; i < ren->nvertices-3; i++) {
- REN_triangle(ren, ren->verts+(i*2), ren->colors);
- //triangle(ren, t0[0],t0[1], t0[2], C_new(0xffffffff));//ren->colors[i]);
- //printf("Vert 1 -> x: %d, y: %d\nVert 2 -> x: %d, y: %d\nVert 3 -> x: %d, y: %d\n", ren->verts[i].x, ren->verts[i].y, ren->verts[i+1].x, ren->verts[i+1].y, ren->verts[i+2].x, ren->verts[i+3].y);
+ for(int i = 0; i < ren->nvertices-3; i+=3) {
+ REN_triangle(ren, ren->verts+i, ren->colors+1);
+ printf("Drawing... %d\n", i/3);
}
-
+ ren->nvertices=0;
}
+
ren->verts = realloc(ren->verts, sizeof(ivec2) * (ren->nvertices + 3));
ren->colors = realloc(ren->colors, sizeof(C) * (ren->nvertices + 3));
+
for (i = 0; i < 3; i++) {
ren->verts[ren->nvertices] = verts[i];
ren->colors[ren->nvertices] = colors[i];
@@ -204,12 +280,10 @@ REN_push_triangle(REN* ren, ivec2 verts[3], C colors[3])
void
REN_draw(REN* ren)
{
- SDL_RenderClear(ren->renderer);
- SDL_UpdateTexture(ren->tex, NULL, ren->fb, W * sizeof(u32));
- SDL_RenderCopy(ren->renderer, ren->tex, NULL, NULL);
-
- // With this uncommented it fucks it up and it doesn't draw
- //ren->nvertices=0;
+ SDL_SetRenderDrawColor(ren->renderer, 0x33, 0x33, 0x33, 0xff);
+ SDL_RenderClear(ren->renderer);
+ SDL_UpdateTexture(ren->tex, NULL, ren->fb, W * sizeof(u32));
+ SDL_RenderCopy(ren->renderer, ren->tex, NULL, NULL);
}
void
@@ -217,5 +291,4 @@ REN_display(REN* ren)
{
REN_draw(ren);
SDL_RenderPresent(ren->renderer);
- //SDL_Delay(1000);
}
diff --git a/src/sr.h b/src/sr.h
@@ -5,13 +5,15 @@
#define W 640
#define H 480
-#define WIN_W 1024
-#define WIN_H 1024
+#define WIN_W 640
+#define WIN_H 480
+#define VERTEX_BUFFER_LEN 64*1024
#define VEC2I_SWAP(x, y) { ivec2 temp = x; x = y; y = temp; }
+#define C_SWAP(x, y) { C temp = x; x = y; y = temp; }
#define I_SWAP(x, y) { int temp = x; x = y; y = temp; }
-typedef struct {u8 b;u8 g;u8 r; u8 a;} C;
+typedef struct {u8 b;u8 g;u8 r;} C;
typedef struct { double x, y, z; } point;
typedef struct { int x, y; } ivec2;
typedef struct { double x, y, z; } vec3f;