Commit eaed92e7 authored by Michael Natterer's avatar Michael Natterer 😴

plug-ins: port lighting to GEGL

parent 75114b1c
......@@ -59,6 +59,7 @@ LDADD = \
$(libgimpmath) \
$(libgimpbase) \
$(GTK_LIBS) \
$(GEGL_LIBS) \
$(RT_LIBS) \
$(INTLLIBS) \
$(lighting_RC)
......@@ -24,7 +24,7 @@ void
compute_image (void)
{
gint xcount, ycount;
GimpRGB color;
GimpRGB color;
glong progress_counter = 0;
GimpVector3 p;
gint32 new_image_id = -1;
......@@ -35,11 +35,9 @@ compute_image (void)
gboolean has_alpha;
get_ray_func ray_func;
if (mapvals.create_new_image == TRUE ||
(mapvals.transparent_background == TRUE &&
! gimp_drawable_has_alpha (input_drawable->drawable_id)))
! gimp_drawable_has_alpha (input_drawable_id)))
{
/* Create a new image */
/* ================== */
......@@ -70,35 +68,33 @@ compute_image (void)
}
gimp_image_insert_layer (new_image_id, new_layer_id, -1, 0);
output_drawable = gimp_drawable_get (new_layer_id);
output_drawable_id = new_layer_id;
}
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);
bumpmap_setup (mapvals.bumpmap_id);
}
precompute_init (width, height);
if (!mapvals.env_mapped || mapvals.envmap_id == -1)
if (! mapvals.env_mapped || mapvals.envmap_id == -1)
{
ray_func = get_ray_color;
}
else
{
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);
envmap_setup (mapvals.envmap_id);
ray_func = get_ray_color_ref;
}
gimp_pixel_rgn_init (&dest_region, output_drawable,
0, 0, width, height, TRUE, TRUE);
dest_buffer = gimp_drawable_get_shadow_buffer (output_drawable_id);
obpp = gimp_drawable_bpp (output_drawable->drawable_id);
has_alpha = gimp_drawable_has_alpha (output_drawable->drawable_id);
has_alpha = gimp_drawable_has_alpha (output_drawable_id);
/* FIXME */
obpp = has_alpha ? 4 : 3; //gimp_drawable_bpp (output_drawable_id);
row = g_new (guchar, obpp * width);
......@@ -127,30 +123,32 @@ compute_image (void)
if (has_alpha)
row[index++] = (guchar) (color.a * 255.0);
if ((progress_counter++ % width) == 0)
gimp_progress_update ((gdouble) progress_counter /
(gdouble) maxcounter);
progress_counter++;
}
gimp_pixel_rgn_set_row (&dest_region, row, 0, ycount, width);
gimp_progress_update ((gdouble) progress_counter /
(gdouble) maxcounter);
gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (0, ycount, width, 1), 0,
has_alpha ?
babl_format ("R'G'B'A u8") : babl_format ("R'G'B' u8"),
row,
GEGL_AUTO_ROWSTRIDE);
}
gimp_progress_update (1.0);
g_free (row);
/* Update image */
/* ============ */
g_object_unref (dest_buffer);
gimp_drawable_flush (output_drawable);
gimp_drawable_merge_shadow (output_drawable->drawable_id, TRUE);
gimp_drawable_update (output_drawable->drawable_id, 0, 0, width, height);
gimp_drawable_merge_shadow (output_drawable_id, TRUE);
gimp_drawable_update (output_drawable_id, 0, 0, width, height);
if (new_image_id!=-1)
{
gimp_display_new (new_image_id);
gimp_displays_flush ();
gimp_drawable_detach (output_drawable);
}
}
......@@ -14,21 +14,25 @@
#include "lighting-ui.h"
GimpDrawable *input_drawable,*output_drawable;
GimpPixelRgn source_region, dest_region;
gint32 input_drawable_id;
gint32 output_drawable_id;
GeglBuffer *source_buffer;
GeglBuffer *dest_buffer;
GimpDrawable *bump_drawable = NULL;
GimpPixelRgn bump_region;
gint32 bump_drawable_id;
GeglBuffer *bump_buffer;
const Babl *bump_format;
GimpDrawable *env_drawable = NULL;
GimpPixelRgn env_region;
gint32 env_drawable_id;
GeglBuffer *env_buffer;
guchar *preview_rgb_data = NULL;
gint preview_rgb_stride;
cairo_surface_t *preview_surface = NULL;
glong maxcounter;
gint imgtype, width, height, env_width, env_height, in_channels, out_channels;
glong maxcounter;
gint width, height;
gint env_width, env_height;
GimpRGB background;
gint border_x1, border_y1, border_x2, border_y2;
......@@ -40,23 +44,25 @@ guchar sinemap[256], spheremap[256], logmap[256];
/******************/
guchar
peek_map (GimpPixelRgn *region,
gint x,
gint y)
peek_map (GeglBuffer *buffer,
const Babl *format,
gint x,
gint y)
{
guchar data[4];
guchar ret_val;
gegl_buffer_sample (buffer, x, y, NULL, data, format,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
gimp_pixel_rgn_get_pixel (region, data, x, y);
if (region->bpp == 1)
{
ret_val = data[0];
} else
{
ret_val = (guchar)((float)((data[0] + data[1] + data[2])/3.0));
}
if (babl_format_get_bytes_per_pixel (format))
{
ret_val = data[0];
}
else
{
ret_val = (guchar)((float)((data[0] + data[1] + data[2])/3.0));
}
return ret_val;
}
......@@ -65,26 +71,14 @@ GimpRGB
peek (gint x,
gint y)
{
guchar data[4];
GimpRGB color;
gimp_pixel_rgn_get_pixel (&source_region,data, x, y);
gegl_buffer_sample (source_buffer, x, y, NULL,
&color, babl_format ("R'G'B'A double"),
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
color.r = (gdouble) (data[0]) / 255.0;
color.g = (gdouble) (data[1]) / 255.0;
color.b = (gdouble) (data[2]) / 255.0;
if (input_drawable->bpp == 4)
{
if (in_channels == 4)
color.a = (gdouble) (data[3]) / 255.0;
else
color.a = 1.0;
}
else
{
color.a = 1.0;
}
if (! babl_format_has_alpha (gegl_buffer_get_format (source_buffer)))
color.a = 1.0;
return color;
}
......@@ -93,7 +87,6 @@ GimpRGB
peek_env_map (gint x,
gint y)
{
guchar data[4];
GimpRGB color;
if (x < 0)
......@@ -105,11 +98,10 @@ peek_env_map (gint x,
else if (y >= env_height)
y = env_height - 1;
gimp_pixel_rgn_get_pixel (&env_region, data, x, y);
gegl_buffer_sample (env_buffer, x, y, NULL,
&color, babl_format ("R'G'B'A double"),
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
color.r = (gdouble) (data[0]) / 255.0;
color.g = (gdouble) (data[1]) / 255.0;
color.b = (gdouble) (data[2]) / 255.0;
color.a = 1.0;
return color;
......@@ -120,8 +112,6 @@ poke (gint x,
gint y,
GimpRGB *color)
{
static guchar data[4];
if (x < 0)
x = 0;
else if (x >= width)
......@@ -131,19 +121,19 @@ poke (gint x,
else if (y >= height)
y = height - 1;
data[0] = (guchar) (color->r * 255.0);
data[1] = (guchar) (color->g * 255.0);
data[2] = (guchar) (color->b * 255.0);
data[3] = (guchar) (color->a * 255.0);
gimp_pixel_rgn_set_pixel (&dest_region, data, x, y);
gegl_buffer_set (dest_buffer, GEGL_RECTANGLE (x, y, 1, 1), 0,
babl_format ("R'G'B'A double"), color,
GEGL_AUTO_ROWSTRIDE);
}
gint
check_bounds (gint x,
gint y)
{
if (x < border_x1 || y < border_y1 || x >= border_x2 || y >= border_y2)
if (x < border_x1 ||
y < border_y1 ||
x >= border_x2 ||
y >= border_y2)
return FALSE;
else
return TRUE;
......@@ -283,10 +273,11 @@ get_image_color (gdouble u,
}
gdouble
get_map_value (GimpPixelRgn *region,
gdouble u,
gdouble v,
gint *inside)
get_map_value (GeglBuffer *buffer,
const Babl *format,
gdouble u,
gdouble v,
gint *inside)
{
gint x1, y1, x2, y2;
gdouble p[4];
......@@ -300,14 +291,14 @@ get_map_value (GimpPixelRgn *region,
if (check_bounds (x2, y2) == FALSE)
{
*inside = TRUE;
return (gdouble) peek_map (region, x1, y1);
return (gdouble) peek_map (buffer, format, x1, y1);
}
*inside = TRUE;
p[0] = (gdouble) peek_map (region, x1, y1);
p[1] = (gdouble) peek_map (region, x2, y1);
p[2] = (gdouble) peek_map (region, x1, y2);
p[3] = (gdouble) peek_map (region, x2, y2);
p[0] = (gdouble) peek_map (buffer, format, x1, y1);
p[1] = (gdouble) peek_map (buffer, format, x2, y1);
p[2] = (gdouble) peek_map (buffer, format, x1, y2);
p[3] = (gdouble) peek_map (buffer, format, x2, y2);
return gimp_bilinear (u, v, p);
}
......@@ -344,21 +335,21 @@ compute_maps (void)
/****************************************/
gint
image_setup (GimpDrawable *drawable,
gint interactive)
image_setup (gint32 drawable_id,
gint interactive)
{
gint w, h;
gboolean ret;
gint w, h;
gboolean ret;
compute_maps ();
/* Get some useful info on the input drawable */
/* ========================================== */
input_drawable = drawable;
output_drawable = drawable;
input_drawable_id = drawable_id;
output_drawable_id = drawable_id;
ret = gimp_drawable_mask_intersect (drawable->drawable_id,
ret = gimp_drawable_mask_intersect (drawable_id,
&border_x1, &border_y1, &w, &h);
border_x2 = border_x1 + w;
......@@ -367,21 +358,13 @@ image_setup (GimpDrawable *drawable,
if (! ret)
return FALSE;
width = input_drawable->width;
height = input_drawable->height;
width = gimp_drawable_width (input_drawable_id);
height = gimp_drawable_height (input_drawable_id);
gimp_pixel_rgn_init (&source_region, input_drawable,
0, 0, width, height, FALSE, FALSE);
source_buffer = gimp_drawable_get_buffer (input_drawable_id);
maxcounter = (glong) width * (glong) height;
/* Assume at least RGB */
/* =================== */
in_channels = 3;
if (gimp_drawable_has_alpha (input_drawable->drawable_id) == TRUE)
in_channels++;
if (interactive)
{
preview_rgb_stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24,
......@@ -396,3 +379,29 @@ image_setup (GimpDrawable *drawable,
return TRUE;
}
void
bumpmap_setup (gint32 bumpmap_id)
{
if (bumpmap_id != -1 && ! bump_buffer)
{
bump_buffer = gimp_drawable_get_buffer (bumpmap_id);
if (gimp_drawable_is_rgb (bumpmap_id))
bump_format = babl_format ("R'G'B' u8");
else
bump_format = babl_format ("Y' u8"); /* FIXME */
}
}
void
envmap_setup (gint32 envmap_id)
{
if (envmap_id != -1 && ! env_buffer)
{
env_width = gimp_drawable_width (envmap_id);
env_height = gimp_drawable_height (envmap_id);
env_buffer = gimp_drawable_get_buffer (envmap_id);
}
}
......@@ -4,33 +4,37 @@
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
extern GimpDrawable *input_drawable,*output_drawable;
extern GimpPixelRgn source_region, dest_region;
extern gint32 input_drawable_id;
extern gint32 output_drawable_id;
extern GeglBuffer *source_buffer;
extern GeglBuffer *dest_buffer;
extern GimpDrawable *bump_drawable;
extern GimpPixelRgn bump_region;
extern gint32 bump_drawable_id;
extern GeglBuffer *bump_buffer;
extern const Babl *bump_format;
extern GimpDrawable *env_drawable;
extern GimpPixelRgn env_region;
extern gint32 env_drawable_id;
extern GeglBuffer *env_buffer;
extern guchar *preview_rgb_data;
extern gint preview_rgb_stride;
extern cairo_surface_t *preview_surface;
extern glong maxcounter;
extern gint imgtype,width,height,env_width,env_height,in_channels,out_channels;
extern glong maxcounter;
extern gint width,height,env_width,env_height;
extern GimpRGB background;
extern gint border_x1,border_y1,border_x2,border_y2;
extern gint border_x1, border_y1, border_x2, border_y2;
extern guchar sinemap[256], spheremap[256], logmap[256];
guchar peek_map (GimpPixelRgn *region,
guchar peek_map (GeglBuffer *buffer,
const Babl *format,
gint x,
gint y);
GimpRGB peek (gint x,
GimpRGB peek (gint x,
gint y);
GimpRGB peek_env_map (gint x,
GimpRGB peek_env_map (gint x,
gint y);
void poke (gint x,
gint y,
......@@ -49,14 +53,17 @@ void pos_to_float (gdouble x,
gdouble y,
gdouble *xf,
gdouble *yf);
GimpRGB get_image_color (gdouble u,
GimpRGB get_image_color (gdouble u,
gdouble v,
gint *inside);
gdouble get_map_value (GimpPixelRgn *region,
gdouble get_map_value (GeglBuffer *buffer,
const Babl *format,
gdouble u,
gdouble v,
gint *inside);
gint image_setup (GimpDrawable *drawable,
gint image_setup (gint32 drawable_id,
gint interactive);
void bumpmap_setup (gint32 bumpmap_id);
void envmap_setup (gint32 envmap_id);
#endif /* __LIGHTING_IMAGE_H__ */
......@@ -211,13 +211,12 @@ run (const gchar *name,
GimpParam **return_vals)
{
static GimpParam values[1];
GimpDrawable *drawable;
GimpRunMode run_mode;
gint32 drawable_id;
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
run_mode = param[0].data.d_int32;
INIT_I18N ();
gegl_init (NULL, NULL);
*nreturn_vals = 1;
*return_vals = values;
......@@ -238,9 +237,10 @@ run (const gchar *name,
/* Get the specified drawable */
/* ========================== */
drawable = gimp_drawable_get (param[2].data.d_drawable);
run_mode = param[0].data.d_int32;
drawable_id = param[2].data.d_drawable;
mapvals.drawable_id = drawable->drawable_id;
mapvals.drawable_id = drawable_id;
check_drawables ();
......@@ -249,17 +249,12 @@ run (const gchar *name,
/* Make sure that the drawable is RGBA or RGB color */
/* ================================================ */
if (gimp_drawable_is_rgb (drawable->drawable_id))
if (gimp_drawable_is_rgb (drawable_id))
{
/* Set the tile cache size */
/* ======================= */
gimp_tile_cache_ntiles (TILE_CACHE_SIZE);
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
if (main_dialog (drawable))
if (main_dialog (drawable_id))
{
compute_image ();
......@@ -270,7 +265,7 @@ run (const gchar *name,
break;
case GIMP_RUN_WITH_LAST_VALS:
if (image_setup (drawable, FALSE))
if (image_setup (drawable_id, FALSE))
compute_image ();
gimp_displays_flush ();
break;
......@@ -305,7 +300,7 @@ run (const gchar *name,
mapvals.transparent_background = (gint) param[23].data.d_int32;
check_drawables ();
if (image_setup (drawable, FALSE))
if (image_setup (drawable_id, FALSE))
compute_image ();
}
default:
......@@ -313,11 +308,12 @@ run (const gchar *name,
}
}
else
status = GIMP_PDB_EXECUTION_ERROR;
{
status = GIMP_PDB_EXECUTION_ERROR;
}
}
values[0].data.d_status = status;
gimp_drawable_detach (drawable);
g_free (xpostab);
g_free (ypostab);
......
......@@ -96,9 +96,7 @@ compute_preview (gint startx, gint starty, gint w, gint h)
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);
bumpmap_setup (mapvals.bumpmap_id);
}
imagey = 0;
......@@ -110,12 +108,7 @@ compute_preview (gint startx, gint starty, gint w, gint h)
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);
envmap_setup (mapvals.envmap_id);
if (mapvals.previewquality)
ray_func = get_ray_color_ref;
......@@ -456,13 +449,12 @@ preview_draw (GtkWidget *area,
void
interactive_preview_callback (GtkWidget *widget)
{
if ( preview_update_timer != 0)
{
g_source_remove ( preview_update_timer );
}
/* start new timer */
if (preview_update_timer != 0)
g_source_remove (preview_update_timer);
preview_update_timer = g_timeout_add (100,
interactive_preview_timer_callback, NULL);
interactive_preview_timer_callback,
NULL);
}
static gboolean
......
......@@ -124,10 +124,11 @@ precompute_init (gint w,
{
if (vertex_normals[n] != NULL)
g_free (vertex_normals[n]);
if (heights[n] != NULL)
g_free (heights[n]);
heights[n] = g_new (gdouble, w);
heights[n] = g_new (gdouble, w);
vertex_normals[n] = g_new (GimpVector3, w);
}
......@@ -135,11 +136,8 @@ precompute_init (gint w,
if (triangle_normals[n] != NULL)
g_free (triangle_normals[n]);
if (bumprow != NULL)
{
g_free (bumprow);
bumprow = NULL;
}
g_clear_pointer (&bumprow, g_free);
if (mapvals.bumpmap_id != -1)
{
bpp = gimp_drawable_bpp(mapvals.bumpmap_id);
......@@ -176,23 +174,30 @@ interpol_row (gint x1,
gint x2,
gint y)
{
GimpVector3 p1, p2, p3;
gint n, i;
guchar *map = NULL;
gint bpp = 1;
guchar* bumprow1 = NULL;
guchar* bumprow2 = NULL;
GimpVector3 p1, p2, p3;
gint n, i;
guchar *map = NULL;
gint bpp = 1;
guchar *bumprow1 = NULL;
guchar *bumprow2 = NULL;
if (mapvals.bumpmap_id != -1)
{
bpp = gimp_drawable_bpp(mapvals.bumpmap_id);
bumpmap_setup (mapvals.bumpmap_id);
bpp = babl_format_get_bytes_per_pixel (bump_format);
}
bumprow1 = g_new (guchar, pre_w * bpp);
bumprow2 = g_new (guchar, pre_w * bpp);
bumprow1 = g_new0 (guchar, pre_w * bpp);
bumprow2 = g_new0 (guchar, pre_w * bpp);
gimp_pixel_rgn_get_row (&bump_region, bumprow1, x1, y, x2 - x1);
gimp_pixel_rgn_get_row (&bump_region, bumprow2, x1, y+1, x2 - x1);
gegl_buffer_get (bump_buffer, GEGL_RECTANGLE (x1, y, x2 - x1, 1), 1.0,
bump_format, bumprow1,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
gegl_buffer_get (bump_buffer, GEGL_RECTANGLE (x1, y - 1, x2 - x1, 1), 1.0,
bump_format, bumprow2,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
if (mapvals.bumpmaptype > 0)
{
......@@ -213,8 +218,8 @@ interpol_row (gint x1,
for (n = 0; n < (x2 - x1); n++)
{
gdouble diff;
guchar mapval;
guchar mapval1, mapval2;
guchar mapval;
guchar mapval1, mapval2;
if (bpp>1)
{
......@@ -285,8 +290,8 @@ precompute_normals (gint x1,
gdouble *tmpd;
gint n, i, nv;
guchar *map = NULL;
gint bpp = 1;
guchar mapval;
gint bpp = 1;
guchar mapval;
/* First, compute the heights */
......@@ -308,10 +313,14 @@ precompute_normals (gint x1,
if (mapvals.bumpmap_id != -1)
{