Bill Skaggs <weskaggs@primate.ucdavis.edu>

* plug-ins/Lighting/lighting_main.c
	* plug-ins/Lighting/lighting_main.h
	* plug-ins/Lighting/lighting_preview.c
	* plug-ins/Lighting/lighting_preview.h
	* plug-ins/Lighting/lighting_shade.c
	* plug-ins/Lighting/lighting_ui.c: completely reworked UI for
	lighting page.  Now supports up to 6 lights (more is trivial).
	Added ability to temporarily isolate selected light.  Added
	light intensity controls.  Can interactively position each light
	(does not quite work yet for directional lights).
This commit is contained in:
William Skaggs 2004-07-20 18:19:47 +00:00
parent 8f74e672a8
commit 85e884cee1
7 changed files with 612 additions and 436 deletions

View file

@ -1,3 +1,16 @@
2004-07-20 Bill Skaggs <weskaggs@primate.ucdavis.edu>
* plug-ins/Lighting/lighting_main.c
* plug-ins/Lighting/lighting_main.h
* plug-ins/Lighting/lighting_preview.c
* plug-ins/Lighting/lighting_preview.h
* plug-ins/Lighting/lighting_shade.c
* plug-ins/Lighting/lighting_ui.c: completely reworked UI for
lighting page. Now supports up to 6 lights (more is trivial).
Added ability to temporarily isolate selected light. Added
light intensity controls. Can interactively position each light
(does not quite work yet for directional lights).
2004-07-20 Michael Natterer <mitch@gimp.org>
* app/actions/tools-actions.c: added an icon to the

View file

@ -51,6 +51,10 @@ set_default_settings (void)
{
gint k;
mapvals.update_enabled = TRUE;
mapvals.light_selected = 0;
mapvals.light_isolated = FALSE;
gimp_vector3_set (&mapvals.viewpoint, 0.5, 0.5, 0.25);
gimp_vector3_set (&mapvals.planenormal, 0.0, 0.0, 1.0);
@ -60,6 +64,7 @@ set_default_settings (void)
gimp_rgba_set (&mapvals.lightsource[0].color, 1.0, 1.0, 1.0, 1.0);
mapvals.lightsource[0].intensity = 1.0;
mapvals.lightsource[0].type = POINT_LIGHT;
mapvals.lightsource[0].active = TRUE;
/* init lights 2 and 3 pos to upper left and below */
gimp_vector3_set (&mapvals.lightsource[1].position, 2.0, -1.0, 1.0);
@ -68,17 +73,25 @@ set_default_settings (void)
gimp_vector3_set (&mapvals.lightsource[2].position, 1.0, 2.0, 1.0);
gimp_vector3_set (&mapvals.lightsource[2].direction, 0.0, 1.0, 1.0);
for (k = 1; k < NUM_LIGHTS; k++)
/* init any remaining lights to directly overhead */
for (k = 3; k < NUM_LIGHTS; k++)
{
gimp_rgba_set (&mapvals.lightsource[k].color, 0.0, 0.0, 0.0, 1.0);
mapvals.lightsource[k].intensity = 1.0;
mapvals.lightsource[k].type = NO_LIGHT;
gimp_vector3_set (&mapvals.lightsource[k].position, 0.0, 0.0, 1.0);
gimp_vector3_set (&mapvals.lightsource[k].direction, 0.0, 0.0, 1.0);
}
mapvals.material.ambient_int = 0.3;
mapvals.material.diffuse_int = 1.0;
for (k = 1; k < NUM_LIGHTS; k++)
{
gimp_rgba_set (&mapvals.lightsource[k].color, 1.0, 1.0, 1.0, 1.0);
mapvals.lightsource[k].intensity = 1.0;
mapvals.lightsource[k].type = NO_LIGHT;
mapvals.lightsource[k].active = TRUE;
}
mapvals.material.ambient_int = 0.2;
mapvals.material.diffuse_int = 0.5;
mapvals.material.diffuse_ref = 0.4;
mapvals.material.specular_ref = 0.6;
mapvals.material.specular_ref = 0.5;
mapvals.material.highlight = 27.0;
mapvals.material.metallic = FALSE;

View file

@ -5,7 +5,7 @@
/* ================= */
#define TILE_CACHE_SIZE 16
#define NUM_LIGHTS 3
#define NUM_LIGHTS 6
/* Typedefs */
/* ======== */
@ -14,7 +14,7 @@ typedef enum
{
POINT_LIGHT,
DIRECTIONAL_LIGHT,
SPOT_LIGHT,
SPOT_LIGHT,
NO_LIGHT
} LightType;
@ -34,13 +34,13 @@ enum
typedef struct
{
gdouble ambient_int;
gdouble diffuse_int;
gdouble diffuse_ref;
gdouble specular_ref;
gdouble highlight;
gboolean metallic;
GimpRGB color;
gdouble ambient_int;
gdouble diffuse_int;
gdouble diffuse_ref;
gdouble specular_ref;
gdouble highlight;
gboolean metallic;
GimpRGB color;
} MaterialSettings;
typedef struct
@ -50,13 +50,14 @@ typedef struct
GimpVector3 direction;
GimpRGB color;
gdouble intensity;
gboolean active;
} LightSettings;
typedef struct
{
gint32 drawable_id;
gint32 bumpmap_id;
gint32 envmap_id;
gint32 drawable_id;
gint32 bumpmap_id;
gint32 envmap_id;
/* Render variables */
/* ================ */
@ -67,34 +68,28 @@ typedef struct
MaterialSettings material;
MaterialSettings ref_material;
gdouble pixel_treshold;
gdouble bumpmax,bumpmin;
/* gdouble wave_cx,wave_cy;
gdouble wave_lx,wave_ly;
gdouble wave_amp,wave_ph; */
gint max_depth;
gint bumpmaptype;
/* gint bumptype; */
gdouble pixel_treshold;
gdouble bumpmax,bumpmin;
gint max_depth;
gint bumpmaptype;
/* Flags */
/* ===== */
gint antialiasing;
gint create_new_image;
gint transparent_background;
gint bump_mapped;
gint env_mapped;
gint ref_mapped;
gint bumpstretch;
gint previewquality;
gboolean symbols;
gboolean interactive_preview;
gint antialiasing;
gint create_new_image;
gint transparent_background;
gint bump_mapped;
gint env_mapped;
gint ref_mapped;
gint bumpstretch;
gint previewquality;
gboolean symbols;
gboolean interactive_preview;
/* Misc */
/* ==== */
gdouble preview_zoom_factor;
gboolean update_enabled;
gint light_selected;
gboolean light_isolated;
gdouble preview_zoom_factor;
} LightingValues;
/* Externally visible variables */

