From: Alexis Laferrière Date: Sun, 22 Feb 2015 17:55:49 +0000 (-0500) Subject: lib/mnit: expand images to the nearest power of 2 for OpenGL ES 1.0 X-Git-Tag: v0.7.4~10^2~2 X-Git-Url: http://nitlanguage.org lib/mnit: expand images to the nearest power of 2 for OpenGL ES 1.0 Signed-off-by: Alexis Laferrière --- diff --git a/lib/mnit/opengles1.nit b/lib/mnit/opengles1.nit index def8598..24a904b 100644 --- a/lib/mnit/opengles1.nit +++ b/lib/mnit/opengles1.nit @@ -55,7 +55,9 @@ in "C header" `{ GLenum mnit_opengles_error_code; - struct mnit_opengles_Texture *mnit_opengles_load_image( const uint_least32_t *pixels, int width, int height, int has_alpha ); + struct mnit_opengles_Texture *mnit_opengles_load_image( + const uint_least32_t *pixels, int width, int height, + int width_pow2, int height_pow2, int has_alpha); `} in "C" `{ @@ -79,7 +81,9 @@ in "C" `{ {1.0f, 0.0f} }; - struct mnit_opengles_Texture *mnit_opengles_load_image( const uint_least32_t *pixels, int width, int height, int has_alpha ) + struct mnit_opengles_Texture *mnit_opengles_load_image( + const uint_least32_t *pixels, int width, int height, + int width_pow2, int height_pow2, int has_alpha) { struct mnit_opengles_Texture *image = malloc(sizeof(struct mnit_opengles_Texture)); int format = has_alpha? GL_RGBA: GL_RGB; @@ -93,8 +97,8 @@ in "C" `{ image->src_xo = 0; image->src_yo = 0; - image->src_xi = 1.0; - image->src_yi = 1.0; + image->src_xi = ((float)width)/width_pow2; + image->src_yi = ((float)height)/height_pow2; if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) { PRINT_ERROR("error loading image after malloc: %i", mnit_opengles_error_code); @@ -112,7 +116,7 @@ in "C" `{ PRINT_ERROR("error loading image glBindTexture: %i", mnit_opengles_error_code); } - glTexImage2D( GL_TEXTURE_2D, 0, format, width, height, + glTexImage2D( GL_TEXTURE_2D, 0, format, width_pow2, height_pow2, 0, format, GL_UNSIGNED_BYTE, (GLvoid*)pixels); if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) { @@ -454,10 +458,12 @@ extern class Opengles1Image in "C" `{struct mnit_opengles_Texture *`} image->scale = recv->scale; image->blended = recv->blended; - image->src_xo = ((float)x)/recv->width; - image->src_yo = ((float)y)/recv->height; - image->src_xi = ((float)x+w)/recv->width; - image->src_yi = ((float)y+h)/recv->height; + float r_dx = recv->src_xi - recv->src_xo; + float r_dy = recv->src_yi - recv->src_yo; + image->src_xo = recv->src_xo + ((float)x)/recv->width*r_dx; + image->src_yo = recv->src_yo + ((float)y)/recv->height*r_dy; + image->src_xi = recv->src_xo + ((float)x+w)/recv->width*r_dx; + image->src_yi = recv->src_yo + ((float)y+h)/recv->height*r_dy; return Opengles1Image_as_Image( image ); `} diff --git a/lib/mnit_android/android_assets.nit b/lib/mnit_android/android_assets.nit index 8f61c90..d1ee104 100644 --- a/lib/mnit_android/android_assets.nit +++ b/lib/mnit_android/android_assets.nit @@ -86,7 +86,7 @@ redef class App var a = load_asset_from_apk(path) if a != null then if path.file_extension == "png" then - var png = new Opengles1Image.from_android_asset(a) + var png = new Opengles1Image.from_android_asset(a) a.close return png else if path.file_extension == "txt" then @@ -118,7 +118,7 @@ end redef class Opengles1Image # Read a png from a zipped stream - new from_android_asset(asset: AndroidAsset) is extern `{ + new from_android_asset(asset: AndroidAsset) import Int.next_pow `{ struct mnit_opengles_Texture *recv = NULL; png_structp png_ptr = NULL; @@ -133,13 +133,16 @@ redef class Opengles1Image unsigned char *pixels = NULL; unsigned int i; + png_uint_32 width_pow2, height_pow2; + unsigned int row_bytes_pow2; + unsigned char sig[8]; int sig_read = AAsset_read(asset, sig, 8); if (png_sig_cmp(sig, 0, sig_read)) { LOGW("invalide png signature"); return NULL; } - + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { LOGW("png_create_read_struct failed"); @@ -176,11 +179,16 @@ redef class Opengles1Image png_read_update_info(png_ptr, info_ptr); } - LOGW("w: %i, h: %i", width, height); + width_pow2 = Int_next_pow(width, 2); + height_pow2 = Int_next_pow(height, 2); + + LOGW("Loading image of w: %i, h: %i, w2: %d, h2: %d", + width, height, width_pow2, height_pow2); row_bytes = png_get_rowbytes(png_ptr, info_ptr); - pixels = malloc(row_bytes * height); - row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); + row_bytes_pow2 = row_bytes * width_pow2 / width; + pixels = malloc(row_bytes_pow2 * height_pow2); + row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height_pow2); for (i=0; ipixels, sdl_image->w, sdl_image->h, sdl_image->format->Amask ); + return mnit_opengles_load_image( sdl_image->pixels, + sdl_image->w, sdl_image->h, + sdl_image->w, sdl_image->h, sdl_image->format->Amask ); `} # using sdl @@ -91,7 +93,9 @@ redef extern class Opengles1Image fprintf(stderr, "SDL failed to load image <%s>: %s\n", String_to_cstring(path), IMG_GetError()); return NULL; } else { - opengles_image = mnit_opengles_load_image( sdl_image->pixels, sdl_image->w, sdl_image->h, sdl_image->format->Amask ); + opengles_image = mnit_opengles_load_image( sdl_image->pixels, + sdl_image->w, sdl_image->h, + sdl_image->w, sdl_image->h, sdl_image->format->Amask ); SDL_FreeSurface(sdl_image); return opengles_image; }