From d2c76fd62fa735f3d4fc3ceb55a75d6f0b2dc758 Mon Sep 17 00:00:00 2001 From: quou Date: Mon, 22 Jul 2024 20:21:34 +1000 Subject: sampling textures in game. --- 3de.c | 20 ++++++++++---------- asset.c | 13 +++++++++++++ asset.h | 9 ++++++++- render.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- render.h | 12 +++++++++--- testbc1.c | 22 ++++++++++++++++++++++ 6 files changed, 112 insertions(+), 23 deletions(-) diff --git a/3de.c b/3de.c index 6197321..eb7a8f8 100644 --- a/3de.c +++ b/3de.c @@ -19,28 +19,28 @@ void draw_spinny(Renderer* r, Colour c) { a += 20; } -void draw_monkey(Renderer* r) { +void draw_gun(Renderer* r) { static int a = 0; - const Mesh* m = get_mesh(asset_id_monkey); - Bitmap tex = { (Colour*)tile_pixels, 16, 16 }; + const Mesh* m = get_mesh(asset_id_gun_mesh); + const Texture* tex = get_texture(asset_id_gun_texture); int p[] = { 0, 0, 0, f1 }; mtx_push_trans(p); /*mtx_push_rot_x(a); mtx_push_rot_y(a); mtx_push_rot_z(a);*/ - ren_mesh(r, m, &tex); + ren_mesh(r, m, tex); mtx_popn(1); a++; } void draw_tri(Renderer* r, int x, int y) { - Bitmap t = { (Colour*)tile_pixels, 16, 16 }; - int v0[] = { 100, 100, 0, 0, 0, f1, 0, 0 }; - int v1[] = { 200, 200, 0, f1, f1/2, 0, f1, 0 }; - int v2[] = { 150, 300, 0, 0, f1, 0, 0, f1 }; + const Texture* tex = get_texture(asset_id_gun_texture); + int v0[] = { 100, 100, 0, 0, 0, f1, f1, f1 }; + int v1[] = { 200, 200, 0, f1, f1/2, f1, f1, f1 }; + int v2[] = { 150, 300, 0, 0, f1, f1, f1, f1 }; v1[0] = x; v1[1] = y; - ren_tri(r, v0, v1, v2, &t); + ren_tri(r, v0, v1, v2, tex); } int entrypoint(int argc, const char** argv, Arena* a) { @@ -95,7 +95,7 @@ int entrypoint(int argc, const char** argv, Arena* a) { sprintf(buf, "MOUSE: %d, %d", app->mx, app->my); ren_texts(&r, blue, 3, 13, buf); push_player_cam(&p); - draw_monkey(&r); + draw_gun(&r); pop_player_cam(); /*draw_tri(&r, app->mx, app->my);*/ ren_end(&r); diff --git a/asset.c b/asset.c index 0eca404..03689b9 100644 --- a/asset.c +++ b/asset.c @@ -22,6 +22,11 @@ static void init_mesh_asset(Asset* asset, void* raw, int size) { m->verts = (Mesh_Vert*)&m->t[m->tc * 2]; } +static void init_texture_asset(Asset* asset, void* raw, int size) { + asset->payload = raw; + asset->payload_size = size; +} + /* Loading assets isn't that efficient. Too bad. */ static int get_asset_info( File* pack, @@ -125,6 +130,9 @@ void preload_assets(Arena* mem) { case asset_type_mesh: init_mesh_asset(asset, raw, size); break; + case asset_type_texture: + init_texture_asset(asset, raw, size); + break; default: print_err("Invalid asset type.\n"); pbreak(error_invalid_asset); @@ -150,3 +158,8 @@ const struct Mesh* get_mesh(Asset_ID id) { return (struct Mesh*)a->payload; } +const struct Texture* get_texture(Asset_ID id) { + const Asset* a = get_asset(id); + return (struct Texture*)a->payload; +} + diff --git a/asset.h b/asset.h index 35496bf..91bb2fe 100644 --- a/asset.h +++ b/asset.h @@ -21,6 +21,11 @@ struct Mesh; asset_type_mesh, \ "gun.msh" \ ) \ + x( \ + asset_id_gun_texture, \ + asset_type_texture, \ + "gun.bc1" \ + ) \ typedef enum { #define x(id, type, path) id, @@ -30,7 +35,8 @@ typedef enum { } Asset_ID; typedef enum { - asset_type_mesh + asset_type_mesh, + asset_type_texture } Asset_Type; typedef struct { @@ -61,5 +67,6 @@ Asset_Data* read_asset_data( ); const struct Mesh* get_mesh(Asset_ID id); +const struct Texture* get_texture(Asset_ID id); #endif diff --git a/render.c b/render.c index 14aa6a1..233c084 100644 --- a/render.c +++ b/render.c @@ -311,16 +311,57 @@ int tri_winding( (v1[0] - v0[0]) * (v2[1] - v1[1]); } +/*Colour sample_tex( + const Texture* t, + int u, + int v +) { + vec3 start, end, col; + int i; + Colour r = { 0 }; + const unsigned* data = (const unsigned*)&t[1]; + int x = ((u * t->w) >> fbits) & (t->w - 1); + int y = ((v * t->h) >> fbits) & (t->h - 1); + unsigned palette = data[(x / 4 + y / 4 * (t->w / 4)) * 2]; + unsigned indices = data[(x / 4 + y / 4 * (t->w / 4)) * 2 + 1]; + start.r = (float)((palette & (31 << 27)) >> 27) / 32.0f; + start.g = (float)((palette & (63 << 21)) >> 21) / 64.0f; + start.b = (float)((palette & (31 << 16)) >> 16) / 32.0f; + end.r = (float)((palette & (31 << 11)) >> 11) / 32.0f; + end.g = (float)((palette & (63 << 5)) >> 5) / 64.0f; + end.b = (float)((palette & (31 )) ) / 32.0f; + i = x % 4 + (y % 4) * 4; + i = (indices & (3 << i * 2)) >> i * 2; + lerp(&col, &start, &end, (float)i / 3.0f); + r.r = (int)(col.r * 255.0f); + r.g = (int)(col.g * 255.0f); + r.b = (int)(col.b * 255.0f); + return r; +}*/ Colour sample_tex( - const Bitmap* t, + const Texture* t, int u, int v ) { - int x = (u * t->w) >> fbits; - int y = (v * t->h) >> fbits; - x &= t->w - 1; - y &= t->h - 1; - return t->p[x + y * t->w]; + int x = ((u * t->w) >> fbits) & (t->w - 1); + int y = ((v * t->h) >> fbits) & (t->h - 1); + Colour r; + int s[3]; + int i; + int coord = ((x >> 2) + (y >> 2) * (t->w >> 2)) << 1; + const unsigned* data = (const unsigned*)&t[1]; + unsigned pal = data[coord]; + unsigned ind = data[coord + 1]; + s[0] = (pal & (31 << 27)) >> 24; + s[1] = (pal & (63 << 21)) >> 19; + s[2] = (pal & (31 << 16)) >> 13; + i = ((x & 3) + ((y & 3) << 2)) << 1; + i = (ind & (3 << i)) >> i; + r.r = s[0] + (i * ((int)((pal & (31 << 11)) >> 8) - s[0]) / 3); + r.g = s[1] + (i * ((int)((pal & (63 << 5)) >> 3) - s[1]) / 3); + r.b = s[2] + (i * ((int)((pal & (31 )) << 3) - s[2]) / 3); + r.a = 0xff; + return r; } typedef struct { @@ -380,7 +421,7 @@ void ren_tri( const int* iv0, const int* iv1, const int* iv2, - const Bitmap* tex + const Texture* tex ) { #define ic 6 #define ec 8 @@ -509,7 +550,7 @@ void ren_tri3( const int* iv0, const int* iv1, const int* iv2, - const Bitmap* tex + const Texture* tex ) { #define ec 8 #define ec2 (ec) @@ -573,7 +614,7 @@ int point_os( void ren_mesh( Renderer* r, const Mesh* m, - const Bitmap* tex + const Texture* tex ) { int vc = m->vc; int tri[8 * 3]; diff --git a/render.h b/render.h index e51478f..996ba37 100644 --- a/render.h +++ b/render.h @@ -24,6 +24,10 @@ typedef struct { int w, h; } Bitmap; +typedef struct Texture { + int w, h; +} Texture; + typedef struct { unsigned short p, n, t; } Mesh_Vert; @@ -54,6 +58,8 @@ int point_os( int y ); +Colour sample_tex(const Texture* t, int u, int v); + void ren_begin(Renderer* r, Colour* t, int* d, int w, int h); void ren_end(Renderer* r); void ren_clear(Renderer* r); @@ -98,19 +104,19 @@ void ren_tri( const int* v0, const int* v1, const int* v2, - const Bitmap* tex + const Texture* tex ); /* Unsafe for 3D. Clips against the r->clip */ void ren_tri3( Renderer* r, const int* v0, const int* v1, const int* v2, - const Bitmap* tex + const Texture* tex ); /* Does perspective calculation and clips against the near. */ void ren_mesh( Renderer* r, const Mesh* mesh, - const Bitmap* tex + const Texture* tex ); #endif diff --git a/testbc1.c b/testbc1.c index 2b9aab4..8475bb2 100644 --- a/testbc1.c +++ b/testbc1.c @@ -13,6 +13,8 @@ void lerp(vec3* d, const vec3* a, const vec3* b, float t) { d->b = a->b + t * (b->b - a->b); } +#define use_float_sample 0 +#if use_float_sample Colour get_pixel(unsigned* data, int x, int y, int w) { vec3 start, end, col; float t; @@ -35,6 +37,26 @@ Colour get_pixel(unsigned* data, int x, int y, int w) { r.b = (int)(col.b * 255.0f); return r; } +#else +Colour get_pixel(unsigned* data, int x, int y, int w) { + Colour r; + int s[3]; + int i; + int coord = ((x >> 2) + (y >> 2) * (w >> 2)) << 1; + unsigned pal = data[coord]; + unsigned ind = data[coord + 1]; + s[0] = (pal & (31 << 27)) >> 24; + s[1] = (pal & (63 << 21)) >> 19; + s[2] = (pal & (31 << 16)) >> 13; + i = ((x & 3) + ((y & 3) << 2)) << 1; + i = (ind & (3 << i)) >> i; + r.r = s[0] + (i * ((int)((pal & (31 << 11)) >> 8) - s[0]) / 3); + r.g = s[1] + (i * ((int)((pal & (63 << 5)) >> 3) - s[1]) / 3); + r.b = s[2] + (i * ((int)((pal & (31 )) << 3) - s[2]) / 3); + r.a = 0xff; + return r; +} +#endif int main(int argc, const char** argv) { FILE* infile, * outfile; -- cgit v1.2.3-54-g00ecf