View file

@ -224,13 +224,14 @@ gboolean
check_handle_hit (gint xpos, gint ypos)
{
gint dx,dy,r;
gint k = mapvals.light_selected;
dx = handle_xpos - xpos;
dy = handle_ypos - ypos;
if (mapvals.lightsource[0].type == POINT_LIGHT ||
mapvals.lightsource[0].type == DIRECTIONAL_LIGHT)
if (mapvals.lightsource[k].type == POINT_LIGHT ||
mapvals.lightsource[k].type == DIRECTIONAL_LIGHT)
{
r = sqrt (dx * dx + dy * dy) + 0.5;
if ((gint) r > 7)
@ -253,10 +254,11 @@ check_handle_hit (gint xpos, gint ypos)
static void
draw_handles (void)
{
gdouble dxpos, dypos;
gint startx, starty, pw, ph;
gdouble dxpos, dypos;
gint startx, starty, pw, ph;
GimpVector3 viewpoint;
GimpVector3 light_position;
gint k = mapvals.light_selected;
gfloat length;
gfloat delta_x = 0.0;
@ -264,15 +266,16 @@ draw_handles (void)
/* calculate handle position */
compute_preview_rectangle (&startx, &starty, &pw, &ph);
switch (mapvals.lightsource[0].type)
switch (mapvals.lightsource[k].type)
{
case NO_LIGHT:
return;
case POINT_LIGHT:
case SPOT_LIGHT:
case NO_LIGHT:
/* swap z to reverse light position */
viewpoint = mapvals.viewpoint;
viewpoint.z = -viewpoint.z;
light_position = mapvals.lightsource[0].position;
light_position = mapvals.lightsource[k].position;
gimp_vector_3d_to_2d (startx, starty, pw, ph, &dxpos, &dypos,
&viewpoint, &light_position);
handle_xpos = (gint) (dxpos + 0.5);
@ -285,8 +288,8 @@ draw_handles (void)
gimp_vector_3d_to_2d (startx, starty, pw, ph, &dxpos, &dypos,
&viewpoint, &light_position);
length = PREVIEW_HEIGHT / 4;
delta_x = mapvals.lightsource[0].direction.x * length;
delta_y = mapvals.lightsource[0].direction.y * length;
delta_x = mapvals.lightsource[k].direction.x * length;
delta_y = mapvals.lightsource[k].direction.y * length;
handle_xpos = dxpos + delta_x;
handle_ypos = dypos + delta_y;
break;
@ -294,7 +297,7 @@ draw_handles (void)
gdk_gc_set_function (gc, GDK_COPY);
if (mapvals.lightsource[0].type != NO_LIGHT)
if (mapvals.lightsource[k].type != NO_LIGHT)
{
GdkColor color;
@ -312,7 +315,7 @@ draw_handles (void)
}
/* calculate backbuffer */
switch (mapvals.lightsource[0].type)
switch (mapvals.lightsource[k].type)
{
case POINT_LIGHT:
backbuf.x = handle_xpos - LIGHT_SYMBOL_SIZE / 2;
@ -335,12 +338,13 @@ draw_handles (void)
backbuf.h = fabs(delta_y) + LIGHT_SYMBOL_SIZE;
break;
case SPOT_LIGHT:
case NO_LIGHT:
backbuf.x = handle_xpos - LIGHT_SYMBOL_SIZE / 2;
backbuf.y = handle_ypos - LIGHT_SYMBOL_SIZE / 2;
backbuf.w = LIGHT_SYMBOL_SIZE;
backbuf.h = LIGHT_SYMBOL_SIZE;
break;
case NO_LIGHT:
break;
}
/* Save background */
@ -372,7 +376,7 @@ draw_handles (void)
gdk_gc_set_rgb_fg_color (gc, &color);
/* draw circle at light position */
switch (mapvals.lightsource[0].type)
switch (mapvals.lightsource[k].type)
{
case POINT_LIGHT:
case SPOT_LIGHT:
@ -406,30 +410,32 @@ void
update_light (gint xpos, gint ypos)
{
gint startx, starty, pw, ph;
GimpVector3 vp;
GimpVector3 vp;
gint k = mapvals.light_selected;
compute_preview_rectangle (&startx, &starty, &pw, &ph);
vp = mapvals.viewpoint;
vp.z = -vp.z;
switch (mapvals.lightsource[0].type)
switch (mapvals.lightsource[k].type)
{
case NO_LIGHT:
break;
case POINT_LIGHT:
case SPOT_LIGHT:
gimp_vector_2d_to_3d (startx,
starty,
pw,
ph,
xpos, ypos, &vp, &mapvals.lightsource[0].position);
xpos, ypos, &vp, &mapvals.lightsource[k].position);
break;
case DIRECTIONAL_LIGHT:
gimp_vector_2d_to_3d (startx,
starty,
pw,
ph,
xpos, ypos, &vp, &mapvals.lightsource[0].direction);
xpos, ypos, &vp, &mapvals.lightsource[k].direction);
break;
}
}
@ -561,23 +567,24 @@ interactive_preview_callback (GtkWidget *widget)
static gboolean
interactive_preview_timer_callback ( gpointer data )
{
gint k;
gint k = mapvals.light_selected;
for (k = 0; k < NUM_LIGHTS; k++)
{
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_pos_x[k]),
mapvals.lightsource[k].position.x);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_pos_y[k]),
mapvals.lightsource[k].position.y);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_pos_z[k]),
mapvals.lightsource[k].position.z);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_dir_x[k]),
mapvals.lightsource[k].direction.x);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_dir_y[k]),
mapvals.lightsource[k].direction.y);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_dir_z[k]),
mapvals.lightsource[k].direction.z);
}
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;
draw_preview_image (TRUE);

View file

@ -35,12 +35,12 @@ extern gdouble *xpostab, *ypostab;
extern gboolean light_hit;
extern gboolean left_button_pressed;
GtkWidget *spin_pos_x[NUM_LIGHTS];
GtkWidget *spin_pos_y[NUM_LIGHTS];
GtkWidget *spin_pos_z[NUM_LIGHTS];
GtkWidget *spin_dir_x[NUM_LIGHTS];
GtkWidget *spin_dir_y[NUM_LIGHTS];
GtkWidget *spin_dir_z[NUM_LIGHTS];
GtkWidget *spin_pos_x;
GtkWidget *spin_pos_y;
GtkWidget *spin_pos_z;
GtkWidget *spin_dir_x;
GtkWidget *spin_dir_y;
GtkWidget *spin_dir_z;
/* Externally visible functions */

