summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2024-07-22 20:21:34 +1000
committerquou <quou@disroot.org>2024-07-22 20:21:34 +1000
commitd2c76fd62fa735f3d4fc3ceb55a75d6f0b2dc758 (patch)
tree92351ab512c5ec914ec5cbd918a5d72ed60bc0b6
parentcf193ce71bd1f13cebcafac718c124640c912060 (diff)
sampling textures in game.
-rw-r--r--3de.c20
-rw-r--r--asset.c13
-rw-r--r--asset.h9
-rw-r--r--render.c59
-rw-r--r--render.h12
-rw-r--r--testbc1.c22
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;