Skip to content

Commit

Permalink
[Web] Pad NPOT theme textures to POT.
Browse files Browse the repository at this point in the history
  • Loading branch information
skylersaleh committed Sep 5, 2024
1 parent 5e209f7 commit 9e71fbe
Showing 1 changed file with 52 additions and 8 deletions.
60 changes: 52 additions & 8 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8273,6 +8273,18 @@ static bool se_load_theme_from_image_format_mini(uint8_t* im, uint32_t im_w, uin
}
return true;
}
static uint8_t * se_pad_image_to_size(uint8_t* im, uint32_t im_w, uint32_t im_h, uint32_t new_w, uint32_t new_h){
uint8_t * new_image = malloc(new_w*new_h*4);
memset(new_image,0,new_w*new_h*4);
for(int y = 0; y< im_h;++y)
for(int x = 0; x< im_w;++x){
new_image[(y*new_w + x)*4+0] = im[(y*im_w+x)*4+0];
new_image[(y*new_w + x)*4+1] = im[(y*im_w+x)*4+1];
new_image[(y*new_w + x)*4+2] = im[(y*im_w+x)*4+2];
new_image[(y*new_w + x)*4+3] = im[(y*im_w+x)*4+3];
}
return new_image;
}
static bool se_load_theme_from_image(uint8_t* im, uint32_t im_w, uint32_t im_h, bool invert){
if(!im){return false; }
bool loaded = false;
Expand All @@ -8290,7 +8302,6 @@ static bool se_load_theme_from_image(uint8_t* im, uint32_t im_w, uint32_t im_h,
return false;
}
if(loaded){
int num_mips = 8;
for(int i=0; i<SE_TOTAL_REGIONS;++i){
se_theme_region_t * region = &theme->regions[i];
region->active = false;
Expand Down Expand Up @@ -8413,17 +8424,38 @@ static bool se_load_theme_from_image(uint8_t* im, uint32_t im_w, uint32_t im_h,
theme->palettes[i*4+2]= 255-theme->palettes[i*4+2];
}
}
//WebGL doesn't support mip mapping of NPOT, so pad them to a power of two.
bool free_mip0 = false;
//#if defined(EMSCRIPTEN)
int pad_pow2 = 1;
while(pad_pow2 < im_w ||pad_pow2<im_h)pad_pow2<<=1;
if(pad_pow2!=im_w ||pad_pow2!=im_h){
uint8_t * old = im;
im = se_pad_image_to_size(im,im_w,im_h,pad_pow2,pad_pow2);
printf("Padding npot texture from {%d, %d} -> {%d %d}\n",im_w,im_h,pad_pow2,pad_pow2);
im_w = pad_pow2;
im_h = pad_pow2;
free_mip0 = true;
}
//#endif
theme->im_h=im_h;
theme->im_w=im_w;
sg_image_data im_data={0};

im_data.subimage[0][0].ptr = im;
im_data.subimage[0][0].size = im_w*im_h*4;
int max_dim = im_h>im_w? im_h:im_w;
int num_mips = 0;
while(max_dim>=(1<<num_mips))++num_mips;

for(int m = 1; m<num_mips;++m){
int mip_w = (im_w)>>(m);
int mip_h = (im_h)>>(m);
im_data.subimage[0][m].size =mip_h*mip_w*4;
uint8_t* data =(uint8_t*)malloc(im_data.subimage[0][m].size);
im_data.subimage[0][m].ptr = data;
uint8_t* data2 = (uint8_t*)im_data.subimage[0][m-1].ptr;
printf("%d %d\n",mip_w,mip_h);
for(int y=0;y<mip_h;++y){
for(int x=0;x<mip_w;++x){
for(int c = 0; c<4;++c){
Expand All @@ -8437,28 +8469,40 @@ static bool se_load_theme_from_image(uint8_t* im, uint32_t im_w, uint32_t im_h,
}
}
}
int drop_mips=0;
if(num_mips>1){
//#if defined(EMSCRIPTEN)
while((im_h>>drop_mips)>2048)drop_mips++;
printf("Dropping %d mip layers\n",drop_mips);
for(int i=0;i<drop_mips;++i){
if(i!=0||free_mip0)free((uint8_t*)im_data.subimage[0][i].ptr);
}
free_mip0|=drop_mips;
for(int i=drop_mips;i<num_mips;++i){
im_data.subimage[0][i-drop_mips]= im_data.subimage[0][i];
}
num_mips-=drop_mips;
}
//#endif
sg_image_desc desc={
.type= SG_IMAGETYPE_2D,
.render_target= false,
.width= im_w,
.height= im_h,
.width= im_w/(1<<drop_mips),
.height= im_h/(1<<drop_mips),
.num_slices= 1,
.num_mipmaps= num_mips,
.usage= SG_USAGE_IMMUTABLE,
.pixel_format= SG_PIXELFORMAT_RGBA8,
.sample_count= 1,
.min_filter= SG_FILTER_LINEAR_MIPMAP_LINEAR,
.min_filter= num_mips>1 ? SG_FILTER_LINEAR_MIPMAP_LINEAR : SG_FILTER_LINEAR,
.mag_filter= SG_FILTER_LINEAR,
.wrap_u= SG_WRAP_CLAMP_TO_EDGE,
.wrap_v= SG_WRAP_CLAMP_TO_EDGE,
.wrap_w= SG_WRAP_CLAMP_TO_EDGE,
.border_color= SG_BORDERCOLOR_OPAQUE_BLACK,
.max_anisotropy= 4,
.min_lod= 0.0f,
.max_lod= 1e9f,
.data= im_data,
};
gui_state.theme.image= sg_make_image(&desc);
if(free_mip0)free((uint8_t*)im_data.subimage[0][0].ptr);
for(int m = 1; m<num_mips;++m){
free((uint8_t*)im_data.subimage[0][m].ptr);
}
Expand Down

0 comments on commit 9e71fbe

Please sign in to comment.