示例#1
0
static VALUE
rb_gimp_rgb_composite_replace (VALUE self,
                               VALUE other,
                               VALUE mode)
{
  gimp_rgb_composite(rb2GimpRGBPtr(self),
                     rb2GimpRGBPtr(other),
                     (GimpRGBCompositeMode)NUM2INT(mode));

  return self;
}
示例#2
0
static VALUE
rb_gimp_rgb_composite (VALUE self,
                       VALUE other,
                       VALUE mode)
{
  GimpRGB color = rb2GimpRGB(self);
  gimp_rgb_composite(&color,
                     rb2GimpRGBPtr(other),
                     (GimpRGBCompositeMode)NUM2INT(mode));

  return GimpRGB2rb(&color);
}
示例#3
0
GimpRGB
get_ray_color_plane (GimpVector3 *pos)
{
  GimpRGB color = background;

  static gint         inside = FALSE;
  static GimpVector3  ray, spos;
  static gdouble      vx, vy;

  /* Construct a line from our VP to the point */
  /* ========================================= */

  gimp_vector3_sub (&ray, pos, &mapvals.viewpoint);
  gimp_vector3_normalize (&ray);

  /* Check for intersection. This is a quasi ray-tracer. */
  /* =================================================== */

  if (plane_intersect (&ray, &mapvals.viewpoint, &spos, &vx, &vy) == TRUE)
    {
      color = get_image_color (vx, vy, &inside);

      if (color.a != 0.0 && inside == TRUE &&
	  mapvals.lightsource.type != NO_LIGHT)
        {
          /* Compute shading at this point */
          /* ============================= */

          color = phong_shade (&spos,
			       &mapvals.viewpoint,
			       &mapvals.normal,
			       &mapvals.lightsource.position,
			       &color,
			       &mapvals.lightsource.color,
			       mapvals.lightsource.type);

          gimp_rgb_clamp (&color);
        }
    }

  if (mapvals.transparent_background == FALSE && color.a < 1.0)
    {
      gimp_rgb_composite (&color, &background,
			  GIMP_RGB_COMPOSITE_BEHIND);
    }

  return color;
}
示例#4
0
static void
compute_preview (gint startx, gint starty, gint w, gint h)
{
  gint xcnt, ycnt, f1, f2;
  gdouble imagex, imagey;
  gint32 index = 0;
  GimpRGB color;
  GimpRGB lightcheck, darkcheck;
  GimpVector3 pos;
  get_ray_func ray_func;

  if (xpostab_size != w)
    {
      if (xpostab)
        {
          g_free (xpostab);
          xpostab = NULL;
        }
    }

  if (!xpostab)
    {
      xpostab = g_new (gdouble, w);
      xpostab_size = w;
    }

  if (ypostab_size != h)
    {
      if (ypostab)
        {
          g_free (ypostab);
          ypostab = NULL;
        }
    }

  if (!ypostab)
    {
      ypostab = g_new (gdouble, h);
      ypostab_size = h;
    }

  for (xcnt = 0; xcnt < w; xcnt++)
    xpostab[xcnt] = (gdouble) width *((gdouble) xcnt / (gdouble) w);
  for (ycnt = 0; ycnt < h; ycnt++)
    ypostab[ycnt] = (gdouble) height *((gdouble) ycnt / (gdouble) h);

  precompute_init (width, height);

  gimp_rgba_set (&lightcheck,
                 GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT,
                 1.0);
  gimp_rgba_set (&darkcheck, GIMP_CHECK_DARK, GIMP_CHECK_DARK,
                 GIMP_CHECK_DARK, 1.0);

  if (mapvals.bump_mapped == TRUE && mapvals.bumpmap_id != -1)
    {
      gimp_pixel_rgn_init (&bump_region,
                           gimp_drawable_get (mapvals.bumpmap_id),
                           0, 0, width, height, FALSE, FALSE);
    }

  imagey = 0;

  if (mapvals.previewquality)
    ray_func = get_ray_color;
  else
    ray_func = get_ray_color_no_bilinear;

  if (mapvals.env_mapped == TRUE && mapvals.envmap_id != -1)
    {
      env_width = gimp_drawable_width (mapvals.envmap_id);
      env_height = gimp_drawable_height (mapvals.envmap_id);

      gimp_pixel_rgn_init (&env_region,
                           gimp_drawable_get (mapvals.envmap_id), 0,
                           0, env_width, env_height, FALSE, FALSE);

      if (mapvals.previewquality)
        ray_func = get_ray_color_ref;
      else
        ray_func = get_ray_color_no_bilinear_ref;
    }

  for (ycnt = 0; ycnt < PREVIEW_HEIGHT; ycnt++)
    {
      for (xcnt = 0; xcnt < PREVIEW_WIDTH; xcnt++)
        {
          if ((ycnt >= starty && ycnt < (starty + h)) &&
              (xcnt >= startx && xcnt < (startx + w)))
            {
              imagex = xpostab[xcnt - startx];
              imagey = ypostab[ycnt - starty];
              pos = int_to_posf (imagex, imagey);

              if (mapvals.bump_mapped == TRUE &&
                  mapvals.bumpmap_id != -1 &&
                  xcnt == startx)
                {
                  pos_to_float (pos.x, pos.y, &imagex, &imagey);
                  precompute_normals (0, width, RINT (imagey));
                }

              color = (*ray_func) (&pos);

              if (color.a < 1.0)
                {
                  f1 = ((xcnt % 32) < 16);
                  f2 = ((ycnt % 32) < 16);
                  f1 = f1 ^ f2;

                  if (f1)
                    {
                      if (color.a == 0.0)
                        color = lightcheck;
                      else
                        gimp_rgb_composite (&color,
                                            &lightcheck,
                                            GIMP_RGB_COMPOSITE_BEHIND);
                    }
                  else
                    {
                      if (color.a == 0.0)
                        color = darkcheck;
                      else
                        gimp_rgb_composite (&color,
                                            &darkcheck,
                                            GIMP_RGB_COMPOSITE_BEHIND);
                    }
                }

              gimp_rgb_get_uchar (&color,
                                  preview_rgb_data + index,
                                  preview_rgb_data + index +
                                  1,
                                  preview_rgb_data + index +
                                  2);
              index += 3;
              imagex++;
            }
          else
            {
              preview_rgb_data[index++] = 200;
              preview_rgb_data[index++] = 200;
              preview_rgb_data[index++] = 200;
            }
        }
    }
}
示例#5
0
GimpRGB
get_ray_color_box (GimpVector3 *pos)
{
  GimpVector3        lvp, ldir, vp, p, dir, ns, nn;
  GimpRGB             color, color2;
  gfloat             m[16];
  gint               i;
  FaceIntersectInfo  face_intersect[2];

  color = background;
  vp = mapvals.viewpoint;
  p = *pos;

  /* Translate viewpoint so that the box has its origin */
  /* at its lower left corner.                          */
  /* ================================================== */

  vp.x = vp.x - mapvals.position.x;
  vp.y = vp.y - mapvals.position.y;
  vp.z = vp.z - mapvals.position.z;

  p.x = p.x - mapvals.position.x;
  p.y = p.y - mapvals.position.y;
  p.z = p.z - mapvals.position.z;

  /* Compute direction */
  /* ================= */

  gimp_vector3_sub (&dir, &p, &vp);
  gimp_vector3_normalize (&dir);

  /* Compute inverse of rotation matrix and apply it to   */
  /* the viewpoint and direction. This transforms the     */
  /* observer into the local coordinate system of the box */
  /* ==================================================== */

  memcpy (m, rotmat, sizeof (gfloat) * 16);

  transpose_mat (m);

  vecmulmat (&lvp, &vp, m);
  vecmulmat (&ldir, &dir, m);

  /* Ok. Now the observer is in the space where the box is located */
  /* with its lower left corner at the origin and its axis aligned */
  /* to the cartesian basis. Check if the transformed ray hits it. */
  /* ============================================================= */

  face_intersect[0].t = 1000000.0;
  face_intersect[1].t = 1000000.0;

  if (intersect_box (mapvals.scale, lvp, ldir, face_intersect) == TRUE)
    {
      /* We've hit the box. Transform the hit points and */
      /* normals back into the world coordinate system   */
      /* =============================================== */

      for (i = 0; i < 2; i++)
        {
          vecmulmat (&ns, &face_intersect[i].s, rotmat);
          vecmulmat (&nn, &face_intersect[i].n, rotmat);

          ns.x = ns.x + mapvals.position.x;
          ns.y = ns.y + mapvals.position.y;
          ns.z = ns.z + mapvals.position.z;

          face_intersect[i].s = ns;
          face_intersect[i].n = nn;
        }

      color = get_box_image_color (face_intersect[0].face,
				   face_intersect[0].u,
				   face_intersect[0].v);

      /* Check for total transparency... */
      /* =============================== */

      if (color.a < 1.0)
        {
          /* Hey, we can see  through here!      */
          /* Lets see what's on the other side.. */
          /* =================================== */

          color = phong_shade (&face_intersect[0].s,
			       &mapvals.viewpoint,
			       &face_intersect[0].n,
			       &mapvals.lightsource.position,
			       &color,
			       &mapvals.lightsource.color,
			       mapvals.lightsource.type);

          gimp_rgb_clamp (&color);

          color2 = get_box_image_color (face_intersect[1].face,
					face_intersect[1].u,
					face_intersect[1].v);

          /* Make the normal point inwards */
          /* ============================= */

          gimp_vector3_mul (&face_intersect[1].n, -1.0);

          color2 = phong_shade (&face_intersect[1].s,
				&mapvals.viewpoint,
				&face_intersect[1].n,
				&mapvals.lightsource.position,
				&color2,
				&mapvals.lightsource.color,
				mapvals.lightsource.type);

          gimp_rgb_clamp (&color2);

          if (mapvals.transparent_background == FALSE && color2.a < 1.0)
            {
	      gimp_rgb_composite (&color2, &background,
				  GIMP_RGB_COMPOSITE_BEHIND);
	    }

          /* Compute a mix of the first and second colors */
          /* ============================================ */

	  gimp_rgb_composite (&color, &color2, GIMP_RGB_COMPOSITE_NORMAL);
          gimp_rgb_clamp (&color);
        }
      else if (color.a != 0.0 && mapvals.lightsource.type != NO_LIGHT)
        {
	  color = phong_shade (&face_intersect[0].s,
			       &mapvals.viewpoint,
			       &face_intersect[0].n,
			       &mapvals.lightsource.position,
			       &color,
			       &mapvals.lightsource.color,
			       mapvals.lightsource.type);

	  gimp_rgb_clamp (&color);
        }
    }
  else
    {
      if (mapvals.transparent_background == TRUE)
	gimp_rgb_set_alpha (&color, 0.0);
    }

  return color;
}
示例#6
0
GimpRGB
get_ray_color_sphere (GimpVector3 *pos)
{
  GimpRGB color = background;

  static GimpRGB      color2;
  static gint         inside = FALSE;
  static GimpVector3  normal, ray, spos1, spos2;
  static gdouble      vx, vy;

  /* Check if ray is within the bounding box */
  /* ======================================= */

  if (pos->x<bx1 || pos->x>bx2 || pos->y<by1 || pos->y>by2)
    return color;

  /* Construct a line from our VP to the point */
  /* ========================================= */

  gimp_vector3_sub (&ray, pos, &mapvals.viewpoint);
  gimp_vector3_normalize (&ray);

  /* Check for intersection. This is a quasi ray-tracer. */
  /* =================================================== */

  if (sphere_intersect (&ray, &mapvals.viewpoint, &spos1, &spos2) == TRUE)
    {
      /* Compute spherical to rectangular mapping */
      /* ======================================== */

      gimp_vector3_sub (&normal, &spos1, &mapvals.position);
      gimp_vector3_normalize (&normal);
      sphere_to_image (&normal, &vx, &vy);
      color = get_image_color (vx, vy, &inside);

      /* Check for total transparency... */
      /* =============================== */

      if (color.a < 1.0)
        {
          /* Hey, we can see  through here!      */
          /* Lets see what's on the other side.. */
          /* =================================== */

          color = phong_shade (&spos1,
			       &mapvals.viewpoint,
			       &normal,
			       &mapvals.lightsource.position,
			       &color,
			       &mapvals.lightsource.color,
			       mapvals.lightsource.type);

          gimp_rgb_clamp (&color);

          gimp_vector3_sub (&normal, &spos2, &mapvals.position);
          gimp_vector3_normalize (&normal);
          sphere_to_image (&normal, &vx, &vy);
          color2 = get_image_color (vx, vy, &inside);

          /* Make the normal point inwards */
          /* ============================= */

          gimp_vector3_mul (&normal, -1.0);

          color2 = phong_shade (&spos2,
				&mapvals.viewpoint,
				&normal,
				&mapvals.lightsource.position,
				&color2,
				&mapvals.lightsource.color,
				mapvals.lightsource.type);

          gimp_rgb_clamp (&color2);

          /* Compute a mix of the first and second colors */
          /* ============================================ */

	  gimp_rgb_composite (&color, &color2, GIMP_RGB_COMPOSITE_NORMAL);
          gimp_rgb_clamp (&color);
        }
      else if (color.a != 0.0 &&
	       inside == TRUE &&
	       mapvals.lightsource.type != NO_LIGHT)
        {
          /* Compute shading at this point */
          /* ============================= */

          color = phong_shade (&spos1,
			       &mapvals.viewpoint,
			       &normal,
			       &mapvals.lightsource.position,
			       &color,
			       &mapvals.lightsource.color,
			       mapvals.lightsource.type);

          gimp_rgb_clamp (&color);
        }
    }

  if (mapvals.transparent_background == FALSE && color.a < 1.0)
    {
      gimp_rgb_composite (&color, &background,
			  GIMP_RGB_COMPOSITE_BEHIND);
    }

  return color;
}
示例#7
0
void
compute_preview (gint x,
		 gint y,
		 gint w,
		 gint h,
		 gint pw,
		 gint ph)
{
  gdouble      xpostab[PREVIEW_WIDTH];
  gdouble      ypostab[PREVIEW_HEIGHT];
  gdouble      realw;
  gdouble      realh;
  GimpVector3  p1, p2;
  GimpRGB      color;
  GimpRGB      lightcheck, darkcheck;
  gint         xcnt, ycnt, f1, f2;
  glong        index = 0;

  init_compute ();

  p1 = int_to_pos (x, y);
  p2 = int_to_pos (x + w, y + h);

  /* First, compute the linear mapping (x,y,x+w,y+h) to (0,0,pw,ph) */
  /* ============================================================== */

  realw = (p2.x - p1.x);
  realh = (p2.y - p1.y);

  for (xcnt = 0; xcnt < pw; xcnt++)
    xpostab[xcnt] = p1.x + realw * ((gdouble) xcnt / (gdouble) pw);

  for (ycnt = 0; ycnt < ph; ycnt++)
    ypostab[ycnt] = p1.y + realh * ((gdouble) ycnt / (gdouble) ph);

  /* Compute preview using the offset tables */
  /* ======================================= */

  if (mapvals.transparent_background == TRUE)
    {
      gimp_rgba_set (&background, 0.0, 0.0, 0.0, 0.0);
    }
  else
    {
      gimp_context_get_background (&background);
      gimp_rgb_set_alpha (&background, 1.0);
    }

  gimp_rgba_set (&lightcheck,
		 GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT, 1.0);
  gimp_rgba_set (&darkcheck,
		 GIMP_CHECK_DARK, GIMP_CHECK_DARK, GIMP_CHECK_DARK, 1.0);
  gimp_vector3_set (&p2, -1.0, -1.0, 0.0);

  for (ycnt = 0; ycnt < ph; ycnt++)
    {
      for (xcnt = 0; xcnt < pw; xcnt++)
        {
          p1.x = xpostab[xcnt];
          p1.y = ypostab[ycnt];

          p2 = p1;
          color = (* get_ray_color) (&p1);

          if (color.a < 1.0)
            {
              f1 = ((xcnt % 32) < 16);
              f2 = ((ycnt % 32) < 16);
              f1 = f1 ^ f2;

              if (f1)
                {
                  if (color.a == 0.0)
		    color = lightcheck;
                  else
		    gimp_rgb_composite (&color, &lightcheck,
					GIMP_RGB_COMPOSITE_BEHIND);
                 }
              else
                {
                  if (color.a == 0.0)
		    color = darkcheck;
                  else
		    gimp_rgb_composite (&color, &darkcheck,
					GIMP_RGB_COMPOSITE_BEHIND);
                }
            }

	  gimp_rgb_get_uchar (&color,
			      preview_rgb_data + index,
			      preview_rgb_data + index + 1,
			      preview_rgb_data + index + 2);
	  index += 3;
        }
    }
}