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" `{
- #define LOGW(...) ((void)fprintf(stderr, "# warn: %s (%i)\n", __VA_ARGS__))
- #ifdef DEBUG
- #define LOGI(...) ((void)fprintf(stderr, "# info: %s (%i)\n", __VA_ARGS__))
- #else
- #define LOGI(...) (void)0
- #endif
-
extern NativeWindowType mnit_window;
extern EGLNativeDisplayType mnit_native_display;
{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;
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) {
- LOGW("error loading image after malloc", mnit_opengles_error_code);
+ PRINT_ERROR("error loading image after malloc: %i", mnit_opengles_error_code);
}
glGenTextures(1, &image->texture);
if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- LOGW("error loading image after glGenTextures", mnit_opengles_error_code);
+ PRINT_ERROR("error loading image after glGenTextures: %i", mnit_opengles_error_code);
}
glBindTexture(GL_TEXTURE_2D, image->texture);
if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- LOGW("error loading image glBindTexture", mnit_opengles_error_code);
+ 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) {
- LOGW("error loading image after glTexImage2D", mnit_opengles_error_code);
+ PRINT_ERROR("error loading image after glTexImage2D: %i", mnit_opengles_error_code);
}
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- LOGW("error loading image after gtTexParameter", mnit_opengles_error_code);
+ PRINT_ERROR("error loading image after gtTexParameter: %i", mnit_opengles_error_code);
}
return image;
EGLDisplay display = eglGetDisplay(mnit_native_display);
if ( display == EGL_NO_DISPLAY) {
- LOGW("Unable to eglGetDisplay", 0);
+ PRINT_ERROR("Unable to eglGetDisplay");
return -1;
}
if ( eglInitialize(display, 0, 0) == EGL_FALSE) {
- LOGW("Unable to eglInitialize", 0);
+ PRINT_ERROR("Unable to eglInitialize");
return -1;
}
if ( eglChooseConfig(display, attribs, &config, 1, &numConfigs) == EGL_FALSE) {
- LOGW("Unable to eglChooseConfig", 0);
+ PRINT_ERROR("Unable to eglChooseConfig");
return -1;
}
if ( numConfigs == 0 ) {
- LOGW("No configs available for egl", 0);
+ PRINT_ERROR("No configs available for egl");
return -1;
}
if ( eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format) == EGL_FALSE) {
- LOGW("Unable to eglGetConfigAttrib", 0);
+ PRINT_ERROR("Unable to eglGetConfigAttrib");
return -1;
}
context = eglCreateContext(display, config, NULL, NULL);
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
- LOGW("Unable to eglMakeCurrent", 0);
+ PRINT_ERROR("Unable to eglMakeCurrent");
return -1;
}
mnit_width = w;
mnit_height = h;
- LOGI("surface", (int)surface);
- LOGI("display", (int)display);
- LOGI("width", w);
- LOGI("height", h);
-
glViewport(0, 0, mnit_width, mnit_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glDisable(GL_TEXTURE_2D);
if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- LOGW("error drawing", mnit_opengles_error_code);
+ PRINT_ERROR("error drawing: %i", mnit_opengles_error_code);
}
`}
glDisable(GL_TEXTURE_2D);
if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- LOGW("error drawing", mnit_opengles_error_code);
+ PRINT_ERROR("error drawing: %i", mnit_opengles_error_code);
}
`}
glDisable(GL_TEXTURE_2D);
if ((mnit_opengles_error_code = glGetError()) != GL_NO_ERROR) {
- LOGW("error drawing", mnit_opengles_error_code);
+ PRINT_ERROR("error drawing: %i", mnit_opengles_error_code);
}
`}
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 );
`}
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
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;
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");
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; i<height; i++)
row_pointers[i] = (png_byte*) malloc(row_bytes);
png_read_image(png_ptr, row_pointers);
for (i = 0; i < height; i++)
- memcpy(pixels + (row_bytes*i),
- row_pointers[i], row_bytes);
+ memcpy(pixels + (row_bytes_pow2*i), row_pointers[i], row_bytes);
+
+ recv = mnit_opengles_load_image((const uint_least32_t *)pixels,
+ width, height, width_pow2, height_pow2, has_alpha);
- recv = mnit_opengles_load_image((const uint_least32_t *)pixels, width, height, has_alpha);
- LOGW("OK");
+ // Calculate the size of the client-side memory allocated and freed
+ float size = ((float)row_bytes_pow2) * height_pow2/1024.0/1024.0;
+ static float total_size = 0;
+ total_size += size;
+ LOGI("Loaded OK %fmb out of %fmb", size, total_size);
close_png_ptr:
if (info_ptr != NULL)
return recv;
`}
end
+
+redef universal Int
+ # The first power of `exp` greater or equal to `self`
+ private fun next_pow(exp: Int): Int
+ do
+ var p = 0
+ while p < self do p = p*exp
+ return p
+ end
+end