diff --git a/plug-ins/map-object/map-object-apply.c b/plug-ins/map-object/map-object-apply.c index 7a7a81c0fc..fb27040ad2 100644 --- a/plug-ins/map-object/map-object-apply.c +++ b/plug-ins/map-object/map-object-apply.c @@ -187,18 +187,12 @@ render (gdouble x, gpointer data) { GimpVector3 pos; - GimpRGB temp; pos.x = x / (gdouble) width; pos.y = y / (gdouble) height; pos.z = 0.0; - temp = get_ray_color (&pos); - - col[0] = temp.r; - col[1] = temp.g; - col[2] = temp.b; - col[3] = temp.a; + get_ray_color (&pos, col); } static void @@ -219,7 +213,7 @@ void compute_image (void) { gint xcount, ycount; - GimpRGB color; + gdouble color[4]; glong progress_counter = 0; GimpVector3 p; GimpImage *new_image = NULL; @@ -229,13 +223,9 @@ compute_image (void) init_compute (); if (mapvals.create_new_image) - { - new_image = gimp_image_new (width, height, GIMP_RGB); - } + new_image = gimp_image_new (width, height, GIMP_RGB); else - { - new_image = image; - } + new_image = image; gimp_image_undo_group_start (new_image); @@ -289,8 +279,8 @@ compute_image (void) for (xcount = 0; xcount < width; xcount++) { p = int_to_pos (xcount, ycount); - color = (* get_ray_color) (&p); - poke (xcount, ycount, &color, NULL); + (* get_ray_color) (&p, color); + poke (xcount, ycount, color, NULL); progress_counter++; } @@ -307,7 +297,7 @@ compute_image (void) mapvals.pixelthreshold, render, NULL, - poke_adaptive, + poke, NULL, show_progress, NULL); @@ -425,6 +415,6 @@ copy_from_config (GimpProcedureConfig *config) /* TODO: Use GeglColor directly in this plug-in */ gegl_color_get_pixel (color, babl_format ("R'G'B'A double"), - &mapvals.lightsource.color); + mapvals.lightsource.color); g_object_unref (color); } diff --git a/plug-ins/map-object/map-object-image.c b/plug-ins/map-object/map-object-image.c index 5a79b00f43..65dd2928d8 100644 --- a/plug-ins/map-object/map-object-image.c +++ b/plug-ins/map-object/map-object-image.c @@ -42,68 +42,66 @@ cairo_surface_t *preview_surface = NULL; glong maxcounter, old_depth, max_depth; gint width, height; -GimpRGB background; +gdouble background[4]; gint border_x, border_y, border_w, border_h; + +void peek_box_image (gint image, + gint x, + gint y, + gdouble *color); + + /******************/ /* Implementation */ /******************/ -GimpRGB -peek (gint x, - gint y) +void +peek (gint x, + gint y, + gdouble *color) { - GimpRGB color; - gegl_buffer_sample (source_buffer, x, y, NULL, - &color, babl_format ("R'G'B'A double"), + color, babl_format ("R'G'B'A double"), GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE); if (! babl_format_has_alpha (gegl_buffer_get_format (source_buffer))) - color.a = 1.0; - - return color; + color[3] = 1.0; } -static GimpRGB -peek_box_image (gint image, - gint x, - gint y) +void +peek_box_image (gint image, + gint x, + gint y, + gdouble *color) { - GimpRGB color; - gegl_buffer_sample (box_buffers[image], x, y, NULL, - &color, babl_format ("R'G'B'A double"), + color, babl_format ("R'G'B'A double"), GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE); if (! babl_format_has_alpha (gegl_buffer_get_format (box_buffers[image]))) - color.a = 1.0; - - return color; + color[3] = 1.0; } -static GimpRGB -peek_cylinder_image (gint image, - gint x, - gint y) +static void +peek_cylinder_image (gint image, + gint x, + gint y, + gdouble *color) { - GimpRGB color; - gegl_buffer_sample (cylinder_buffers[image], x, y, NULL, - &color, babl_format ("R'G'B'A double"), + color, babl_format ("R'G'B'A double"), GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE); if (! babl_format_has_alpha (gegl_buffer_get_format (cylinder_buffers[image]))) - color.a = 1.0; - - return color; + color[3] = 1.0; } void poke (gint x, gint y, - GimpRGB *color, + gdouble *color, gpointer user_data) { gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (x, y, 1, 1), 0, @@ -111,17 +109,6 @@ poke (gint x, GEGL_AUTO_ROWSTRIDE); } -void -poke_adaptive (gint x, - gint y, - gdouble *color, - gpointer user_data) -{ - gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (x, y, 1, 1), 0, - babl_format ("R'G'B'A double"), color, - GEGL_AUTO_ROWSTRIDE); -} - gint checkbounds (gint x, gint y) @@ -195,18 +182,17 @@ pos_to_int (gdouble x, /* Quartics bilinear interpolation stuff. */ /**********************************************/ -GimpRGB +void get_image_color (gdouble u, gdouble v, - gint *inside) + gint *inside, + gdouble *color) { gint x1; gint y1; gint x2; gint y2; - GimpRGB p[4]; - GimpRGB p_rgba; - gdouble pixel[4]; + gdouble p[4]; gdouble pixels[16]; pos_to_int (u, v, &x1, &y1); @@ -224,31 +210,32 @@ get_image_color (gdouble u, x2 = (x1 + 1) % width; y2 = (y1 + 1) % height; - p[0] = peek (x1, y1); - p[1] = peek (x2, y1); - p[2] = peek (x1, y2); - p[3] = peek (x2, y2); - + peek (x1, y1, p); for (gint i = 0; i < 4; i++) - { - pixels[(i * 4)] = p[i].r; - pixels[(i * 4) + 1] = p[i].g; - pixels[(i * 4) + 2] = p[i].b; - pixels[(i * 4) + 3] = p[i].a; - } + pixels[i] = p[i]; + peek (x2, y1, p); + for (gint i = 0; i < 4; i++) + pixels[i + 4] = p[i]; + peek (x1, y2, p); + for (gint i = 0; i < 4; i++) + pixels[i + 8] = p[i]; + peek (x2, y2, p); + for (gint i = 0; i < 4; i++) + pixels[i + 12] = p[i]; - gimp_bilinear_rgb (u * width, v * height, pixels, TRUE, pixel); + gimp_bilinear_rgb (u * width, v * height, pixels, TRUE, color); - gimp_rgba_set (&p_rgba, pixel[0], pixel[1], pixel[2], pixel[3]); - - return p_rgba; + return; } if (checkbounds (x1, y1) == FALSE) { *inside =FALSE; - return background; + for (gint i = 0; i < 4; i++) + color[i] = background[i]; + + return; } x2 = (x1 + 1); @@ -258,35 +245,32 @@ get_image_color (gdouble u, { *inside = TRUE; - return peek (x1, y1); + return peek (x1, y1, color); } *inside = TRUE; - p[0] = peek (x1, y1); - p[1] = peek (x2, y1); - p[2] = peek (x1, y2); - p[3] = peek (x2, y2); - + peek (x1, y1, p); for (gint i = 0; i < 4; i++) - { - pixels[(i * 4)] = p[i].r; - pixels[(i * 4) + 1] = p[i].g; - pixels[(i * 4) + 2] = p[i].b; - pixels[(i * 4) + 3] = p[i].a; - } + pixels[i] = p[i]; + peek (x2, y1, p); + for (gint i = 0; i < 4; i++) + pixels[i + 4] = p[i]; + peek (x1, y2, p); + for (gint i = 0; i < 4; i++) + pixels[i + 8] = p[i]; + peek (x2, y2, p); + for (gint i = 0; i < 4; i++) + pixels[i + 12] = p[i]; - gimp_bilinear_rgb (u * width, v * height, pixels, TRUE, pixel); - - gimp_rgba_set (&p_rgba, pixel[0], pixel[1], pixel[2], pixel[3]); - - return p_rgba; + gimp_bilinear_rgb (u * width, v * height, pixels, TRUE, color); } -GimpRGB -get_box_image_color (gint image, - gdouble u, - gdouble v) +void +get_box_image_color (gint image, + gdouble u, + gdouble v, + gdouble *color) { gint w; gint h; @@ -294,9 +278,7 @@ get_box_image_color (gint image, gint y1; gint x2; gint y2; - GimpRGB p[4]; - GimpRGB p_rgba; - gdouble pixel[4]; + gdouble p[4]; gdouble pixels[16]; w = gegl_buffer_get_width (box_buffers[image]); @@ -306,38 +288,40 @@ get_box_image_color (gint image, y1 = (gint) ((v * (gdouble) h)); if (checkbounds_box_image (image, x1, y1) == FALSE) - return background; + { + for (gint i = 0; i < 4; i++) + color[i] = background[i]; + + return; + } x2 = (x1 + 1); y2 = (y1 + 1); if (checkbounds_box_image (image, x2, y2) == FALSE) - return peek_box_image (image, x1,y1); - - p[0] = peek_box_image (image, x1, y1); - p[1] = peek_box_image (image, x2, y1); - p[2] = peek_box_image (image, x1, y2); - p[3] = peek_box_image (image, x2, y2); + return peek_box_image (image, x1, y1, color); + peek_box_image (image, x1, y1, p); for (gint i = 0; i < 4; i++) - { - pixels[(i * 4)] = p[i].r; - pixels[(i * 4) + 1] = p[i].g; - pixels[(i * 4) + 2] = p[i].b; - pixels[(i * 4) + 3] = p[i].a; - } + pixels[i] = p[i]; + peek_box_image (image, x2, y1, p); + for (gint i = 0; i < 4; i++) + pixels[i + 4] = p[i]; + peek_box_image (image, x1, y2, p); + for (gint i = 0; i < 4; i++) + pixels[i + 8] = p[i]; + peek_box_image (image, x2, y2, p); + for (gint i = 0; i < 4; i++) + pixels[i + 12] = p[i]; - gimp_bilinear_rgb (u * w, v * h, pixels, TRUE, pixel); - - gimp_rgba_set (&p_rgba, pixel[0], pixel[1], pixel[2], pixel[3]); - - return p_rgba; + gimp_bilinear_rgb (u * w, v * w, pixels, TRUE, color); } -GimpRGB -get_cylinder_image_color (gint image, - gdouble u, - gdouble v) +void +get_cylinder_image_color (gint image, + gdouble u, + gdouble v, + gdouble *color) { gint w; gint h; @@ -345,9 +329,7 @@ get_cylinder_image_color (gint image, gint y1; gint x2; gint y2; - GimpRGB p[4]; - GimpRGB p_rgba; - gdouble pixel[4]; + gdouble p[4]; gdouble pixels[16]; w = gegl_buffer_get_width (cylinder_buffers[image]); @@ -357,32 +339,33 @@ get_cylinder_image_color (gint image, y1 = (gint) ((v * (gdouble) h)); if (checkbounds_cylinder_image (image, x1, y1) == FALSE) - return background; + { + for (gint i = 0; i < 4; i++) + color[i] = background[i]; + + return; + } x2 = (x1 + 1); y2 = (y1 + 1); if (checkbounds_cylinder_image (image, x2, y2) == FALSE) - return peek_cylinder_image (image, x1,y1); - - p[0] = peek_cylinder_image (image, x1, y1); - p[1] = peek_cylinder_image (image, x2, y1); - p[2] = peek_cylinder_image (image, x1, y2); - p[3] = peek_cylinder_image (image, x2, y2); + return peek_cylinder_image (image, x1, y1, color); + peek_cylinder_image (image, x1, y1, p); for (gint i = 0; i < 4; i++) - { - pixels[(i * 4)] = p[i].r; - pixels[(i * 4) + 1] = p[i].g; - pixels[(i * 4) + 2] = p[i].b; - pixels[(i * 4) + 3] = p[i].a; - } + pixels[i] = p[i]; + peek_cylinder_image (image, x2, y1, p); + for (gint i = 0; i < 4; i++) + pixels[i + 4] = p[i]; + peek_cylinder_image (image, x1, y2, p); + for (gint i = 0; i < 4; i++) + pixels[i + 8] = p[i]; + peek_cylinder_image (image, x2, y2, p); + for (gint i = 0; i < 4; i++) + pixels[i + 12] = p[i]; - gimp_bilinear_rgb (u * w, v * h, pixels, TRUE, pixel); - - gimp_rgba_set (&p_rgba, pixel[0], pixel[1], pixel[2], pixel[3]); - - return p_rgba; + gimp_bilinear_rgb (u * w, v * h, pixels, TRUE, color); } /****************************************/ @@ -416,7 +399,8 @@ image_setup (GimpDrawable *drawable, if (transparent_background == TRUE) { - gimp_rgba_set (&background, 0.0, 0.0, 0.0, 0.0); + for (gint i = 0; i < 4; i++) + background[i] = 0; } else { @@ -424,7 +408,8 @@ image_setup (GimpDrawable *drawable, gegl_color = gimp_context_get_background (); gimp_color_set_alpha (gegl_color, 1.0); - gegl_color_get_rgba_with_space (gegl_color, &background.r, &background.g, &background.b, &background.a, NULL); + gegl_color_get_rgba_with_space (gegl_color, &background[0], &background[1], + &background[2], &background[3], NULL); g_object_unref (gegl_color); } diff --git a/plug-ins/map-object/map-object-image.h b/plug-ins/map-object/map-object-image.h index d99247bee3..4260b62aa6 100644 --- a/plug-ins/map-object/map-object-image.h +++ b/plug-ins/map-object/map-object-image.h @@ -23,7 +23,7 @@ extern cairo_surface_t *preview_surface; extern glong maxcounter, old_depth, max_depth; extern gint width, height; -extern GimpRGB background; +extern gdouble background[4]; extern gint border_x1, border_y1, border_x2, border_y2; @@ -40,14 +40,10 @@ extern glong out_xy_to_index (gint x, gint y); extern gint checkbounds (gint x, gint y); -extern GimpRGB peek (gint x, - gint y); -extern void poke (gint x, +extern void peek (gint x, gint y, - GimpRGB *color, - gpointer user_data); -/* TODO: Merge back with poke when removing GimpRGB fully */ -extern void poke_adaptive (gint x, + gdouble *color); +extern void poke (gint x, gint y, gdouble *color, gpointer user_data); @@ -58,14 +54,17 @@ extern void pos_to_int (gdouble x, gint *scr_x, gint *scr_y); -extern GimpRGB get_image_color (gdouble u, +extern void get_image_color (gdouble u, gdouble v, - gint *inside); -extern GimpRGB get_box_image_color (gint image, + gint *inside, + gdouble *color); +extern void get_box_image_color (gint image, gdouble u, - gdouble v); -extern GimpRGB get_cylinder_image_color (gint image, + gdouble v, + gdouble *color); +extern void get_cylinder_image_color (gint image, gdouble u, - gdouble v); + gdouble v, + gdouble *color); #endif /* __MAPOBJECT_IMAGE_H__ */ diff --git a/plug-ins/map-object/map-object-main.c b/plug-ins/map-object/map-object-main.c index ac69a28cc2..13e731cdef 100644 --- a/plug-ins/map-object/map-object-main.c +++ b/plug-ins/map-object/map-object-main.c @@ -471,7 +471,8 @@ set_default_settings (void) mapvals.showgrid = TRUE; mapvals.lightsource.intensity = 1.0; - gimp_rgba_set (&mapvals.lightsource.color, 1.0, 1.0, 1.0, 1.0); + for (i = 0; i < 4; i++) + mapvals.lightsource.color[i] = 1.0; mapvals.material.ambient_int = 0.3; mapvals.material.diffuse_int = 1.0; diff --git a/plug-ins/map-object/map-object-main.h b/plug-ins/map-object/map-object-main.h index 5958c7cd8e..686e505f53 100644 --- a/plug-ins/map-object/map-object-main.h +++ b/plug-ins/map-object/map-object-main.h @@ -28,6 +28,12 @@ typedef enum MAP_CYLINDER } MapType; +typedef enum +{ + COMPOSITE_NORMAL, + COMPOSITE_BEHIND, +} CompositeType; + /* Typedefs */ /* ======== */ @@ -38,7 +44,7 @@ typedef struct gdouble diffuse_ref; gdouble specular_ref; gdouble highlight; - GimpRGB color; + gdouble color[4]; } MaterialSettings; typedef struct @@ -46,7 +52,7 @@ typedef struct LightType type; GimpVector3 position; GimpVector3 direction; - GimpRGB color; + gdouble color[4]; gdouble intensity; } LightSettings; diff --git a/plug-ins/map-object/map-object-preview.c b/plug-ins/map-object/map-object-preview.c index d572b084e7..36bb66252e 100644 --- a/plug-ins/map-object/map-object-preview.c +++ b/plug-ins/map-object/map-object-preview.c @@ -88,8 +88,9 @@ compute_preview (gint x, gdouble realw; gdouble realh; GimpVector3 p1, p2; - GimpRGB color; - GimpRGB lightcheck, darkcheck; + gdouble color[4]; + gdouble lightcheck[4] = { GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT, 1.0 }; + gdouble darkcheck[4] = { GIMP_CHECK_DARK, GIMP_CHECK_DARK, GIMP_CHECK_DARK, 1.0 }; gint xcnt, ycnt, f1, f2; guchar r, g, b; glong index = 0; @@ -119,7 +120,8 @@ compute_preview (gint x, if (mapvals.transparent_background == TRUE) { - gimp_rgba_set (&background, 0.0, 0.0, 0.0, 0.0); + for (gint i = 0; i < 4; i++) + background[i] = 0.0; } else { @@ -127,15 +129,12 @@ compute_preview (gint x, gegl_color = gimp_context_get_background (); gimp_color_set_alpha (gegl_color, 1.0); - gegl_color_get_rgba_with_space (gegl_color, &background.r, &background.g, &background.b, &background.a, NULL); + gegl_color_get_rgba_with_space (gegl_color, &background[0], &background[1], + &background[2], &background[3], NULL); g_object_unref (gegl_color); } - 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); cairo_surface_flush (preview_surface); @@ -149,9 +148,9 @@ compute_preview (gint x, p1.y = ypostab[ycnt]; p2 = p1; - color = (* get_ray_color) (&p1); + (* get_ray_color) (&p1, color); - if (color.a < 1.0) + if (color[3] < 1.0) { f1 = ((xcnt % 32) < 16); f2 = ((ycnt % 32) < 16); @@ -159,23 +158,33 @@ compute_preview (gint x, if (f1) { - if (color.a == 0.0) - color = lightcheck; + if (color[3] == 0.0) + { + for (gint i = 0; i < 4; i++) + color[i] = lightcheck[i]; + } else - gimp_rgb_composite (&color, &lightcheck, - GIMP_RGB_COMPOSITE_BEHIND); + { + composite (color, lightcheck, COMPOSITE_BEHIND); + } } else { - if (color.a == 0.0) - color = darkcheck; + if (color[3] == 0.0) + { + for (gint i = 0; i < 4; i++) + color[i] = darkcheck[i]; + } else - gimp_rgb_composite (&color, &darkcheck, - GIMP_RGB_COMPOSITE_BEHIND); + { + composite (color, darkcheck, COMPOSITE_BEHIND); + } } } - gimp_rgb_get_uchar (&color, &r, &g, &b); + r = (guchar) (color[0] * 255); + g = (guchar) (color[1] * 255); + b = (guchar) (color[2] * 255); GIMP_CAIRO_RGB24_SET_PIXEL((preview_rgb_data + index), r, g, b); index += 4; } diff --git a/plug-ins/map-object/map-object-shade.c b/plug-ins/map-object/map-object-shade.c index f91345b0e1..409faacd8e 100644 --- a/plug-ins/map-object/map-object-shade.c +++ b/plug-ins/map-object/map-object-shade.c @@ -31,17 +31,17 @@ typedef struct /* Phong shading */ /*****************/ -static GimpRGB +static void phong_shade (GimpVector3 *pos, GimpVector3 *viewpoint, GimpVector3 *normal, - GimpRGB *diff_col, - GimpRGB *spec_col, + gdouble *diff_col, + gdouble *spec_col, LightType type) { - GimpRGB ambientcolor, diffusecolor, specularcolor; - gdouble NL, RV, dist; - GimpVector3 L, NN, V, N; + gdouble ambientcolor[4], diffusecolor[4], specularcolor[4]; + gdouble NL, RV, dist; + GimpVector3 L, NN, V, N; GimpVector3 *light; light = mapvals.lightsource.type == DIRECTIONAL_LIGHT @@ -52,8 +52,10 @@ phong_shade (GimpVector3 *pos, /* ========================= */ N = *normal; - ambientcolor = *diff_col; - gimp_rgb_multiply (&ambientcolor, mapvals.material.ambient_int); + for (gint i = 0; i < 4; i++) + ambientcolor[i] = diff_col[i]; + for (gint i = 0; i < 3; i++) + ambientcolor[i] *= mapvals.material.ambient_int; /* Compute (N*L) term of Phong's equation */ /* ====================================== */ @@ -86,22 +88,33 @@ phong_shade (GimpVector3 *pos, /* Compute diffuse and specular intensity contribution */ /* =================================================== */ - diffusecolor = *diff_col; - gimp_rgb_multiply (&diffusecolor, mapvals.material.diffuse_ref); - gimp_rgb_multiply (&diffusecolor, NL); + for (gint i = 0; i < 4; i++) + diffusecolor[i] = diff_col[i]; + for (gint i = 0; i < 3; i++) + { + diffusecolor[i] *= mapvals.material.diffuse_ref; + diffusecolor[i] *= NL; + } - specularcolor = *spec_col; - gimp_rgb_multiply (&specularcolor, mapvals.material.specular_ref); - gimp_rgb_multiply (&specularcolor, RV); + for (gint i = 0; i < 4; i++) + specularcolor[i] = spec_col[i]; + for (gint i = 0; i < 3; i++) + { + specularcolor[i] *= mapvals.material.specular_ref; + specularcolor[i] *= RV; + } - gimp_rgb_add (&diffusecolor, &specularcolor); - gimp_rgb_multiply (&diffusecolor, mapvals.material.diffuse_int); - gimp_rgb_clamp (&diffusecolor); - - gimp_rgb_add (&ambientcolor, &diffusecolor); + for (gint i = 0; i < 3; i++) + { + diffusecolor[i] += specularcolor[i]; + diffusecolor[i] *= mapvals.material.diffuse_int; + diffusecolor[i] = CLAMP (diffusecolor[i], 0.0, 1.0); + ambientcolor[i] += diffusecolor[i]; + } } - return ambientcolor; + for (gint i = 0; i < 4; i++) + diff_col[i] = ambientcolor[i]; } static gint @@ -183,11 +196,10 @@ plane_intersect (GimpVector3 *dir, * of the plane at a given point *****************************************************************************/ -GimpRGB -get_ray_color_plane (GimpVector3 *pos) +void +get_ray_color_plane (GimpVector3 *pos, + gdouble *color) { - GimpRGB color = background; - static gint inside = FALSE; static GimpVector3 ray, spos; static gdouble vx, vy; @@ -195,6 +207,9 @@ get_ray_color_plane (GimpVector3 *pos) /* Construct a line from our VP to the point */ /* ========================================= */ + for (gint i = 0; i < 4; i++) + color[i] = background[i]; + gimp_vector3_sub (&ray, pos, &mapvals.viewpoint); gimp_vector3_normalize (&ray); @@ -203,32 +218,28 @@ get_ray_color_plane (GimpVector3 *pos) if (plane_intersect (&ray, &mapvals.viewpoint, &spos, &vx, &vy) == TRUE) { - color = get_image_color (vx, vy, &inside); + get_image_color (vx, vy, &inside, color); - if (color.a != 0.0 && inside == TRUE && + if (color[3] != 0.0 && inside == TRUE && mapvals.lightsource.type != NO_LIGHT) { /* Compute shading at this point */ /* ============================= */ - color = phong_shade (&spos, - &mapvals.viewpoint, - &mapvals.normal, - &color, - &mapvals.lightsource.color, - mapvals.lightsource.type); + phong_shade (&spos, + &mapvals.viewpoint, + &mapvals.normal, + color, + mapvals.lightsource.color, + mapvals.lightsource.type); - gimp_rgb_clamp (&color); + for (gint i = 0; i < 4; i++) + color[i] = CLAMP (color[i], 0.0, 1.0); } } - if (mapvals.transparent_background == FALSE && color.a < 1.0) - { - gimp_rgb_composite (&color, &background, - GIMP_RGB_COMPOSITE_BEHIND); - } - - return color; + if (mapvals.transparent_background == FALSE && color[3] < 1.0) + composite (color, background, COMPOSITE_BEHIND); } /***********************************************************************/ @@ -323,21 +334,22 @@ sphere_intersect (GimpVector3 *dir, * of the sphere at a given point *****************************************************************************/ -GimpRGB -get_ray_color_sphere (GimpVector3 *pos) +void +get_ray_color_sphere (GimpVector3 *pos, + gdouble *color) { - GimpRGB color = background; - - static GimpRGB color2; + static gdouble color2[4]; static gint inside = FALSE; static GimpVector3 normal, ray, spos1, spos2; static gdouble vx, vy; + for (gint i = 0; i < 4; i++) + color[i] = background[i]; /* Check if ray is within the bounding box */ /* ======================================= */ if (pos->xx>bx2 || pos->yy>by2) - return color; + return; /* Construct a line from our VP to the point */ /* ========================================= */ @@ -356,76 +368,75 @@ get_ray_color_sphere (GimpVector3 *pos) gimp_vector3_sub (&normal, &spos1, &mapvals.position); gimp_vector3_normalize (&normal); sphere_to_image (&normal, &vx, &vy); - color = get_image_color (vx, vy, &inside); + get_image_color (vx, vy, &inside, color); /* Check for total transparency... */ /* =============================== */ - if (color.a < 1.0) + if (color[3] < 1.0) { /* Hey, we can see through here! */ /* Lets see what's on the other side.. */ /* =================================== */ - color = phong_shade (&spos1, - &mapvals.viewpoint, - &normal, - &color, - &mapvals.lightsource.color, - mapvals.lightsource.type); + phong_shade (&spos1, + &mapvals.viewpoint, + &normal, + color, + mapvals.lightsource.color, + mapvals.lightsource.type); - gimp_rgb_clamp (&color); + for (gint i = 0; i < 4; i++) + color[i] = CLAMP (color[i], 0.0, 1.0); gimp_vector3_sub (&normal, &spos2, &mapvals.position); gimp_vector3_normalize (&normal); sphere_to_image (&normal, &vx, &vy); - color2 = get_image_color (vx, vy, &inside); + get_image_color (vx, vy, &inside, color2); /* Make the normal point inwards */ /* ============================= */ gimp_vector3_mul (&normal, -1.0); - color2 = phong_shade (&spos2, - &mapvals.viewpoint, - &normal, - &color2, - &mapvals.lightsource.color, - mapvals.lightsource.type); + phong_shade (&spos2, + &mapvals.viewpoint, + &normal, + color2, + mapvals.lightsource.color, + mapvals.lightsource.type); - gimp_rgb_clamp (&color2); + for (gint i = 0; i < 4; i++) + color2[i] = CLAMP (color2[i], 0.0, 1.0); /* Compute a mix of the first and second colors */ /* ============================================ */ - gimp_rgb_composite (&color, &color2, GIMP_RGB_COMPOSITE_NORMAL); - gimp_rgb_clamp (&color); + composite (color, color2, COMPOSITE_NORMAL); + for (gint i = 0; i < 4; i++) + color[i] = CLAMP (color[i], 0.0, 1.0); } - else if (color.a != 0.0 && + else if (color[3] != 0.0 && inside == TRUE && mapvals.lightsource.type != NO_LIGHT) { /* Compute shading at this point */ /* ============================= */ - color = phong_shade (&spos1, - &mapvals.viewpoint, - &normal, - &color, - &mapvals.lightsource.color, - mapvals.lightsource.type); + phong_shade (&spos1, + &mapvals.viewpoint, + &normal, + color, + mapvals.lightsource.color, + mapvals.lightsource.type); - gimp_rgb_clamp (&color); + for (gint i = 0; i < 4; i++) + color[i] = CLAMP (color[i], 0.0, 1.0); } } - if (mapvals.transparent_background == FALSE && color.a < 1.0) - { - gimp_rgb_composite (&color, &background, - GIMP_RGB_COMPOSITE_BEHIND); - } - - return color; + if (mapvals.transparent_background == FALSE && color[3] < 1.0) + composite (color, background, COMPOSITE_BEHIND); } /***************************************************/ @@ -834,16 +845,19 @@ intersect_box (GimpVector3 scale, return result; } -GimpRGB -get_ray_color_box (GimpVector3 *pos) +void +get_ray_color_box (GimpVector3 *pos, + gdouble *color) { GimpVector3 lvp, ldir, vp, p, dir, ns, nn; - GimpRGB color, color2; + gdouble color2[4]; gfloat m[16]; gint i; FaceIntersectInfo face_intersect[2]; - color = background; + for (i = 0; i < 4; i++) + color[i] = background[i]; + vp = mapvals.viewpoint; p = *pos; @@ -904,77 +918,78 @@ get_ray_color_box (GimpVector3 *pos) face_intersect[i].n = nn; } - color = get_box_image_color (face_intersect[0].face, - face_intersect[0].u, - face_intersect[0].v); + get_box_image_color (face_intersect[0].face, + face_intersect[0].u, + face_intersect[0].v, + color); /* Check for total transparency... */ /* =============================== */ - if (color.a < 1.0) + if (color[3] < 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, - &color, - &mapvals.lightsource.color, - mapvals.lightsource.type); + phong_shade (&face_intersect[0].s, + &mapvals.viewpoint, + &face_intersect[0].n, + color, + mapvals.lightsource.color, + mapvals.lightsource.type); - gimp_rgb_clamp (&color); + for (gint i = 0; i < 4; i++) + color[i] = CLAMP (color[i], 0.0, 1.0); - color2 = get_box_image_color (face_intersect[1].face, - face_intersect[1].u, - face_intersect[1].v); + get_box_image_color (face_intersect[1].face, + face_intersect[1].u, + face_intersect[1].v, + color2); /* 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, - &color2, - &mapvals.lightsource.color, - mapvals.lightsource.type); + phong_shade (&face_intersect[1].s, + &mapvals.viewpoint, + &face_intersect[1].n, + color2, + mapvals.lightsource.color, + mapvals.lightsource.type); - gimp_rgb_clamp (&color2); + for (gint i = 0; i < 4; i++) + color2[i] = CLAMP (color2[i], 0.0, 1.0); - if (mapvals.transparent_background == FALSE && color2.a < 1.0) - { - gimp_rgb_composite (&color2, &background, - GIMP_RGB_COMPOSITE_BEHIND); - } + if (mapvals.transparent_background == FALSE && color2[3] < 1.0) + composite (color2, background, COMPOSITE_BEHIND); /* Compute a mix of the first and second colors */ /* ============================================ */ - gimp_rgb_composite (&color, &color2, GIMP_RGB_COMPOSITE_NORMAL); - gimp_rgb_clamp (&color); + composite (color, color2, COMPOSITE_NORMAL); + for (gint i = 0; i < 4; i++) + color[i] = CLAMP (color[i], 0.0, 1.0); } - else if (color.a != 0.0 && mapvals.lightsource.type != NO_LIGHT) + else if (color[3] != 0.0 && mapvals.lightsource.type != NO_LIGHT) { - color = phong_shade (&face_intersect[0].s, - &mapvals.viewpoint, - &face_intersect[0].n, - &color, - &mapvals.lightsource.color, - mapvals.lightsource.type); + phong_shade (&face_intersect[0].s, + &mapvals.viewpoint, + &face_intersect[0].n, + color, + mapvals.lightsource.color, + mapvals.lightsource.type); - gimp_rgb_clamp (&color); + for (gint i = 0; i < 4; i++) + color[i] = CLAMP (color[i], 0.0, 1.0); } } else { if (mapvals.transparent_background == TRUE) - gimp_rgb_set_alpha (&color, 0.0); + color[3] = 0.0; } - - return color; } static gboolean @@ -1106,32 +1121,32 @@ intersect_cylinder (GimpVector3 vp, return result; } -static GimpRGB -get_cylinder_color (gint face, - gdouble u, - gdouble v) +static void +get_cylinder_color (gint face, + gdouble u, + gdouble v, + gdouble *color) { - GimpRGB color; - gint inside; + gint inside; if (face == 0) - color = get_image_color (u, v, &inside); + get_image_color (u, v, &inside, color); else - color = get_cylinder_image_color (face - 1, u, v); - - return color; + get_cylinder_image_color (face - 1, u, v, color); } -GimpRGB -get_ray_color_cylinder (GimpVector3 *pos) +void +get_ray_color_cylinder (GimpVector3 *pos, + gdouble *color) { GimpVector3 lvp, ldir, vp, p, dir, ns, nn; - GimpRGB color, color2; + gdouble color2[4]; gfloat m[16]; gint i; FaceIntersectInfo face_intersect[2]; - color = background; + for (i = 0; i < 4; i++) + color[i] = background[i]; vp = mapvals.viewpoint; p = *pos; @@ -1180,75 +1195,117 @@ get_ray_color_cylinder (GimpVector3 *pos) face_intersect[i].n = nn; } - color = get_cylinder_color (face_intersect[0].face, - face_intersect[0].u, - face_intersect[0].v); + get_cylinder_color (face_intersect[0].face, + face_intersect[0].u, + face_intersect[0].v, + color); /* Check for transparency... */ /* ========================= */ - if (color.a < 1.0) + if (color[3] < 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, - &color, - &mapvals.lightsource.color, - mapvals.lightsource.type); + phong_shade (&face_intersect[0].s, + &mapvals.viewpoint, + &face_intersect[0].n, + color, + mapvals.lightsource.color, + mapvals.lightsource.type); - gimp_rgb_clamp (&color); + for (gint i = 0; i < 4; i++) + color[i] = CLAMP (color[i], 0.0, 1.0); - color2 = get_cylinder_color (face_intersect[1].face, - face_intersect[1].u, - face_intersect[1].v); + get_cylinder_color (face_intersect[1].face, + face_intersect[1].u, + face_intersect[1].v, + color2); /* 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, - &color2, - &mapvals.lightsource.color, - mapvals.lightsource.type); + phong_shade (&face_intersect[1].s, + &mapvals.viewpoint, + &face_intersect[1].n, + color2, + mapvals.lightsource.color, + mapvals.lightsource.type); - gimp_rgb_clamp (&color2); + for (gint i = 0; i < 4; i++) + color2[i] = CLAMP (color2[i], 0.0, 1.0); - if (mapvals.transparent_background == FALSE && color2.a < 1.0) - { - gimp_rgb_composite (&color2, &background, - GIMP_RGB_COMPOSITE_BEHIND); - } + if (mapvals.transparent_background == FALSE && color2[3] < 1.0) + composite (color2, background, COMPOSITE_BEHIND); /* Compute a mix of the first and second colors */ /* ============================================ */ - gimp_rgb_composite (&color, &color2, GIMP_RGB_COMPOSITE_NORMAL); - gimp_rgb_clamp (&color); + composite (color, color2, COMPOSITE_NORMAL); + for (gint i = 0; i < 4; i++) + color[i] = CLAMP (color[i], 0.0, 1.0); } - else if (color.a != 0.0 && mapvals.lightsource.type != NO_LIGHT) + else if (color[3] != 0.0 && mapvals.lightsource.type != NO_LIGHT) { - color = phong_shade (&face_intersect[0].s, - &mapvals.viewpoint, - &face_intersect[0].n, - &color, - &mapvals.lightsource.color, - mapvals.lightsource.type); + phong_shade (&face_intersect[0].s, + &mapvals.viewpoint, + &face_intersect[0].n, + color, + mapvals.lightsource.color, + mapvals.lightsource.type); - gimp_rgb_clamp (&color); + for (gint i = 0; i < 4; i++) + color[i] = CLAMP (color[i], 0.0, 1.0); } } else { if (mapvals.transparent_background == TRUE) - gimp_rgb_set_alpha (&color, 0.0); + color[3] = 0.0; + } +} + +void +composite (gdouble *color1, + gdouble *color2, + CompositeType composite) +{ + g_return_if_fail (color1 != NULL); + g_return_if_fail (color2 != NULL); + + if (composite == COMPOSITE_NORMAL) + { + /* put color2 on top of color1 */ + if (color2[3] == 1.0) + { + for (gint i = 0; i < 4; i++) + color1[i] = color2[i]; + } + else + { + gdouble factor = color1[3] * (1.0 - color2[3]); + + color1[0] = color1[0] * factor + color2[0] * color2[3]; + color1[1] = color1[1] * factor + color2[1] * color2[3]; + color1[2] = color1[2] * factor + color2[2] * color2[3]; + color1[3] = factor + color2[3]; + } + } + else if (composite == COMPOSITE_BEHIND) + { + /* put color2 below color1 */ + if (color1[3] < 1.0) + { + gdouble factor = color2[3] * (1.0 - color1[3]); + + color1[0] = color2[0] * factor + color1[0] * color1[3]; + color1[1] = color2[1] * factor + color1[1] * color1[3]; + color1[2] = color2[2] * factor + color1[2] * color1[3]; + color1[3] = factor + color1[3]; + } } - - return color; } diff --git a/plug-ins/map-object/map-object-shade.h b/plug-ins/map-object/map-object-shade.h index 259e5ebdce..367308347e 100644 --- a/plug-ins/map-object/map-object-shade.h +++ b/plug-ins/map-object/map-object-shade.h @@ -1,26 +1,35 @@ #ifndef __MAPOBJECT_SHADE_H__ #define __MAPOBJECT_SHADE_H__ -typedef GimpRGB (* get_ray_color_func) (GimpVector3 *pos); +typedef void (* get_ray_color_func) (GimpVector3 *pos, + gdouble *color); extern get_ray_color_func get_ray_color; -GimpRGB get_ray_color_plane (GimpVector3 *pos); -GimpRGB get_ray_color_sphere (GimpVector3 *pos); -GimpRGB get_ray_color_box (GimpVector3 *pos); -GimpRGB get_ray_color_cylinder (GimpVector3 *pos); +void get_ray_color_plane (GimpVector3 *pos, + gdouble *color); +void get_ray_color_sphere (GimpVector3 *pos, + gdouble *color); +void get_ray_color_box (GimpVector3 *pos, + gdouble *color); +void get_ray_color_cylinder (GimpVector3 *pos, + gdouble *color); void compute_bounding_box (void); -void vecmulmat (GimpVector3 *u, - GimpVector3 *v, - gfloat m[16]); -void rotatemat (gfloat angle, - GimpVector3 *v, - gfloat m[16]); -void transpose_mat (gfloat m[16]); -void matmul (gfloat a[16], - gfloat b[16], - gfloat c[16]); -void ident_mat (gfloat m[16]); +void vecmulmat (GimpVector3 *u, + GimpVector3 *v, + gfloat m[16]); +void rotatemat (gfloat angle, + GimpVector3 *v, + gfloat m[16]); +void transpose_mat (gfloat m[16]); +void matmul (gfloat a[16], + gfloat b[16], + gfloat c[16]); +void ident_mat (gfloat m[16]); + +void composite (gdouble *color1, + gdouble *color2, + CompositeType mode); #endif /* __MAPOBJECT_SHADE_H__ */