static void gvv_render(glw_video_t *gv, glw_rctx_t *rc) { glw_video_surface_t *sa = gv->gv_sa; glw_video_surface_t *sb = gv->gv_sb; glw_program_t *gp; glw_backend_root_t *gbr = &gv->w.glw_root->gr_be; if(sa == NULL) return; gv->gv_width = sa->gvs_width[0]; gv->gv_height = sa->gvs_height[0]; upload_texture(gv, sa); const float yshift_a = (-0.5 * sa->gvs_yshift) / (float)sa->gvs_height[0]; glw_renderer_vtx_st(&gv->gv_quad, 0, 0, 1 + yshift_a); glw_renderer_vtx_st(&gv->gv_quad, 1, 1, 1 + yshift_a); glw_renderer_vtx_st(&gv->gv_quad, 2, 1, 0 + yshift_a); glw_renderer_vtx_st(&gv->gv_quad, 3, 0, 0 + yshift_a); if(sb != NULL) { // Two pictures that should be mixed upload_texture(gv, sb); gp = gbr->gbr_rgb2rgb_2f; const float yshift_b = (-0.5 * sb->gvs_yshift) / (float)sb->gvs_height[0]; glw_renderer_vtx_st2(&gv->gv_quad, 0, 0, 1 + yshift_b); glw_renderer_vtx_st2(&gv->gv_quad, 1, 1, 1 + yshift_b); glw_renderer_vtx_st2(&gv->gv_quad, 2, 1, 0 + yshift_b); glw_renderer_vtx_st2(&gv->gv_quad, 3, 0, 0 + yshift_b); } else { gp = gbr->gbr_rgb2rgb_1f; } gv->gv_gpa.gpa_prog = gp; glw_renderer_draw(&gv->gv_quad, gv->w.glw_root, rc, &sa->gvs_texture, sb != NULL ? &sb->gvs_texture : NULL, NULL, NULL, rc->rc_alpha * gv->w.glw_alpha, 0, &gv->gv_gpa); }
static void gvv_render(glw_video_t *gv, glw_rctx_t *rc) { glw_video_surface_t *sa = gv->gv_sa; glw_video_surface_t *sb = gv->gv_sa; if(sa == NULL) return; gv->gv_width = sa->gvs_width[0]; gv->gv_height = sa->gvs_height[0]; upload_texture(gv, sa); if(sb != NULL) upload_texture(gv, sb); glw_backend_root_t *gbr = &gv->w.glw_root->gr_be; glw_program_t *gp; if(sb != NULL) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, sb->gvs_texture); glActiveTexture(GL_TEXTURE0); gp = gbr->gbr_rgb2rgb_2f; } else { gp = gbr->gbr_rgb2rgb_1f; } glBindTexture(GL_TEXTURE_2D, sa->gvs_texture); glw_rctx_t rc0 = *rc; rc0.rc_alpha *= gv->gv_cmatrix_cur[0]; if(rc0.rc_alpha > 0.98f) glDisable(GL_BLEND); else glEnable(GL_BLEND); glw_render_video_quad(0, 0, sa->gvs_width[0], sa->gvs_height[0], 0, 0, gbr, gp, gv, &rc0); glEnable(GL_BLEND); }
void Image::draw(int x, int y, int src_x, int src_y, int w, int h, Color c) { if (tex == 0) { upload_texture(); if (tex == 0) return; } int x2 = x + w; int y2 = y + h; float t_x1 = float(src_x) / float(width); float t_x2 = t_x1 + float(w) / float(width); float t_y1 = float(src_y) / float(height); float t_y2 = t_y1 + float(h) / float(height); Render::draw_tex(x, y, x2, y2, c, tex, t_x1, t_y1, t_x2, t_y2); }
void Image::draw_flip_x(int x, int y, Color color, float angle, float scale_x, float scale_y) { if (tex == 0) { upload_texture(); if (tex == 0) return; } if (angle == 0.0f && scale_x == 1.0f && scale_y == 1.0f) { int xx = x - hotspot_x; int yy = y - hotspot_y; Render::draw_tex(xx + width, yy, xx, yy + height, color, tex); return; } float r = rad(angle); float c = cos(r); float s = sin(r); float x2 = -hotspot_x * scale_x; float y1 = -hotspot_y * scale_y; float x1 = (-hotspot_x + width) * scale_x; float y2 = (-hotspot_y + height) * scale_y; float x1c = x1 * c; float x1s = -x1 * s; float y1c = y1 * c; float y1s = y1 * s; float x2c = x2 * c; float x2s = -x2 * s; float y2c = y2 * c; float y2s = y2 * s; float p[8] = { x1c + y1s + x, x1s + y1c + y, x2c + y1s + x, x2s + y1c + y, x2c + y2s + x, x2s + y2c + y, x1c + y2s + x, x1s + y2c + y }; Render::draw_tex(&p[0], color, tex); }
// Pull a texture off the graphics card // Load a PNG file, and send it to upload_texture SPTexture* SPTexture_frompng(const char* path) { SPTexture* texture = NULL; spTexID texid = spTexID_Bad; FILE* pngf = fopen(path, "rb"); uint32_t width = 0; uint32_t height = 0; ubyte* pixmap = NULL; png_byte** row_heads = NULL; const size_t SIG_LENGTH = 8; png_structp png_state = NULL; png_infop png_info = NULL; if(pngf == NULL) { return texture; } // Ensure that the given path really is a PNG file { ubyte signature[8]; size_t bytes_read = fread(signature, sizeof(byte), SIG_LENGTH, pngf); if(bytes_read < 8) { fclose(pngf); printf("Error\n"); return texture; } if(png_sig_cmp(signature, 0, SIG_LENGTH)) { fclose(pngf); return texture; } } // Read the PNG file png_state = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_info = png_create_info_struct(png_state); png_init_io(png_state, pngf); png_set_sig_bytes(png_state, SIG_LENGTH); if(setjmp(png_jmpbuf(png_state))) { // Something went wrong while reading the PNG data png_destroy_read_struct(&png_state, &png_info, NULL); if(pixmap) { free(pixmap); } if(row_heads) { free(row_heads); } fclose(pngf); return spTexID_Bad; } // Prep work for reading the PNG { png_read_info(png_state, png_info); width = png_get_image_width(png_state, png_info); height = png_get_image_height(png_state, png_info); // We use signed integers to correspond with glTexImage2D, but PNG uses uint32_t if(width >= INT_MAX || height >= INT_MAX) { return spTexID_Bad; } png_byte bit_depth = png_get_bit_depth(png_state, png_info); png_byte color_type = png_get_color_type(png_state, png_info); png_size_t stride = 0; // Ensure RGBA color if(color_type == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_state); } if(color_type == PNG_COLOR_TYPE_RGB) { png_set_add_alpha(png_state, 0xFF, PNG_FILLER_AFTER); } // Ensure exactly 8 bits of color if(bit_depth > 8) { png_set_strip_16(png_state); } else if(bit_depth < 8) { png_set_packing(png_state); } png_read_update_info(png_state, png_info); // Create blank, safe-ish row pointers that point inside a dense pixmap stride = png_get_rowbytes(png_state, png_info); pixmap = malloc(stride * height); row_heads = calloc(sizeof(byte*), height); for(uint32_t row=0; row<height; row++) { // I've read that OpenGL expects rows in the opposite order, but // this works fine row_heads[row] = pixmap + row*stride; // row_heads[row] = &(pixmap[(height-row-1)*stride]); } // Read in the PNG data png_read_image(png_state, row_heads); texid = upload_texture(spTextureFmt_RGBA, (GLsizei)width, (GLsizei)height, pixmap); // Goodness gracious, Spaceman! What a mess to clean! png_destroy_read_struct(&png_state, &png_info, NULL); free(row_heads); free(pixmap); } fclose(pngf); texture = SPTexture_new(width, height, texid); return texture; }