static void glw_gradient_layout(glw_t *W, glw_rctx_t *rc) { glw_gradient_t *gg = (void *)W; glw_root_t *gr = W->glw_root; int w, h, i, tiles; w = rc->rc_width; h = rc->rc_height; tiles = gg->gg_image_flags & (GLW_IMAGE_BEVEL_LEFT | GLW_IMAGE_BEVEL_RIGHT) ? 3 : 1; for(i = gg->gg_tiles; i < tiles; i++) { glw_renderer_init_quad(&gg->gg_gr[i]); gg->gg_gr_initialized = tiles; } if(gg->gg_width != w || gg->gg_height != h || gg->gg_tiles != tiles) { gg->gg_width = w; gg->gg_height = h; gg->gg_tiles = tiles; gg->gg_height2 = glw_can_tnpo2(gr) ? h : 1 << (av_log2(h)); float xs = gr->gr_normalized_texture_coords ? 1.0 : TILEWIDTH; float ys = gr->gr_normalized_texture_coords ? 1.0 : gg->gg_height2; glw_renderer_t *r; if(tiles == 1) { r = &gg->gg_gr[0]; float u = xs * rc->rc_width / TILEWIDTH; glw_renderer_vtx_pos(r, 0, -1.0, -1.0, 0.0); glw_renderer_vtx_st (r, 0, 0.0, ys); glw_renderer_vtx_pos(r, 1, 1.0, -1.0, 0.0); glw_renderer_vtx_st (r, 1, u, ys); glw_renderer_vtx_pos(r, 2, 1.0, 1.0, 0.0); glw_renderer_vtx_st (r, 2, u, 0.0); glw_renderer_vtx_pos(r, 3, -1.0, 1.0, 0.0); glw_renderer_vtx_st (r, 3, 0.0, 0.0); } else { r = &gg->gg_gr[0]; float u = xs * (rc->rc_width - TILEWIDTH * 2) / TILEWIDTH; float x1 = -1.0 + 2.0 * TILEWIDTH / gg->gg_width; float x2 = -1.0 + 2.0 * (gg->gg_width - TILEWIDTH) / gg->gg_width; glw_renderer_vtx_pos(r, 0, x1, -1.0, 0.0); glw_renderer_vtx_st (r, 0, 0.0, ys); glw_renderer_vtx_pos(r, 1, x2, -1.0, 0.0); glw_renderer_vtx_st (r, 1, u, ys); glw_renderer_vtx_pos(r, 2, x2, 1.0, 0.0); glw_renderer_vtx_st (r, 2, u, 0.0); glw_renderer_vtx_pos(r, 3, x1, 1.0, 0.0); glw_renderer_vtx_st (r, 3, 0.0, 0.0); r = &gg->gg_gr[1]; glw_renderer_vtx_pos(r, 0, -1.0, -1.0, 0.0); glw_renderer_vtx_st (r, 0, 0.0, ys); glw_renderer_vtx_pos(r, 1, x1, -1.0, 0.0); glw_renderer_vtx_st (r, 1, xs, ys); glw_renderer_vtx_pos(r, 2, x1, 1.0, 0.0); glw_renderer_vtx_st (r, 2, xs, 0.0); glw_renderer_vtx_pos(r, 3, -1.0, 1.0, 0.0); glw_renderer_vtx_st (r, 3, 0.0, 0.0); r = &gg->gg_gr[2]; glw_renderer_vtx_pos(r, 0, x2, -1.0, 0.0); glw_renderer_vtx_st (r, 0, 0.0, ys); glw_renderer_vtx_pos(r, 1, 1.0, -1.0, 0.0); glw_renderer_vtx_st (r, 1, xs, ys); glw_renderer_vtx_pos(r, 2, 1.0, 1.0, 0.0); glw_renderer_vtx_st (r, 2, xs, 0.0); glw_renderer_vtx_pos(r, 3, x2, 1.0, 0.0); glw_renderer_vtx_st (r, 3, 0.0, 0.0); } gg->gg_repaint = 1; } if(gg->gg_repaint) { gg->gg_repaint = 0; repaint(gg, gr, i, TILEWIDTH, gg->gg_height2, gg->gg_tiles); } }
int glw_tex_backend_load(glw_root_t *gr, glw_loadable_texture_t *glt, AVPicture *pict, int pix_fmt, int src_w, int src_h, int req_w0, int req_h0) { int r, x, y, i; int need_format_conv = 0; int want_rescale = 0; // Want rescaling cause it looks better int must_rescale = 0; // Must rescale cause we cant display it otherwise uint32_t *palette, *u32p; uint8_t *map; int bpp = 0; switch(pix_fmt) { default: need_format_conv = 1; break; case PIX_FMT_RGB24: bpp = 3; glt->glt_format = GL_RGB; glt->glt_ext_format = GL_RGB; glt->glt_ext_type = GL_UNSIGNED_BYTE; break; case PIX_FMT_BGRA: bpp = 4; glt->glt_format = GL_RGBA; glt->glt_ext_format = GL_BGRA; glt->glt_ext_type = GL_UNSIGNED_BYTE; break; case PIX_FMT_RGBA: bpp = 4; glt->glt_format = GL_RGBA; glt->glt_ext_format = GL_RGBA; glt->glt_ext_type = GL_UNSIGNED_BYTE; break; case PIX_FMT_Y400A: bpp = 2; glt->glt_format = GL_LUMINANCE_ALPHA; glt->glt_ext_format = GL_LUMINANCE_ALPHA; glt->glt_ext_type = GL_UNSIGNED_BYTE; break; case PIX_FMT_GRAY8: bpp = 1; glt->glt_format = GL_LUMINANCE; glt->glt_ext_format = GL_LUMINANCE; glt->glt_ext_type = GL_UNSIGNED_BYTE; break; case PIX_FMT_PAL8: /* FFmpeg can not convert palette alpha values so we need to do this ourselfs */ /* It seems that some png implementation leavs the color set even if alpha is set to zero. This resluts in ugly aliasing effects when scaling image in opengl, so if alpha == 0, clear RGB */ map = pict->data[1]; for(i = 0; i < 4*256; i+=4) { if(map[i + 3] == 0) { map[i + 0] = 0; map[i + 1] = 0; map[i + 2] = 0; } } map = pict->data[0]; palette = (uint32_t *)pict->data[1]; AVPicture pict2; memset(&pict2, 0, sizeof(pict2)); pict2.data[0] = av_malloc(src_w * src_h * 4); pict2.linesize[0] = src_w * 4; u32p = (void *)pict2.data[0]; for(y = 0; y < src_h; y++) { for(x = 0; x < src_w; x++) { *u32p++ = palette[map[x]]; } map += pict->linesize[0]; } r = glw_tex_backend_load(gr, glt, &pict2, PIX_FMT_BGRA, src_w, src_h, req_w0, req_h0); av_free(pict2.data[0]); return r; } int req_w = req_w0, req_h = req_h0; if(!glw_can_tnpo2(gr)) { /* We lack non-power-of-two texture support, check if we must rescale. * Since the bitmap aspect is already calculated, it will automatically * compensate the rescaling when we render the texture. */ if(1 << av_log2(req_w0) != req_w0) req_w = make_powerof2(req_w0); if(1 << av_log2(req_h0) != req_h0) req_h = make_powerof2(req_h0); must_rescale = req_w != src_w || req_h != src_h; } else { want_rescale = req_w != src_w || req_h != src_h; } if(must_rescale || want_rescale || need_format_conv) { if(!texture_load_rescale_swscale(pict, pix_fmt, src_w, src_h, req_w, req_h, glt)) return 0; if(need_format_conv) { return texture_load_rescale_swscale(pict, pix_fmt, src_w, src_h, src_w, src_h, glt); } if(must_rescale) { glt->glt_tex_width = 1 << (av_log2(src_w - 1) + 1); glt->glt_tex_height = 1 << (av_log2(src_h - 1) + 1); } } glt->glt_xs = src_w; glt->glt_ys = src_h; texture_load_direct(pict, glt, bpp); return 0; }