void gr_fill(int x, int y, int w, int h) { GGLContext *gl = gr_context; if(gr_is_curr_clr_opaque) gl->disable(gl, GGL_BLEND); gl->recti(gl, x, y, x + w, y + h); if(gr_is_curr_clr_opaque) gl->enable(gl, GGL_BLEND); }
void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { GGLContext *gl = gr_context; GGLint color[4]; color[0] = ((r << 8) | r) + 1; color[1] = ((g << 8) | g) + 1; color[2] = ((b << 8) | b) + 1; color[3] = ((a << 8) | a) + 1; gl->color4xv(gl, color); gr_is_curr_clr_opaque = (a == 255); }
void gr_fill(int x1, int y1, int x2, int y2) { x1 += overscan_offset_x; y1 += overscan_offset_y; x2 += overscan_offset_x; y2 += overscan_offset_y; GGLContext *gl = gr_context; gl->disable(gl, GGL_TEXTURE_2D); gl->recti(gl, x1, y1, x2, y2); }
void gr_flip(void) { GGLContext *gl = gr_context; /* currently active buffer becomes the backbuffer */ gl->colorBuffer(gl, gr_framebuffer + gr_active_fb); /* swap front and back buffers */ gr_active_fb = (gr_active_fb + 1) & 1; /* inform the display driver */ set_active_framebuffer(gr_active_fb); }
int gr_init(void) { gglInit(&gr_context); GGLContext *gl = gr_context; gr_mem_surface.data = NULL; gr_init_font(); gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC); if (gr_vt_fd < 0) { gr_vt_fd = open("/dev/tty", O_RDWR | O_SYNC); } if (gr_vt_fd < 0) { // This is non-fatal; post-Cupcake kernels don't have tty0. perror("can't open /dev/tty0"); } else { ioctl(gr_vt_fd, KDGETMODE, &gr_vt_mode); if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) { // However, if we do open tty0, we expect the ioctl to work. perror("failed KDSETMODE to KD_GRAPHICS on tty0"); gr_exit(); return -1; } } gr_fb_fd = get_framebuffer(gr_framebuffer); if (gr_fb_fd < 0) { perror("unable to get framebuffer"); gr_exit(); return -1; } get_memory_surface(&gr_mem_surface); fprintf(stderr, "framebuffer: fd %d (%d x %d)\n", gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height); /* start with 0 as front (displayed) and 1 as back (drawing) */ gr_active_fb = 0; set_active_framebuffer(0); gl->colorBuffer(gl, &gr_mem_surface); gl->activeTexture(gl, 0); gl->enable(gl, GGL_BLEND); gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA); gr_fb_blank(true); gr_fb_blank(false); return 0; }
void gr_line(int x0, int y0, int x1, int y1, int width) { GGLContext *gl = gr_context; if(gr_is_curr_clr_opaque) gl->disable(gl, GGL_BLEND); const int coords0[2] = { x0 << 4, y0 << 4 }; const int coords1[2] = { x1 << 4, y1 << 4 }; gl->linex(gl, coords0, coords1, width << 4); if(gr_is_curr_clr_opaque) gl->enable(gl, GGL_BLEND); }
void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { GGLContext *gl = gr_context; GGLint color[4]; color[0] = ((r << 8) | r) + 1; color[1] = ((g << 8) | g) + 1; color[2] = ((b << 8) | b) + 1; color[3] = ((a << 8) | a) + 1; #ifdef COLORS_REVERSED color[0] = ((b << 8) | b) + 1; color[2] = ((r << 8) | r) + 1; #endif gl->color4xv(gl, color); }
void gr_fill(int x, int y, int w, int h) { GGLContext *gl = gr_context; x += overscan_offset_x; y += overscan_offset_y; w += overscan_offset_x; h += overscan_offset_y; //fprintf(stderr, "gr_fill: x=%d,y=%d,w=%d,h=%d\n", x, y, w, h); gl->disable(gl, GGL_TEXTURE_2D); gl->recti(gl, x, y, w, h); }
int gr_init(void) { gglInit(&gr_context); GGLContext *gl = gr_context; gr_init_font(); gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC); if (gr_vt_fd < 0) { // This is non-fatal; post-Cupcake kernels don't have tty0. } else if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) { // However, if we do open tty0, we expect the ioctl to work. perror("failed KDSETMODE to KD_GRAPHICS on tty0"); gr_exit(); return -1; } gr_fb_fd = get_framebuffer(gr_framebuffer); if (gr_fb_fd < 0) { perror("Unable to get framebuffer.\n"); gr_exit(); return -1; } get_memory_surface(&gr_mem_surface); fprintf(stderr, "framebuffer: fd %d (%d x %d)\n", gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height); /* start with 0 as front (displayed) and 1 as back (drawing) */ gr_active_fb = 0; if (!has_overlay) set_active_framebuffer(0); gl->colorBuffer(gl, &gr_mem_surface); gl->activeTexture(gl, 0); gl->enable(gl, GGL_BLEND); gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA); #ifdef TW_SCREEN_BLANK_ON_BOOT printf("TW_SCREEN_BLANK_ON_BOOT := true\n"); gr_fb_blank(true); gr_fb_blank(false); #endif if (!alloc_ion_mem(fi.line_length * vi.yres)) allocate_overlay(gr_fb_fd, gr_framebuffer); return 0; }
int gr_text(int x, int y, const char *s, int bold) { GGLContext *gl = gr_context; GRFont *font = gr_font; unsigned off; x += overscan_offset_x; y += overscan_offset_y; y -= font->ascent; gl->bindTexture(gl, &font->texture); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); while((off = *s++)) { off -= 32; if (off < 96) { gl->texCoord2i(gl, (off * font->cwidth) - x, 0 - y); gl->recti(gl, x, y, x + font->cwidth, y + font->cheight); } x += font->cwidth; } return x; }
int gr_text_l(int x, int y, const char *s) { GGLContext *gl = gr_context; GRFont *font = gr_font_l; unsigned off; y -= font->ascent; gl->bindTexture(gl, &font->texture); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); while((off = *s++)) { off -= 32; if (off < 96) { gl->texCoord2i(gl, 0 - (gr_fb_width() - y), (off * font->cwidth) - x + 1); gl->recti(gl, gr_fb_width() - y - font->cheight, x, gr_fb_width() - 1 - y, x + font->cwidth); } x += font->cwidth; } return x; }
int gr_textEx(int x, int y, const char *s, void* pFont) { GGLContext *gl = gr_context; GRFont *font = (GRFont*) pFont; unsigned off; unsigned cwidth; /* Handle default font */ if (!font) font = gr_font; gl->bindTexture(gl, &font->texture); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); while((off = *s++)) { off -= 32; cwidth = 0; if (off < 96) { cwidth = font->offset[off+1] - font->offset[off]; gl->texCoord2i(gl, (font->offset[off]) - x, 0 - y); gl->recti(gl, x, y, x + cwidth, y + font->cheight); x += cwidth; } } return x; }
int twgr_text(int x, int y, const char *s) { GGLContext *gl = gr_context; GRFont *font = gr_font; unsigned off; unsigned cwidth = 0; y -= font->ascent; gl->bindTexture(gl, &font->texture); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); while((off = *s++)) { off -= 32; if (off < 96) { cwidth = font->offset[off+1] - font->offset[off]; gl->texCoord2i(gl, (off * cwidth) - x, 0 - y); gl->recti(gl, x, y, x + cwidth, y + font->cheight); } x += cwidth; } return x; }
int gr_textExW(int x, int y, const char *s, void* pFont, int max_width) { GGLContext *gl = gr_context; GRFont *font = (GRFont*) pFont; unsigned off; unsigned cwidth; /* Handle default font */ if (!font) font = gr_font; #ifndef TW_DISABLE_TTF if(font->type == FONT_TYPE_TTF) return gr_ttf_textExWH(gl, x, y, s, pFont, max_width, -1); #endif gl->bindTexture(gl, &font->texture); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); while((off = *s++)) { off -= 32; cwidth = 0; if (off < 96) { cwidth = font->offset[off+1] - font->offset[off]; if ((x + (int)cwidth) < max_width) { gl->texCoord2i(gl, (font->offset[off]) - x, 0 - y); gl->recti(gl, x, y, x + cwidth, y + font->cheight); x += cwidth; } else { gl->texCoord2i(gl, (font->offset[off]) - x, 0 - y); gl->recti(gl, x, y, max_width, y + font->cheight); x = max_width; return x; } } } gl->disable(gl, GGL_TEXTURE_2D); return x; }
void gr_update_surface_dimensions() { if(gr_rotation%180 == 0) { gr_mem_surface.width = vi.xres; gr_mem_surface.height = vi.yres; if(gr_rotation == 0) gr_mem_surface.stride = vi.xres_virtual; else gr_mem_surface.stride = vi.xres; } else { gr_mem_surface.width = vi.yres; gr_mem_surface.height = vi.xres; gr_mem_surface.stride = vi.yres; } GGLContext *gl = gr_context; gl->colorBuffer(gl, &gr_mem_surface); }
int gr_init(void) { GGLContext *gl; int fd; gglInit(&gr_context); gl = gr_context; gr_init_font(); fd = open("/dev/tty0", O_RDWR | O_SYNC); if(fd < 0) return -1; if(ioctl(fd, KDSETMODE, (void*) KD_GRAPHICS)) { close(fd); return -1; } gr_fb_fd = get_framebuffer(gr_framebuffer); if(gr_fb_fd < 0) { ioctl(fd, KDSETMODE, (void*) KD_TEXT); close(fd); return -1; } gr_vt_fd = fd; /* start with 0 as front (displayed) and 1 as back (drawing) */ gr_active_fb = 0; set_active_framebuffer(0); gl->colorBuffer(gl, gr_framebuffer + 1); gl->activeTexture(gl, 0); gl->enable(gl, GGL_BLEND); gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA); return 0; }
int gr_textExW(int x, int y, const char *s, void* pFont, int max_width) { GGLContext *gl = gr_context; GRFont *gfont = (GRFont*) pFont; unsigned off, width, height, n; wchar_t ch; /* Handle default font */ if (!gfont) gfont = gr_font; y -= gfont->ascent; gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); while(*s) { if(*((unsigned char*)(s)) < 0x20) { s++; continue; } off = getCharID(s,pFont); n = utf8_mbtowc(&ch, s, strlen(s)); if(n <= 0) break; s += n; width = gfont->cwidth[off]; height = gfont->cheight[off]; memcpy(&font_ftex, &gfont->texture, sizeof(font_ftex)); font_ftex.width = width; font_ftex.height = height; font_ftex.stride = width; font_ftex.data = gfont->fontdata[off]; gl->bindTexture(gl, &font_ftex); gl->texCoord2i(gl, 0 - x, 0 - y); if ((x + (int)width) < max_width) { gl->recti(gl, x, y, x + width, y + height); x += width; } else { gl->recti(gl, x, y, max_width, y + height); x += max_width; return x; } } return x; }
void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy) { if (gr_context == NULL) { return; } GGLContext *gl = gr_context; GGLSurface *surface = (GGLSurface*)source; if(surface->format == GGL_PIXEL_FORMAT_RGBX_8888) gl->disable(gl, GGL_BLEND); gl->bindTexture(gl, surface); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); gl->texCoord2i(gl, sx - dx, sy - dy); gl->recti(gl, dx, dy, dx + w, dy + h); gl->disable(gl, GGL_TEXTURE_2D); if(surface->format == GGL_PIXEL_FORMAT_RGBX_8888) gl->enable(gl, GGL_BLEND); }
void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy) { if (gr_context == NULL) { return; } GGLContext *gl = gr_context; gl->bindTexture(gl, (GGLSurface*) source); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); gl->texCoord2i(gl, sx - dx, sy - dy); gl->recti(gl, dx, dy, dx + w, dy + h); }
int gr_text(int x, int y, const char *s) { GGLContext *gl = gr_context; GRFont *gfont = gr_font; unsigned off, width, height, font_bitmap_width, n; y -= gfont->ascent; gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); while((off = *s)) { if(*((unsigned char*)(s)) < 0x20) { s++; continue; } width = gfont->cwidth; height = gfont->cheight; off = ch_utf8_to_custom(s); if(off >= 96) width *= 2; memcpy(&font_ftex, &gfont->texture, sizeof(font_ftex)); font_bitmap_width = (font.width % (font.cwidth * font_char_per_bitmap)); if(!font_bitmap_width) font_bitmap_width = font.cwidth * font_char_per_bitmap; font_ftex.width = font_bitmap_width; font_ftex.stride = font_bitmap_width; font_ftex.data = font_data[(off < 96) ? (off / font_char_per_bitmap) : ((96 + (off - 96) * 2) / font_char_per_bitmap)]; gl->bindTexture(gl, &font_ftex); if(off >= 96) gl->texCoord2i(gl, ((96 + (off - 96) * 2) * font.cwidth) % (font_char_per_bitmap * font.cwidth) - x, 0 - y); else gl->texCoord2i(gl, (off % font_char_per_bitmap) * width - x, 0 - y); gl->recti(gl, x, y, x + width, y + height); x += width; n = ch_utf8_length(s); if(n <= 0) break; s += n; } return x; }
void gr_texticon(int x, int y, gr_surface icon) { if (gr_context == NULL || icon == NULL) { return; } GGLContext* gl = gr_context; gl->bindTexture(gl, (GGLSurface*) icon); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); int w = gr_get_width(icon); int h = gr_get_height(icon); gl->texCoord2i(gl, -x, -y); gl->recti(gl, x, y, x+gr_get_width(icon), y+gr_get_height(icon)); }
int gr_text(int x, int y, const char *s, int bold) { GGLContext *gl = gr_context; GRFont *gfont = NULL; unsigned off, width, height, n; wchar_t ch; /* Handle default font */ if (!gfont) gfont = gr_font; x += overscan_offset_x; y += overscan_offset_y; y -= gfont->ascent; // fprintf(stderr, "gr_text: x=%d,y=%d,w=%s\n", x, y, s); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); while(*s) { if(*((unsigned char*)(s)) < 0x20) { s++; continue; } off = getCharID(s,NULL); n = utf8_mbtowc(&ch, s, strlen(s)); if(n <= 0) break; s += n; width = gfont->cwidth[off]; height = gfont->cheight[off]; memcpy(&font_ftex, &gfont->texture, sizeof(font_ftex)); font_ftex.width = width; font_ftex.height = height; font_ftex.stride = width; font_ftex.data = gfont->fontdata[off]; gl->bindTexture(gl, &font_ftex); gl->texCoord2i(gl, 0 - x, 0 - y); gl->recti(gl, x, y, x + width, y + height); x += width; } return x; }
int gr_textExWH(int x, int y, const char *s, void* pFont, int max_width, int max_height) { GGLContext *gl = gr_context; GRFont *font = (GRFont*) pFont; unsigned off; unsigned cwidth; int rect_x, rect_y; /* Handle default font */ if (!font) font = gr_font; gl->bindTexture(gl, &font->texture); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); while((off = *s++)) { off -= 32; cwidth = 0; if (off < 96) { cwidth = font->offset[off+1] - font->offset[off]; if ((x + (int)cwidth) < max_width) rect_x = x + cwidth; else rect_x = max_width; if (y + font->cheight < (unsigned int)(max_height)) rect_y = y + font->cheight; else rect_y = max_height; gl->texCoord2i(gl, (font->offset[off]) - x, 0 - y); gl->recti(gl, x, y, rect_x, rect_y); x += cwidth; if (x > max_width) return x; } } return x; }
int gr_save_screenshot(const char *dest) { uint32_t y, stride_bytes; int res = -1; GGLContext *gl = NULL; GGLSurface surface; uint8_t * volatile img_data = NULL; uint8_t *ptr; FILE *fp = NULL; png_structp png_ptr = NULL; png_infop info_ptr = NULL; fp = fopen(dest, "wb"); if(!fp) goto exit; img_data = malloc(vi.xres * vi.yres * 3); surface.version = sizeof(surface); surface.width = gr_mem_surface.width; surface.height = gr_mem_surface.height; surface.stride = gr_mem_surface.width; surface.data = img_data; surface.format = GGL_PIXEL_FORMAT_RGB_888; gglInit(&gl); gl->colorBuffer(gl, &surface); gl->activeTexture(gl, 0); gl->bindTexture(gl, &gr_mem_surface); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); gl->enable(gl, GGL_TEXTURE_2D); gl->texCoord2i(gl, 0, 0); gl->recti(gl, 0, 0, gr_mem_surface.width, gr_mem_surface.height); gglUninit(gl); gl = NULL; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) goto exit; info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) goto exit; if (setjmp(png_jmpbuf(png_ptr))) goto exit; png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, surface.width, surface.height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); ptr = img_data; stride_bytes = surface.width*3; for(y = 0; y < surface.height; ++y) { png_write_row(png_ptr, ptr); ptr += stride_bytes; } png_write_end(png_ptr, NULL); res = 0; exit: if(info_ptr) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); if(png_ptr) png_destroy_write_struct(&png_ptr, (png_infopp)NULL); if(gl) gglUninit(gl); if(img_data) free(img_data); if(fp) fclose(fp); return res; }
void gr_noclip() { GGLContext *gl = gr_context; gl->scissor(gl, 0, 0, gr_fb_width(), gr_fb_height()); gl->disable(gl, GGL_SCISSOR_TEST); }
void gr_clip(int x, int y, int w, int h) { GGLContext *gl = gr_context; gl->scissor(gl, x, y, w, h); gl->enable(gl, GGL_SCISSOR_TEST); }
// Scale image function int res_scale_surface(gr_surface source, gr_surface* destination, float scale_w, float scale_h) { GGLContext *gl = NULL; GGLSurface* sc_mem_surface = NULL; *destination = NULL; GGLSurface *surface = (GGLSurface*)source; int w = gr_get_width(source), h = gr_get_height(source); int sx = 0, sy = 0, dx = 0, dy = 0; float dw = (float)w * scale_w; float dh = (float)h * scale_h; // Create a new surface that is the appropriate size sc_mem_surface = init_display_surface((int)dw, (int)dh); if (!sc_mem_surface) { printf("gr_scale_surface failed to init_display_surface\n"); return -1; } sc_mem_surface->format = surface->format; // Initialize the context gglInit(&gl); gl->colorBuffer(gl, sc_mem_surface); gl->activeTexture(gl, 0); // Enable or disable blending based on source surface format if (surface->format == GGL_PIXEL_FORMAT_RGBX_8888) { gl->disable(gl, GGL_BLEND); } else { gl->enable(gl, GGL_BLEND); gl->blendFunc(gl, GGL_ONE, GGL_ZERO); } // Bind our source surface to the context gl->bindTexture(gl, surface); // Deal with the scaling gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_MIN_FILTER, GGL_LINEAR); gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_MAG_FILTER, GGL_LINEAR); gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP); gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP); gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC); gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC); gl->enable(gl, GGL_TEXTURE_2D); int32_t grad[8]; memset(grad, 0, sizeof(grad)); // s, dsdx, dsdy, scale, t, dtdx, dtdy, tscale <- this is wrong! // This api uses block floating-point for S and T texture coordinates. // All values are given in 16.16, scaled by 'scale'. In other words, // set scale to 0, for 16.16 values. // s, dsdx, dsdy, t, dtdx, dtdy, sscale, tscale float dsdx = (float)w / dw; float dtdy = (float)h / dh; grad[0] = ((float)sx - (dsdx * dx)) * 65536; grad[1] = dsdx * 65536; grad[3] = ((float)sy - (dtdy * dy)) * 65536; grad[5] = dtdy * 65536; // printf("blit: w=%d h=%d dx=%d dy=%d dw=%f dh=%f dsdx=%f dtdy=%f s0=%x dsdx=%x t0=%x dtdy=%x\n", // w, h, dx, dy, dw, dh, dsdx, dtdy, grad[0], grad[1], grad[3], grad[5]); gl->texCoordGradScale8xv(gl, 0 /*tmu*/, grad); // draw / scale the source surface to our target context gl->recti(gl, dx, dy, dx + dw, dy + dh); gglUninit(gl); gl = NULL; // put the scaled surface in our destination *destination = (gr_surface*) sc_mem_surface; // free memory used in the source res_free_surface(source); source = NULL; return 0; }
void gr_fill(int x, int y, int w, int h) { GGLContext *gl = gr_context; gl->disable(gl, GGL_TEXTURE_2D); gl->recti(gl, x, y, w, h); }
void gr_fill_l(int x, int y, int w, int h) { GGLContext *gl = gr_context; gl->disable(gl, GGL_TEXTURE_2D); gl->recti(gl, gr_fb_width() - h, x, gr_fb_width() - y, w); }