commit ccdb9723373b4dfee6cb0b97aef5392a07cc973a
parent 748005be4e763f175c13cae5eddf867fb07eaf3c
Author: amin <dev@aminmesbah.com>
Date: Fri, 5 Jul 2019 19:50:56 +0000
Load a run length encoded tga file
FossilOrigin-Name: 9a1ade5bbf7c8a38d53d64ce2b8720b1460127d6346f7da9be0750fa2fdea271
Diffstat:
M | src/game.c | | | 69 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
1 file changed, 61 insertions(+), 8 deletions(-)
diff --git a/src/game.c b/src/game.c
@@ -49,27 +49,79 @@ void img_tga_header_print(struct ImgTgaHeader h)
internal u8 *img_load_from_memory(u8 *buffer, size_t len, i32 *out_width, i32 *out_height, struct StackAllocator *allocator)
{
+ assert(buffer);
+ u8 *one_past_last = buffer + (len * sizeof(u8));
+
+ assert(len >= sizeof(struct ImgTgaHeader));
struct ImgTgaHeader h = *(struct ImgTgaHeader *)buffer;
img_tga_header_print(h);
+
+ // Image descriptor not currently accounted for
+ assert(h.id_length == 0);
// Color maps not currently supported
assert(h.color_map_type == 0);
- // Only uncompressed RGB is supported
- assert(h.data_type_code == 2);
+ // Only RGB is supported
+ assert(h.data_type_code == 2 || h.data_type_code == 10);
- if (out_width && out_height)
+ if (out_width)
{
*out_width = h.width;
+ }
+ if (out_height)
+ {
*out_height = h.height;
}
buffer += sizeof(struct ImgTgaHeader);
- u32 bytes_per_pixel = h.bits_per_pixel / 8;
+ u8 bytes_per_pixel = h.bits_per_pixel / 8;
size_t pixel_buffer_length = h.width * h.height * bytes_per_pixel;
u8 *pixels = mem_st_alloc_buffer(allocator, u8, pixel_buffer_length);
- for (size_t i = 0; i < pixel_buffer_length; i++)
+ assert(pixels);
+
+ if (h.data_type_code == 2)
{
- pixels[i] = *buffer++;
+ for (size_t i = 0; i < pixel_buffer_length; i++)
+ {
+ pixels[i] = *buffer++;
+ }
+ }
+ else if (h.data_type_code == 10)
+ {
+ size_t pixel_bytes_read = 0;
+ while (pixel_bytes_read < pixel_buffer_length)
+ {
+ u8 packet_header = *buffer++;
+ printf("h: %X --- ", packet_header);
+
+ u8 run_length_header_bit = packet_header >> 7;
+ u8 run_count = (packet_header & (~(1 << 7))) + 1;
+ assert(run_count <= 128);
+ printf("run_count: %u\n", run_count);
+ if (run_length_header_bit)
+ {
+ printf("rl\n");
+ u8 pixel[4] = {0};
+ for (u8 i = 0; i < bytes_per_pixel; i++)
+ {
+ pixel[i] = *buffer++;
+ }
+ for (u8 i = 0; i < run_count * bytes_per_pixel; i++)
+ {
+ pixels[pixel_bytes_read + i] = pixel[i % bytes_per_pixel];
+ }
+ pixel_bytes_read += run_count * bytes_per_pixel;
+ }
+ else
+ {
+ printf("raw\n");
+ for (u8 i = 0; i < run_count * bytes_per_pixel; i++)
+ {
+ pixels[pixel_bytes_read + i] = *buffer++;
+ }
+ pixel_bytes_read += run_count * bytes_per_pixel;
+ }
+ }
}
u32 bytes_per_row = h.width * bytes_per_pixel;
@@ -264,7 +316,8 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer)
// game_texture_load
{
size_t file_len = 0;
- u8 *t = platform.platform_read_entire_file("assets/test_sw_origin.tga", &file_len);
+ //u8 *t = platform.platform_read_entire_file("assets/test_sw_origin.tga", &file_len);
+ u8 *t = platform.platform_read_entire_file("assets/test_sw_origin_rle.tga", &file_len);
assert(t);
size_t image_load_free_marker = mem_st_get_marker(&game_state->world_allocator);
@@ -282,7 +335,7 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glActiveTexture(GL_TEXTURE0);
}