diff --git a/filters/filter_bumpmap.c b/filters/filter_bumpmap.c index f10136a..4b69294 100644 --- a/filters/filter_bumpmap.c +++ b/filters/filter_bumpmap.c @@ -18,24 +18,127 @@ #define ASSIGN_IMAGE(k, v) \ if (!strcmp((k), par->key)) { \ if (par->type == VAR_PTR) { \ - (v) = (Imlib_Image)(par->data); \ + (v) = ((Imlib_Image)par->data); \ } else if (par->type == VAR_CHAR) { \ - (v) = imlib_load_image(par->data); \ + if (!free_map) \ + (v) = imlib_load_image(par->data); \ + free_map = 1; \ } \ } -#define ASSIGN_DOUBLE(k, v) \ +#define ASSIGN_INT(k, v) \ if (!strcmp((k), par->key)) { \ if (par->type == VAR_PTR) { \ - (v) = (double)(*(int *)par->data); \ + (v) = (*(int *)par->data); \ } else if (par->type == VAR_CHAR) { \ - (v) = strtod(par->data, 0); \ + (v) = strtol(par->data, 0, 0); \ } \ } +#define PI (4 * atan(1)) + static Imlib_Image bump_map(Imlib_Image im, pIFunctionParam par) { + Imlib_Image map = im; + double an = 0, el = 30, d = 0x200; + double red = 0x200, green = 0x200, blue = 0x200; + double ambient = 0; + + int free_map = 0; + DATA32 *src; + DATA32 *mp, *mpy, *mpp; + double z, z_2, x2, y2; + int w, h, i, j, w2, h2, wh2, mx, my; + + for (; par; par = par->next) { + ASSIGN_IMAGE("map", map); + ASSIGN_INT ("angle", an); + ASSIGN_INT ("elevation", el); + ASSIGN_INT ("depth", d); + ASSIGN_INT ("red", red); + ASSIGN_INT ("green", green); + ASSIGN_INT ("blue", blue); + ASSIGN_INT ("ambient", ambient); + } + if (!map) return im; + + red /= 0x100; + green /= 0x100; + blue /= 0x100; + ambient /= 0x100; + d /= 0x100; + + imlib_context_set_image(im); + src = imlib_image_get_data(); + w = imlib_image_get_width(); + h = imlib_image_get_height(); + + imlib_context_set_image(map); + mpp = imlib_image_get_data_for_reading_only(); + w2 = imlib_image_get_width(); + h2 = imlib_image_get_height(); + wh2 = w2 * h2; + + an *= (PI / 180); + el *= (PI / 180); + + x2 = sin(an) * cos(el); + y2 = cos(an) * cos(el); + z = sin(el); + + d /= (255 * (255 + 255 + 255)); + z_2 = z * z; + + my = h2; + for (j = h; --j >= 0; ) { + mp = mpp; + mpp += w2; + if (--my <= 0) { + mpp -= wh2; + my = h2; + } + mpy = mpp; + mx = w2; + for (i = w; --i >= 0; ) { + double x1, y1, v; + int r, g, b, gr; + + gr = A_VAL(mp) * (R_VAL(mp) + G_VAL(mp) + B_VAL(mp)); + y1 = d * (double)(A_VAL(mpy) * (R_VAL(mpy) + + G_VAL(mpy) + B_VAL(mpy)) - gr); + mp++; + mpy++; + if (--mx <= 0) { + mp -= w2; + mpy -= w2; + mx = w2; + } + x1 = d * (double)(A_VAL(mp) * (R_VAL(mp) + + G_VAL(mp) + B_VAL(mp)) - gr); + v = x1 * x2 + y1 * y2 + z; + v /= sqrt((x1 * x1) + (y1 * y1) + 1.0); + v += ambient; + r = v * R_VAL(src) * red; + g = v * G_VAL(src) * green; + b = v * B_VAL(src) * blue; + if (r < 0) r = 0; + if (r > 255) r = 255; + if (g < 0) g = 0; + if (g > 255) g = 255; + if (b < 0) b = 0; + if (b > 255) b = 255; + R_VAL(src) = r; + G_VAL(src) = g; + B_VAL(src) = b; + + src++; + } + } + if (free_map) { + imlib_context_set_image(map); + imlib_free_image(); + } return im; } @@ -43,26 +146,35 @@ static Imlib_Image bump_map_point(Imlib_Image im, pIFunctionParam par) { Imlib_Image map = im; - double x = 0, y = 0, z = 30, d = 2; - double red = 2, green = 2, blue = 2; + double x = 0, y = 0, z = 30, d = 0x200; + double red = 0x200, green = 0x200, blue = 0x200; + double ambient = 0; + int free_map = 0; DATA32 *src; DATA32 *mp, *mpy, *mpp; double z_2, x2, y2; int w, h, i, j, w2, h2, wh2, mx, my; for (; par; par = par->next) { - ASSIGN_IMAGE ("map", map); - ASSIGN_DOUBLE("x", x); - ASSIGN_DOUBLE("y", y); - ASSIGN_DOUBLE("z", z); - ASSIGN_DOUBLE("depth", d); - ASSIGN_DOUBLE("red", red); - ASSIGN_DOUBLE("green", green); - ASSIGN_DOUBLE("blue", blue); + ASSIGN_IMAGE("map", map); + ASSIGN_INT ("x", x); + ASSIGN_INT ("y", y); + ASSIGN_INT ("z", z); + ASSIGN_INT ("depth", d); + ASSIGN_INT ("red", red); + ASSIGN_INT ("green", green); + ASSIGN_INT ("blue", blue); + ASSIGN_INT ("ambient", ambient); } if (!map) return im; + red /= 0x100; + green /= 0x100; + blue /= 0x100; + ambient /= 0x100; + d /= 0x100; + imlib_context_set_image(im); src = imlib_image_get_data(); w = imlib_image_get_width(); @@ -108,6 +220,7 @@ bump_map_point(Imlib_Image im, pIFunctionParam par) v = x1 * x2 + y1 * y2 + z; v /= sqrt((x1 * x1) + (y1 * y1) + 1.0); v /= sqrt((x2 * x2) + (y2 * y2) + z_2); + v += ambient; r = v * R_VAL(src) * red; g = v * G_VAL(src) * green; b = v * B_VAL(src) * blue; @@ -126,6 +239,10 @@ bump_map_point(Imlib_Image im, pIFunctionParam par) } y2++; } + if (free_map) { + imlib_context_set_image(map); + imlib_free_image(); + } return im; } @@ -133,9 +250,7 @@ void init(struct imlib_filter_info *info) { char *filters[] = { "bump_map_point", "bump_map" }; - int i; - - i = (sizeof(filters) / sizeof(*filters)); + int i = (sizeof(filters) / sizeof(*filters)); info->num_filters = i; info->filters = malloc(sizeof(char *) * i); while (--i >= 0) @@ -146,7 +261,7 @@ init(struct imlib_filter_info *info) void deinit() { - return; + return; } void * diff --git a/test/main.c b/test/main.c index a96030d..978cf11 100644 --- a/test/main.c +++ b/test/main.c @@ -76,6 +76,7 @@ int main (int argc, char **argv) int scaleup = 0; int scaleboth = 0; int origone = 0; + int bump_map_to_point = 0; Imlib_Color_Modifier colormod = 0; /** @@ -108,6 +109,7 @@ int main (int argc, char **argv) printf ("-blendtest\tPerforms a blending test on the file.\n"); printf ("-rotatetest\tPerforms a rotate test on the file.\n"); printf ("-filter\t\tPerforms filtering. Possible filters are,\n\t\t\t1:Blur filter, 2:Sharpen filter, 3:Color blur filter, \n\t\t\t4:Emboss filter, 5:Grayscale filter, 6:Saturation filter,\n\t\t\t7:Edge detection filter.\n"); + printf ("-bmp2pt\t\tPerformas Bump Mapping to a point\n"); return 0; } @@ -128,6 +130,8 @@ int main (int argc, char **argv) scaleup = 1; else if (!strcmp(argv[i], "-both")) scaleboth = 1; + else if (!strcmp(argv[i], "-bmp2pt")) + bump_map_to_point = 1; else if (!strcmp(argv[i], "-orig")) origone = 1; else if (!strcmp(argv[i], "-blend")) @@ -741,7 +745,11 @@ int main (int argc, char **argv) imlib_image_get_height()); } - imlib_apply_filter("bump_map_point(x=[],y=[],map=test_images/bulb.png);", &x, &y, NULL); + if( bump_map_to_point ) + imlib_apply_filter("bump_map_to_point(x=[],y=[],map=test_images/bulb.png);", &x, &y, NULL); + else + imlib_apply_filter("bump_map(x=[],y=[],map=test_images/bulb.png);", &x, &y, NULL); + up = imlib_update_append_rect(up, 0, 0, imlib_image_get_width(), imlib_image_get_height());