예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
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);
}
예제 #5
0
파일: texture.c 프로젝트: i80and/spray
// 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;
}