diff options
Diffstat (limited to 'convtexture.c')
-rw-r--r-- | convtexture.c | 76 |
1 files changed, 55 insertions, 21 deletions
diff --git a/convtexture.c b/convtexture.c index a04e3c9..2670b59 100644 --- a/convtexture.c +++ b/convtexture.c @@ -29,10 +29,19 @@ const char* format_names[] = { #undef x }; +unsigned encode_endpoint(const vec3* v) { + return + ((unsigned)(v->r * 31.9999f) << 11) | + ((unsigned)(v->g * 63.9999f) << 5) | + ((unsigned)(v->b * 31.9999f)); +} + void get_block(Block* block, Colour* pixels, int stride) { int x, y, i; vec3 cols[4 * 4]; + vec3 palette[3]; vec3 s, e; + unsigned es, ee; float cd; for (y = 0; y < 4; y++) { for (x = 0; x < 4; x++) { @@ -61,19 +70,48 @@ void get_block(Block* block, Colour* pixels, int stride) { } } } + es = encode_endpoint(&s); + ee = encode_endpoint(&e); + if (es == ee) { + block->start = s; + block->end.r = 0.0f; + block->end.g = 0.0f; + block->end.b = 0.0f; + for (i = 0; i < 16; i++) { + block->indices[i] = 0; + } + return; + } + if (es < ee) { + /* todo alpha */ + vec3 t = s; + s = e; + e = t; + } + palette[0] = s; + palette[1] = e; + palette[2].r = 0.666666f*palette[0].r + 0.333333f*palette[1].r; + palette[2].g = 0.666666f*palette[0].g + 0.333333f*palette[1].g; + palette[2].b = 0.666666f*palette[0].b + 0.333333f*palette[1].b; + palette[3].r = 0.333333f*palette[0].r + 0.666666f*palette[1].r; + palette[3].g = 0.333333f*palette[0].g + 0.666666f*palette[1].g; + palette[3].b = 0.333333f*palette[0].b + 0.666666f*palette[1].b; for (i = 0; i < 4 * 4; i++) { vec3* col = &cols[i]; - float d; - d = - (e.r - col->r) * (e.r - col->r) + - (e.g - col->g) * (e.g - col->g) + - (e.b - col->b) * (e.b - col->b); - if (cd < 0.0001f) - block->indices[i] = 0; - else { - d = d / cd; - block->indices[i] = (int)((1.0f - d) * 3.1f); + int closest = 0, j; + float cd = 99999.0f; + for (j = 0; j < 4; j++) { + vec3* p = &palette[j]; + float d = + (p->r - col->r) * (p->r - col->r) + + (p->g - col->g) * (p->g - col->g) + + (p->b - col->b) * (p->b - col->b); + if (d < cd) { + cd = d; + closest = j; + } } + block->indices[i] = closest; } block->start = s; block->end = e; @@ -81,19 +119,15 @@ void get_block(Block* block, Colour* pixels, int stride) { void compress_block(const Block* block, FILE* f) { int i; - unsigned start = - ((unsigned)(block->start.r * 31.9999f) << 11) | - ((unsigned)(block->start.g * 63.9999f) << 5) | - ((unsigned)(block->start.b * 31.9999f)); - unsigned end = - ((unsigned)(block->end.r * 31.9999f) << 11) | - ((unsigned)(block->end.g * 63.9999f) << 5) | - ((unsigned)(block->end.b * 31.9999f)); - unsigned palette = (start << 16) | end; + unsigned start = encode_endpoint(&block->start); + unsigned end = encode_endpoint(&block->end); unsigned indices = 0; - fwrite(&palette, 1, 4, f); + fwrite(&start, 1, 2, f); + fwrite(&end, 1, 2, f); for (i = 0; i < 4 * 4; i++) { - indices |= block->indices[i] << (i * 2); + int idx = (4 * 4 - 1) - i; + idx = i; + indices |= block->indices[i] << (idx * 2); } fwrite(&indices, 1, 4, f); } |