// mlx_new_image // // by Ol // #import #import #include "mlx_int.h" #include "mlx_new_window.h" void *mlx_new_image(mlx_ptr_t *mlx_ptr, int width, int height) { mlx_img_list_t *newimg; // if (mlx_ptr->win_list == NULL) // return (NULL); // need at leat one window created to have openGL context and create texture if ((newimg = malloc(sizeof(*newimg))) == NULL) return ((void *)0); newimg->next = mlx_ptr->img_list; mlx_ptr->img_list = newimg; newimg->width = width; newimg->height = height; newimg->vertexes[0] = 0.0; newimg->vertexes[1] = 0.0; newimg->vertexes[2] = width; newimg->vertexes[3] = 0.0; newimg->vertexes[4] = width; newimg->vertexes[5] = -height; newimg->vertexes[6] = 0.0; newimg->vertexes[7] = -height; newimg->buffer = malloc(UNIQ_BPP*width*height); bzero(newimg->buffer, UNIQ_BPP*width*height); return (newimg); } mlx_img_ctx_t *add_img_to_ctx(mlx_img_list_t *img, mlx_win_list_t *win) { mlx_img_ctx_t *imgctx; imgctx = win->img_list; while (imgctx) { if (imgctx->img == img) return (imgctx); imgctx = imgctx->next; } imgctx = malloc(sizeof(*imgctx)); imgctx->img = img; imgctx->next = win->img_list; win->img_list = imgctx; glGenTextures(1, &(imgctx->texture)); glBindTexture(GL_TEXTURE_2D, imgctx->texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D( GL_TEXTURE_2D, 0, /* target, level of detail */ GL_RGBA8, /* internal format */ img->width, img->height, 0, /* width, height, border */ GL_BGRA, GL_UNSIGNED_BYTE, /* external format, type */ img->buffer /* pixels */ ); glGenBuffers(1, &(imgctx->vbuffer)); glBindBuffer(GL_ARRAY_BUFFER, imgctx->vbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(img->vertexes), img->vertexes, GL_DYNAMIC_DRAW); // 4 points buff return (imgctx); } void mlx_put_image_to_window(mlx_ptr_t *mlx_ptr, mlx_win_list_t *win_ptr, mlx_img_list_t *img_ptr, int x, int y) { mlx_img_ctx_t *imgctx; if (!win_ptr->pixmgt) return ; [(id)(win_ptr->winid) selectGLContext]; imgctx = add_img_to_ctx(img_ptr, win_ptr); // update texture glBindTexture(GL_TEXTURE_2D, imgctx->texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, img_ptr->width, img_ptr->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, img_ptr->buffer); [(id)(win_ptr->winid) mlx_gl_draw_img:img_ptr andCtx:imgctx andX:x andY:y]; win_ptr->nb_flush ++; } // assume here 32bpp little endian char *mlx_get_data_addr(mlx_img_list_t *img_ptr, int *bits_per_pixel, int *size_line, int *endian) { *bits_per_pixel = UNIQ_BPP*8; *size_line = img_ptr->width*UNIQ_BPP; *endian = 0; // little endian for now on mac-intel return (img_ptr->buffer); } unsigned int mlx_get_color_value(mlx_ptr_t *mlx_ptr, int color) { return (color); } int mlx_string_put(mlx_ptr_t *mlx_ptr, mlx_win_list_t *win_ptr, int x, int y, int color, unsigned char *string) { mlx_img_ctx_t *imgctx; int gX; int gY; if (!win_ptr->pixmgt) return(0); #ifdef STRINGPUTX11 y -= (FONT_HEIGHT * 2)/3; #endif [(id)(win_ptr->winid) selectGLContext]; imgctx = add_img_to_ctx(mlx_ptr->font, win_ptr); while (*string) { if (*string >= 32 && *string <= 127) { gX = (FONT_WIDTH+2)*(*string-32); gY = 0; // printf("put char %c pos %d %d\n", *string, gX, gY); [(id)(win_ptr->winid) mlx_gl_draw_font:mlx_ptr->font andCtx:imgctx andX:x andY:y andColor:color glyphX:gX glyphY:gY]; #ifdef STRINGPUTX11 x += FONT_WIDTH/1.4; #else x += FONT_WIDTH; #endif } string ++; } win_ptr->nb_flush ++; return (0); } int mlx_destroy_image(mlx_ptr_t *mlx_ptr, mlx_img_list_t *img_todel) { mlx_img_ctx_t ctx_first; mlx_img_ctx_t *ctx; mlx_img_ctx_t *ctx_to_del; mlx_img_list_t img_first; mlx_img_list_t *img; mlx_win_list_t *win; img_first.next = mlx_ptr->img_list; img = &img_first; while (img && img->next) { if (img->next == img_todel) img->next = img->next->next; img = img->next; } mlx_ptr->img_list = img_first.next; win = mlx_ptr->win_list; while (win) { ctx_first.next = win->img_list; ctx = &ctx_first; while (ctx && ctx->next) { if (ctx->next->img == img_todel) { [(id)(win->winid) selectGLContext]; glDeleteBuffers(1, &(ctx->next->vbuffer)); glDeleteTextures(1, &(ctx->next->texture)); ctx_to_del = ctx->next; ctx->next = ctx->next->next; free(ctx_to_del); } ctx = ctx->next; } win->img_list = ctx_first.next; win = win->next; } free(img_todel->buffer); free(img_todel); // printf("destroy image done.\n"); return (0); }