1997-11-25 06:05:25 +08:00
|
|
|
/* The GIMP -- an image manipulation program
|
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
|
|
|
* Bump map plug-in --- emboss an image by using another image as a bump map
|
2000-04-16 06:40:05 +08:00
|
|
|
* Copyright (C) 1997 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
|
|
|
* Copyright (C) 1997-2000 Jens Lautenbacher <jtl@gimp.org>
|
|
|
|
* Copyright (C) 2000 Sven Neumann <sven@gimp.org>
|
2003-11-06 23:27:05 +08:00
|
|
|
*
|
1997-11-25 06:05:25 +08:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
1998-04-13 13:44:11 +08:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/* This plug-in uses the algorithm described by John Schlag, "Fast
|
|
|
|
* Embossing Effects on Raster Image Data" in Graphics Gems IV (ISBN
|
|
|
|
* 0-12-336155-9). It takes a grayscale image to be applied as a
|
|
|
|
* bump-map to another image, producing a nice embossing effect.
|
|
|
|
*/
|
|
|
|
|
2000-04-20 23:31:56 +08:00
|
|
|
/* Version 3.0-pre1-ac2:
|
|
|
|
*
|
|
|
|
* - waterlevel/ambient restricted to 0-255
|
2000-04-21 03:00:40 +08:00
|
|
|
* - correctly initialize bumpmap_offsets
|
2003-11-06 23:27:05 +08:00
|
|
|
*/
|
2000-04-20 23:31:56 +08:00
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
/* Version 3.0-pre1-ac1:
|
|
|
|
*
|
|
|
|
* - Now able not to tile the bumpmap - this is the default.
|
|
|
|
* - Added new PDB call plug_in_bumpmap_tiled.
|
|
|
|
* - Added scrollbars for preview.
|
|
|
|
* - Fixed slider feedback for bumpmap offset and set initial offsets
|
|
|
|
* from drawable offsets.
|
|
|
|
* - Make it work as intended from the very beginning...
|
|
|
|
*/
|
2003-11-06 23:27:05 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Version 2.04:
|
|
|
|
*
|
|
|
|
* - The preview is now scrollable via draging with button 1 in the
|
|
|
|
* preview area. Thanks to Quartic for helping with gdk event handling.
|
|
|
|
*
|
|
|
|
* - The bumpmap's offset can alternatively be adjusted by dragging with
|
|
|
|
* button 3 in the preview area.
|
|
|
|
*/
|
2003-11-06 23:27:05 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Version 2.03:
|
|
|
|
*
|
|
|
|
* - Now transparency in the bumpmap drawable is handled as specified
|
|
|
|
* by the waterlevel parameter. Thanks to Jens for suggesting it!
|
|
|
|
*
|
|
|
|
* - New cool ambient lighting method. Thanks to Jens Lautenbacher
|
|
|
|
* for creating it! Something useful actually came out of those IRC
|
|
|
|
* sessions ;-)
|
|
|
|
*
|
|
|
|
* - Added proper rounding wherever it seemed appropriate. This fixes
|
|
|
|
* some minor artifacts in the output.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/* Version 2.02:
|
|
|
|
*
|
|
|
|
* - Fixed a stupid bug in the preview code (offsets were not wrapped
|
|
|
|
* correctly in some situations). Thanks to Jens Lautenbacher for
|
|
|
|
* reporting it!
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/* Version 2.01:
|
|
|
|
*
|
|
|
|
* - For the preview, vertical scrolling and setting the vertical
|
|
|
|
* bumpmap offset are now *much* faster. Instead of calling
|
|
|
|
* gimp_pixel_rgn_get_row() a lot of times, I now use an adapted
|
|
|
|
* version of gimp_pixel_rgn_get_rect().
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/* Version 2.00:
|
|
|
|
*
|
|
|
|
* - Rewrote from the 0.54 version (well, from the 0.99.9
|
|
|
|
* distribution, actually...). New in this release are the correct
|
|
|
|
* handling of all image depths, sizes, and offsets. Also the
|
|
|
|
* different map types, the compensation and map inversion options
|
|
|
|
* were added. The preview widget is new, too.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/* TODO:
|
|
|
|
*
|
|
|
|
* - Speed-ups
|
|
|
|
*/
|
|
|
|
|
1999-05-29 09:28:24 +08:00
|
|
|
#include "config.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-06-28 14:33:38 +08:00
|
|
|
#include <stdio.h>
|
1997-11-25 06:05:25 +08:00
|
|
|
#include <stdlib.h>
|
2000-10-01 04:13:06 +08:00
|
|
|
#include <string.h>
|
1999-05-29 09:28:24 +08:00
|
|
|
#ifdef HAVE_UNISTD_H
|
1997-11-25 06:05:25 +08:00
|
|
|
#include <unistd.h>
|
1999-05-29 09:28:24 +08:00
|
|
|
#endif
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-12-29 21:26:29 +08:00
|
|
|
#ifdef __GNUC__
|
|
|
|
#warning GTK_DISABLE_DEPRECATED
|
|
|
|
#endif
|
|
|
|
#undef GTK_DISABLE_DEPRECATED
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
|
|
|
#include <libgimp/gimp.h>
|
|
|
|
#include <libgimp/gimpui.h>
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-05-30 00:35:47 +08:00
|
|
|
#include "libgimp/stdplugins-intl.h"
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/***** Magic numbers *****/
|
|
|
|
|
2000-04-20 23:31:56 +08:00
|
|
|
#define PLUG_IN_VERSION "April 2000, 3.0-pre1-ac2"
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-15 23:32:28 +08:00
|
|
|
#define PREVIEW_SIZE 128
|
2000-02-04 23:12:17 +08:00
|
|
|
#define SCALE_WIDTH 0
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/***** Types *****/
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
LINEAR = 0,
|
|
|
|
SPHERICAL,
|
|
|
|
SINUOSIDAL
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
DRAG_NONE = 0,
|
|
|
|
DRAG_SCROLL,
|
|
|
|
DRAG_BUMPMAP
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
gint32 bumpmap_id;
|
|
|
|
gdouble azimuth;
|
|
|
|
gdouble elevation;
|
|
|
|
gint depth;
|
|
|
|
gint xofs;
|
|
|
|
gint yofs;
|
|
|
|
gint waterlevel;
|
|
|
|
gint ambient;
|
|
|
|
gint compensate;
|
|
|
|
gint invert;
|
|
|
|
gint type;
|
2000-04-16 06:40:05 +08:00
|
|
|
gint tiled;
|
1997-11-25 06:05:25 +08:00
|
|
|
} bumpmap_vals_t;
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
typedef struct
|
|
|
|
{
|
2000-04-16 06:40:05 +08:00
|
|
|
gint lx, ly; /* X and Y components of light vector */
|
|
|
|
gint nz2, nzlz; /* nz^2, nz*lz */
|
|
|
|
gint background; /* Shade for vertical normals */
|
|
|
|
gdouble compensation; /* Background compensation */
|
|
|
|
guchar lut[256]; /* Look-up table for modes */
|
1997-11-25 06:05:25 +08:00
|
|
|
} bumpmap_params_t;
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
typedef struct
|
|
|
|
{
|
2000-04-16 06:40:05 +08:00
|
|
|
GtkWidget *preview;
|
|
|
|
GtkObject *preview_adj_x;
|
|
|
|
GtkObject *preview_adj_y;
|
|
|
|
gint preview_width;
|
|
|
|
gint preview_height;
|
|
|
|
gint mouse_x;
|
|
|
|
gint mouse_y;
|
|
|
|
gint preview_xofs;
|
|
|
|
gint preview_yofs;
|
|
|
|
gint drag_mode;
|
|
|
|
|
|
|
|
GtkObject *offset_adj_x;
|
|
|
|
GtkObject *offset_adj_y;
|
2003-11-06 23:27:05 +08:00
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
guchar *check_row_0;
|
|
|
|
guchar *check_row_1;
|
|
|
|
|
|
|
|
guchar **src_rows;
|
|
|
|
guchar **bm_rows;
|
|
|
|
|
|
|
|
gint src_yofs;
|
|
|
|
gint bm_yofs;
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
GimpDrawable *bm_drawable;
|
2000-04-16 06:40:05 +08:00
|
|
|
gint bm_width;
|
|
|
|
gint bm_height;
|
|
|
|
gint bm_bpp;
|
|
|
|
gint bm_has_alpha;
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
GimpPixelRgn src_rgn;
|
|
|
|
GimpPixelRgn bm_rgn;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bumpmap_params_t params;
|
1997-11-25 06:05:25 +08:00
|
|
|
} bumpmap_interface_t;
|
|
|
|
|
|
|
|
|
|
|
|
/***** Prototypes *****/
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
static void query (void);
|
2003-07-02 02:54:28 +08:00
|
|
|
static void run (const gchar *name,
|
|
|
|
gint nparams,
|
|
|
|
const GimpParam *param,
|
|
|
|
gint *nreturn_vals,
|
|
|
|
GimpParam **return_vals);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
static void bumpmap (void);
|
|
|
|
static void bumpmap_init_params (bumpmap_params_t *params);
|
|
|
|
static void bumpmap_row (guchar *src_row,
|
|
|
|
guchar *dest_row,
|
2000-02-03 01:59:44 +08:00
|
|
|
gint width,
|
|
|
|
gint bpp,
|
|
|
|
gint has_alpha,
|
2000-01-13 23:39:26 +08:00
|
|
|
guchar *bm_row1,
|
|
|
|
guchar *bm_row2,
|
|
|
|
guchar *bm_row3,
|
2000-02-03 01:59:44 +08:00
|
|
|
gint bm_width,
|
|
|
|
gint bm_xofs,
|
2000-04-16 06:40:05 +08:00
|
|
|
gboolean tiled,
|
2003-11-06 23:27:05 +08:00
|
|
|
gboolean row_in_bumpmap,
|
2000-01-13 23:39:26 +08:00
|
|
|
bumpmap_params_t *params);
|
2000-02-03 01:59:44 +08:00
|
|
|
static void bumpmap_convert_row (guchar *row,
|
|
|
|
gint width,
|
|
|
|
gint bpp,
|
|
|
|
gint has_alpha,
|
|
|
|
guchar *lut);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-15 23:32:28 +08:00
|
|
|
static gint bumpmap_dialog (void);
|
|
|
|
static void dialog_init_preview (void);
|
2000-04-21 03:00:40 +08:00
|
|
|
static void dialog_new_bumpmap (gboolean init_offsets);
|
2000-01-15 23:32:28 +08:00
|
|
|
static void dialog_update_preview (void);
|
|
|
|
static gint dialog_preview_events (GtkWidget *widget, GdkEvent *event);
|
|
|
|
static void dialog_scroll_src (void);
|
|
|
|
static void dialog_scroll_bumpmap (void);
|
2000-08-22 09:26:57 +08:00
|
|
|
static void dialog_get_rows (GimpPixelRgn *pr, guchar **rows,
|
2000-02-03 01:59:44 +08:00
|
|
|
gint x, gint y,
|
|
|
|
gint width, gint height);
|
|
|
|
static void dialog_fill_src_rows (gint start, gint how_many, gint yofs);
|
|
|
|
static void dialog_fill_bumpmap_rows (gint start, gint how_many, gint yofs);
|
2000-01-15 23:32:28 +08:00
|
|
|
|
|
|
|
static void dialog_compensate_callback (GtkWidget *widget, gpointer data);
|
|
|
|
static void dialog_invert_callback (GtkWidget *widget, gpointer data);
|
2000-04-16 06:40:05 +08:00
|
|
|
static void dialog_tiled_callback (GtkWidget *widget, gpointer data);
|
2000-01-15 23:32:28 +08:00
|
|
|
static void dialog_map_type_callback (GtkWidget *widget, gpointer data);
|
|
|
|
static gint dialog_constrain (gint32 image_id, gint32 drawable_id,
|
|
|
|
gpointer data);
|
|
|
|
static void dialog_bumpmap_callback (gint32 id, gpointer data);
|
|
|
|
static void dialog_dscale_update (GtkAdjustment *adjustment,
|
|
|
|
gdouble *value);
|
|
|
|
static void dialog_iscale_update_normal (GtkAdjustment *adjustment, gint *value);
|
|
|
|
static void dialog_iscale_update_full (GtkAdjustment *adjustment, gint *value);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/***** Variables *****/
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
GimpPlugInInfo PLUG_IN_INFO =
|
2000-01-13 23:39:26 +08:00
|
|
|
{
|
2000-02-03 01:59:44 +08:00
|
|
|
NULL, /* init_proc */
|
|
|
|
NULL, /* quit_proc */
|
|
|
|
query, /* query_proc */
|
|
|
|
run /* run_proc */
|
2000-01-13 23:39:26 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static bumpmap_vals_t bmvals =
|
|
|
|
{
|
|
|
|
-1, /* bumpmap_id */
|
|
|
|
135.0, /* azimuth */
|
|
|
|
45.0, /* elevation */
|
|
|
|
3, /* depth */
|
|
|
|
0, /* xofs */
|
|
|
|
0, /* yofs */
|
|
|
|
0, /* waterlevel */
|
|
|
|
0, /* ambient */
|
|
|
|
FALSE, /* compensate */
|
|
|
|
FALSE, /* invert */
|
2000-04-16 06:40:05 +08:00
|
|
|
LINEAR, /* type */
|
|
|
|
FALSE /* tiled */
|
2000-01-13 23:39:26 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static bumpmap_interface_t bmint =
|
|
|
|
{
|
|
|
|
NULL, /* preview */
|
2000-04-16 06:40:05 +08:00
|
|
|
NULL, /* preview_adj_x */
|
|
|
|
NULL, /* preview_adj_y */
|
2000-01-13 23:39:26 +08:00
|
|
|
0, /* preview_width */
|
|
|
|
0, /* preview_height */
|
|
|
|
0, /* mouse_x */
|
|
|
|
0, /* mouse_y */
|
|
|
|
0, /* preview_xofs */
|
|
|
|
0, /* preview_yofs */
|
|
|
|
DRAG_NONE, /* drag_mode */
|
2000-04-16 06:40:05 +08:00
|
|
|
NULL, /* offset_adj_x */
|
|
|
|
NULL, /* offset_adj_y */
|
2000-01-13 23:39:26 +08:00
|
|
|
NULL, /* check_row_0 */
|
|
|
|
NULL, /* check_row_1 */
|
|
|
|
NULL, /* src_rows */
|
|
|
|
NULL, /* bm_rows */
|
|
|
|
0, /* src_yofs */
|
|
|
|
-1, /* bm_yofs */
|
|
|
|
NULL, /* bm_drawable */
|
|
|
|
0, /* bm_width */
|
|
|
|
0, /* bm_height */
|
|
|
|
0, /* bm_bpp */
|
|
|
|
0, /* bm_has_alpha */
|
|
|
|
{ 0 }, /* src_rgn */
|
|
|
|
{ 0 }, /* bm_rgn */
|
2003-11-06 23:27:05 +08:00
|
|
|
{ 0 } /* params */
|
2000-01-13 23:39:26 +08:00
|
|
|
};
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
static GimpDrawable *drawable = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
static gint sel_x1, sel_y1;
|
|
|
|
static gint sel_x2, sel_y2;
|
|
|
|
static gint sel_width, sel_height;
|
|
|
|
static gint img_bpp;
|
|
|
|
static gboolean img_has_alpha;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-04-17 20:06:03 +08:00
|
|
|
/***** Macros *****/
|
|
|
|
|
|
|
|
#define MOD(x, y) \
|
|
|
|
((x) < 0 ? ((y) - 1 - ((y) - 1 - (x)) % (y)) : (x) % (y))
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/***** Functions *****/
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
MAIN ()
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2000-01-13 23:39:26 +08:00
|
|
|
query (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
static GimpParamDef args[] =
|
2000-01-13 23:39:26 +08:00
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
|
|
|
|
{ GIMP_PDB_IMAGE, "image", "Input image" },
|
|
|
|
{ GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
|
|
|
|
{ GIMP_PDB_DRAWABLE, "bumpmap", "Bump map drawable" },
|
|
|
|
{ GIMP_PDB_FLOAT, "azimuth", "Azimuth" },
|
|
|
|
{ GIMP_PDB_FLOAT, "elevation", "Elevation" },
|
|
|
|
{ GIMP_PDB_INT32, "depth", "Depth" },
|
|
|
|
{ GIMP_PDB_INT32, "xofs", "X offset" },
|
|
|
|
{ GIMP_PDB_INT32, "yofs", "Y offset" },
|
|
|
|
{ GIMP_PDB_INT32, "waterlevel", "Level that full transparency should represent" },
|
|
|
|
{ GIMP_PDB_INT32, "ambient", "Ambient lighting factor" },
|
|
|
|
{ GIMP_PDB_INT32, "compensate", "Compensate for darkening" },
|
|
|
|
{ GIMP_PDB_INT32, "invert", "Invert bumpmap" },
|
|
|
|
{ GIMP_PDB_INT32, "type", "Type of map (LINEAR (0), SPHERICAL (1), SINUOSIDAL (2))" }
|
2000-01-13 23:39:26 +08:00
|
|
|
};
|
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
gimp_install_procedure ("plug_in_bump_map",
|
2000-02-03 01:59:44 +08:00
|
|
|
"Create an embossing effect using an image as a "
|
|
|
|
"bump map",
|
|
|
|
"This plug-in uses the algorithm described by John "
|
|
|
|
"Schlag, \"Fast Embossing Effects on Raster Image "
|
|
|
|
"Data\" in Graphics GEMS IV (ISBN 0-12-336155-9). "
|
2000-04-16 06:40:05 +08:00
|
|
|
"It takes a drawable to be applied as a bump "
|
2000-02-03 01:59:44 +08:00
|
|
|
"map to another image and produces a nice embossing "
|
|
|
|
"effect.",
|
2000-04-16 06:40:05 +08:00
|
|
|
"Federico Mena Quintero, Jens Lautenbacher & Sven Neumann",
|
|
|
|
"Federico Mena Quintero, Jens Lautenbacher & Sven Neumann",
|
2000-01-13 23:39:26 +08:00
|
|
|
PLUG_IN_VERSION,
|
2003-07-17 23:47:18 +08:00
|
|
|
N_("<Image>/Filters/Map/_Bump Map..."),
|
2000-01-13 23:39:26 +08:00
|
|
|
"RGB*, GRAY*",
|
2000-08-22 09:26:57 +08:00
|
|
|
GIMP_PLUGIN,
|
2001-12-06 10:28:58 +08:00
|
|
|
G_N_ELEMENTS (args), 0,
|
2000-02-03 01:59:44 +08:00
|
|
|
args, NULL);
|
2000-04-16 06:40:05 +08:00
|
|
|
|
|
|
|
gimp_install_procedure ("plug_in_bump_map_tiled",
|
|
|
|
"Create an embossing effect using a tiled image "
|
|
|
|
"as a bump map",
|
|
|
|
"This plug-in uses the algorithm described by John "
|
|
|
|
"Schlag, \"Fast Embossing Effects on Raster Image "
|
|
|
|
"Data\" in Graphics GEMS IV (ISBN 0-12-336155-9). "
|
|
|
|
"It takes a drawable to be tiled and applied as a "
|
|
|
|
"bump map to another image and produces a nice "
|
|
|
|
"embossing effect.",
|
|
|
|
"Federico Mena Quintero, Jens Lautenbacher & Sven Neumann",
|
|
|
|
"Federico Mena Quintero, Jens Lautenbacher & Sven Neumann",
|
|
|
|
PLUG_IN_VERSION,
|
|
|
|
NULL,
|
|
|
|
"RGB*, GRAY*",
|
2000-08-22 09:26:57 +08:00
|
|
|
GIMP_PLUGIN,
|
2001-12-06 10:28:58 +08:00
|
|
|
G_N_ELEMENTS (args), 0,
|
2000-04-16 06:40:05 +08:00
|
|
|
args, NULL);
|
2000-01-13 23:39:26 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2003-07-02 02:54:28 +08:00
|
|
|
run (const gchar *name,
|
|
|
|
gint nparams,
|
|
|
|
const GimpParam *param,
|
|
|
|
gint *nreturn_vals,
|
|
|
|
GimpParam **return_vals)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
static GimpParam values[1];
|
2000-01-13 23:39:26 +08:00
|
|
|
|
2001-12-19 08:13:16 +08:00
|
|
|
GimpRunMode run_mode;
|
2000-08-22 09:26:57 +08:00
|
|
|
GimpPDBStatusType status;
|
2000-01-13 23:39:26 +08:00
|
|
|
|
2003-03-26 00:38:19 +08:00
|
|
|
INIT_I18N ();
|
2000-01-13 23:39:26 +08:00
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
status = GIMP_PDB_SUCCESS;
|
2000-01-13 23:39:26 +08:00
|
|
|
run_mode = param[0].data.d_int32;
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
values[0].type = GIMP_PDB_STATUS;
|
2000-01-13 23:39:26 +08:00
|
|
|
values[0].data.d_status = status;
|
|
|
|
|
|
|
|
*nreturn_vals = 1;
|
|
|
|
*return_vals = values;
|
|
|
|
|
|
|
|
/* Get drawable information */
|
|
|
|
drawable = gimp_drawable_get (param[2].data.d_drawable);
|
|
|
|
|
2001-06-15 04:07:38 +08:00
|
|
|
gimp_drawable_mask_bounds (drawable->drawable_id,
|
|
|
|
&sel_x1, &sel_y1, &sel_x2, &sel_y2);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
sel_width = sel_x2 - sel_x1;
|
|
|
|
sel_height = sel_y2 - sel_y1;
|
2001-06-15 04:07:38 +08:00
|
|
|
img_bpp = gimp_drawable_bpp (drawable->drawable_id);
|
|
|
|
img_has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
/* See how we will run */
|
|
|
|
switch (run_mode)
|
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
case GIMP_RUN_INTERACTIVE:
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Possibly retrieve data */
|
2000-04-16 06:40:05 +08:00
|
|
|
gimp_get_data (name, &bmvals);
|
2003-11-06 23:27:05 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Get information from the dialog */
|
|
|
|
if (!bumpmap_dialog ())
|
|
|
|
return;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
case GIMP_RUN_NONINTERACTIVE:
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Make sure all the arguments are present */
|
|
|
|
if (nparams != 14)
|
2000-02-03 01:59:44 +08:00
|
|
|
{
|
2000-08-22 09:26:57 +08:00
|
|
|
status = GIMP_PDB_CALLING_ERROR;
|
2000-02-03 01:59:44 +08:00
|
|
|
}
|
|
|
|
else
|
2000-01-13 23:39:26 +08:00
|
|
|
{
|
|
|
|
bmvals.bumpmap_id = param[3].data.d_drawable;
|
|
|
|
bmvals.azimuth = param[4].data.d_float;
|
|
|
|
bmvals.elevation = param[5].data.d_float;
|
|
|
|
bmvals.depth = param[6].data.d_int32;
|
|
|
|
bmvals.depth = param[6].data.d_int32;
|
|
|
|
bmvals.xofs = param[7].data.d_int32;
|
|
|
|
bmvals.yofs = param[8].data.d_int32;
|
|
|
|
bmvals.waterlevel = param[9].data.d_int32;
|
|
|
|
bmvals.ambient = param[10].data.d_int32;
|
|
|
|
bmvals.compensate = param[11].data.d_int32;
|
|
|
|
bmvals.invert = param[12].data.d_int32;
|
|
|
|
bmvals.type = param[13].data.d_int32;
|
2003-11-06 23:27:05 +08:00
|
|
|
bmvals.tiled = strcmp (name, "plug_in_bump_map_tiled") == 0;
|
2000-01-13 23:39:26 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
case GIMP_RUN_WITH_LAST_VALS:
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Possibly retrieve data */
|
2000-04-16 06:40:05 +08:00
|
|
|
gimp_get_data (name, &bmvals);
|
2000-01-13 23:39:26 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Bumpmap the image */
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
if (status == GIMP_PDB_SUCCESS)
|
2000-01-13 23:39:26 +08:00
|
|
|
{
|
2001-06-15 04:07:38 +08:00
|
|
|
if ((gimp_drawable_is_rgb(drawable->drawable_id) ||
|
|
|
|
gimp_drawable_is_gray(drawable->drawable_id)))
|
2000-01-13 23:39:26 +08:00
|
|
|
{
|
|
|
|
/* Run! */
|
|
|
|
bumpmap ();
|
|
|
|
|
|
|
|
/* If run mode is interactive, flush displays */
|
2000-08-22 09:26:57 +08:00
|
|
|
if (run_mode != GIMP_RUN_NONINTERACTIVE)
|
2000-01-13 23:39:26 +08:00
|
|
|
gimp_displays_flush ();
|
|
|
|
|
|
|
|
/* Store data */
|
2000-08-22 09:26:57 +08:00
|
|
|
if (run_mode == GIMP_RUN_INTERACTIVE)
|
2000-04-16 06:40:05 +08:00
|
|
|
gimp_set_data (name, &bmvals, sizeof (bumpmap_vals_t));
|
2000-01-13 23:39:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2000-08-22 09:26:57 +08:00
|
|
|
status = GIMP_PDB_EXECUTION_ERROR;
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
values[0].data.d_status = status;
|
|
|
|
|
|
|
|
gimp_drawable_detach (drawable);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
1999-11-24 04:29:20 +08:00
|
|
|
bumpmap (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-13 23:39:26 +08:00
|
|
|
bumpmap_params_t params;
|
2003-04-17 20:06:03 +08:00
|
|
|
GimpDrawable *bm_drawable;
|
|
|
|
GimpPixelRgn src_rgn, dest_rgn, bm_rgn;
|
2000-02-03 01:59:44 +08:00
|
|
|
gint bm_width, bm_height, bm_bpp, bm_has_alpha;
|
|
|
|
gint yofs1, yofs2, yofs3;
|
2003-04-17 20:06:03 +08:00
|
|
|
gboolean row_in_bumpmap;
|
2000-01-13 23:39:26 +08:00
|
|
|
guchar *bm_row1, *bm_row2, *bm_row3, *bm_tmprow;
|
|
|
|
guchar *src_row, *dest_row;
|
2000-02-03 01:59:44 +08:00
|
|
|
gint y;
|
|
|
|
gint progress;
|
2001-04-23 23:46:23 +08:00
|
|
|
gint drawable_tiles_per_row, bm_tiles_per_row;
|
2000-01-13 23:39:26 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#if 0
|
2000-01-13 23:39:26 +08:00
|
|
|
g_print ("bumpmap: waiting... (pid %d)\n", getpid ());
|
|
|
|
kill (getpid (), SIGSTOP);
|
1997-11-25 06:05:25 +08:00
|
|
|
#endif
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
gimp_progress_init (_("Bump-mapping..."));
|
2003-11-06 23:27:05 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Get the bumpmap drawable */
|
|
|
|
if (bmvals.bumpmap_id != -1)
|
|
|
|
bm_drawable = gimp_drawable_get (bmvals.bumpmap_id);
|
|
|
|
else
|
|
|
|
bm_drawable = drawable;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
if (!bm_drawable)
|
|
|
|
return;
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Get image information */
|
2001-06-15 04:07:38 +08:00
|
|
|
bm_width = gimp_drawable_width (bm_drawable->drawable_id);
|
|
|
|
bm_height = gimp_drawable_height (bm_drawable->drawable_id);
|
|
|
|
bm_bpp = gimp_drawable_bpp (bm_drawable->drawable_id);
|
|
|
|
bm_has_alpha = gimp_drawable_has_alpha (bm_drawable->drawable_id);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-04-23 23:46:23 +08:00
|
|
|
/* Set the tile cache size */
|
|
|
|
/* Compute number of tiles needed for one row of the drawable */
|
|
|
|
drawable_tiles_per_row =
|
|
|
|
1
|
|
|
|
+ (sel_x2 + gimp_tile_width () - 1) / gimp_tile_width ()
|
|
|
|
- sel_x1 / gimp_tile_width ();
|
|
|
|
/* Compute number of tiles needed for one row of the bitmap */
|
|
|
|
bm_tiles_per_row = (bm_width + gimp_tile_width () - 1) / gimp_tile_width ();
|
|
|
|
/* Cache one row of source, destination and bitmap */
|
|
|
|
gimp_tile_cache_ntiles (bm_tiles_per_row + 2 * drawable_tiles_per_row);
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Initialize offsets */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-04-17 20:06:03 +08:00
|
|
|
if (bmvals.tiled)
|
|
|
|
{
|
|
|
|
yofs2 = MOD (bmvals.yofs + sel_y1, bm_height);
|
|
|
|
yofs1 = MOD (yofs2 - 1, bm_height);
|
|
|
|
yofs3 = MOD (yofs2 + 1, bm_height);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
yofs1 = 0;
|
|
|
|
yofs2 = 0;
|
|
|
|
yofs3 = CLAMP (yofs2 + 1, 0, bm_height - 1);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Initialize row buffers */
|
|
|
|
bm_row1 = g_new (guchar, bm_width * bm_bpp);
|
|
|
|
bm_row2 = g_new (guchar, bm_width * bm_bpp);
|
|
|
|
bm_row3 = g_new (guchar, bm_width * bm_bpp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
src_row = g_new (guchar, sel_width * img_bpp);
|
|
|
|
dest_row = g_new (guchar, sel_width * img_bpp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Initialize pixel regions */
|
|
|
|
gimp_pixel_rgn_init (&src_rgn, drawable,
|
|
|
|
sel_x1, sel_y1, sel_width, sel_height, FALSE, FALSE);
|
|
|
|
gimp_pixel_rgn_init (&dest_rgn, drawable,
|
|
|
|
sel_x1, sel_y1, sel_width, sel_height, TRUE, TRUE);
|
|
|
|
gimp_pixel_rgn_init (&bm_rgn, bm_drawable,
|
|
|
|
0, 0, bm_width, bm_height, FALSE, FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Bumpmap */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bumpmap_init_params (¶ms);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
gimp_pixel_rgn_get_row (&bm_rgn, bm_row1, 0, yofs1, bm_width);
|
|
|
|
gimp_pixel_rgn_get_row (&bm_rgn, bm_row2, 0, yofs2, bm_width);
|
|
|
|
gimp_pixel_rgn_get_row (&bm_rgn, bm_row3, 0, yofs3, bm_width);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bumpmap_convert_row (bm_row1, bm_width, bm_bpp, bm_has_alpha, params.lut);
|
|
|
|
bumpmap_convert_row (bm_row2, bm_width, bm_bpp, bm_has_alpha, params.lut);
|
|
|
|
bumpmap_convert_row (bm_row3, bm_width, bm_bpp, bm_has_alpha, params.lut);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
progress = 0;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
for (y = sel_y1; y < sel_y2; y++)
|
|
|
|
{
|
2003-04-17 20:06:03 +08:00
|
|
|
row_in_bumpmap = (y >= - bmvals.yofs && y < - bmvals.yofs + bm_height);
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
gimp_pixel_rgn_get_row (&src_rgn, src_row, sel_x1, y, sel_width);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bumpmap_row (src_row, dest_row, sel_width, img_bpp, img_has_alpha,
|
2000-04-16 06:40:05 +08:00
|
|
|
bm_row1, bm_row2, bm_row3, bm_width, bmvals.xofs,
|
2003-11-06 23:27:05 +08:00
|
|
|
bmvals.tiled,
|
2003-04-17 20:06:03 +08:00
|
|
|
row_in_bumpmap,
|
2000-04-16 06:40:05 +08:00
|
|
|
¶ms);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
gimp_pixel_rgn_set_row (&dest_rgn, dest_row, sel_x1, y, sel_width);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Next line */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-04-17 20:06:03 +08:00
|
|
|
if (bmvals.tiled || row_in_bumpmap)
|
|
|
|
{
|
|
|
|
bm_tmprow = bm_row1;
|
|
|
|
bm_row1 = bm_row2;
|
|
|
|
bm_row2 = bm_row3;
|
|
|
|
bm_row3 = bm_tmprow;
|
|
|
|
|
|
|
|
if (++yofs2 == bm_height)
|
|
|
|
yofs2 = 0;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-04-17 20:06:03 +08:00
|
|
|
if (bmvals.tiled)
|
|
|
|
yofs3 = MOD (yofs2 + 1, bm_height);
|
|
|
|
else
|
|
|
|
yofs3 = CLAMP (yofs2 + 1, 0, bm_height - 1);
|
|
|
|
|
|
|
|
gimp_pixel_rgn_get_row (&bm_rgn, bm_row3, 0, yofs3, bm_width);
|
|
|
|
bumpmap_convert_row (bm_row3, bm_width, bm_bpp, bm_has_alpha,
|
|
|
|
params.lut);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
gimp_progress_update ((double) ++progress / sel_height);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Done */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
g_free (bm_row1);
|
|
|
|
g_free (bm_row2);
|
|
|
|
g_free (bm_row3);
|
|
|
|
g_free (src_row);
|
|
|
|
g_free (dest_row);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (bm_drawable != drawable)
|
|
|
|
gimp_drawable_detach (bm_drawable);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
gimp_drawable_flush (drawable);
|
2001-06-15 04:07:38 +08:00
|
|
|
gimp_drawable_merge_shadow (drawable->drawable_id, TRUE);
|
|
|
|
gimp_drawable_update (drawable->drawable_id, sel_x1, sel_y1, sel_width, sel_height);
|
2000-01-13 23:39:26 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
1999-11-24 04:29:20 +08:00
|
|
|
bumpmap_init_params (bumpmap_params_t *params)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-02-03 01:59:44 +08:00
|
|
|
gdouble azimuth;
|
|
|
|
gdouble elevation;
|
|
|
|
gint lz, nz;
|
|
|
|
gint i;
|
|
|
|
gdouble n;
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
/* Convert to radians */
|
|
|
|
azimuth = G_PI * bmvals.azimuth / 180.0;
|
|
|
|
elevation = G_PI * bmvals.elevation / 180.0;
|
|
|
|
|
|
|
|
/* Calculate the light vector */
|
|
|
|
params->lx = cos(azimuth) * cos(elevation) * 255.0;
|
|
|
|
params->ly = sin(azimuth) * cos(elevation) * 255.0;
|
|
|
|
lz = sin(elevation) * 255.0;
|
|
|
|
|
|
|
|
/* Calculate constant Z component of surface normal */
|
|
|
|
nz = (6 * 255) / bmvals.depth;
|
|
|
|
params->nz2 = nz * nz;
|
|
|
|
params->nzlz = nz * lz;
|
|
|
|
|
|
|
|
/* Optimize for vertical normals */
|
|
|
|
params->background = lz;
|
|
|
|
|
|
|
|
/* Calculate darkness compensation factor */
|
|
|
|
params->compensation = sin(elevation);
|
|
|
|
|
|
|
|
/* Create look-up table for map type */
|
|
|
|
for (i = 0; i < 256; i++)
|
|
|
|
{
|
|
|
|
switch (bmvals.type)
|
|
|
|
{
|
|
|
|
case SPHERICAL:
|
|
|
|
n = i / 255.0 - 1.0;
|
|
|
|
params->lut[i] = (int) (255.0 * sqrt(1.0 - n * n) + 0.5);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SINUOSIDAL:
|
|
|
|
n = i / 255.0;
|
|
|
|
params->lut[i] = (int) (255.0 * (sin((-G_PI / 2.0) + G_PI * n) + 1.0) /
|
|
|
|
2.0 + 0.5);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LINEAR:
|
|
|
|
default:
|
|
|
|
params->lut[i] = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bmvals.invert)
|
|
|
|
params->lut[i] = 255 - params->lut[i];
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2000-04-16 06:40:05 +08:00
|
|
|
bumpmap_row (guchar *src,
|
|
|
|
guchar *dest,
|
2000-02-03 01:59:44 +08:00
|
|
|
gint width,
|
|
|
|
gint bpp,
|
|
|
|
gint has_alpha,
|
1999-11-24 04:29:20 +08:00
|
|
|
guchar *bm_row1,
|
|
|
|
guchar *bm_row2,
|
|
|
|
guchar *bm_row3,
|
2000-02-03 01:59:44 +08:00
|
|
|
gint bm_width,
|
|
|
|
gint bm_xofs,
|
2000-04-16 06:40:05 +08:00
|
|
|
gboolean tiled,
|
2003-11-06 23:27:05 +08:00
|
|
|
gboolean row_in_bumpmap,
|
1999-11-24 04:29:20 +08:00
|
|
|
bumpmap_params_t *params)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-04-21 03:00:40 +08:00
|
|
|
gint xofs1, xofs2, xofs3;
|
|
|
|
gint shade;
|
|
|
|
gint ndotl;
|
|
|
|
gint nx, ny;
|
|
|
|
gint x, k;
|
|
|
|
gint pbpp;
|
|
|
|
gint result;
|
|
|
|
gint tmp;
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
if (has_alpha)
|
|
|
|
pbpp = bpp - 1;
|
|
|
|
else
|
|
|
|
pbpp = bpp;
|
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
tmp = bm_xofs + sel_x1;
|
2003-04-17 20:06:03 +08:00
|
|
|
xofs2 = MOD (tmp, bm_width);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
for (x = 0; x < width; x++)
|
|
|
|
{
|
|
|
|
/* Calculate surface normal from bump map */
|
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
if (tiled || (row_in_bumpmap &&
|
2003-04-17 20:06:03 +08:00
|
|
|
x >= - tmp && x < - tmp + bm_width))
|
2000-04-16 06:40:05 +08:00
|
|
|
{
|
2003-04-17 20:06:03 +08:00
|
|
|
if (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);
|
|
|
|
}
|
2000-04-16 06:40:05 +08:00
|
|
|
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]);
|
|
|
|
}
|
2003-11-06 23:27:05 +08:00
|
|
|
else
|
2000-04-16 06:40:05 +08:00
|
|
|
{
|
|
|
|
nx = ny = 0;
|
|
|
|
}
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
/* Shade */
|
|
|
|
|
|
|
|
if ((nx == 0) && (ny == 0))
|
|
|
|
shade = params->background;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ndotl = nx * params->lx + ny * params->ly + params->nzlz;
|
|
|
|
|
|
|
|
if (ndotl < 0)
|
|
|
|
shade = params->compensation * bmvals.ambient;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
shade = ndotl / sqrt(nx * nx + ny * ny + params->nz2);
|
|
|
|
|
|
|
|
shade = shade + MAX(0, (255 * params->compensation - shade)) *
|
|
|
|
bmvals.ambient / 255;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Paint */
|
|
|
|
|
|
|
|
if (bmvals.compensate)
|
|
|
|
for (k = pbpp; k; k--)
|
|
|
|
{
|
|
|
|
result = (*src++ * shade) / (params->compensation * 255);
|
|
|
|
*dest++ = MIN(255, result);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
for (k = pbpp; k; k--)
|
|
|
|
*dest++ = *src++ * shade / 255;
|
|
|
|
|
|
|
|
if (has_alpha)
|
|
|
|
*dest++ = *src++;
|
|
|
|
|
|
|
|
/* Next pixel */
|
|
|
|
|
|
|
|
if (++xofs2 == bm_width)
|
|
|
|
xofs2 = 0;
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
bumpmap_convert_row (guchar *row,
|
|
|
|
gint width,
|
|
|
|
gint bpp,
|
|
|
|
gint has_alpha,
|
1999-11-24 04:29:20 +08:00
|
|
|
guchar *lut)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-13 23:39:26 +08:00
|
|
|
guchar *p;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
p = row;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
has_alpha = has_alpha ? 1 : 0;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (bpp >= 3)
|
|
|
|
for (; width; width--)
|
|
|
|
{
|
|
|
|
if (has_alpha)
|
|
|
|
*p++ = lut[(int) (bmvals.waterlevel +
|
2003-11-06 23:27:05 +08:00
|
|
|
(((int) (INTENSITY (row[0], row[1], row[2]) + 0.5) -
|
|
|
|
bmvals.waterlevel) *
|
2000-01-13 23:39:26 +08:00
|
|
|
row[3]) / 255.0)];
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
2000-01-31 07:56:04 +08:00
|
|
|
*p++ = lut[(int) (INTENSITY (row[0], row[1], row[2]) + 0.5)];
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
row += 3 + has_alpha;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
for (; width; width--)
|
|
|
|
{
|
|
|
|
if (has_alpha)
|
|
|
|
*p++ = lut[bmvals.waterlevel +
|
|
|
|
((row[0] - bmvals.waterlevel) * row[1]) / 255];
|
|
|
|
else
|
|
|
|
*p++ = lut[*row];
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
row += 1 + has_alpha;
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static gint
|
1999-11-24 04:29:20 +08:00
|
|
|
bumpmap_dialog (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-15 23:32:28 +08:00
|
|
|
GtkWidget *dialog;
|
2000-01-26 01:46:56 +08:00
|
|
|
GtkWidget *top_vbox;
|
|
|
|
GtkWidget *hbox;
|
2000-01-15 23:32:28 +08:00
|
|
|
GtkWidget *frame;
|
2000-04-16 06:40:05 +08:00
|
|
|
GtkWidget *preview;
|
2000-02-04 23:12:17 +08:00
|
|
|
GtkWidget *vbox;
|
2000-01-26 01:46:56 +08:00
|
|
|
GtkWidget *sep;
|
|
|
|
GtkWidget *abox;
|
|
|
|
GtkWidget *pframe;
|
2000-04-16 06:40:05 +08:00
|
|
|
GtkWidget *ptable;
|
|
|
|
GtkWidget *scrollbar;
|
2000-01-15 23:32:28 +08:00
|
|
|
GtkWidget *table;
|
|
|
|
GtkWidget *right_vbox;
|
|
|
|
GtkWidget *option_menu;
|
|
|
|
GtkWidget *menu;
|
|
|
|
GtkWidget *button;
|
|
|
|
GtkObject *adj;
|
2000-04-16 06:40:05 +08:00
|
|
|
gint i;
|
|
|
|
gint row;
|
2003-11-06 23:27:05 +08:00
|
|
|
gboolean run;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-05-01 05:03:44 +08:00
|
|
|
gimp_ui_init ("bumpmap", TRUE);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
dialog = gimp_dialog_new (_("Bump Map"), "bumpmap",
|
2003-11-06 23:27:05 +08:00
|
|
|
NULL, 0,
|
2000-05-23 01:10:28 +08:00
|
|
|
gimp_standard_help_func, "filters/bumpmap.html",
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
|
|
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
NULL);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
top_vbox = gtk_vbox_new (FALSE, 4);
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (top_vbox), 6);
|
|
|
|
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), top_vbox,
|
2000-01-13 23:39:26 +08:00
|
|
|
FALSE, FALSE, 0);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_widget_show (top_vbox);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
hbox = gtk_hbox_new (FALSE, 6);
|
|
|
|
gtk_box_pack_start (GTK_BOX (top_vbox), hbox, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (hbox);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
/* Preview */
|
|
|
|
abox = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
|
2000-04-16 06:40:05 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), abox, FALSE, FALSE, 0);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_widget_show (abox);
|
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
ptable = gtk_table_new (2, 2, FALSE);
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (ptable), 4);
|
|
|
|
gtk_container_add (GTK_CONTAINER (abox), ptable);
|
|
|
|
gtk_widget_show (ptable);
|
2003-11-06 23:27:05 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
pframe = gtk_frame_new (NULL);
|
|
|
|
gtk_frame_set_shadow_type (GTK_FRAME (pframe), GTK_SHADOW_IN);
|
2000-04-16 06:40:05 +08:00
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (pframe), 0);
|
2003-11-06 23:27:05 +08:00
|
|
|
gtk_table_attach (GTK_TABLE (ptable), pframe, 0, 1, 0, 1,
|
2000-04-16 06:40:05 +08:00
|
|
|
GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_widget_show (pframe);
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bmint.preview_width = MIN (sel_width, PREVIEW_SIZE);
|
|
|
|
bmint.preview_height = MIN (sel_height, PREVIEW_SIZE);
|
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
bmint.preview = preview = gtk_preview_new (GTK_PREVIEW_COLOR);
|
2000-01-13 23:39:26 +08:00
|
|
|
gtk_preview_size (GTK_PREVIEW (bmint.preview),
|
|
|
|
bmint.preview_width, bmint.preview_height);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_container_add (GTK_CONTAINER (pframe), bmint.preview);
|
2000-01-13 23:39:26 +08:00
|
|
|
gtk_widget_show (bmint.preview);
|
2003-11-06 23:27:05 +08:00
|
|
|
|
|
|
|
bmint.preview_adj_x =
|
2000-04-16 06:40:05 +08:00
|
|
|
gtk_adjustment_new (0, 0, sel_width, 1, 10, bmint.preview_width);
|
|
|
|
if (sel_width > PREVIEW_SIZE)
|
|
|
|
{
|
|
|
|
scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (bmint.preview_adj_x));
|
2003-11-06 23:27:05 +08:00
|
|
|
gtk_table_attach (GTK_TABLE (ptable), scrollbar, 0, 1, 1, 2,
|
2000-04-16 06:40:05 +08:00
|
|
|
GTK_FILL | GTK_EXPAND, 0, 0, 0);
|
|
|
|
gtk_widget_show (scrollbar);
|
|
|
|
}
|
2003-11-06 23:27:05 +08:00
|
|
|
|
|
|
|
bmint.preview_adj_y =
|
2000-04-16 06:40:05 +08:00
|
|
|
gtk_adjustment_new (0, 0, sel_height, 1, 10, bmint.preview_height);
|
|
|
|
if (sel_height > PREVIEW_SIZE)
|
|
|
|
{
|
|
|
|
scrollbar = gtk_vscrollbar_new (GTK_ADJUSTMENT (bmint.preview_adj_y));
|
2003-11-06 23:27:05 +08:00
|
|
|
gtk_table_attach (GTK_TABLE (ptable), scrollbar, 1, 2, 0,1,
|
2000-04-16 06:40:05 +08:00
|
|
|
0, GTK_FILL | GTK_EXPAND, 0, 0);
|
|
|
|
gtk_widget_show (scrollbar);
|
|
|
|
}
|
2000-01-13 23:39:26 +08:00
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
gtk_widget_set_events (bmint.preview,
|
2000-01-13 23:39:26 +08:00
|
|
|
GDK_BUTTON_PRESS_MASK |
|
2003-11-06 23:27:05 +08:00
|
|
|
GDK_BUTTON_RELEASE_MASK |
|
2000-01-13 23:39:26 +08:00
|
|
|
GDK_BUTTON_MOTION_MASK |
|
|
|
|
GDK_POINTER_MOTION_HINT_MASK);
|
2001-12-29 21:26:29 +08:00
|
|
|
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (bmint.preview, "event",
|
2001-12-29 21:26:29 +08:00
|
|
|
G_CALLBACK (dialog_preview_events),
|
|
|
|
NULL);
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (bmint.preview_adj_x, "value_changed",
|
2003-11-06 23:27:05 +08:00
|
|
|
G_CALLBACK (dialog_iscale_update_normal),
|
2001-12-29 21:26:29 +08:00
|
|
|
&bmint.preview_xofs);
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (bmint.preview_adj_y, "value_changed",
|
2003-11-06 23:27:05 +08:00
|
|
|
G_CALLBACK (dialog_iscale_update_normal),
|
2001-12-29 21:26:29 +08:00
|
|
|
&bmint.preview_yofs);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
dialog_init_preview ();
|
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
/* Type of map */
|
|
|
|
frame =
|
2003-11-15 02:05:39 +08:00
|
|
|
gimp_int_radio_group_new (TRUE, _("Map Type"),
|
|
|
|
G_CALLBACK (dialog_map_type_callback),
|
|
|
|
&bmvals.type, bmvals.type,
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2003-11-15 02:05:39 +08:00
|
|
|
_("_Linear Map"), LINEAR, NULL,
|
|
|
|
_("_Spherical Map"), SPHERICAL, NULL,
|
|
|
|
_("S_inuosidal Map"), SINUOSIDAL, NULL,
|
2000-01-26 01:46:56 +08:00
|
|
|
|
2003-11-15 02:05:39 +08:00
|
|
|
NULL);
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (frame);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
2000-01-26 01:46:56 +08:00
|
|
|
right_vbox = GTK_BIN (frame)->child;
|
|
|
|
|
|
|
|
sep = gtk_hseparator_new ();
|
|
|
|
gtk_box_pack_start (GTK_BOX (right_vbox), sep, FALSE, FALSE, 1);
|
|
|
|
gtk_widget_show (sep);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
/* Compensate darkening */
|
2002-06-09 00:18:25 +08:00
|
|
|
button = gtk_check_button_new_with_mnemonic (_("Co_mpensate for Darkening"));
|
2000-01-26 01:46:56 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (right_vbox), button, FALSE, FALSE, 0);
|
2000-04-16 06:40:05 +08:00
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
|
2000-01-13 23:39:26 +08:00
|
|
|
bmvals.compensate ? TRUE : FALSE);
|
|
|
|
gtk_widget_show (button);
|
|
|
|
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (button, "toggled",
|
2001-12-29 21:26:29 +08:00
|
|
|
G_CALLBACK (dialog_compensate_callback),
|
|
|
|
NULL);
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Invert bumpmap */
|
2002-06-09 00:18:25 +08:00
|
|
|
button = gtk_check_button_new_with_mnemonic (_("I_nvert Bumpmap"));
|
2000-01-13 23:39:26 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (right_vbox), button, FALSE, FALSE, 0);
|
2000-04-16 06:40:05 +08:00
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
|
2000-01-13 23:39:26 +08:00
|
|
|
bmvals.invert ? TRUE : FALSE);
|
|
|
|
gtk_widget_show (button);
|
|
|
|
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (button, "toggled",
|
2001-12-29 21:26:29 +08:00
|
|
|
G_CALLBACK (dialog_invert_callback),
|
|
|
|
NULL);
|
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
/* Tile bumpmap */
|
2002-06-09 00:18:25 +08:00
|
|
|
button = gtk_check_button_new_with_mnemonic (_("_Tile Bumpmap"));
|
2000-04-16 06:40:05 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (right_vbox), button, FALSE, FALSE, 0);
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
|
|
|
|
bmvals.tiled ? TRUE : FALSE);
|
2003-11-06 23:27:05 +08:00
|
|
|
gtk_widget_show (button);
|
2000-04-16 06:40:05 +08:00
|
|
|
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (button, "toggled",
|
2001-12-29 21:26:29 +08:00
|
|
|
G_CALLBACK (dialog_tiled_callback),
|
|
|
|
NULL);
|
|
|
|
|
2003-09-14 02:07:44 +08:00
|
|
|
vbox = gimp_parameter_settings_new (top_vbox, 0, 0);
|
2000-02-04 23:12:17 +08:00
|
|
|
|
|
|
|
/* Bump map menu */
|
|
|
|
table = gtk_table_new (1, 2, FALSE);
|
2000-01-13 23:39:26 +08:00
|
|
|
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
|
2000-02-04 23:12:17 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
|
2000-01-13 23:39:26 +08:00
|
|
|
gtk_widget_show (table);
|
|
|
|
|
|
|
|
option_menu = gtk_option_menu_new ();
|
|
|
|
menu = gimp_drawable_menu_new (dialog_constrain,
|
|
|
|
dialog_bumpmap_callback,
|
|
|
|
NULL,
|
|
|
|
bmvals.bumpmap_id);
|
2000-02-04 23:12:17 +08:00
|
|
|
gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
|
2000-01-31 11:13:02 +08:00
|
|
|
gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
|
2002-06-09 00:18:25 +08:00
|
|
|
_("_Bump Map:"), 1.0, 0.5,
|
2000-02-04 23:12:17 +08:00
|
|
|
option_menu, 2, TRUE);
|
|
|
|
|
|
|
|
sep = gtk_hseparator_new ();
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), sep, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (sep);
|
|
|
|
|
|
|
|
/* Table for bottom controls */
|
|
|
|
|
|
|
|
table = gtk_table_new (7, 3, FALSE);
|
|
|
|
gtk_table_set_col_spacings (GTK_TABLE (table), 4);
|
|
|
|
gtk_table_set_row_spacings (GTK_TABLE (table), 2);
|
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (table);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
/* Controls */
|
2000-02-04 23:12:17 +08:00
|
|
|
row = 0;
|
2000-01-13 23:39:26 +08:00
|
|
|
|
2000-02-04 23:12:17 +08:00
|
|
|
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
|
2002-09-07 04:44:47 +08:00
|
|
|
_("_Azimuth:"), SCALE_WIDTH, 6,
|
2000-01-15 23:32:28 +08:00
|
|
|
bmvals.azimuth, 0.0, 360.0, 1.0, 15.0, 2,
|
2000-02-04 23:12:17 +08:00
|
|
|
TRUE, 0, 0,
|
2000-01-15 23:32:28 +08:00
|
|
|
NULL, NULL);
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (adj, "value_changed",
|
2001-12-29 21:26:29 +08:00
|
|
|
G_CALLBACK (dialog_dscale_update),
|
|
|
|
&bmvals.azimuth);
|
2000-01-15 23:32:28 +08:00
|
|
|
|
2000-02-04 23:12:17 +08:00
|
|
|
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
|
2002-09-07 04:44:47 +08:00
|
|
|
_("_Elevation:"), SCALE_WIDTH, 6,
|
2000-01-15 23:32:28 +08:00
|
|
|
bmvals.elevation, 0.5, 90.0, 1.0, 5.0, 2,
|
2000-02-04 23:12:17 +08:00
|
|
|
TRUE, 0, 0,
|
2000-01-15 23:32:28 +08:00
|
|
|
NULL, NULL);
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (adj, "value_changed",
|
2001-12-29 21:26:29 +08:00
|
|
|
G_CALLBACK (dialog_dscale_update),
|
|
|
|
&bmvals.elevation);
|
2000-01-15 23:32:28 +08:00
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row,
|
2002-09-07 04:44:47 +08:00
|
|
|
_("_Depth:"), SCALE_WIDTH, 6,
|
2000-01-15 23:32:28 +08:00
|
|
|
bmvals.depth, 1.0, 65.0, 1.0, 5.0, 0,
|
2000-02-04 23:12:17 +08:00
|
|
|
TRUE, 0, 0,
|
2000-01-15 23:32:28 +08:00
|
|
|
NULL, NULL);
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (adj, "value_changed",
|
2001-12-29 21:26:29 +08:00
|
|
|
G_CALLBACK (dialog_iscale_update_normal),
|
|
|
|
&bmvals.depth);
|
2000-04-16 06:40:05 +08:00
|
|
|
gtk_table_set_row_spacing (GTK_TABLE (table), row++, 8);
|
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
bmint.offset_adj_x = adj =
|
2000-04-16 06:40:05 +08:00
|
|
|
gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
|
2002-09-07 04:44:47 +08:00
|
|
|
_("_X Offset:"), SCALE_WIDTH, 6,
|
2000-04-16 06:40:05 +08:00
|
|
|
bmvals.xofs, -1000.0, 1001.0, 1.0, 10.0, 0,
|
|
|
|
TRUE, 0, 0,
|
|
|
|
NULL, NULL);
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (adj, "value_changed",
|
2001-12-29 21:26:29 +08:00
|
|
|
G_CALLBACK (dialog_iscale_update_normal),
|
|
|
|
&bmvals.xofs);
|
2000-01-15 23:32:28 +08:00
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
bmint.offset_adj_y = adj =
|
2000-04-16 06:40:05 +08:00
|
|
|
gimp_scale_entry_new (GTK_TABLE (table), 0, row,
|
2002-09-07 04:44:47 +08:00
|
|
|
_("_Y Offset:"), SCALE_WIDTH, 6,
|
2000-04-16 06:40:05 +08:00
|
|
|
bmvals.yofs, -1000.0, 1001.0, 1.0, 10.0, 0,
|
|
|
|
TRUE, 0, 0,
|
|
|
|
NULL, NULL);
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (adj, "value_changed",
|
2001-12-29 21:26:29 +08:00
|
|
|
G_CALLBACK (dialog_iscale_update_normal),
|
|
|
|
&bmvals.yofs);
|
2000-04-16 06:40:05 +08:00
|
|
|
gtk_table_set_row_spacing (GTK_TABLE (table), row++, 8);
|
2000-01-15 23:32:28 +08:00
|
|
|
|
2000-02-04 23:12:17 +08:00
|
|
|
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
|
2002-09-07 04:44:47 +08:00
|
|
|
_("_Waterlevel:"), SCALE_WIDTH, 6,
|
2000-04-20 23:31:56 +08:00
|
|
|
bmvals.waterlevel, 0.0, 255.0, 1.0, 8.0, 0,
|
2000-02-04 23:12:17 +08:00
|
|
|
TRUE, 0, 0,
|
2000-01-15 23:32:28 +08:00
|
|
|
NULL, NULL);
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (adj, "value_changed",
|
2001-12-29 21:26:29 +08:00
|
|
|
G_CALLBACK (dialog_iscale_update_full),
|
|
|
|
&bmvals.waterlevel);
|
2000-01-15 23:32:28 +08:00
|
|
|
|
2000-02-04 23:12:17 +08:00
|
|
|
adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,
|
2002-09-07 04:44:47 +08:00
|
|
|
_("A_mbient:"), SCALE_WIDTH, 6,
|
2000-04-20 23:31:56 +08:00
|
|
|
bmvals.ambient, 0.0, 255.0, 1.0, 8.0, 0,
|
2000-02-04 23:12:17 +08:00
|
|
|
TRUE, 0, 0,
|
2000-01-15 23:32:28 +08:00
|
|
|
NULL, NULL);
|
2003-01-07 14:16:02 +08:00
|
|
|
g_signal_connect (adj, "value_changed",
|
2001-12-29 21:26:29 +08:00
|
|
|
G_CALLBACK (dialog_iscale_update_normal),
|
|
|
|
&bmvals.ambient);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
/* Done */
|
|
|
|
|
|
|
|
gtk_widget_show (dialog);
|
|
|
|
|
2003-11-12 02:11:56 +08:00
|
|
|
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
|
2003-11-06 23:27:05 +08:00
|
|
|
|
|
|
|
gtk_widget_destroy (dialog);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
g_free (bmint.check_row_0);
|
|
|
|
g_free (bmint.check_row_1);
|
|
|
|
|
|
|
|
for (i = 0; i < bmint.preview_height; i++)
|
|
|
|
g_free (bmint.src_rows[i]);
|
|
|
|
|
|
|
|
g_free (bmint.src_rows);
|
|
|
|
|
|
|
|
for (i = 0; i < (bmint.preview_height + 2); i++)
|
|
|
|
g_free (bmint.bm_rows[i]);
|
|
|
|
|
|
|
|
g_free (bmint.bm_rows);
|
|
|
|
|
|
|
|
if (bmint.bm_drawable != drawable)
|
|
|
|
gimp_drawable_detach (bmint.bm_drawable);
|
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
return run;
|
2000-01-13 23:39:26 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
1999-11-24 04:29:20 +08:00
|
|
|
dialog_init_preview (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-02-03 01:59:44 +08:00
|
|
|
gint x;
|
2003-11-06 23:27:05 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Create checkerboard rows */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bmint.check_row_0 = g_new (guchar, bmint.preview_width);
|
|
|
|
bmint.check_row_1 = g_new (guchar, bmint.preview_width);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
for (x = 0; x < bmint.preview_width; x++)
|
|
|
|
if ((x / GIMP_CHECK_SIZE) & 1)
|
|
|
|
{
|
2000-04-21 03:00:40 +08:00
|
|
|
bmint.check_row_0[x] = GIMP_CHECK_DARK * 255;
|
2000-01-13 23:39:26 +08:00
|
|
|
bmint.check_row_1[x] = GIMP_CHECK_LIGHT * 255;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bmint.check_row_0[x] = GIMP_CHECK_LIGHT * 255;
|
2000-04-21 03:00:40 +08:00
|
|
|
bmint.check_row_1[x] = GIMP_CHECK_DARK * 255;
|
2000-01-13 23:39:26 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Initialize source rows */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
gimp_pixel_rgn_init (&bmint.src_rgn, drawable,
|
|
|
|
sel_x1, sel_y1, sel_width, sel_height, FALSE, FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bmint.src_rows = g_new (guchar *, bmint.preview_height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
for (x = 0; x < bmint.preview_height; x++)
|
|
|
|
bmint.src_rows[x] = g_new (guchar, sel_width * 4);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
dialog_fill_src_rows (0,
|
|
|
|
bmint.preview_height,
|
|
|
|
sel_y1 + bmint.preview_yofs);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Initialize bumpmap rows */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bmint.bm_rows = g_new (guchar *, bmint.preview_height + 2);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
for (x = 0; x < (bmint.preview_height + 2); x++)
|
|
|
|
bmint.bm_rows[x] = NULL;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static gint
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_preview_events (GtkWidget *widget,
|
1999-11-24 04:29:20 +08:00
|
|
|
GdkEvent *event)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-13 23:39:26 +08:00
|
|
|
gint x, y;
|
|
|
|
gint dx, dy;
|
|
|
|
GdkEventButton *bevent;
|
2003-11-06 23:27:05 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
gtk_widget_get_pointer (widget, &x, &y);
|
|
|
|
|
|
|
|
bevent = (GdkEventButton *) event;
|
|
|
|
|
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case GDK_BUTTON_PRESS:
|
|
|
|
switch (bevent->button)
|
|
|
|
{
|
|
|
|
case 1:
|
2003-11-06 23:27:05 +08:00
|
|
|
case 2:
|
2000-01-13 23:39:26 +08:00
|
|
|
if (bevent->state & GDK_SHIFT_MASK)
|
|
|
|
bmint.drag_mode = DRAG_BUMPMAP;
|
|
|
|
else
|
|
|
|
bmint.drag_mode = DRAG_SCROLL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
bmint.drag_mode = DRAG_BUMPMAP;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bmint.mouse_x = x;
|
|
|
|
bmint.mouse_y = y;
|
|
|
|
|
|
|
|
gtk_grab_add (widget);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GDK_BUTTON_RELEASE:
|
|
|
|
if (bmint.drag_mode != DRAG_NONE)
|
|
|
|
{
|
|
|
|
gtk_grab_remove (widget);
|
|
|
|
bmint.drag_mode = DRAG_NONE;
|
|
|
|
dialog_update_preview ();
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GDK_MOTION_NOTIFY:
|
|
|
|
dx = x - bmint.mouse_x;
|
|
|
|
dy = y - bmint.mouse_y;
|
|
|
|
|
|
|
|
bmint.mouse_x = x;
|
|
|
|
bmint.mouse_y = y;
|
|
|
|
|
|
|
|
if ((dx == 0) && (dy == 0))
|
|
|
|
break;
|
|
|
|
|
|
|
|
switch (bmint.drag_mode)
|
|
|
|
{
|
|
|
|
case DRAG_SCROLL:
|
|
|
|
bmint.preview_xofs = CLAMP (bmint.preview_xofs - dx,
|
|
|
|
0,
|
|
|
|
sel_width - bmint.preview_width);
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_block_by_func (bmint.preview_adj_x,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmint.preview_xofs);
|
2003-11-06 23:27:05 +08:00
|
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (bmint.preview_adj_x),
|
2000-04-16 06:40:05 +08:00
|
|
|
bmint.preview_xofs);
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_unblock_by_func (bmint.preview_adj_x,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmint.preview_xofs);
|
2000-01-13 23:39:26 +08:00
|
|
|
bmint.preview_yofs = CLAMP (bmint.preview_yofs - dy,
|
|
|
|
0,
|
|
|
|
sel_height - bmint.preview_height);
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_block_by_func (bmint.preview_adj_y,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmint.preview_yofs);
|
2003-11-06 23:27:05 +08:00
|
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (bmint.preview_adj_y),
|
2000-04-16 06:40:05 +08:00
|
|
|
bmint.preview_yofs);
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_unblock_by_func (bmint.preview_adj_y,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmint.preview_yofs);
|
2003-11-06 23:27:05 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DRAG_BUMPMAP:
|
|
|
|
bmvals.xofs = CLAMP (bmvals.xofs - dx, -1000, 1000);
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_block_by_func (bmint.offset_adj_x,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmvals.xofs);
|
2003-11-06 23:27:05 +08:00
|
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (bmint.offset_adj_x),
|
2000-04-16 06:40:05 +08:00
|
|
|
bmvals.xofs);
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_unblock_by_func (bmint.offset_adj_x,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmvals.xofs);
|
2000-04-16 06:40:05 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bmvals.yofs = CLAMP (bmvals.yofs - dy, -1000, 1000);
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_block_by_func (bmint.offset_adj_y,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmvals.yofs);
|
2003-11-06 23:27:05 +08:00
|
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (bmint.offset_adj_y),
|
2000-04-16 06:40:05 +08:00
|
|
|
bmvals.yofs);
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_unblock_by_func (bmint.offset_adj_y,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmvals.yofs);
|
2000-04-16 06:40:05 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
dialog_update_preview ();
|
2000-04-16 06:40:05 +08:00
|
|
|
|
2003-11-06 23:27:05 +08:00
|
|
|
break;
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2000-04-21 03:00:40 +08:00
|
|
|
dialog_new_bumpmap (gboolean init_offsets)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-04-16 06:40:05 +08:00
|
|
|
GtkAdjustment *adj;
|
|
|
|
gint i;
|
|
|
|
gint yofs;
|
|
|
|
gint bump_offset_x;
|
|
|
|
gint bump_offset_y;
|
|
|
|
gint draw_offset_y;
|
|
|
|
gint draw_offset_x;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Get drawable */
|
|
|
|
if (bmint.bm_drawable && (bmint.bm_drawable != drawable))
|
|
|
|
gimp_drawable_detach (bmint.bm_drawable);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (bmvals.bumpmap_id != -1)
|
|
|
|
bmint.bm_drawable = gimp_drawable_get (bmvals.bumpmap_id);
|
|
|
|
else
|
|
|
|
bmint.bm_drawable = drawable;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
if (!bmint.bm_drawable)
|
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
/* Get sizes */
|
2001-06-15 04:07:38 +08:00
|
|
|
bmint.bm_width = gimp_drawable_width (bmint.bm_drawable->drawable_id);
|
|
|
|
bmint.bm_height = gimp_drawable_height (bmint.bm_drawable->drawable_id);
|
|
|
|
bmint.bm_bpp = gimp_drawable_bpp (bmint.bm_drawable->drawable_id);
|
|
|
|
bmint.bm_has_alpha = gimp_drawable_has_alpha (bmint.bm_drawable->drawable_id);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-04-21 03:00:40 +08:00
|
|
|
if (init_offsets)
|
2003-11-06 23:27:05 +08:00
|
|
|
{
|
2001-06-15 04:07:38 +08:00
|
|
|
gimp_drawable_offsets (bmint.bm_drawable->drawable_id,
|
|
|
|
&bump_offset_x, &bump_offset_y);
|
|
|
|
gimp_drawable_offsets (drawable->drawable_id,
|
|
|
|
&draw_offset_x, &draw_offset_y);
|
2003-11-06 23:27:05 +08:00
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
bmvals.xofs = draw_offset_x - bump_offset_x;
|
|
|
|
bmvals.yofs = draw_offset_y - bump_offset_y;
|
|
|
|
}
|
|
|
|
|
|
|
|
adj = (GtkAdjustment *) bmint.offset_adj_x;
|
|
|
|
if (adj)
|
|
|
|
{
|
|
|
|
adj->value = bmvals.xofs;
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_block_by_func (adj,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmvals.xofs);
|
2000-04-16 06:40:05 +08:00
|
|
|
gtk_adjustment_value_changed (adj);
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_unblock_by_func (adj,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmvals.xofs);
|
2000-04-16 06:40:05 +08:00
|
|
|
}
|
2003-11-06 23:27:05 +08:00
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
adj = (GtkAdjustment *) bmint.offset_adj_y;
|
|
|
|
if (adj)
|
|
|
|
{
|
|
|
|
adj->value = bmvals.yofs;
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_block_by_func (adj,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmvals.yofs);
|
2000-04-16 06:40:05 +08:00
|
|
|
gtk_adjustment_value_changed (adj);
|
2003-02-28 09:14:30 +08:00
|
|
|
g_signal_handlers_unblock_by_func (adj,
|
|
|
|
dialog_iscale_update_normal,
|
|
|
|
&bmvals.yofs);
|
2000-04-16 06:40:05 +08:00
|
|
|
}
|
2003-11-06 23:27:05 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Initialize pixel region */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
gimp_pixel_rgn_init (&bmint.bm_rgn, bmint.bm_drawable,
|
|
|
|
0, 0, bmint.bm_width, bmint.bm_height, FALSE, FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Initialize row buffers */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
yofs = bmvals.yofs + bmint.preview_yofs - 1; /* Minus 1 for conv. matrix */
|
2003-04-17 20:06:03 +08:00
|
|
|
yofs = MOD (yofs, bmint.bm_height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bmint.bm_yofs = yofs;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
for (i = 0; i < (bmint.preview_height + 2); i++)
|
|
|
|
{
|
2002-06-09 00:18:25 +08:00
|
|
|
g_free (bmint.bm_rows[i]);
|
2000-04-16 06:40:05 +08:00
|
|
|
bmint.bm_rows[i] = g_new (guchar, bmint.bm_width * bmint.bm_bpp);
|
2000-01-13 23:39:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bumpmap_init_params (&bmint.params);
|
|
|
|
dialog_fill_bumpmap_rows (0, bmint.preview_height + 2, yofs);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
1999-11-24 04:29:20 +08:00
|
|
|
dialog_update_preview (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-13 23:39:26 +08:00
|
|
|
static guchar dest_row[PREVIEW_SIZE * 4];
|
|
|
|
static guchar preview_row[PREVIEW_SIZE * 3];
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-02-03 01:59:44 +08:00
|
|
|
guchar *check_row;
|
|
|
|
guchar check;
|
|
|
|
gint xofs;
|
|
|
|
gint x, y;
|
|
|
|
guchar *sp, *p;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bumpmap_init_params (&bmint.params);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Scroll the row buffers */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
dialog_scroll_src ();
|
|
|
|
dialog_scroll_bumpmap ();
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Bumpmap */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
xofs = bmint.preview_xofs;
|
|
|
|
|
|
|
|
for (y = 0; y < bmint.preview_height; y++)
|
|
|
|
{
|
2003-04-17 20:06:03 +08:00
|
|
|
gint isfirst = ((y == - bmvals.yofs - bmint.preview_yofs - sel_y1)
|
|
|
|
&& ! bmvals.tiled) ? 1 : 0;
|
|
|
|
gint islast = (y == (- bmvals.yofs - bmint.preview_yofs - sel_y1
|
|
|
|
+ bmint.bm_height - 1) && ! bmvals.tiled) ? 1 : 0;
|
2000-01-13 23:39:26 +08:00
|
|
|
bumpmap_row (bmint.src_rows[y] + 4 * xofs, dest_row,
|
|
|
|
bmint.preview_width, 4, TRUE,
|
2003-04-17 20:06:03 +08:00
|
|
|
bmint.bm_rows[y + isfirst],
|
2000-04-16 06:40:05 +08:00
|
|
|
bmint.bm_rows[y + 1],
|
2003-04-17 20:06:03 +08:00
|
|
|
bmint.bm_rows[y + 2 - islast],
|
2000-04-16 06:40:05 +08:00
|
|
|
bmint.bm_width, xofs + bmvals.xofs,
|
2003-11-06 23:27:05 +08:00
|
|
|
bmvals.tiled,
|
2003-04-17 20:06:03 +08:00
|
|
|
y >= - bmvals.yofs - bmint.preview_yofs - sel_y1 &&
|
|
|
|
y < (- bmvals.yofs - bmint.preview_yofs - sel_y1
|
|
|
|
+ bmint.bm_height),
|
2000-04-16 06:40:05 +08:00
|
|
|
&bmint.params);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Paint row */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
sp = dest_row;
|
|
|
|
p = preview_row;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if ((y / GIMP_CHECK_SIZE) & 1)
|
|
|
|
check_row = bmint.check_row_0;
|
|
|
|
else
|
|
|
|
check_row = bmint.check_row_1;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
for (x = 0; x < bmint.preview_width; x++)
|
|
|
|
{
|
|
|
|
check = check_row[x];
|
|
|
|
|
|
|
|
p[0] = check + ((sp[0] - check) * sp[3]) / 255;
|
|
|
|
p[1] = check + ((sp[1] - check) * sp[3]) / 255;
|
|
|
|
p[2] = check + ((sp[2] - check) * sp[3]) / 255;
|
|
|
|
|
|
|
|
sp += 4;
|
|
|
|
p += 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
gtk_preview_draw_row (GTK_PREVIEW(bmint.preview),
|
|
|
|
preview_row, 0, y, bmint.preview_width);
|
|
|
|
}
|
|
|
|
|
2001-12-29 21:26:29 +08:00
|
|
|
gtk_widget_queue_draw (bmint.preview);
|
2000-01-13 23:39:26 +08:00
|
|
|
gdk_flush ();
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
#define SWAP_ROWS(a, b, t) { t = a; a = b; b = t; }
|
|
|
|
|
|
|
|
static void
|
1999-11-24 04:29:20 +08:00
|
|
|
dialog_scroll_src (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-02-03 01:59:44 +08:00
|
|
|
gint yofs;
|
|
|
|
gint y, ofs;
|
2000-01-13 23:39:26 +08:00
|
|
|
guchar *tmp;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
yofs = bmint.preview_yofs;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (yofs == bmint.src_yofs)
|
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (yofs < bmint.src_yofs)
|
|
|
|
{
|
|
|
|
ofs = bmint.src_yofs - yofs;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Scroll useful rows... */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (ofs < bmint.preview_height)
|
|
|
|
for (y = (bmint.preview_height - 1); y >= ofs; y--)
|
|
|
|
SWAP_ROWS (bmint.src_rows[y], bmint.src_rows[y - ofs], tmp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* ... and get the new ones */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
dialog_fill_src_rows (0, MIN (ofs, bmint.preview_height), sel_y1 + yofs);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ofs = yofs - bmint.src_yofs;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Scroll useful rows... */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (ofs < bmint.preview_height)
|
|
|
|
for (y = 0; y < (bmint.preview_height - ofs); y++)
|
|
|
|
SWAP_ROWS (bmint.src_rows[y], bmint.src_rows[y + ofs], tmp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* ... and get the new ones */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
dialog_fill_src_rows ((bmint.preview_height -
|
|
|
|
MIN (ofs, bmint.preview_height)),
|
|
|
|
MIN (ofs, bmint.preview_height),
|
|
|
|
(sel_y1 + yofs + bmint.preview_height -
|
|
|
|
MIN (ofs, bmint.preview_height)));
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bmint.src_yofs = yofs;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
1999-11-24 04:29:20 +08:00
|
|
|
dialog_scroll_bumpmap (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-02-03 01:59:44 +08:00
|
|
|
gint yofs;
|
|
|
|
gint y, ofs;
|
2000-01-13 23:39:26 +08:00
|
|
|
guchar *tmp;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
yofs = bmvals.yofs + bmint.preview_yofs - 1; /* Minus 1 for conv. matrix */
|
2003-04-17 20:06:03 +08:00
|
|
|
yofs = MOD (yofs, bmint.bm_height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (yofs == bmint.bm_yofs)
|
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (yofs < bmint.bm_yofs)
|
|
|
|
{
|
|
|
|
ofs = bmint.bm_yofs - yofs;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Scroll useful rows... */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (ofs < (bmint.preview_height + 2))
|
|
|
|
for (y = (bmint.preview_height + 1); y >= ofs; y--)
|
|
|
|
SWAP_ROWS (bmint.bm_rows[y], bmint.bm_rows[y - ofs], tmp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* ... and get the new ones */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
dialog_fill_bumpmap_rows (0,
|
|
|
|
MIN (ofs, bmint.preview_height + 2),
|
|
|
|
yofs);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ofs = yofs - bmint.bm_yofs;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* Scroll useful rows... */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (ofs < (bmint.preview_height + 2))
|
|
|
|
for (y = 0; y < (bmint.preview_height + 2 - ofs); y++)
|
|
|
|
SWAP_ROWS (bmint.bm_rows[y], bmint.bm_rows[y + ofs], tmp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
/* ... and get the new ones */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
dialog_fill_bumpmap_rows ((bmint.preview_height + 2 -
|
|
|
|
MIN (ofs, bmint.preview_height + 2)),
|
|
|
|
MIN (ofs, bmint.preview_height + 2),
|
|
|
|
(yofs + bmint.preview_height + 2 -
|
|
|
|
MIN (ofs, bmint.preview_height + 2)) %
|
|
|
|
bmint.bm_height);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bmint.bm_yofs = yofs;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_get_rows (GimpPixelRgn *pr,
|
|
|
|
guchar **rows,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint width,
|
2000-02-03 01:59:44 +08:00
|
|
|
gint height)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-13 23:39:26 +08:00
|
|
|
/* This is shamelessly ripped off from gimp_pixel_rgn_get_rect().
|
|
|
|
* Its function is exactly the same, but it can fetch an image
|
|
|
|
* rectangle to a sparse buffer which is defined as separate
|
|
|
|
* rows instead of one big linear region.
|
|
|
|
*/
|
|
|
|
|
2000-08-22 09:26:57 +08:00
|
|
|
GimpTile *tile;
|
2000-01-13 23:39:26 +08:00
|
|
|
guchar *src, *dest;
|
2000-02-03 01:59:44 +08:00
|
|
|
gint xstart, ystart;
|
|
|
|
gint xend, yend;
|
|
|
|
gint xboundary;
|
|
|
|
gint yboundary;
|
|
|
|
gint xstep, ystep;
|
|
|
|
gint b, bpp;
|
|
|
|
gint tx, ty;
|
|
|
|
gint tile_width, tile_height;
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
tile_width = gimp_tile_width();
|
|
|
|
tile_height = gimp_tile_height();
|
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
bpp = pr->bpp;
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
xstart = x;
|
|
|
|
ystart = y;
|
|
|
|
xend = x + width;
|
|
|
|
yend = y + height;
|
|
|
|
ystep = 0; /* Shut up -Wall */
|
|
|
|
|
|
|
|
while (y < yend)
|
|
|
|
{
|
|
|
|
x = xstart;
|
|
|
|
|
|
|
|
while (x < xend)
|
|
|
|
{
|
|
|
|
tile = gimp_drawable_get_tile2 (pr->drawable, pr->shadow, x, y);
|
|
|
|
gimp_tile_ref (tile);
|
|
|
|
|
|
|
|
xstep = tile->ewidth - (x % tile_width);
|
|
|
|
ystep = tile->eheight - (y % tile_height);
|
|
|
|
xboundary = x + xstep;
|
|
|
|
yboundary = y + ystep;
|
|
|
|
xboundary = MIN (xboundary, xend);
|
|
|
|
yboundary = MIN (yboundary, yend);
|
|
|
|
|
|
|
|
for (ty = y; ty < yboundary; ty++)
|
|
|
|
{
|
|
|
|
src = tile->data + tile->bpp * (tile->ewidth * (ty % tile_height) +
|
|
|
|
(x % tile_width));
|
|
|
|
dest = rows[ty - ystart] + bpp * (x - xstart);
|
|
|
|
|
|
|
|
for (tx = x; tx < xboundary; tx++)
|
|
|
|
for (b = bpp; b; b--)
|
|
|
|
*dest++ = *src++;
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_tile_unref (tile, FALSE);
|
|
|
|
|
|
|
|
x += xstep;
|
|
|
|
}
|
|
|
|
|
|
|
|
y += ystep;
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_fill_src_rows (gint start,
|
|
|
|
gint how_many,
|
2000-02-03 01:59:44 +08:00
|
|
|
gint yofs)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-04-16 06:40:05 +08:00
|
|
|
gint x;
|
|
|
|
gint y;
|
|
|
|
guchar *sp;
|
|
|
|
guchar *p;
|
2000-01-13 23:39:26 +08:00
|
|
|
|
|
|
|
dialog_get_rows (&bmint.src_rgn,
|
|
|
|
bmint.src_rows + start,
|
|
|
|
sel_x1,
|
|
|
|
yofs,
|
|
|
|
sel_width,
|
|
|
|
how_many);
|
|
|
|
|
|
|
|
/* Convert to RGBA. We move backwards! */
|
|
|
|
|
|
|
|
for (y = start; y < (start + how_many); y++)
|
|
|
|
{
|
|
|
|
sp = bmint.src_rows[y] + img_bpp * sel_width - 1;
|
|
|
|
p = bmint.src_rows[y] + 4 * sel_width - 1;
|
|
|
|
|
|
|
|
for (x = 0; x < sel_width; x++)
|
|
|
|
{
|
|
|
|
if (img_has_alpha)
|
|
|
|
*p-- = *sp--;
|
|
|
|
else
|
|
|
|
*p-- = 255;
|
|
|
|
|
|
|
|
if (img_bpp < 3)
|
|
|
|
{
|
|
|
|
*p-- = *sp;
|
|
|
|
*p-- = *sp;
|
|
|
|
*p-- = *sp--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*p-- = *sp--;
|
|
|
|
*p-- = *sp--;
|
|
|
|
*p-- = *sp--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_fill_bumpmap_rows (gint start,
|
|
|
|
gint how_many,
|
2000-02-03 01:59:44 +08:00
|
|
|
gint yofs)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-02-03 01:59:44 +08:00
|
|
|
gint buf_row_ofs;
|
|
|
|
gint remaining;
|
|
|
|
gint this_pass;
|
2000-01-13 23:39:26 +08:00
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
/* Adapt to offset of selection */
|
2003-04-17 20:06:03 +08:00
|
|
|
yofs = MOD (yofs + sel_y1, bmint.bm_height);
|
2000-04-16 06:40:05 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
buf_row_ofs = start;
|
|
|
|
remaining = how_many;
|
|
|
|
|
|
|
|
while (remaining > 0)
|
|
|
|
{
|
|
|
|
this_pass = MIN (remaining, bmint.bm_height - yofs);
|
|
|
|
|
|
|
|
dialog_get_rows (&bmint.bm_rgn,
|
|
|
|
bmint.bm_rows + buf_row_ofs,
|
|
|
|
0,
|
|
|
|
yofs,
|
|
|
|
bmint.bm_width,
|
|
|
|
this_pass);
|
|
|
|
|
|
|
|
yofs = (yofs + this_pass) % bmint.bm_height;
|
|
|
|
remaining -= this_pass;
|
|
|
|
buf_row_ofs += this_pass;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert rows */
|
|
|
|
|
|
|
|
for (; how_many; how_many--)
|
|
|
|
{
|
|
|
|
bumpmap_convert_row (bmint.bm_rows[start],
|
|
|
|
bmint.bm_width,
|
|
|
|
bmint.bm_bpp,
|
|
|
|
bmint.bm_has_alpha,
|
|
|
|
bmint.params.lut);
|
|
|
|
|
|
|
|
start++;
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_compensate_callback (GtkWidget *widget,
|
1999-11-24 04:29:20 +08:00
|
|
|
gpointer data)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-13 23:39:26 +08:00
|
|
|
bmvals.compensate = GTK_TOGGLE_BUTTON (widget)->active;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
dialog_update_preview ();
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_invert_callback (GtkWidget *widget,
|
1999-11-24 04:29:20 +08:00
|
|
|
gpointer data)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-13 23:39:26 +08:00
|
|
|
bmvals.invert = GTK_TOGGLE_BUTTON (widget)->active;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
bumpmap_init_params (&bmint.params);
|
|
|
|
dialog_fill_bumpmap_rows (0, bmint.preview_height + 2, bmint.bm_yofs);
|
|
|
|
dialog_update_preview ();
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-04-16 06:40:05 +08:00
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_tiled_callback (GtkWidget *widget,
|
2000-04-16 06:40:05 +08:00
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
bmvals.tiled = GTK_TOGGLE_BUTTON (widget)->active;
|
|
|
|
|
|
|
|
bumpmap_init_params (&bmint.params);
|
|
|
|
dialog_fill_bumpmap_rows (0, bmint.preview_height + 2, bmint.bm_yofs);
|
|
|
|
dialog_update_preview ();
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_map_type_callback (GtkWidget *widget,
|
1999-11-24 04:29:20 +08:00
|
|
|
gpointer data)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-15 23:32:28 +08:00
|
|
|
gimp_radio_button_update (widget, data);
|
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
if (GTK_TOGGLE_BUTTON (widget)->active)
|
|
|
|
{
|
|
|
|
bumpmap_init_params (&bmint.params);
|
|
|
|
dialog_fill_bumpmap_rows (0, bmint.preview_height + 2, bmint.bm_yofs);
|
|
|
|
dialog_update_preview ();
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static gint
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_constrain (gint32 image_id,
|
|
|
|
gint32 drawable_id,
|
1999-11-24 04:29:20 +08:00
|
|
|
gpointer data)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-13 23:39:26 +08:00
|
|
|
if (drawable_id == -1)
|
|
|
|
return TRUE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-13 23:39:26 +08:00
|
|
|
return (gimp_drawable_is_rgb (drawable_id) ||
|
|
|
|
gimp_drawable_is_gray (drawable_id));
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_bumpmap_callback (gint32 id,
|
1999-11-24 04:29:20 +08:00
|
|
|
gpointer data)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-04-21 03:00:40 +08:00
|
|
|
if (bmvals.bumpmap_id == id)
|
|
|
|
{
|
|
|
|
dialog_new_bumpmap (FALSE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bmvals.bumpmap_id = id;
|
|
|
|
dialog_new_bumpmap (TRUE);
|
|
|
|
}
|
2000-01-13 23:39:26 +08:00
|
|
|
dialog_update_preview ();
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_dscale_update (GtkAdjustment *adjustment,
|
1999-11-24 04:29:20 +08:00
|
|
|
gdouble *value)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-15 23:32:28 +08:00
|
|
|
gimp_double_adjustment_update (adjustment, value);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
2000-01-15 23:32:28 +08:00
|
|
|
dialog_update_preview ();
|
2000-01-13 23:39:26 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_iscale_update_normal (GtkAdjustment *adjustment,
|
1999-11-24 04:29:20 +08:00
|
|
|
gint *value)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-15 23:32:28 +08:00
|
|
|
gimp_int_adjustment_update (adjustment, value);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-15 23:32:28 +08:00
|
|
|
dialog_update_preview ();
|
2000-01-13 23:39:26 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2003-11-06 23:27:05 +08:00
|
|
|
dialog_iscale_update_full (GtkAdjustment *adjustment,
|
1999-11-24 04:29:20 +08:00
|
|
|
gint *value)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-01-15 23:32:28 +08:00
|
|
|
gimp_int_adjustment_update (adjustment, value);
|
2000-01-13 23:39:26 +08:00
|
|
|
|
2000-01-15 23:32:28 +08:00
|
|
|
bumpmap_init_params (&bmint.params);
|
|
|
|
dialog_fill_bumpmap_rows (0, bmint.preview_height + 2, bmint.bm_yofs);
|
|
|
|
dialog_update_preview ();
|
2000-01-13 23:39:26 +08:00
|
|
|
}
|