[gegl/dov/wip/bump-map] Fixed multiple boundary problems.
- From: Dov Grobgeld <dov src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/dov/wip/bump-map] Fixed multiple boundary problems.
- Date: Tue, 25 Jun 2013 19:54:13 +0000 (UTC)
commit 9724f9bd2a06822d0cd621362e2ca9fe26a3b11f
Author: Dov Grobgeld <dov grobgeld gmail com>
Date: Tue Jun 25 22:54:03 2013 +0300
Fixed multiple boundary problems.
operations/common/bump-map.c | 175 +++++++++++++++++++++++++++---------------
1 files changed, 114 insertions(+), 61 deletions(-)
---
diff --git a/operations/common/bump-map.c b/operations/common/bump-map.c
index 1e9866b..679f1da 100644
--- a/operations/common/bump-map.c
+++ b/operations/common/bump-map.c
@@ -46,12 +46,12 @@ gegl_chant_double(elevation,_("Elevation"),
gegl_chant_double(depth,_("Depth"),
0.0005,100,0.005,
_("depth"))
-gegl_chant_double(xofs,_("xofs"),
- -1000.0,1000.0,0.0,
- _("xofs"))
-gegl_chant_double(yofs,_("yofs"),
- -1000.0,1000.0,0.0,
- _("yofs"))
+gegl_chant_int(xofs,_("xofs"),
+ -1000,1000,0,
+ _("xofs"))
+gegl_chant_int(yofs,_("yofs"),
+ -1000,1000,0,
+ _("yofs"))
gegl_chant_double(waterlevel,_("waterlevel"),
0.0,1.0,0.0,
_("waterlevel"))
@@ -84,6 +84,11 @@ gegl_chant_boolean(tiled,_("Tiled"),FALSE, _("tiled"))
#include "gegl-chant.h"
#include <math.h>
+/***** Macros *****/
+
+#define MOD(x, y) \
+ ((x) < 0 ? ((y) - 1 - ((y) - 1 - (x)) % (y)) : (x) % (y))
+
typedef struct
{
gdouble lx, ly; /* X and Y components of light vector */
@@ -157,7 +162,9 @@ bumpmap_row (const gfloat *src,
const gfloat *bm_row1,
const gfloat *bm_row2,
const gfloat *bm_row3,
+ gint bm_width,
gint bm_xofs,
+ gboolean row_in_bumpmap,
GeglChantO *o,
bumpmap_params_t *params)
{
@@ -165,20 +172,39 @@ bumpmap_row (const gfloat *src,
gint x, k;
gdouble result;
- xofs2 = bm_xofs;
+ xofs2 = MOD (bm_xofs,bm_width);
for (x = 0; x < width; x++)
{
double shade;
double nx, ny;
- xofs1 = CLAMP (xofs2 - 1, 0, width - 1);
- xofs3 = CLAMP (xofs2 + 1, 0, width - 1);
+ /* Calculate surface normal from bump map */
+
+ if (o->tiled || (row_in_bumpmap &&
+ x >= - bm_xofs && x < - bm_xofs + bm_width))
+ {
+ if (o->tiled)
+ {
+ xofs1 = MOD (xofs2 - 1, bm_width);
+ xofs3 = MOD (xofs2 + 1, bm_width);
+ }
+ else
+ {
+ xofs1 = CLAMP (xofs2 - 1, 0, bm_width - 1);
+ xofs3 = CLAMP (xofs2 + 1, 0, bm_width - 1);
+ }
+
+ nx = (bm_row1[xofs1] + bm_row2[xofs1] + bm_row3[xofs1] -
+ bm_row1[xofs3] - bm_row2[xofs3] - bm_row3[xofs3]);
+ ny = (bm_row3[xofs1] + bm_row3[xofs2] + bm_row3[xofs3] -
+ bm_row1[xofs1] - bm_row1[xofs2] - bm_row1[xofs3]);
+ }
+ else
+ {
+ nx = ny = 0;
+ }
- nx = (bm_row1[xofs1] + bm_row2[xofs1] + bm_row3[xofs1] -
- bm_row1[xofs3] - bm_row2[xofs3] - bm_row3[xofs3]);
- ny = (bm_row3[xofs1] + bm_row3[xofs2] + bm_row3[xofs3] -
- bm_row1[xofs1] - bm_row1[xofs2] - bm_row1[xofs3]);
if ((nx == 0) && (ny == 0))
{
shade = params->background;
@@ -215,12 +241,12 @@ bumpmap_row (const gfloat *src,
*dest++ = *src++ * shade;
}
- // Skip alpha
if (has_alpha)
*dest++ = *src++;
/* Next pixel */
- xofs2++;
+ if (++xofs2 == bm_width)
+ xofs2 = 0;
}
}
@@ -258,70 +284,92 @@ process (GeglOperation *operation,
gint level)
{
GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
- gfloat *src_buf, *aux_buf, *dst_buf, *bm_row1, *bm_row2, *bm_row3, *src_row, *dest_row, *bm_tmprow;
+ gfloat *src_buf, *dst_buf, *bm_row1, *bm_row2, *bm_row3, *src_row, *dest_row, *bm_tmprow;
const Babl *format = gegl_operation_get_format(operation,"output");
gint channels = babl_format_get_n_components(format);
bumpmap_params_t params;
gint yofs1, yofs2, yofs3;
gint row_stride;
gint row, y;
- gint slice_thickness = 32;
+ gint bm_width, bm_height;
+ gint slice_thickness = 32;
gboolean first_time = TRUE;
// This should be made more sophisticated
int has_alpha = (channels == 4) || (channels == 2);
+ bm_width = gegl_buffer_get_width(aux);
+ bm_height = gegl_buffer_get_height(aux);
+
src_buf = g_new0 (gfloat, rect->width * slice_thickness * channels);
- aux_buf = g_new0 (gfloat, rect->width * (slice_thickness+2));
dst_buf = g_new0 (gfloat, rect->width * slice_thickness * channels);
bumpmap_setup_calc (o, ¶ms);
/* Initialize offsets */
- yofs2 = CLAMP ((int)(o->yofs), 0, rect->height - 1);
- yofs1 = yofs2;
- yofs3 = CLAMP (yofs2 + 1, 0, rect->height - 1);
+ if (o->tiled)
+ {
+ yofs2 = MOD (o->yofs, bm_height);
+ yofs1 = MOD (yofs2 - 1, bm_height);
+ yofs3 = MOD (yofs2 + 1, bm_height);
+ }
+ else
+ {
+ yofs2 = o->yofs;
+ yofs1 = yofs2-1;
+ yofs3 = yofs2+1;
+ }
/* Initialize three line fifo buffers */
- bm_row1 = g_new (gfloat, rect->width);
- bm_row2 = g_new (gfloat, rect->width);
- bm_row3 = g_new (gfloat, rect->width);
+ bm_row1 = g_new (gfloat, bm_width);
+ bm_row2 = g_new (gfloat, bm_width);
+ bm_row3 = g_new (gfloat, bm_width);
// The source and destination row stride in floats
row_stride = rect->width*channels;
+ // Process the input buffer one slice at a time, but the bumpmap one row at a time.
for (row=rect->y; row < rect->y+rect->height; row+= slice_thickness)
{
- GeglRectangle rect_slice, bm_rect_slice;
+ GeglRectangle rect_slice, bm_rect;
rect_slice.x = rect->x;
rect_slice.width = rect->width;
rect_slice.y = rect->y+row;
rect_slice.height = MIN(slice_thickness, rect->height-row);
- bm_rect_slice = rect_slice;
- bm_rect_slice.height += 2;
-
gegl_buffer_get (input, &rect_slice, 1.0, babl_format ("RGBA float"), src_buf,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
- gegl_buffer_get (aux, &bm_rect_slice, 1.0, babl_format ("Y float"), aux_buf,
- GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
-
- // Fill three row FIFO the first time
- if (first_time)
- {
- first_time = FALSE;
-
- memcpy(bm_row1, aux_buf + yofs1 * rect->width, rect->width * sizeof(gfloat));
- memcpy(bm_row2, aux_buf + yofs2 * rect->width, rect->width * sizeof(gfloat));
- memcpy(bm_row3, aux_buf + yofs3 * rect->width, rect->width * sizeof(gfloat));
-
- bumpmap_convert_row (bm_row1, rect->width, params.lut, o->waterlevel);
- bumpmap_convert_row (bm_row2, rect->width, params.lut, o->waterlevel);
- bumpmap_convert_row (bm_row3, rect->width, params.lut, o->waterlevel);
- }
-
+ // Get the bumpmap one row at a time. The following values are constant
+ // in the bumpmap buffer access.
+ bm_rect.x = 0;
+ bm_rect.width = bm_width;
+ bm_rect.height = 1;
+
for (y = 0; y < rect_slice.height; y++)
{
+ gboolean row_in_bumpmap = (yofs2 > 0 && yofs2 < bm_height);
+
+ // Fill in the three rows FIFO the first time we are inside the bumpmap.
+ if (row_in_bumpmap && first_time)
+ {
+ first_time = FALSE;
+
+ bm_rect.y = yofs1;
+ gegl_buffer_get (aux, &bm_rect, 1.0, babl_format ("Y float"), bm_row1,
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+ bm_rect.y = yofs2;
+ gegl_buffer_get (aux, &bm_rect, 1.0, babl_format ("Y float"), bm_row2,
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+ bm_rect.y = yofs3;
+ gegl_buffer_get (aux, &bm_rect, 1.0, babl_format ("Y float"), bm_row3,
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+
+ bumpmap_convert_row (bm_row1, bm_width, params.lut, o->waterlevel);
+ bumpmap_convert_row (bm_row2, bm_width, params.lut, o->waterlevel);
+ bumpmap_convert_row (bm_row3, bm_width, params.lut, o->waterlevel);
+ }
+
+
src_row = src_buf + y * row_stride;
dest_row = dst_buf + y * row_stride;
@@ -330,30 +378,36 @@ process (GeglOperation *operation,
channels,
has_alpha,
bm_row1, bm_row2, bm_row3,
+ bm_width,
o->xofs,
+ row_in_bumpmap,
o,
¶ms);
- /* Next line */
- bm_tmprow = bm_row1;
- bm_row1 = bm_row2;
- bm_row2 = bm_row3;
- bm_row3 = bm_tmprow;
+ if (!first_time)
+ {
+ /* Next line */
+ bm_tmprow = bm_row1;
+ bm_row1 = bm_row2;
+ bm_row2 = bm_row3;
+ bm_row3 = bm_tmprow;
+ }
- if (++yofs2 == rect->height)
+ if (++yofs2 == bm_height && o->tiled)
yofs2 = 0;
- yofs3 = CLAMP (yofs2 + 1, 0, rect->height);
- memcpy(bm_row3, aux_buf + (yofs3-rect_slice.y) * rect->width, rect->width * sizeof(gfloat));
- if (yofs2 > 98 && yofs2 < 102)
+ if (o->tiled)
+ yofs3 = MOD (yofs2 + 1, bm_height);
+ else
+ yofs3 = CLAMP (yofs2 + 1, 0, bm_height);
+
+ if (!first_time)
{
- int i;
- double sum = 0;
- for (i=0;i<rect->width; i++)
- sum+= bm_row3[i];
+ bm_rect.y = yofs3;
+ gegl_buffer_get (aux, &bm_rect, 1.0, babl_format ("Y float"), bm_row3,
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
+ bumpmap_convert_row (bm_row3, bm_width, params.lut, o->waterlevel);
}
-
- bumpmap_convert_row (bm_row3, rect->width, params.lut, o->waterlevel);
}
gegl_buffer_set (output, &rect_slice, 0, babl_format ("RGBA float"),
dst_buf, GEGL_AUTO_ROWSTRIDE);
@@ -365,7 +419,6 @@ process (GeglOperation *operation,
g_free (dst_buf);
g_free (src_buf);
- g_free (aux_buf);
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]