1998-06-11 14:04:59 +08:00
|
|
|
/*************************************************/
|
|
|
|
/* Compute a preview image and preview wireframe */
|
|
|
|
/*************************************************/
|
|
|
|
|
2000-12-30 08:23:34 +08:00
|
|
|
#include "config.h"
|
2000-02-18 21:59:18 +08:00
|
|
|
|
2003-12-15 01:17:56 +08:00
|
|
|
#include <gtk/gtk.h>
|
2000-02-18 21:59:18 +08:00
|
|
|
|
2003-12-15 01:17:56 +08:00
|
|
|
#include <libgimp/gimp.h>
|
|
|
|
#include <libgimpmath/gimpmath.h>
|
2000-02-18 21:59:18 +08:00
|
|
|
|
2008-03-25 02:33:25 +08:00
|
|
|
#include "lighting-main.h"
|
|
|
|
#include "lighting-ui.h"
|
|
|
|
#include "lighting-image.h"
|
|
|
|
#include "lighting-apply.h"
|
|
|
|
#include "lighting-shade.h"
|
|
|
|
|
|
|
|
#include "lighting-preview.h"
|
2000-02-18 21:59:18 +08:00
|
|
|
|
1998-06-11 14:04:59 +08:00
|
|
|
|
2002-10-17 05:18:11 +08:00
|
|
|
#define LIGHT_SYMBOL_SIZE 8
|
2000-12-30 08:23:34 +08:00
|
|
|
|
2008-03-29 17:25:34 +08:00
|
|
|
static gint handle_xpos = 0, handle_ypos = 0;
|
2002-12-18 04:18:16 +08:00
|
|
|
|
2002-10-17 05:18:11 +08:00
|
|
|
/* g_free()'ed on exit */
|
2000-02-18 21:59:18 +08:00
|
|
|
gdouble *xpostab = NULL;
|
|
|
|
gdouble *ypostab = NULL;
|
1998-06-11 14:04:59 +08:00
|
|
|
|
2004-07-17 03:41:21 +08:00
|
|
|
static gint xpostab_size = -1; /* if preview size change, do realloc */
|
2000-02-18 21:59:18 +08:00
|
|
|
static gint ypostab_size = -1;
|
applied gimp-lecorfec-99041[02]-0, changes follow
* applied gimp-lecorfec-99041[02]-0, changes follow
* plug-ins/FractalExplorer/Dialogs.h (make_color_map):
replaced free with g_free to fix segfault.
* plug-ins/Lighting/lighting_preview.c (compute_preview):
allocate xpostab and ypostab only when needed (it could also be
allocated on stack with a compilation-fixed size like MapObject).
It avoids to lose some Kb on each preview :)
Also reindented (unfortunate C-c C-q) some other lines.
* plug-ins/Lighting/lighting_main.c (run):
release allocated postabs.
* plug-ins/Lighting/lighting_ui.c:
callbacks now have only one argument because gck widget use
gtk_signal_connect_object. Caused segfault for scale widget.
* plug-ins/autocrop/autocrop.c (doit):
return if image has only background (thus fixing a segfault).
* plug-ins/emboss/emboss.c (pluginCore, emboss_do_preview):
replaced malloc/free with g_malloc/g_free (unneeded, but
shouldn't everyone use glib calls ? :)
* plug-ins/flame/flame.c :
replaced a segfaulting free, and several harmless malloc/free pairs.
* plug-ins/flame/megawidget.c (mw_preview_build):
replaced harmless malloc/free pair.
Note : mwp->bits is malloc'ed but seems to be never freed.
* plug-ins/fractaltrace/fractaltrace.c (pixels_free):
replaced a bunch of segfaulting free.
(pixels_get, dialog_show): replaced gtk_signal_connect_object
with gtk_signal_connect to accomodate callbacks (caused STRANGE
dialog behaviour, coz you destroyed buttons one by one).
* plug-ins/illusion/illusion.c (dialog):
same gtk_signal_connect_object replacement for same reasons.
* plug-ins/libgck/gck/gckcolor.c :
changed all gck_rgb_to_color* functions to use a static GdkColor
instead of a malloc'ed area. Provided reentrant functions with
the old behaviour (gck_rgb_to_color*_r). Made some private functions
static, too.
gck_rgb_to_gdkcolor now use the new functions while
gck_rgb_to_gdkcolor_r is the reentrant version.
Also affected by this change: gck_gc_set_foreground and
gck_gc_set_background (no more free(color)).
* plug-ins/libgck/gck/gckcolor.h :
added the gck_rgb_to_gdkcolor_r proto.
* plug-ins/lic/lic.c (ok_button_clicked, cancel_button_clicked) :
segfault on gtk_widget_destroy, now calls gtk_main_quit.
(dialog_destroy) : segfault on window closure when called by
"destroy" event. Now called by "delete_event".
* plug-ins/megawidget/megawidget.c (mw_preview_build):
replaced harmless malloc/free pair.
Note : mwp->bits is malloc'ed but seems to be never freed.
* plug-ins/png/png.c (load_image):
replaced 2 segfaulting free.
* plug-ins/print/print-ps.c (ps_print):
replaced a segfaulting free (called many times :).
* plug-ins/sgi/sgi.c (load_image, save_image):
replaced a bunch of segfaulting free, and did some harmless
inits to avoid a few gcc warnings.
* plug-ins/wind/wind.c (render_wind):
replaced a segfaulting free.
(render_blast): replaced harmless malloc/free pair.
* plug-ins/bmp/bmpread.c (ReadImage):
yet another free()/g_free() problem fixed.
* plug-ins/exchange/exchange.c (real_exchange):
ditto.
* plug-ins/fp/fp.h: added Frames_Check_Button_In_A_Box proto.
* plug-ins/fp/fp_gtk.c: closing subdialogs via window manager
wasn't handled, thus leading to errors and crashes.
Now delete_event signals the dialog control button
to close a dialog with the good way.
* plug-ins/ifscompose/ifscompose.c (value_pair_create):
tried to set events mask on scale widget (a NO_WINDOW widget).
* plug-ins/png/png.c (save_image):
Replaced 2 free() with g_free() for g_malloc'ed memory.
Mysteriously I corrected the loading bug but not the saving one :)
-Yosh
1999-04-16 05:49:09 +08:00
|
|
|
|
2010-11-01 02:03:18 +08:00
|
|
|
static gboolean light_hit = FALSE;
|
|
|
|
static gboolean left_button_pressed = FALSE;
|
2002-10-17 05:18:11 +08:00
|
|
|
static guint preview_update_timer = 0;
|
|
|
|
|
|
|
|
|
1998-06-11 14:04:59 +08:00
|
|
|
/* Protos */
|
|
|
|
/* ====== */
|
2003-01-31 11:08:29 +08:00
|
|
|
static gboolean
|
|
|
|
interactive_preview_timer_callback ( gpointer data );
|
1998-06-11 14:04:59 +08:00
|
|
|
|
2000-02-18 21:59:18 +08:00
|
|
|
static void
|
2002-10-17 05:18:11 +08:00
|
|
|
compute_preview (gint startx, gint starty, gint w, gint h)
|
1998-06-11 14:04:59 +08:00
|
|
|
{
|
2003-12-14 23:41:37 +08:00
|
|
|
gint xcnt, ycnt, f1, f2;
|
2010-11-01 02:03:18 +08:00
|
|
|
guchar r, g, b;
|
2003-12-14 23:41:37 +08:00
|
|
|
gdouble imagex, imagey;
|
|
|
|
gint32 index = 0;
|
|
|
|
GimpRGB color;
|
|
|
|
GimpRGB lightcheck, darkcheck;
|
|
|
|
GimpVector3 pos;
|
|
|
|
get_ray_func ray_func;
|
|
|
|
|
|
|
|
if (xpostab_size != w)
|
|
|
|
{
|
|
|
|
if (xpostab)
|
|
|
|
{
|
|
|
|
g_free (xpostab);
|
|
|
|
xpostab = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!xpostab)
|
|
|
|
{
|
|
|
|
xpostab = g_new (gdouble, w);
|
|
|
|
xpostab_size = w;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ypostab_size != h)
|
|
|
|
{
|
|
|
|
if (ypostab)
|
|
|
|
{
|
|
|
|
g_free (ypostab);
|
|
|
|
ypostab = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ypostab)
|
|
|
|
{
|
|
|
|
ypostab = g_new (gdouble, h);
|
|
|
|
ypostab_size = h;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (xcnt = 0; xcnt < w; xcnt++)
|
|
|
|
xpostab[xcnt] = (gdouble) width *((gdouble) xcnt / (gdouble) w);
|
|
|
|
for (ycnt = 0; ycnt < h; ycnt++)
|
|
|
|
ypostab[ycnt] = (gdouble) height *((gdouble) ycnt / (gdouble) h);
|
|
|
|
|
|
|
|
precompute_init (width, height);
|
|
|
|
|
|
|
|
gimp_rgba_set (&lightcheck,
|
|
|
|
GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT,
|
|
|
|
1.0);
|
|
|
|
gimp_rgba_set (&darkcheck, GIMP_CHECK_DARK, GIMP_CHECK_DARK,
|
|
|
|
GIMP_CHECK_DARK, 1.0);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
imagey = 0;
|
|
|
|
|
|
|
|
if (mapvals.previewquality)
|
|
|
|
ray_func = get_ray_color;
|
|
|
|
else
|
|
|
|
ray_func = get_ray_color_no_bilinear;
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
if (mapvals.previewquality)
|
|
|
|
ray_func = get_ray_color_ref;
|
|
|
|
else
|
|
|
|
ray_func = get_ray_color_no_bilinear_ref;
|
|
|
|
}
|
|
|
|
|
2010-11-01 02:03:18 +08:00
|
|
|
cairo_surface_flush (preview_surface);
|
|
|
|
|
2003-12-14 23:41:37 +08:00
|
|
|
for (ycnt = 0; ycnt < PREVIEW_HEIGHT; ycnt++)
|
|
|
|
{
|
2010-11-01 02:03:18 +08:00
|
|
|
index = ycnt * preview_rgb_stride;
|
2003-12-14 23:41:37 +08:00
|
|
|
for (xcnt = 0; xcnt < PREVIEW_WIDTH; xcnt++)
|
|
|
|
{
|
|
|
|
if ((ycnt >= starty && ycnt < (starty + h)) &&
|
|
|
|
(xcnt >= startx && xcnt < (startx + w)))
|
|
|
|
{
|
|
|
|
imagex = xpostab[xcnt - startx];
|
|
|
|
imagey = ypostab[ycnt - starty];
|
|
|
|
pos = int_to_posf (imagex, imagey);
|
|
|
|
|
|
|
|
if (mapvals.bump_mapped == TRUE &&
|
|
|
|
mapvals.bumpmap_id != -1 &&
|
|
|
|
xcnt == startx)
|
|
|
|
{
|
|
|
|
pos_to_float (pos.x, pos.y, &imagex, &imagey);
|
|
|
|
precompute_normals (0, width, RINT (imagey));
|
|
|
|
}
|
|
|
|
|
|
|
|
color = (*ray_func) (&pos);
|
|
|
|
|
|
|
|
if (color.a < 1.0)
|
|
|
|
{
|
|
|
|
f1 = ((xcnt % 32) < 16);
|
|
|
|
f2 = ((ycnt % 32) < 16);
|
|
|
|
f1 = f1 ^ f2;
|
|
|
|
|
|
|
|
if (f1)
|
|
|
|
{
|
|
|
|
if (color.a == 0.0)
|
|
|
|
color = lightcheck;
|
|
|
|
else
|
|
|
|
gimp_rgb_composite (&color,
|
|
|
|
&lightcheck,
|
|
|
|
GIMP_RGB_COMPOSITE_BEHIND);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (color.a == 0.0)
|
|
|
|
color = darkcheck;
|
|
|
|
else
|
|
|
|
gimp_rgb_composite (&color,
|
|
|
|
&darkcheck,
|
|
|
|
GIMP_RGB_COMPOSITE_BEHIND);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-01 02:03:18 +08:00
|
|
|
gimp_rgb_get_uchar (&color, &r, &g, &b);
|
|
|
|
GIMP_CAIRO_RGB24_SET_PIXEL((preview_rgb_data + index), r, g, b);
|
|
|
|
index += 4;
|
2003-12-14 23:41:37 +08:00
|
|
|
imagex++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
preview_rgb_data[index++] = 200;
|
|
|
|
preview_rgb_data[index++] = 200;
|
|
|
|
preview_rgb_data[index++] = 200;
|
2010-11-01 02:03:18 +08:00
|
|
|
index++;
|
2003-12-14 23:41:37 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-11-01 02:03:18 +08:00
|
|
|
cairo_surface_mark_dirty (preview_surface);
|
1998-06-11 14:04:59 +08:00
|
|
|
}
|
|
|
|
|
2000-02-18 21:59:18 +08:00
|
|
|
static void
|
2002-10-17 05:18:11 +08:00
|
|
|
compute_preview_rectangle (gint * xp, gint * yp, gint * wid, gint * heig)
|
1998-06-11 14:04:59 +08:00
|
|
|
{
|
2002-12-18 04:18:16 +08:00
|
|
|
gdouble x, y, w, h;
|
1998-06-11 14:04:59 +08:00
|
|
|
|
2002-12-18 04:18:16 +08:00
|
|
|
if (width >= height)
|
|
|
|
{
|
|
|
|
w = (PREVIEW_WIDTH - 50.0);
|
|
|
|
h = (gdouble) height *(w / (gdouble) width);
|
2003-10-30 04:57:21 +08:00
|
|
|
|
2002-12-18 04:18:16 +08:00
|
|
|
x = (PREVIEW_WIDTH - w) / 2.0;
|
|
|
|
y = (PREVIEW_HEIGHT - h) / 2.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
h = (PREVIEW_HEIGHT - 50.0);
|
|
|
|
w = (gdouble) width *(h / (gdouble) height);
|
|
|
|
x = (PREVIEW_WIDTH - w) / 2.0;
|
|
|
|
y = (PREVIEW_HEIGHT - h) / 2.0;
|
|
|
|
}
|
|
|
|
*xp = RINT (x);
|
|
|
|
*yp = RINT (y);
|
|
|
|
*wid = RINT (w);
|
|
|
|
*heig = RINT (h);
|
1998-06-11 14:04:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************/
|
|
|
|
/* Check if the given position is within the */
|
|
|
|
/* light marker. Return TRUE if so, FALSE if not */
|
|
|
|
/*************************************************/
|
|
|
|
|
2006-10-31 05:36:08 +08:00
|
|
|
static gboolean
|
2002-12-18 04:18:16 +08:00
|
|
|
check_handle_hit (gint xpos, gint ypos)
|
1998-06-11 14:04:59 +08:00
|
|
|
{
|
2002-12-18 04:18:16 +08:00
|
|
|
gint dx,dy,r;
|
2004-07-21 02:19:47 +08:00
|
|
|
gint k = mapvals.light_selected;
|
2002-10-17 05:18:11 +08:00
|
|
|
|
2002-12-18 04:18:16 +08:00
|
|
|
dx = handle_xpos - xpos;
|
|
|
|
dy = handle_ypos - ypos;
|
2002-10-17 05:18:11 +08:00
|
|
|
|
|
|
|
|
2004-07-21 02:19:47 +08:00
|
|
|
if (mapvals.lightsource[k].type == POINT_LIGHT ||
|
|
|
|
mapvals.lightsource[k].type == DIRECTIONAL_LIGHT)
|
2002-12-18 04:18:16 +08:00
|
|
|
{
|
|
|
|
r = sqrt (dx * dx + dy * dy) + 0.5;
|
|
|
|
if ((gint) r > 7)
|
2004-07-17 03:41:21 +08:00
|
|
|
{
|
|
|
|
return (FALSE);
|
|
|
|
}
|
2002-12-18 04:18:16 +08:00
|
|
|
else
|
2004-07-17 03:41:21 +08:00
|
|
|
{
|
|
|
|
return (TRUE);
|
|
|
|
}
|
2002-12-18 04:18:16 +08:00
|
|
|
}
|
|
|
|
return FALSE;
|
1998-06-11 14:04:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************/
|
2002-10-17 05:18:11 +08:00
|
|
|
/* Draw a light symbol */
|
1998-06-11 14:04:59 +08:00
|
|
|
/****************************************/
|
|
|
|
|
2002-10-17 05:18:11 +08:00
|
|
|
|
2000-02-18 21:59:18 +08:00
|
|
|
static void
|
2003-12-15 01:17:56 +08:00
|
|
|
draw_handles (void)
|
1998-06-11 14:04:59 +08:00
|
|
|
{
|
2004-07-21 02:19:47 +08:00
|
|
|
gdouble dxpos, dypos;
|
|
|
|
gint startx, starty, pw, ph;
|
2002-12-18 04:18:16 +08:00
|
|
|
GimpVector3 viewpoint;
|
|
|
|
GimpVector3 light_position;
|
2004-07-21 02:19:47 +08:00
|
|
|
gint k = mapvals.light_selected;
|
2003-10-30 04:57:21 +08:00
|
|
|
|
2002-12-18 04:18:16 +08:00
|
|
|
gfloat length;
|
2003-12-15 01:17:56 +08:00
|
|
|
gfloat delta_x = 0.0;
|
|
|
|
gfloat delta_y = 0.0;
|
2002-10-17 05:18:11 +08:00
|
|
|
|
2002-12-18 04:18:16 +08:00
|
|
|
/* calculate handle position */
|
|
|
|
compute_preview_rectangle (&startx, &starty, &pw, &ph);
|
2004-07-21 02:19:47 +08:00
|
|
|
switch (mapvals.lightsource[k].type)
|
2002-12-18 04:18:16 +08:00
|
|
|
{
|
2004-07-21 02:19:47 +08:00
|
|
|
case NO_LIGHT:
|
|
|
|
return;
|
2003-12-14 23:41:37 +08:00
|
|
|
case POINT_LIGHT:
|
|
|
|
case SPOT_LIGHT:
|
2002-12-18 04:18:16 +08:00
|
|
|
/* swap z to reverse light position */
|
|
|
|
viewpoint = mapvals.viewpoint;
|
|
|
|
viewpoint.z = -viewpoint.z;
|
2004-07-21 02:19:47 +08:00
|
|
|
light_position = mapvals.lightsource[k].position;
|
2002-12-18 04:18:16 +08:00
|
|
|
gimp_vector_3d_to_2d (startx, starty, pw, ph, &dxpos, &dypos,
|
2004-07-17 03:41:21 +08:00
|
|
|
&viewpoint, &light_position);
|
2002-12-18 04:18:16 +08:00
|
|
|
handle_xpos = (gint) (dxpos + 0.5);
|
|
|
|
handle_ypos = (gint) (dypos + 0.5);
|
|
|
|
break;
|
2003-12-14 23:41:37 +08:00
|
|
|
case DIRECTIONAL_LIGHT:
|
2002-12-18 04:18:16 +08:00
|
|
|
light_position.x = light_position.y = 0.5;
|
|
|
|
light_position.z = 0;
|
|
|
|
viewpoint.z = -viewpoint.z;
|
|
|
|
gimp_vector_3d_to_2d (startx, starty, pw, ph, &dxpos, &dypos,
|
2004-07-17 03:41:21 +08:00
|
|
|
&viewpoint, &light_position);
|
2002-12-18 04:18:16 +08:00
|
|
|
length = PREVIEW_HEIGHT / 4;
|
2004-07-21 02:19:47 +08:00
|
|
|
delta_x = mapvals.lightsource[k].direction.x * length;
|
|
|
|
delta_y = mapvals.lightsource[k].direction.y * length;
|
2002-12-18 04:18:16 +08:00
|
|
|
handle_xpos = dxpos + delta_x;
|
|
|
|
handle_ypos = dypos + delta_y;
|
|
|
|
break;
|
|
|
|
}
|
2002-10-17 05:18:11 +08:00
|
|
|
|
2004-07-21 02:19:47 +08:00
|
|
|
if (mapvals.lightsource[k].type != NO_LIGHT)
|
2002-12-18 04:18:16 +08:00
|
|
|
{
|
2003-12-15 01:17:56 +08:00
|
|
|
GdkColor color;
|
2010-11-01 02:03:18 +08:00
|
|
|
cairo_t *cr;
|
|
|
|
cr = gdk_cairo_create (gtk_widget_get_window (previewarea));
|
|
|
|
|
|
|
|
cairo_set_line_width (cr, 1.0);
|
2003-12-15 01:17:56 +08:00
|
|
|
|
|
|
|
color.red = 0x0;
|
|
|
|
color.green = 0x4000;
|
|
|
|
color.blue = 0xFFFF;
|
2010-11-01 02:03:18 +08:00
|
|
|
gdk_cairo_set_source_color (cr, &color);
|
1998-06-11 14:04:59 +08:00
|
|
|
|
2002-12-18 04:18:16 +08:00
|
|
|
/* draw circle at light position */
|
2004-07-21 02:19:47 +08:00
|
|
|
switch (mapvals.lightsource[k].type)
|
2004-07-17 03:41:21 +08:00
|
|
|
{
|
|
|
|
case POINT_LIGHT:
|
|
|
|
case SPOT_LIGHT:
|
2010-11-01 02:03:18 +08:00
|
|
|
cairo_arc (cr, handle_xpos, handle_ypos,
|
|
|
|
LIGHT_SYMBOL_SIZE/2, 0, 2 * M_PI);
|
|
|
|
cairo_fill (cr);
|
2004-07-17 03:41:21 +08:00
|
|
|
break;
|
|
|
|
case DIRECTIONAL_LIGHT:
|
2010-11-01 02:03:18 +08:00
|
|
|
cairo_arc (cr, handle_xpos, handle_ypos,
|
|
|
|
LIGHT_SYMBOL_SIZE/2, 0, 2 * M_PI);
|
|
|
|
cairo_fill (cr);
|
|
|
|
cairo_move_to (cr, handle_xpos, handle_ypos);
|
|
|
|
cairo_line_to (cr, startx + pw/2, starty + ph/2);
|
|
|
|
cairo_stroke (cr);
|
2004-07-17 03:41:21 +08:00
|
|
|
break;
|
|
|
|
case NO_LIGHT:
|
|
|
|
break;
|
|
|
|
}
|
2010-11-01 02:03:18 +08:00
|
|
|
cairo_destroy (cr);
|
2002-12-18 04:18:16 +08:00
|
|
|
}
|
1998-06-11 14:04:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-17 05:18:11 +08:00
|
|
|
/*************************************************/
|
|
|
|
/* Update light position given new screen coords */
|
|
|
|
/*************************************************/
|
2000-12-30 08:23:34 +08:00
|
|
|
|
2002-10-17 05:18:11 +08:00
|
|
|
void
|
|
|
|
update_light (gint xpos, gint ypos)
|
|
|
|
{
|
2002-12-18 04:18:16 +08:00
|
|
|
gint startx, starty, pw, ph;
|
2004-07-21 02:19:47 +08:00
|
|
|
GimpVector3 vp;
|
|
|
|
gint k = mapvals.light_selected;
|
2003-10-30 04:57:21 +08:00
|
|
|
|
2002-12-18 04:18:16 +08:00
|
|
|
compute_preview_rectangle (&startx, &starty, &pw, &ph);
|
2002-10-17 05:18:11 +08:00
|
|
|
|
2002-12-18 04:18:16 +08:00
|
|
|
vp = mapvals.viewpoint;
|
|
|
|
vp.z = -vp.z;
|
1998-06-11 14:04:59 +08:00
|
|
|
|
2004-07-21 02:19:47 +08:00
|
|
|
switch (mapvals.lightsource[k].type)
|
2002-12-18 04:18:16 +08:00
|
|
|
{
|
|
|
|
case NO_LIGHT:
|
2004-07-21 02:19:47 +08:00
|
|
|
break;
|
2004-07-17 03:41:21 +08:00
|
|
|
case POINT_LIGHT:
|
|
|
|
case SPOT_LIGHT:
|
2002-12-18 04:18:16 +08:00
|
|
|
gimp_vector_2d_to_3d (startx,
|
2004-07-17 03:41:21 +08:00
|
|
|
starty,
|
|
|
|
pw,
|
|
|
|
ph,
|
2004-07-21 02:19:47 +08:00
|
|
|
xpos, ypos, &vp, &mapvals.lightsource[k].position);
|
2002-12-18 04:18:16 +08:00
|
|
|
break;
|
|
|
|
case DIRECTIONAL_LIGHT:
|
|
|
|
gimp_vector_2d_to_3d (startx,
|
2004-07-17 03:41:21 +08:00
|
|
|
starty,
|
|
|
|
pw,
|
|
|
|
ph,
|
2004-07-21 02:19:47 +08:00
|
|
|
xpos, ypos, &vp, &mapvals.lightsource[k].direction);
|
2002-12-18 04:18:16 +08:00
|
|
|
break;
|
|
|
|
}
|
1998-06-11 14:04:59 +08:00
|
|
|
}
|
|
|
|
|
2002-10-17 05:18:11 +08:00
|
|
|
|
1998-06-11 14:04:59 +08:00
|
|
|
/******************************************************************/
|
|
|
|
/* Draw preview image. if DoCompute is TRUE then recompute image. */
|
|
|
|
/******************************************************************/
|
|
|
|
|
2000-02-18 07:48:13 +08:00
|
|
|
void
|
2011-02-20 23:43:36 +08:00
|
|
|
preview_compute (void)
|
1998-06-11 14:04:59 +08:00
|
|
|
{
|
2011-02-20 23:43:36 +08:00
|
|
|
GdkDisplay *display = gtk_widget_get_display (previewarea);
|
|
|
|
GdkCursor *cursor;
|
|
|
|
gint startx, starty, pw, ph;
|
1998-06-11 14:04:59 +08:00
|
|
|
|
2002-12-18 04:18:16 +08:00
|
|
|
compute_preview_rectangle (&startx, &starty, &pw, &ph);
|
2002-10-17 05:18:11 +08:00
|
|
|
|
2011-02-20 23:43:36 +08:00
|
|
|
cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
|
2002-12-18 04:18:16 +08:00
|
|
|
|
2011-02-20 23:43:36 +08:00
|
|
|
gdk_window_set_cursor (gtk_widget_get_window (previewarea), cursor);
|
|
|
|
gdk_cursor_unref (cursor);
|
2003-10-30 04:57:21 +08:00
|
|
|
|
2011-02-20 23:43:36 +08:00
|
|
|
compute_preview (startx, starty, pw, ph);
|
|
|
|
cursor = gdk_cursor_new_for_display (display, GDK_HAND2);
|
|
|
|
gdk_window_set_cursor (gtk_widget_get_window (previewarea), cursor);
|
|
|
|
gdk_cursor_unref (cursor);
|
|
|
|
gdk_flush ();
|
2002-10-17 05:18:11 +08:00
|
|
|
}
|
|
|
|
|
2011-02-20 23:43:36 +08:00
|
|
|
|
2002-10-17 05:18:11 +08:00
|
|
|
/******************************/
|
|
|
|
/* Preview area event handler */
|
|
|
|
/******************************/
|
2000-02-18 07:48:13 +08:00
|
|
|
|
2003-12-14 23:41:37 +08:00
|
|
|
gboolean
|
2002-10-17 05:18:11 +08:00
|
|
|
preview_events (GtkWidget *area,
|
2004-07-17 03:41:21 +08:00
|
|
|
GdkEvent *event)
|
2002-10-17 05:18:11 +08:00
|
|
|
{
|
|
|
|
switch (event->type)
|
|
|
|
{
|
2002-12-18 04:18:16 +08:00
|
|
|
case GDK_ENTER_NOTIFY:
|
|
|
|
break;
|
|
|
|
case GDK_LEAVE_NOTIFY:
|
|
|
|
break;
|
|
|
|
case GDK_BUTTON_PRESS:
|
|
|
|
light_hit = check_handle_hit (event->button.x, event->button.y);
|
|
|
|
left_button_pressed = TRUE;
|
|
|
|
break;
|
|
|
|
case GDK_BUTTON_RELEASE:
|
|
|
|
left_button_pressed = FALSE;
|
|
|
|
break;
|
|
|
|
case GDK_MOTION_NOTIFY:
|
2003-10-30 04:57:21 +08:00
|
|
|
if (left_button_pressed == TRUE &&
|
2004-07-17 03:41:21 +08:00
|
|
|
light_hit == TRUE &&
|
|
|
|
mapvals.interactive_preview == TRUE )
|
|
|
|
{
|
2011-02-20 23:43:36 +08:00
|
|
|
gtk_widget_queue_draw (previewarea);
|
2004-07-17 03:41:21 +08:00
|
|
|
interactive_preview_callback(NULL);
|
|
|
|
update_light (event->motion.x, event->motion.y);
|
|
|
|
}
|
2002-12-18 04:18:16 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2000-02-18 07:48:13 +08:00
|
|
|
}
|
1998-06-11 14:04:59 +08:00
|
|
|
|
2002-10-17 05:18:11 +08:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2011-02-20 23:43:36 +08:00
|
|
|
gboolean
|
|
|
|
preview_expose (GtkWidget *area,
|
|
|
|
GdkEventExpose *eevent)
|
|
|
|
{
|
|
|
|
cairo_t *cr;
|
|
|
|
|
|
|
|
cr = gdk_cairo_create (eevent->window);
|
|
|
|
|
|
|
|
cairo_set_source_surface (cr, preview_surface, 0.0, 0.0);
|
|
|
|
|
|
|
|
cairo_paint (cr);
|
|
|
|
|
|
|
|
/* draw symbols if enabled in UI */
|
|
|
|
if (mapvals.interactive_preview)
|
|
|
|
{
|
|
|
|
draw_handles ();
|
|
|
|
}
|
|
|
|
|
|
|
|
cairo_destroy (cr);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2002-12-18 04:18:16 +08:00
|
|
|
void
|
2002-10-17 05:18:11 +08:00
|
|
|
interactive_preview_callback (GtkWidget *widget)
|
|
|
|
{
|
2002-12-18 04:18:16 +08:00
|
|
|
if ( preview_update_timer != 0)
|
|
|
|
{
|
2003-01-31 11:08:29 +08:00
|
|
|
g_source_remove ( preview_update_timer );
|
2002-12-18 04:18:16 +08:00
|
|
|
}
|
|
|
|
/* start new timer */
|
2003-12-14 23:41:37 +08:00
|
|
|
preview_update_timer = g_timeout_add (100,
|
|
|
|
interactive_preview_timer_callback, NULL);
|
2002-10-17 05:18:11 +08:00
|
|
|
}
|
|
|
|
|
2003-01-31 11:08:29 +08:00
|
|
|
static gboolean
|
2011-02-20 23:43:36 +08:00
|
|
|
interactive_preview_timer_callback (gpointer data)
|
2002-10-17 05:18:11 +08:00
|
|
|
{
|
2004-07-21 02:19:47 +08:00
|
|
|
gint k = mapvals.light_selected;
|
|
|
|
|
|
|
|
mapvals.update_enabled = FALSE; /* disable apply_settings() */
|
|
|
|
|
|
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_pos_x),
|
|
|
|
mapvals.lightsource[k].position.x);
|
|
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_pos_y),
|
|
|
|
mapvals.lightsource[k].position.y);
|
|
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_pos_z),
|
|
|
|
mapvals.lightsource[k].position.z);
|
|
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_dir_x),
|
|
|
|
mapvals.lightsource[k].direction.x);
|
|
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_dir_y),
|
|
|
|
mapvals.lightsource[k].direction.y);
|
|
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_dir_z),
|
|
|
|
mapvals.lightsource[k].direction.z);
|
|
|
|
|
|
|
|
mapvals.update_enabled = TRUE;
|
2002-12-18 04:18:16 +08:00
|
|
|
|
2011-02-20 23:43:36 +08:00
|
|
|
preview_compute ();
|
|
|
|
|
|
|
|
gtk_widget_queue_draw (previewarea);
|
2003-01-31 11:08:29 +08:00
|
|
|
|
|
|
|
preview_update_timer = 0;
|
|
|
|
|
|
|
|
return FALSE;
|
1998-06-11 14:04:59 +08:00
|
|
|
}
|