示例#1
0
static void
lic_image (GimpPixelRgn *src_rgn,
           gint          x,
           gint          y,
           gdouble       vx,
           gdouble       vy,
           GimpRGB      *color)
{
  gdouble u, step = 2.0 * l / isteps;
  gdouble xx = (gdouble) x, yy = (gdouble) y;
  gdouble c, s;
  GimpRGB col = { 0, 0, 0, 0 };
  GimpRGB col1, col2, col3;

  /* Get vector at x,y */
  /* ================= */

  c = vx;
  s = vy;

  /* Calculate integral numerically */
  /* ============================== */

  getpixel (src_rgn, &col1, xx + l * c, yy + l * s);
  if (source_drw_has_alpha)
    gimp_rgba_multiply (&col1, filter (-l));
  else
    gimp_rgb_multiply (&col1, filter (-l));

  for (u = -l + step; u <= l; u += step)
    {
      getpixel (src_rgn, &col2, xx - u * c, yy - u * s);
      if (source_drw_has_alpha)
        {
          gimp_rgba_multiply (&col2, filter (u));

          col3 = col1;
          gimp_rgba_add (&col3, &col2);
          gimp_rgba_multiply (&col3, 0.5 * step);
          gimp_rgba_add (&col, &col3);
        }
      else
        {
          gimp_rgb_multiply (&col2, filter (u));

          col3 = col1;
          gimp_rgb_add (&col3, &col2);
          gimp_rgb_multiply (&col3, 0.5 * step);
          gimp_rgb_add (&col, &col3);
        }
      col1 = col2;
    }
  if (source_drw_has_alpha)
    gimp_rgba_multiply (&col, 1.0 / l);
  else
    gimp_rgb_multiply (&col, 1.0 / l);
  gimp_rgb_clamp (&col);

  *color = col;
}
示例#2
0
static VALUE
rb_gimp_rgb_add (VALUE self,
                 VALUE other)
{
  GimpRGB result = rb2GimpRGB(self);
  gimp_rgb_add(&result, rb2GimpRGBPtr(other));

  return GimpRGB2rb(&result);
}
示例#3
0
/* do the exchanging */
static void
exchange (GimpDrawable *drawable,
          GimpPreview  *preview)
{
  GimpPixelRgn  srcPR, destPR;
  guchar        min_red,  min_green,  min_blue;
  guchar        max_red,  max_green,  max_blue;
  guchar        from_red, from_green, from_blue;
  guchar        to_red,   to_green,   to_blue;
  guchar       *src_row, *dest_row;
  gint          x, y, bpp = drawable->bpp;
  gboolean      has_alpha;
  gint          x1, y1, y2;
  gint          width, height;
  GimpRGB       min;
  GimpRGB       max;

  if (preview)
    {
      gimp_preview_get_position (preview, &x1, &y1);
      gimp_preview_get_size (preview, &width, &height);
    }
  else if (! gimp_drawable_mask_intersect (drawable->drawable_id,
                                           &x1, &y1, &width, &height))
    {
      return;
    }

  y2 = y1 + height;

  has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
  /* allocate memory */
  src_row = g_new (guchar, drawable->width * bpp);

  gimp_rgb_get_uchar (&xargs.from, &from_red, &from_green, &from_blue);
  gimp_rgb_get_uchar (&xargs.to,   &to_red,   &to_green,   &to_blue);

  /* get boundary values */
  min = xargs.from;
  gimp_rgb_subtract (&min, &xargs.threshold);
  gimp_rgb_clamp (&min);
  gimp_rgb_get_uchar (&min, &min_red, &min_green, &min_blue);

  max = xargs.from;
  gimp_rgb_add (&max, &xargs.threshold);
  gimp_rgb_clamp (&max);
  gimp_rgb_get_uchar (&max, &max_red, &max_green, &max_blue);

  dest_row = g_new (guchar, drawable->width * bpp);

  gimp_pixel_rgn_init (&srcPR, drawable,
                       x1, y1, width, height, FALSE, FALSE);
  gimp_pixel_rgn_init (&destPR, drawable,
                       x1, y1, width, height, (preview == NULL), TRUE);

  for (y = y1; y < y2; y++)
    {
      gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y, width);

      for (x = 0; x < width; x++)
        {
          guchar pixel_red, pixel_green, pixel_blue;
          guchar new_red, new_green, new_blue;
          guint  idx;

          /* get current pixel-values */
          pixel_red   = src_row[x * bpp];
          pixel_green = src_row[x * bpp + 1];
          pixel_blue  = src_row[x * bpp + 2];

          idx = x * bpp;

          /* want this pixel? */
          if (pixel_red >= min_red &&
              pixel_red <= max_red &&
              pixel_green >= min_green &&
              pixel_green <= max_green &&
              pixel_blue >= min_blue &&
              pixel_blue <= max_blue)
            {
              guchar red_delta, green_delta, blue_delta;

              red_delta   = pixel_red > from_red ?
                pixel_red - from_red : from_red - pixel_red;
              green_delta = pixel_green > from_green ?
                pixel_green - from_green : from_green - pixel_green;
              blue_delta  = pixel_blue > from_blue ?
                pixel_blue - from_blue : from_blue - pixel_blue;

              new_red   = CLAMP (to_red   + red_delta,   0, 255);
              new_green = CLAMP (to_green + green_delta, 0, 255);
              new_blue  = CLAMP (to_blue  + blue_delta,  0, 255);
            }
          else
            {
              new_red   = pixel_red;
              new_green = pixel_green;
              new_blue  = pixel_blue;
            }

          /* fill buffer */
          dest_row[idx + 0] = new_red;
          dest_row[idx + 1] = new_green;
          dest_row[idx + 2] = new_blue;

          /* copy alpha-channel */
          if (has_alpha)
            dest_row[idx + 3] = src_row[x * bpp + 3];
        }
      /* store the dest */
      gimp_pixel_rgn_set_row (&destPR, dest_row, x1, y, width);

      /* and tell the user what we're doing */
      if (!preview && (y % 10) == 0)
        gimp_progress_update ((gdouble) y / (gdouble) height);
    }

  g_free (src_row);
  g_free (dest_row);

  if (preview)
    {
      gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview),
                                         &destPR);
    }
  else
    {
      gimp_progress_update (1.0);
      /* update the processed region */
      gimp_drawable_flush (drawable);
      gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
      gimp_drawable_update (drawable->drawable_id, x1, y1, width, height);
    }
}
示例#4
0
static GimpRGB
phong_shade (GimpVector3 *pos,
	     GimpVector3 *viewpoint,
	     GimpVector3 *normal,
	     GimpVector3 *light,
	     GimpRGB      *diff_col,
	     GimpRGB      *spec_col,
	     gint         type)
{
  GimpRGB       ambientcolor, diffusecolor, specularcolor;
  gdouble      NL, RV, dist;
  GimpVector3  L, NN, V, N;

  /* Compute ambient intensity */
  /* ========================= */

  N = *normal;
  ambientcolor = *diff_col;
  gimp_rgb_multiply (&ambientcolor, mapvals.material.ambient_int);

  /* Compute (N*L) term of Phong's equation */
  /* ====================================== */

  if (type == POINT_LIGHT)
    gimp_vector3_sub (&L, light, pos);
  else
    L = *light;

  dist = gimp_vector3_length (&L);

  if (dist != 0.0)
    gimp_vector3_mul (&L, 1.0 / dist);

  NL = 2.0 * gimp_vector3_inner_product (&N, &L);

  if (NL >= 0.0)
    {
      /* Compute (R*V)^alpha term of Phong's equation */
      /* ============================================ */

      gimp_vector3_sub (&V, viewpoint, pos);
      gimp_vector3_normalize (&V);

      gimp_vector3_mul (&N, NL);
      gimp_vector3_sub (&NN, &N, &L);
      RV = gimp_vector3_inner_product (&NN, &V);
      RV = pow (RV, mapvals.material.highlight);

      /* Compute diffuse and specular intensity contribution */
      /* =================================================== */

      diffusecolor = *diff_col;
      gimp_rgb_multiply (&diffusecolor, mapvals.material.diffuse_ref);
      gimp_rgb_multiply (&diffusecolor, NL);

      specularcolor = *spec_col;
      gimp_rgb_multiply (&specularcolor, mapvals.material.specular_ref);
      gimp_rgb_multiply (&specularcolor, RV);

      gimp_rgb_add (&diffusecolor, &specularcolor);
      gimp_rgb_multiply (&diffusecolor, mapvals.material.diffuse_int);
      gimp_rgb_clamp (&diffusecolor);

      gimp_rgb_add (&ambientcolor, &diffusecolor);
    }

  return ambientcolor;
}
示例#5
0
GimpRGB
get_ray_color_no_bilinear_ref (GimpVector3 *position)
{
  GimpRGB      color_sum;
  GimpRGB      color_int;
  GimpRGB      light_color;
  GimpRGB      color, env_color;
  gint         x;
  gdouble      xf, yf;
  GimpVector3  normal, *p, v, r;
  gint         k;
  gdouble      tmpval;

  pos_to_float (position->x, position->y, &xf, &yf);

  x = RINT (xf);

  if (mapvals.bump_mapped == FALSE || mapvals.bumpmap_id == -1)
    normal = mapvals.planenormal;
  else
    normal = vertex_normals[1][(gint) RINT (xf)];
  gimp_vector3_normalize (&normal);

  if (mapvals.transparent_background && heights[1][x] == 0)
    {
      gimp_rgb_set_alpha (&color_sum, 0.0);
    }
  else
    {
      color = peek (RINT (xf), RINT (yf));
      color_sum = color;
      gimp_rgb_multiply (&color_sum, mapvals.material.ambient_int);

      for (k = 0; k < NUM_LIGHTS; k++)
        {
          p = &mapvals.lightsource[k].direction;

          if (!mapvals.lightsource[k].active
              || mapvals.lightsource[k].type == NO_LIGHT)
            continue;
          else if (mapvals.lightsource[k].type == POINT_LIGHT)
            p = &mapvals.lightsource[k].position;

          color_int = mapvals.lightsource[k].color;
          gimp_rgb_multiply (&color_int, mapvals.lightsource[k].intensity);

              light_color = phong_shade (position,
                                         &mapvals.viewpoint,
                                         &normal,
                                         p,
                                         &color,
                                         &color_int,
                                         mapvals.lightsource[0].type);
        }

      gimp_vector3_sub (&v, &mapvals.viewpoint, position);
      gimp_vector3_normalize (&v);

      r = compute_reflected_ray (&normal, &v);

      /* Get color in the direction of r */
      /* =============================== */

      sphere_to_image (&r, &xf, &yf);
      env_color = peek_env_map (RINT (env_width * xf),
                                RINT (env_height * yf));

      tmpval = mapvals.material.diffuse_int;
      mapvals.material.diffuse_int = 0.;

      light_color = phong_shade (position,
                                 &mapvals.viewpoint,
                                 &normal,
                                 &r,
                                 &color,
                                 &env_color,
                                 DIRECTIONAL_LIGHT);

      mapvals.material.diffuse_int = tmpval;

      gimp_rgb_add (&color_sum, &light_color);
    }

 gimp_rgb_clamp (&color_sum);
 return color_sum;
}
示例#6
0
GimpRGB
get_ray_color_no_bilinear (GimpVector3 *position)
{
  GimpRGB       color;
  GimpRGB       color_int;
  GimpRGB       color_sum;
  GimpRGB       light_color;
  gint          x;
  gdouble       xf, yf;
  GimpVector3   normal, *p;
  gint          k;


  pos_to_float (position->x, position->y, &xf, &yf);

  x = RINT (xf);

  if (mapvals.transparent_background && heights[1][x] == 0)
    {
      gimp_rgb_set_alpha (&color_sum, 0.0);
    }
  else
    {
      color = peek (x, RINT (yf));

      color_sum = color;
      gimp_rgb_multiply (&color_sum, mapvals.material.ambient_int);

      for (k = 0; k < NUM_LIGHTS; k++)
        {
          p = &mapvals.lightsource[k].direction;

          if (!mapvals.lightsource[k].active
              || mapvals.lightsource[k].type == NO_LIGHT)
            continue;
          else if (mapvals.lightsource[k].type == POINT_LIGHT)
            p = &mapvals.lightsource[k].position;

          color_int = mapvals.lightsource[k].color;
          gimp_rgb_multiply (&color_int, mapvals.lightsource[k].intensity);

          if (mapvals.bump_mapped == FALSE || mapvals.bumpmap_id == -1)
            {
              light_color = phong_shade (position,
                                         &mapvals.viewpoint,
                                         &mapvals.planenormal,
                                         p,
                                         &color,
                                         &color_int,
                                         mapvals.lightsource[k].type);
            }
          else
            {
              normal = vertex_normals[1][x];

              light_color = phong_shade (position,
                                         &mapvals.viewpoint,
                                         &normal,
                                         p,
                                         &color,
                                         &color_int,
                                         mapvals.lightsource[k].type);
            }

          gimp_rgb_add (&color_sum, &light_color);
        }
    }

  gimp_rgb_clamp (&color_sum);
  return color_sum;
}
示例#7
0
static GimpRGB
phong_shade (GimpVector3 *position,
             GimpVector3 *viewpoint,
             GimpVector3 *normal,
             GimpVector3 *lightposition,
             GimpRGB      *diff_col,
             GimpRGB      *light_col,
             LightType    light_type)
{
  GimpRGB       diffuse_color, specular_color;
  gdouble      nl, rv, dist;
  GimpVector3  l, v, n, lnormal, h;

  /* Compute ambient intensity */
  /* ========================= */

  n = *normal;

  /* Compute (N*L) term of Phong's equation */
  /* ====================================== */

  if (light_type == POINT_LIGHT)
    gimp_vector3_sub (&l, lightposition, position);
  else
    {
      l = *lightposition;
      gimp_vector3_normalize (&l);
    }

  dist = gimp_vector3_length (&l);

  if (dist != 0.0)
    gimp_vector3_mul (&l, 1.0 / dist);

  nl = MAX (0., 2.0 * gimp_vector3_inner_product (&n, &l));

  lnormal = l;
  gimp_vector3_normalize (&lnormal);

  if (nl >= 0.0)
    {
      /* Compute (R*V)^alpha term of Phong's equation */
      /* ============================================ */

      gimp_vector3_sub (&v, viewpoint, position);
      gimp_vector3_normalize (&v);

      gimp_vector3_add (&h, &lnormal, &v);
      gimp_vector3_normalize (&h);

      rv = MAX (0.01, gimp_vector3_inner_product (&n, &h));
      rv = pow (rv, mapvals.material.highlight);
      rv *= nl;

      /* Compute diffuse and specular intensity contribution */
      /* =================================================== */

      diffuse_color = *light_col;
      gimp_rgb_multiply (&diffuse_color, mapvals.material.diffuse_int);
      diffuse_color.r *= diff_col->r;
      diffuse_color.g *= diff_col->g;
      diffuse_color.b *= diff_col->b;
      gimp_rgb_multiply (&diffuse_color, nl);

      specular_color = *light_col;
      if (mapvals.material.metallic)  /* for metals, specular color = diffuse color */
        {
          specular_color.r *= diff_col->r;
          specular_color.g *= diff_col->g;
          specular_color.b *= diff_col->b;
        }
      gimp_rgb_multiply (&specular_color, mapvals.material.specular_ref);
      gimp_rgb_multiply (&specular_color, rv);

      gimp_rgb_add (&diffuse_color, &specular_color);
      gimp_rgb_clamp (&diffuse_color);
    }

  gimp_rgb_clamp (&diffuse_color);

  return diffuse_color;
}