View file

@ -143,8 +143,8 @@ precompute_init (gint w,
if (mapvals.bumpmap_id != -1)
{
bpp = gimp_drawable_bpp(mapvals.bumpmap_id);
}
}
bumprow = g_new (guchar, w * bpp);
triangle_normals[0] = g_new (GimpVector3, (w << 1) + 2);
@ -202,10 +202,10 @@ precompute_normals (gint x1,
heights[2] = tmpd;
if (mapvals.bumpmap_id != -1)
{
{
bpp = gimp_drawable_bpp(mapvals.bumpmap_id);
}
gimp_pixel_rgn_get_row (&bump_region, bumprow, x1, y, x2 - x1);
if (mapvals.bumpmaptype > 0)
@ -228,7 +228,7 @@ precompute_normals (gint x1,
if (bpp>1)
{
mapval = (guchar)((float)((bumprow[n * bpp] +bumprow[n * bpp +1] + bumprow[n * bpp + 2])/3.0 )) ;
}
}
else
{
mapval = bumprow[n * bpp];
@ -244,7 +244,7 @@ precompute_normals (gint x1,
if (bpp>1)
{
mapval = (guchar)((float)((bumprow[n * bpp] +bumprow[n * bpp +1] + bumprow[n * bpp + 2])/3.0 )) ;
}
}
else
{
mapval = bumprow[n * bpp];
@ -252,7 +252,7 @@ precompute_normals (gint x1,
heights[2][n] = (gdouble) mapvals.bumpmax * (gdouble) mapval / 255.0;
}
}
/* Compute triangle normals */
/* ======================== */
@ -260,7 +260,7 @@ precompute_normals (gint x1,
for (n = 0; n < (x2 - x1 - 1); n++)
{
p1.x = 0.0;
p1.y = ystep;
p1.y = ystep;
p1.z = heights[2][n] - heights[1][n];
p2.x = xstep;
@ -384,7 +384,7 @@ sphere_to_image (GimpVector3 *normal,
if (fac>1.0)
fac = 1.0;
else if (fac<-1.0)
else if (fac<-1.0)
fac = -1.0;
*u = acos (fac) / (2.0 * G_PI);
@ -404,17 +404,18 @@ GimpRGB
get_ray_color (GimpVector3 *position)
{
GimpRGB color;
GimpRGB color_int;
GimpRGB color_sum;
GimpRGB light_color;
gint x, f;
gdouble xf, yf;
GimpVector3 normal, *p;
gint k;
pos_to_float (position->x, position->y, &xf, &yf);
x = RINT (xf);
if (mapvals.transparent_background && heights[1][x] == 0)
{
gimp_rgb_set_alpha (&color_sum, 0.0);
@ -422,19 +423,23 @@ get_ray_color (GimpVector3 *position)
else
{
color = get_image_color (xf, yf, &f);
color_sum = color;
gimp_rgb_multiply (&color_sum, mapvals.material.ambient_int);
for (k = 0; k < NUM_LIGHTS; k++)
{
if (mapvals.lightsource[k].type == NO_LIGHT)
if (!mapvals.lightsource[k].active
|| mapvals.lightsource[k].type == NO_LIGHT)
continue;
else if (mapvals.lightsource[k].type == POINT_LIGHT)
p = &mapvals.lightsource[k].position;
else
p = &mapvals.lightsource[k].direction;
color_int = mapvals.lightsource[k].color;
gimp_rgb_multiply (&color_int, mapvals.lightsource[k].intensity);
if (mapvals.bump_mapped == FALSE || mapvals.bumpmap_id == -1)
{
light_color = phong_shade (position,
@ -442,22 +447,22 @@ get_ray_color (GimpVector3 *position)
&mapvals.planenormal,
p,
&color,
&mapvals.lightsource[k].color,
&color_int,
mapvals.lightsource[k].type);
}
else
{
normal = vertex_normals[1][(gint) RINT (xf)];
light_color = phong_shade (position,
&mapvals.viewpoint,
&normal,
p,
&color,
&mapvals.lightsource[k].color,
&color_int,
mapvals.lightsource[k].type);
}
gimp_rgb_add (&color_sum, &light_color);
}
}
@ -469,10 +474,14 @@ get_ray_color (GimpVector3 *position)
GimpRGB
get_ray_color_ref (GimpVector3 *position)
{
GimpRGB color_sum;
GimpRGB color_int;
GimpRGB light_color;
GimpRGB color, env_color;
gint x, f;
gdouble xf, yf;
GimpVector3 normal, *p, v, r;
gint x, f;
gdouble xf, yf;
GimpVector3 normal, *p, v, r;
gint k;
pos_to_float (position->x, position->y, &xf, &yf);
@ -485,60 +494,74 @@ get_ray_color_ref (GimpVector3 *position)
else
{
color = get_image_color (xf, yf, &f);
color_sum = color;
if (mapvals.lightsource[0].type == POINT_LIGHT)
p = &mapvals.lightsource[0].position;
else
p = &mapvals.lightsource[0].direction;
if (mapvals.bump_mapped == FALSE || mapvals.bumpmap_id == -1)
for (k = 0; k < NUM_LIGHTS; k++)
{
color = phong_shade (position,
&mapvals.viewpoint,
&mapvals.planenormal,
p,
&color,
&mapvals.lightsource[0].color,
mapvals.lightsource[0].type);
}
else
{
normal = vertex_normals[1][(gint) RINT (xf)];
if (!mapvals.lightsource[k].active
|| mapvals.lightsource[k].type == NO_LIGHT)
continue;
else if (mapvals.lightsource[k].type == POINT_LIGHT)
p = &mapvals.lightsource[k].position;
else
p = &mapvals.lightsource[k].direction;
gimp_vector3_sub (&v, &mapvals.viewpoint,position);
gimp_vector3_normalize (&v);
color_int = mapvals.lightsource[k].color;
gimp_rgb_multiply (&color_int, mapvals.lightsource[k].intensity);
r = compute_reflected_ray (&normal, &v);
if (mapvals.bump_mapped == FALSE || mapvals.bumpmap_id == -1)
{
light_color = phong_shade (position,
&mapvals.viewpoint,
&mapvals.planenormal,
p,
&color,
&color_int,
mapvals.lightsource[0].type);
}
else
{
normal = vertex_normals[1][(gint) RINT (xf)];
/* Get color in the direction of r */
/* =============================== */
gimp_vector3_sub (&v, &mapvals.viewpoint,position);
gimp_vector3_normalize (&v);
sphere_to_image (&r, &xf, &yf);
env_color = peek_env_map (RINT (env_width * xf),
RINT (env_height * yf));
r = compute_reflected_ray (&normal, &v);
color = phong_shade (position,
&mapvals.viewpoint,
&normal,
p,
&env_color,
&mapvals.lightsource[0].color,
mapvals.lightsource[0].type);
/* Get color in the direction of r */
/* =============================== */
sphere_to_image (&r, &xf, &yf);
env_color = peek_env_map (RINT (env_width * xf),
RINT (env_height * yf));
light_color = phong_shade (position,
&mapvals.viewpoint,
&normal,
p,
&env_color,
&color_int,
mapvals.lightsource[0].type);
}
gimp_rgb_add (&color_sum, &light_color);
}
}
return color;
gimp_rgb_clamp (&color_sum);
return color_sum;
}
GimpRGB
get_ray_color_no_bilinear (GimpVector3 *position)
{
GimpRGB color;
GimpRGB color;
GimpRGB color_int;
GimpRGB color_sum;
GimpRGB light_color;
gint x;
gdouble xf, yf;
GimpVector3 normal, *p;
gint x;
gdouble xf, yf;
GimpVector3 normal, *p;
gint k;
@ -559,13 +582,17 @@ get_ray_color_no_bilinear (GimpVector3 *position)
for (k = 0; k < NUM_LIGHTS; k++)
{
if (mapvals.lightsource[k].type == NO_LIGHT)
if (!mapvals.lightsource[k].active
|| mapvals.lightsource[k].type == NO_LIGHT)
continue;
else if (mapvals.lightsource[k].type == POINT_LIGHT)
p = &mapvals.lightsource[k].position;
else
p = &mapvals.lightsource[k].direction;
color_int = mapvals.lightsource[k].color;
gimp_rgb_multiply (&color_int, mapvals.lightsource[k].intensity);
if (mapvals.bump_mapped == FALSE || mapvals.bumpmap_id == -1)
{
light_color = phong_shade (position,
@ -573,26 +600,26 @@ get_ray_color_no_bilinear (GimpVector3 *position)
&mapvals.planenormal,
p,
&color,
&mapvals.lightsource[k].color,
&color_int,
mapvals.lightsource[k].type);
}
else
{
normal = vertex_normals[1][x];
light_color = phong_shade (position,
&mapvals.viewpoint,
&normal,
p,
&color,
&mapvals.lightsource[k].color,
&color_int,
mapvals.lightsource[k].type);
}
gimp_rgb_add (&color_sum, &light_color);
}
}
gimp_rgb_clamp (&color_sum);
return color_sum;
}
@ -600,10 +627,14 @@ get_ray_color_no_bilinear (GimpVector3 *position)
GimpRGB
get_ray_color_no_bilinear_ref (GimpVector3 *position)
{
GimpRGB color_sum;
GimpRGB color_int;
GimpRGB light_color;
GimpRGB color, env_color;
gint x;
gdouble xf, yf;
GimpVector3 normal, *p, v, r;
gint x;
gdouble xf, yf;
GimpVector3 normal, *p, v, r;
gint k;
pos_to_float (position->x, position->y, &xf, &yf);
@ -611,71 +642,84 @@ get_ray_color_no_bilinear_ref (GimpVector3 *position)
if (mapvals.transparent_background && heights[1][x] == 0)
{
gimp_rgb_set_alpha (&color, 0.0);
gimp_rgb_set_alpha (&color_sum, 0.0);
}
else
{
color = peek (RINT (xf), RINT (yf));
color_sum = color;
if (mapvals.lightsource[0].type == POINT_LIGHT)
p = &mapvals.lightsource[0].position;
else
p = &mapvals.lightsource[0].direction;
if (mapvals.bump_mapped == FALSE || mapvals.bumpmap_id == -1)
for (k = 0; k < NUM_LIGHTS; k++)
{
pos_to_float (position->x, position->y, &xf, &yf);
if (!mapvals.lightsource[k].active
|| mapvals.lightsource[k].type == NO_LIGHT)
continue;
else if (mapvals.lightsource[k].type == POINT_LIGHT)
p = &mapvals.lightsource[k].position;
else
p = &mapvals.lightsource[k].direction;
color = peek (RINT (xf), RINT (yf));
color_int = mapvals.lightsource[k].color;
gimp_rgb_multiply (&color_int, mapvals.lightsource[k].intensity);
gimp_vector3_sub (&v, &mapvals.viewpoint, position);
gimp_vector3_normalize (&v);
if (mapvals.bump_mapped == FALSE || mapvals.bumpmap_id == -1)
{
pos_to_float (position->x, position->y, &xf, &yf);
r = compute_reflected_ray (&mapvals.planenormal, &v);
color = peek (RINT (xf), RINT (yf));
/* Get color in the direction of r */
/* =============================== */
gimp_vector3_sub (&v, &mapvals.viewpoint, position);
gimp_vector3_normalize (&v);
sphere_to_image (&r, &xf, &yf);
env_color = peek_env_map (RINT (env_width * xf),
RINT (env_height * yf));
r = compute_reflected_ray (&mapvals.planenormal, &v);
color = phong_shade (position,
&mapvals.viewpoint,
&mapvals.planenormal,
p,
&env_color,
&mapvals.lightsource[0].color,
mapvals.lightsource[0].type);
}
else
{
normal = vertex_normals[1][(gint) RINT (xf)];
/* Get color in the direction of r */
/* =============================== */
pos_to_float (position->x, position->y, &xf, &yf);
color = peek (RINT (xf), RINT (yf));
sphere_to_image (&r, &xf, &yf);
env_color = peek_env_map (RINT (env_width * xf),
RINT (env_height * yf));
gimp_vector3_sub (&v, &mapvals.viewpoint, position);
gimp_vector3_normalize (&v);
light_color = phong_shade (position,
&mapvals.viewpoint,
&mapvals.planenormal,
p,
&env_color,
&color_int,
mapvals.lightsource[0].type);
}
else
{
normal = vertex_normals[1][(gint) RINT (xf)];
r = compute_reflected_ray (&normal, &v);
pos_to_float (position->x, position->y, &xf, &yf);
color = peek (RINT (xf), RINT (yf));
/* Get color in the direction of r */
/* =============================== */
sphere_to_image (&r, &xf, &yf);
env_color = peek_env_map (RINT (env_width * xf),
RINT (env_height * yf));
gimp_vector3_sub (&v, &mapvals.viewpoint, position);
gimp_vector3_normalize (&v);
color = phong_shade (position,
&mapvals.viewpoint,
&normal,
p,
&env_color,
&mapvals.lightsource[0].color,
mapvals.lightsource[0].type);
r = compute_reflected_ray (&normal, &v);
/* Get color in the direction of r */
/* =============================== */
sphere_to_image (&r, &xf, &yf);
env_color = peek_env_map (RINT (env_width * xf),
RINT (env_height * yf));
light_color = phong_shade (position,
&mapvals.viewpoint,
&normal,
p,
&env_color,
&color_int,
mapvals.lightsource[0].type);
gimp_rgb_add (&color_sum, &light_color);
}
}
}
return color;
gimp_rgb_clamp (&color_sum);
return color_sum;
}

View file

@ -35,53 +35,54 @@
#include "libgimp/stdplugins-intl.h"
extern LightingValues mapvals;
static GtkWidget *appwin = NULL;
static GtkNotebook *options_note_book = NULL;
GdkGC *gc = NULL;
GtkWidget *previewarea = NULL;
GdkGC *gc = NULL;
GtkWidget *previewarea = NULL;
static GtkWidget *pointlightwid[NUM_LIGHTS];
static GtkWidget *dirlightwid[NUM_LIGHTS];
static GtkWidget *colorbutton[NUM_LIGHTS];
static GtkWidget *light_type_combo[NUM_LIGHTS];
static GtkWidget *colorbutton;
static GtkWidget *light_type_combo;
static GtkWidget *lightselect_combo;
static GtkWidget *spin_intensity;
static GtkWidget *isolate_button;
static gchar *lighting_effects_path = NULL;
static void create_main_notebook (GtkWidget *container);
static void create_main_notebook (GtkWidget *container);
#ifdef _LIGHTNING_UNUSED_CODE
static void xyzval_update (GtkEntry *entry);
static void xyzval_update (GtkEntry *entry);
#endif
static void toggle_update (GtkWidget *widget,
gpointer data);
static void toggle_update (GtkWidget *widget,
gpointer data);
static void lightmenu_callback (GtkWidget *widget,
gpointer data);
static gboolean bumpmap_constrain (gint32 image_id,
gint32 drawable_id,
gpointer data);
static gboolean envmap_constrain (gint32 image_id,
gint32 drawable_id,
gpointer data);
static void envmap_combo_callback (GtkWidget *widget,
gpointer data);
static void save_lighting_preset (GtkWidget *widget,
gpointer data);
static void file_chooser_response (GtkFileChooser *chooser,
gint response_id,
gpointer data);
static void load_lighting_preset (GtkWidget *widget,
gpointer data);
static gboolean bumpmap_constrain (gint32 image_id,
gint32 drawable_id,
gpointer data);
static gboolean envmap_constrain (gint32 image_id,
gint32 drawable_id,
gpointer data);
static void envmap_combo_callback (GtkWidget *widget,
gpointer data);
static void save_lighting_preset (GtkWidget *widget,
gpointer data);
static void file_chooser_response (GtkFileChooser *chooser,
gint response_id,
gpointer data);
static void load_lighting_preset (GtkWidget *widget,
gpointer data);
static void load_file_chooser_response (GtkFileChooser *chooser,
gint response_id,
gpointer data);
gint response_id,
gpointer data);
static void lightselect_callback (GimpIntComboBox *combo,
gpointer data);
static void apply_settings (GtkWidget *widget,
gpointer data);
static void isolate_selected_light (GtkWidget *widget,
gpointer data);
#ifdef _LIGHTNING_UNUSED_CODE
@ -122,35 +123,42 @@ toggle_update (GtkWidget *widget,
/*****************************************/
static void
lightmenu_callback (GtkWidget *widget,
gpointer data)
apply_settings (GtkWidget *widget,
gpointer data)
{
gint k;
gint valid;
gint type;
gint k = mapvals.light_selected;
gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), (gint *) data);
for (k = 0; k < NUM_LIGHTS; k++)
if (mapvals.update_enabled)
{
switch (mapvals.lightsource[k].type)
{
case POINT_LIGHT:
gtk_widget_hide (dirlightwid[k]);
gtk_widget_show (pointlightwid[k]);
break;
valid = gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (light_type_combo),
&type);
if (valid)
mapvals.lightsource[k].type = type;
case DIRECTIONAL_LIGHT:
gtk_widget_hide (pointlightwid[k]);
gtk_widget_show (dirlightwid[k]);
break;
gimp_color_button_get_color (GIMP_COLOR_BUTTON (colorbutton),
&mapvals.lightsource[k].color);
default:
gtk_widget_hide (pointlightwid[k]);
gtk_widget_hide (dirlightwid[k]);
break;
}
mapvals.lightsource[k].position.x
= gtk_spin_button_get_value (GTK_SPIN_BUTTON(spin_pos_x));
mapvals.lightsource[k].position.y
= gtk_spin_button_get_value (GTK_SPIN_BUTTON(spin_pos_y));
mapvals.lightsource[k].position.z
= gtk_spin_button_get_value (GTK_SPIN_BUTTON(spin_pos_z));
mapvals.lightsource[k].direction.x
= gtk_spin_button_get_value (GTK_SPIN_BUTTON(spin_dir_x));
mapvals.lightsource[k].direction.y
= gtk_spin_button_get_value (GTK_SPIN_BUTTON(spin_dir_y));
mapvals.lightsource[k].direction.z
= gtk_spin_button_get_value (GTK_SPIN_BUTTON(spin_dir_z));
mapvals.lightsource[k].intensity
= gtk_spin_button_get_value (GTK_SPIN_BUTTON(spin_intensity));
interactive_preview_callback(NULL);
}
interactive_preview_callback(NULL);
}
static void
@ -311,13 +319,11 @@ create_light_page (void)
GtkWidget *page;
GtkWidget *frame;
GtkWidget *table;
GtkWidget *table2;
GtkWidget *ebox;
GtkWidget *button;
GtkObject *adj;
GtkWidget *label;
gint k;
gchar label_text[20];
gint k = mapvals.light_selected;
page = gtk_vbox_new (FALSE, 12);
gtk_container_set_border_width (GTK_CONTAINER (page), 12);
@ -332,6 +338,22 @@ create_light_page (void)
gtk_container_add (GTK_CONTAINER (frame), table);
gtk_widget_show (table);
gtk_table_set_col_spacing (GTK_TABLE (table), 1, 12);
gtk_table_set_col_spacing (GTK_TABLE (table), 3, 12);
lightselect_combo = gimp_int_combo_box_new (_("Light 1"), 0,
_("Light 2"), 1,
_("Light 3"), 2,
_("Light 4"), 3,
_("Light 5"), 4,
_("Light 6"), 5,
NULL);
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (lightselect_combo), k);
gtk_table_attach_defaults (GTK_TABLE (table), lightselect_combo, 0, 2, 0, 1);
g_signal_connect (lightselect_combo, "changed",
G_CALLBACK (lightselect_callback), NULL);
gtk_widget_show (lightselect_combo);
/* row labels */
label = gtk_label_new (_("Type:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
@ -343,193 +365,169 @@ create_light_page (void)
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
gtk_widget_show (label);
gtk_table_set_col_spacing (GTK_TABLE (table), 2, 12);
gtk_table_set_col_spacing (GTK_TABLE (table), 4, 12);
light_type_combo =
gimp_int_combo_box_new (_("None"), NO_LIGHT,
_("Directional"), DIRECTIONAL_LIGHT,
_("Point"), POINT_LIGHT,
/* _("Spot"), SPOT_LIGHT, */
NULL);
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (light_type_combo),
mapvals.lightsource[k].type);
g_signal_connect (light_type_combo, "changed",
G_CALLBACK (apply_settings),
NULL);
for (k = 0; k < NUM_LIGHTS; k++)
{
g_snprintf (label_text, sizeof (label_text), "Light %d", k + 1);
label = gtk_label_new (label_text);
gtk_table_attach_defaults (GTK_TABLE (table),
label, 2*k + 1, 2*k + 2, 0, 1);
gtk_widget_show (label);
ebox = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (ebox), light_type_combo);
gtk_widget_show (ebox);
gtk_table_attach_defaults (GTK_TABLE (table),
ebox, 1, 2, 1, 2);
gtk_widget_show (light_type_combo);
gimp_help_set_help_data (ebox, _("Type of light source to apply"), NULL);
light_type_combo[k] =
gimp_int_combo_box_new (_("None"), NO_LIGHT,
_("Directional"), DIRECTIONAL_LIGHT,
_("Point"), POINT_LIGHT,
/* _("Spot"), SPOT_LIGHT, */
NULL);
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (light_type_combo[k]),
mapvals.lightsource[k].type);
g_signal_connect (light_type_combo[k], "changed",
G_CALLBACK (lightmenu_callback),
&mapvals.lightsource[k].type);
colorbutton = gimp_color_button_new (_("Select lightsource color"),
64, 16,
&mapvals.lightsource[k].color,
GIMP_COLOR_AREA_FLAT);
gimp_color_button_set_update (GIMP_COLOR_BUTTON (colorbutton), TRUE);
g_signal_connect (colorbutton, "color_changed",
G_CALLBACK (apply_settings),
NULL);
gtk_widget_show (colorbutton);
gtk_table_attach_defaults (GTK_TABLE (table),
colorbutton, 1, 2, 2, 3);
gimp_help_set_help_data (colorbutton,
_("Set light source color"), NULL);
ebox = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (ebox), light_type_combo[k]);
gtk_widget_show (ebox);
gtk_table_attach_defaults (GTK_TABLE (table),
ebox, 2*k + 1, 2*k + 2, 1, 2);
gtk_widget_show (light_type_combo[k]);
gimp_help_set_help_data (ebox, _("Type of light source to apply"), NULL);
colorbutton[k] = gimp_color_button_new (_("Select lightsource color"),
64, 16,
&mapvals.lightsource[k].color,
GIMP_COLOR_AREA_FLAT);
g_signal_connect (colorbutton[k], "color_changed",
G_CALLBACK (gimp_color_button_get_color),
&mapvals.lightsource[k].color);
g_signal_connect (colorbutton[k], "color_changed",
G_CALLBACK (interactive_preview_callback),
NULL);
gtk_widget_show (colorbutton[k]);
gtk_table_attach_defaults (GTK_TABLE (table),
colorbutton[k], 2*k + 1, 2*k + 2, 2, 3);
gimp_help_set_help_data (colorbutton[k],
_("Set light source color"), NULL);
spin_intensity = gimp_spin_button_new (&adj,
mapvals.lightsource[k].intensity,
0.0, 100.0,
0.01, 0.1, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 3,
_("_Intensity:"), 0.0, 0.5,
spin_intensity, 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (apply_settings),
NULL);
gimp_help_set_help_data (spin_intensity,
_("Light intensity"), NULL);
/* Position vector settings */
pointlightwid[k] = gtk_vbox_new (FALSE, 0);
if (mapvals.lightsource[k].type == POINT_LIGHT)
gtk_widget_show (pointlightwid[k]);
table2 = gtk_table_new (3, 2, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table2), 6);
gtk_table_set_row_spacings (GTK_TABLE (table2), 6);
gtk_container_add (GTK_CONTAINER (pointlightwid[k]), table2);
gtk_table_attach_defaults (GTK_TABLE (table),
pointlightwid[k], 2*k + 1, 2*k + 2, 4, 5);
gtk_widget_show (table2);
label = gtk_label_new (_("Position"));
gtk_table_attach_defaults (GTK_TABLE (table), label, 3, 4, 0, 1);
gtk_widget_show (label);
spin_pos_x[k] = gimp_spin_button_new (&adj,
mapvals.lightsource[k].position.x,
-100.0, 100.0,
0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table2), 0, 0,
spin_pos_x = gimp_spin_button_new (&adj,
mapvals.lightsource[k].position.x,
-100.0, 100.0,
0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table), 2, 1,
_("_X:"), 0.0, 0.5,
spin_pos_x[k], 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&mapvals.lightsource[k].position.x);
g_signal_connect (adj, "value_changed",
G_CALLBACK (interactive_preview_callback),
NULL);
gimp_help_set_help_data (spin_pos_x[k],
_("Light source X position in XYZ space"), NULL);
spin_pos_x, 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (apply_settings),
NULL);
gimp_help_set_help_data (spin_pos_x,
_("Light source X position in XYZ space"), NULL);
spin_pos_y[k] = gimp_spin_button_new (&adj,
mapvals.lightsource[k].position.y,
-100.0, 100.0,
0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table2), 0, 1,
_("_Y:"), 0.0, 0.5,
spin_pos_y[k], 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&mapvals.lightsource[k].position.y);
g_signal_connect (adj, "value_changed",
G_CALLBACK (interactive_preview_callback),
NULL);
gimp_help_set_help_data (spin_pos_y[k],
spin_pos_y = gimp_spin_button_new (&adj,
mapvals.lightsource[k].position.y,
-100.0, 100.0,
0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table), 2, 2,
_("_Y:"), 0.0, 0.5,
spin_pos_y, 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (apply_settings),
NULL);
gimp_help_set_help_data (spin_pos_y,
_("Light source Y position in XYZ space"), NULL);
spin_pos_z[k] = gimp_spin_button_new (&adj,
mapvals.lightsource[k].position.z,
-100.0, 100.0,
0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table2), 0, 2,
_("_Z:"), 0.0, 0.5,
spin_pos_z[k], 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&mapvals.lightsource[k].position.z);
g_signal_connect (adj, "value_changed",
G_CALLBACK (interactive_preview_callback),
NULL);
gimp_help_set_help_data (spin_pos_z[k],
_("Light source Z position in XYZ space"), NULL);
spin_pos_z = gimp_spin_button_new (&adj,
mapvals.lightsource[k].position.z,
-100.0, 100.0,
0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table), 2, 3,
_("_Z:"), 0.0, 0.5,
spin_pos_z, 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (apply_settings),
NULL);
gimp_help_set_help_data (spin_pos_z,
_("Light source Z position in XYZ space"), NULL);
/* Direction vector settings */
dirlightwid[k] = gtk_vbox_new (FALSE, 0);
if (mapvals.lightsource[k].type == DIRECTIONAL_LIGHT)
gtk_widget_show (dirlightwid[k]);
table2 = gtk_table_new (3, 2, FALSE);
gtk_widget_show (table2);
gtk_table_set_col_spacings (GTK_TABLE (table2), 6);
gtk_table_set_row_spacings (GTK_TABLE (table2), 6);
gtk_container_add (GTK_CONTAINER (dirlightwid[k]), table2);
gtk_table_attach_defaults (GTK_TABLE (table),
dirlightwid[k], 2*k + 1, 2*k + 2, 4, 5);
label = gtk_label_new (_("Direction"));
gtk_table_attach_defaults (GTK_TABLE (table), label, 5, 6, 0, 1);
gtk_widget_show (label);
spin_dir_x[k] = gimp_spin_button_new (&adj,
mapvals.lightsource[k].direction.x,
-100.0, 100.0, 0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table2), 0, 0,
_("X:"), 0.0, 0.5,
spin_dir_x[k], 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&mapvals.lightsource[k].direction.x);
g_signal_connect (adj, "value_changed",
G_CALLBACK (interactive_preview_callback),
NULL);
gimp_help_set_help_data (spin_dir_x[k],
_("Light source X direction in XYZ space"), NULL);
spin_dir_x = gimp_spin_button_new (&adj,
mapvals.lightsource[k].direction.x,
-100.0, 100.0, 0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table), 4, 1,
_("X:"), 0.0, 0.5,
spin_dir_x, 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (apply_settings),
NULL);
gimp_help_set_help_data (spin_dir_x,
_("Light source X direction in XYZ space"), NULL);
spin_dir_y[k] = gimp_spin_button_new (&adj,
mapvals.lightsource[k].direction.y,
-100.0, 100.0, 0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table2), 0, 1,
_("Y:"), 0.0, 0.5,
spin_dir_y[k], 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&mapvals.lightsource[k].direction.y);
g_signal_connect (adj, "value_changed",
G_CALLBACK (interactive_preview_callback),
NULL);
gimp_help_set_help_data (spin_dir_y[k],
_("Light source Y direction in XYZ space"), NULL);
spin_dir_y = gimp_spin_button_new (&adj,
mapvals.lightsource[k].direction.y,
-100.0, 100.0, 0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table), 4, 2,
_("Y:"), 0.0, 0.5,
spin_dir_y, 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (apply_settings),
NULL);
gimp_help_set_help_data (spin_dir_y,
_("Light source Y direction in XYZ space"), NULL);
spin_dir_z[k] = gimp_spin_button_new (&adj,
mapvals.lightsource[k].direction.z,
-100.0, 100.0, 0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table2), 0, 2,
_("Z:"), 0.0, 0.5,
spin_dir_z[k], 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&mapvals.lightsource[k].direction.z);
g_signal_connect (adj, "value_changed",
G_CALLBACK (interactive_preview_callback),
NULL);
gimp_help_set_help_data (spin_dir_z[k],
_("Light source Z direction in XYZ space"),
NULL);
spin_dir_z = gimp_spin_button_new (&adj,
mapvals.lightsource[k].direction.z,
-100.0, 100.0, 0.1, 1.0, 1.0, 0.0, 2);
gimp_table_attach_aligned (GTK_TABLE (table), 4, 3,
_("Z:"), 0.0, 0.5,
spin_dir_z, 1, TRUE);
g_signal_connect (adj, "value_changed",
G_CALLBACK (apply_settings),
NULL);
gimp_help_set_help_data (spin_dir_z,
_("Light source Z direction in XYZ space"),
NULL);
label = gtk_label_new (_("Lighting preset:"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_set_row_spacing (GTK_TABLE (table), 4, 24);
gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 3, 5, 6);
gtk_widget_show (label);
isolate_button = gtk_toggle_button_new_with_mnemonic (_("I_solate"));
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (isolate_button), FALSE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (isolate_button),
mapvals.light_isolated);
g_signal_connect (isolate_button, "toggled",
G_CALLBACK (isolate_selected_light),
NULL);
gtk_table_attach_defaults (GTK_TABLE (table), isolate_button, 0, 1, 5, 6);
gtk_widget_show (isolate_button);
button = gtk_button_new_from_stock (GTK_STOCK_SAVE);
gtk_table_attach_defaults (GTK_TABLE (table), button, 3, 4, 5, 6);
g_signal_connect (button, "clicked",
G_CALLBACK (save_lighting_preset),
NULL);
gtk_widget_show (button);
label = gtk_label_new (_("Lighting preset:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_set_row_spacing (GTK_TABLE (table), 5, 12);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 2, 6, 7);
gtk_widget_show (label);
button = gtk_button_new_from_stock (GTK_STOCK_OPEN);
gtk_table_attach_defaults (GTK_TABLE (table), button, 5, 6, 5, 6);
g_signal_connect (button, "clicked",
G_CALLBACK (load_lighting_preset),
NULL);
gtk_widget_show (button);
}
button = gtk_button_new_from_stock (GTK_STOCK_SAVE);
gtk_table_attach_defaults (GTK_TABLE (table), button, 2, 4, 6, 7);
g_signal_connect (button, "clicked",
G_CALLBACK (save_lighting_preset),
NULL);
gtk_widget_show (button);
button = gtk_button_new_from_stock (GTK_STOCK_OPEN);
gtk_table_attach_defaults (GTK_TABLE (table), button, 4, 6, 6, 7);
g_signal_connect (button, "clicked",
G_CALLBACK (load_lighting_preset),
NULL);
gtk_widget_show (button);
gtk_widget_show (page);
@ -579,7 +577,7 @@ create_material_page (void)
image, 1, FALSE);
gtk_size_group_add_widget (group, label);
spinbutton = gimp_spin_button_new (&adj, mapvals.material.ambient_int,
0, G_MAXFLOAT, 0.1, 1.0, 1.0, 0.0, 2);
0, G_MAXFLOAT, 0.01, 0.1, 1.0, 0.0, 2);
gtk_table_attach (GTK_TABLE (table), spinbutton, 2, 3, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
g_signal_connect (adj, "value_changed",
@ -608,7 +606,7 @@ create_material_page (void)
image, 1, FALSE);
gtk_size_group_add_widget (group, label);
spinbutton = gimp_spin_button_new (&adj, mapvals.material.diffuse_int,
0, G_MAXFLOAT, 0.1, 1.0, 1.0, 0.0, 2);
0, G_MAXFLOAT, 0.01, 0.1, 1.0, 0.0, 2);
gtk_table_attach (GTK_TABLE (table), spinbutton, 2, 3, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
g_signal_connect (adj, "value_changed",
@ -637,7 +635,7 @@ create_material_page (void)
image, 1, FALSE);
gtk_size_group_add_widget (group, label);
spinbutton = gimp_spin_button_new (&adj, mapvals.material.specular_ref,
0, G_MAXFLOAT, 0.1, 1.0, 1.0, 0.0, 2);
0, G_MAXFLOAT, 0.01, 0.1, 1.0, 0.0, 2);
gtk_table_attach (GTK_TABLE (table), spinbutton, 2, 3, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
g_signal_connect (adj, "value_changed",
@ -665,7 +663,7 @@ create_material_page (void)
image, 1, FALSE);
gtk_size_group_add_widget (group, label);
spinbutton = gimp_spin_button_new (&adj, mapvals.material.highlight,
0, G_MAXFLOAT, 0.1, 1.0, 1.0, 0.0, 2);
0, G_MAXFLOAT, 0.01, 0.1, 1.0, 0.0, 2);
gtk_table_attach (GTK_TABLE (table), spinbutton, 2, 3, 3, 4,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
g_signal_connect (adj, "value_changed",
@ -1001,7 +999,6 @@ main_dialog (GimpDrawable *drawable)
G_CALLBACK (interactive_preview_callback),
NULL);
gtk_widget_show (toggle);
gimp_help_set_help_data (toggle,
@ -1083,7 +1080,6 @@ save_lighting_preset (GtkWidget *widget,
g_get_tmp_dir ());
}
gtk_window_present (GTK_WINDOW (window));
}
@ -1255,6 +1251,10 @@ load_file_chooser_response (GtkFileChooser *chooser,
{
fscanf (fp, "Number of lights: %d", &num_lights);
/* initialize lights to off */
for (k = 0; k < NUM_LIGHTS; k++)
mapvals.lightsource[k].type = NO_LIGHT;
for (k = 0; k < num_lights; k++)
{
source = &mapvals.lightsource[k];
@ -1293,17 +1293,121 @@ load_file_chooser_response (GtkFileChooser *chooser,
fscanf (fp, " Intensity: %s", buffer1);
source->intensity = g_ascii_strtod (buffer1, &endptr);
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (light_type_combo[k]),
source->type);
gimp_color_button_set_color (GIMP_COLOR_BUTTON (colorbutton[k]),
&source->color);
}
}
fclose (fp);
}
}
lightselect_callback (GIMP_INT_COMBO_BOX (lightselect_combo), NULL);
}
gtk_widget_destroy (GTK_WIDGET (chooser));
interactive_preview_callback (GTK_WIDGET (chooser));
}
static void
lightselect_callback (GimpIntComboBox *combo,
gpointer data)
{
gint valid;
gint j, k;
valid = gimp_int_combo_box_get_active (combo, &k);
if (valid)
{
mapvals.update_enabled = FALSE; /* prevent apply_settings() */
mapvals.light_selected = k;
gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (light_type_combo),
mapvals.lightsource[k].type);
gimp_color_button_set_color (GIMP_COLOR_BUTTON (colorbutton),
&mapvals.lightsource[k].color);
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);
gtk_spin_button_set_value (GTK_SPIN_BUTTON(spin_intensity),
mapvals.lightsource[k].intensity);
mapvals.update_enabled = TRUE;
switch (mapvals.lightsource[k].type)
{
case NO_LIGHT:
gtk_widget_set_sensitive (spin_pos_x, FALSE);
gtk_widget_set_sensitive (spin_pos_y, FALSE);
gtk_widget_set_sensitive (spin_pos_z, FALSE);
gtk_widget_set_sensitive (spin_dir_x, FALSE);
gtk_widget_set_sensitive (spin_dir_y, FALSE);
gtk_widget_set_sensitive (spin_dir_z, FALSE);
break;
case POINT_LIGHT:
gtk_widget_set_sensitive (spin_pos_x, TRUE);
gtk_widget_set_sensitive (spin_pos_y, TRUE);
gtk_widget_set_sensitive (spin_pos_z, TRUE);
gtk_widget_set_sensitive (spin_dir_x, FALSE);
gtk_widget_set_sensitive (spin_dir_y, FALSE);
gtk_widget_set_sensitive (spin_dir_z, FALSE);
break;
case DIRECTIONAL_LIGHT:
gtk_widget_set_sensitive (spin_pos_x, FALSE);
gtk_widget_set_sensitive (spin_pos_y, FALSE);
gtk_widget_set_sensitive (spin_pos_z, FALSE);
gtk_widget_set_sensitive (spin_dir_x, TRUE);
gtk_widget_set_sensitive (spin_dir_y, TRUE);
gtk_widget_set_sensitive (spin_dir_z, TRUE);
break;
default:
break;
}
/* if we are isolating a light, need to switch */
if (mapvals.light_isolated)
{
for (j = 0; j < NUM_LIGHTS; j++)
if (j == mapvals.light_selected)
mapvals.lightsource[j].active = TRUE;
else
mapvals.lightsource[j].active = FALSE;
}
interactive_preview_callback (NULL);
}
}
static void
isolate_selected_light (GtkWidget *widget,
gpointer data)
{
gint k;
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
{
mapvals.light_isolated = TRUE;
for (k = 0; k < NUM_LIGHTS; k++)
if (k == mapvals.light_selected)
mapvals.lightsource[k].active = TRUE;
else
mapvals.lightsource[k].active = FALSE;
}
else
{
mapvals.light_isolated = FALSE;
for (k = 0; k < NUM_LIGHTS; k++)
mapvals.lightsource[k].active = TRUE;
}
interactive_preview_callback (NULL);
}