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; }
static VALUE rb_gimp_rgb_add (VALUE self, VALUE other) { GimpRGB result = rb2GimpRGB(self); gimp_rgb_add(&result, rb2GimpRGBPtr(other)); return GimpRGB2rb(&result); }
/* 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); } }
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; }
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; }
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; }
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; }