true 16-bit color... glorious
This commit is contained in:
parent
3dccce8a81
commit
b1e8525c3e
30 changed files with 678 additions and 652 deletions
|
|
@ -5,6 +5,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "pxl8_color.h"
|
||||
#include "pxl8_macros.h"
|
||||
|
||||
typedef struct pxl8_skyline_fit {
|
||||
|
|
@ -82,7 +83,7 @@ static pxl8_skyline_fit pxl8_skyline_find_position(
|
|||
return result;
|
||||
}
|
||||
|
||||
static void pxl8_skyline_add_rect(pxl8_skyline* skyline, pxl8_point pos, u32 w, u32 h) {
|
||||
static bool pxl8_skyline_add_rect(pxl8_skyline* skyline, pxl8_point pos, u32 w, u32 h) {
|
||||
u32 node_idx = 0;
|
||||
for (u32 i = 0; i < skyline->count; i++) {
|
||||
if (skyline->nodes[i].x == pos.x) {
|
||||
|
|
@ -101,11 +102,14 @@ static void pxl8_skyline_add_rect(pxl8_skyline* skyline, pxl8_point pos, u32 w,
|
|||
}
|
||||
|
||||
if (skyline->count - nodes_to_remove + 1 > skyline->capacity) {
|
||||
skyline->capacity = (skyline->count - nodes_to_remove + 1) * 2;
|
||||
skyline->nodes = (pxl8_skyline_node*)realloc(
|
||||
u32 new_capacity = (skyline->count - nodes_to_remove + 1) * 2;
|
||||
pxl8_skyline_node* new_nodes = (pxl8_skyline_node*)realloc(
|
||||
skyline->nodes,
|
||||
skyline->capacity * sizeof(pxl8_skyline_node)
|
||||
new_capacity * sizeof(pxl8_skyline_node)
|
||||
);
|
||||
if (!new_nodes) return false;
|
||||
skyline->nodes = new_nodes;
|
||||
skyline->capacity = new_capacity;
|
||||
}
|
||||
|
||||
if (nodes_to_remove > 0) {
|
||||
|
|
@ -118,6 +122,7 @@ static void pxl8_skyline_add_rect(pxl8_skyline* skyline, pxl8_point pos, u32 w,
|
|||
|
||||
skyline->nodes[node_idx] = (pxl8_skyline_node){pos.x, pos.y + (i32)h, (i32)w};
|
||||
skyline->count = skyline->count - nodes_to_remove + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void pxl8_skyline_compact(pxl8_skyline* skyline) {
|
||||
|
|
@ -143,14 +148,14 @@ pxl8_atlas* pxl8_atlas_create(u32 width, u32 height, pxl8_color_mode color_mode)
|
|||
atlas->height = height;
|
||||
atlas->width = width;
|
||||
|
||||
i32 bytes_per_pixel = (color_mode == PXL8_COLOR_MODE_HICOLOR) ? 4 : 1;
|
||||
i32 bytes_per_pixel = pxl8_bytes_per_pixel(color_mode);
|
||||
atlas->pixels = (u8*)calloc(width * height, bytes_per_pixel);
|
||||
if (!atlas->pixels) {
|
||||
free(atlas);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
atlas->entry_capacity = 64;
|
||||
atlas->entry_capacity = PXL8_DEFAULT_ATLAS_ENTRY_CAPACITY;
|
||||
atlas->entries = (pxl8_atlas_entry*)calloc(atlas->entry_capacity, sizeof(pxl8_atlas_entry));
|
||||
if (!atlas->entries) {
|
||||
free(atlas->pixels);
|
||||
|
|
@ -197,7 +202,7 @@ void pxl8_atlas_destroy(pxl8_atlas* atlas) {
|
|||
bool pxl8_atlas_expand(pxl8_atlas* atlas, pxl8_color_mode color_mode) {
|
||||
if (!atlas || atlas->width >= 4096) return false;
|
||||
|
||||
i32 bytes_per_pixel = (color_mode == PXL8_COLOR_MODE_HICOLOR) ? 4 : 1;
|
||||
i32 bytes_per_pixel = pxl8_bytes_per_pixel(color_mode);
|
||||
u32 new_size = atlas->width * 2;
|
||||
u32 old_width = atlas->width;
|
||||
|
||||
|
|
@ -236,8 +241,8 @@ bool pxl8_atlas_expand(pxl8_atlas* atlas, pxl8_color_mode color_mode) {
|
|||
for (u32 x = 0; x < (u32)atlas->entries[i].w; x++) {
|
||||
u32 src_idx = (atlas->entries[i].y + y) * old_width + (atlas->entries[i].x + x);
|
||||
u32 dst_idx = (fit.pos.y + y) * new_size + (fit.pos.x + x);
|
||||
if (bytes_per_pixel == 4) {
|
||||
((u32*)new_pixels)[dst_idx] = ((u32*)atlas->pixels)[src_idx];
|
||||
if (bytes_per_pixel == 2) {
|
||||
((u16*)new_pixels)[dst_idx] = ((u16*)atlas->pixels)[src_idx];
|
||||
} else {
|
||||
new_pixels[dst_idx] = atlas->pixels[src_idx];
|
||||
}
|
||||
|
|
@ -247,7 +252,11 @@ bool pxl8_atlas_expand(pxl8_atlas* atlas, pxl8_color_mode color_mode) {
|
|||
atlas->entries[i].x = fit.pos.x;
|
||||
atlas->entries[i].y = fit.pos.y;
|
||||
|
||||
pxl8_skyline_add_rect(&new_skyline, fit.pos, atlas->entries[i].w, atlas->entries[i].h);
|
||||
if (!pxl8_skyline_add_rect(&new_skyline, fit.pos, atlas->entries[i].w, atlas->entries[i].h)) {
|
||||
free(new_skyline.nodes);
|
||||
free(new_pixels);
|
||||
return false;
|
||||
}
|
||||
pxl8_skyline_compact(&new_skyline);
|
||||
}
|
||||
|
||||
|
|
@ -290,11 +299,14 @@ u32 pxl8_atlas_add_texture(
|
|||
texture_id = atlas->free_list[--atlas->free_count];
|
||||
} else {
|
||||
if (atlas->entry_count >= atlas->entry_capacity) {
|
||||
atlas->entry_capacity *= 2;
|
||||
atlas->entries = (pxl8_atlas_entry*)realloc(
|
||||
u32 new_capacity = atlas->entry_capacity * 2;
|
||||
pxl8_atlas_entry* new_entries = (pxl8_atlas_entry*)realloc(
|
||||
atlas->entries,
|
||||
atlas->entry_capacity * sizeof(pxl8_atlas_entry)
|
||||
new_capacity * sizeof(pxl8_atlas_entry)
|
||||
);
|
||||
if (!new_entries) return UINT32_MAX;
|
||||
atlas->entries = new_entries;
|
||||
atlas->entry_capacity = new_capacity;
|
||||
}
|
||||
texture_id = atlas->entry_count++;
|
||||
}
|
||||
|
|
@ -307,21 +319,24 @@ u32 pxl8_atlas_add_texture(
|
|||
entry->w = w;
|
||||
entry->h = h;
|
||||
|
||||
i32 bytes_per_pixel = (color_mode == PXL8_COLOR_MODE_HICOLOR) ? 4 : 1;
|
||||
i32 bytes_per_pixel = pxl8_bytes_per_pixel(color_mode);
|
||||
for (u32 y = 0; y < h; y++) {
|
||||
for (u32 x = 0; x < w; x++) {
|
||||
u32 src_idx = y * w + x;
|
||||
u32 dst_idx = (fit.pos.y + y) * atlas->width + (fit.pos.x + x);
|
||||
|
||||
if (bytes_per_pixel == 4) {
|
||||
((u32*)atlas->pixels)[dst_idx] = ((const u32*)pixels)[src_idx];
|
||||
if (bytes_per_pixel == 2) {
|
||||
((u16*)atlas->pixels)[dst_idx] = ((const u16*)pixels)[src_idx];
|
||||
} else {
|
||||
atlas->pixels[dst_idx] = pixels[src_idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pxl8_skyline_add_rect(&atlas->skyline, fit.pos, w, h);
|
||||
if (!pxl8_skyline_add_rect(&atlas->skyline, fit.pos, w, h)) {
|
||||
entry->active = false;
|
||||
return UINT32_MAX;
|
||||
}
|
||||
pxl8_skyline_compact(&atlas->skyline);
|
||||
|
||||
atlas->dirty = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue