1 /* Lighting Effects 0.2.2 -- image filter plug-in for GIMP
2 *
3 * Copyright (C) 1996-98 Tom Bech
4 * Copyright (C) 1996-98 Federico Mena Quintero
5 *
6 * E-mail: tomb@gimp.org (Tom) or quartic@gimp.org (Federico)
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include "config.h"
23
24 #include <gtk/gtk.h>
25
26 #include <libgimp/gimp.h>
27
28 #include "lighting-apply.h"
29 #include "lighting-image.h"
30 #include "lighting-main.h"
31 #include "lighting-preview.h"
32 #include "lighting-shade.h"
33 #include "lighting-ui.h"
34
35 #include "libgimp/stdplugins-intl.h"
36
37
38 LightingValues mapvals;
39
40 /******************/
41 /* Implementation */
42 /******************/
43
44 /*************************************/
45 /* Set parameters to standard values */
46 /*************************************/
47
48 static void
set_default_settings(void)49 set_default_settings (void)
50 {
51 gint k;
52
53 mapvals.update_enabled = TRUE;
54 mapvals.light_selected = 0;
55 mapvals.light_isolated = FALSE;
56
57 gimp_vector3_set (&mapvals.viewpoint, 0.5, 0.5, 0.25);
58 gimp_vector3_set (&mapvals.planenormal, 0.0, 0.0, 1.0);
59
60 gimp_vector3_set (&mapvals.lightsource[0].position, -1.0, -1.0, 1.0);
61 gimp_vector3_set (&mapvals.lightsource[0].direction, -1.0, -1.0, 1.0);
62
63 gimp_rgba_set (&mapvals.lightsource[0].color, 1.0, 1.0, 1.0, 1.0);
64 mapvals.lightsource[0].intensity = 1.0;
65 mapvals.lightsource[0].type = POINT_LIGHT;
66 mapvals.lightsource[0].active = TRUE;
67
68 /* init lights 2 and 3 pos to upper left and below */
69 gimp_vector3_set (&mapvals.lightsource[1].position, 2.0, -1.0, 1.0);
70 gimp_vector3_set (&mapvals.lightsource[1].direction, 1.0, -1.0, 1.0);
71
72 gimp_vector3_set (&mapvals.lightsource[2].position, 1.0, 2.0, 1.0);
73 gimp_vector3_set (&mapvals.lightsource[2].direction, 0.0, 1.0, 1.0);
74
75 /* init any remaining lights to directly overhead */
76 for (k = 3; k < NUM_LIGHTS; k++)
77 {
78 gimp_vector3_set (&mapvals.lightsource[k].position, 0.0, 0.0, 1.0);
79 gimp_vector3_set (&mapvals.lightsource[k].direction, 0.0, 0.0, 1.0);
80 }
81
82 for (k = 1; k < NUM_LIGHTS; k++)
83 {
84 gimp_rgba_set (&mapvals.lightsource[k].color, 1.0, 1.0, 1.0, 1.0);
85 mapvals.lightsource[k].intensity = 1.0;
86 mapvals.lightsource[k].type = NO_LIGHT;
87 mapvals.lightsource[k].active = TRUE;
88 }
89
90 mapvals.material.ambient_int = 0.2;
91 mapvals.material.diffuse_int = 0.5;
92 mapvals.material.diffuse_ref = 0.4;
93 mapvals.material.specular_ref = 0.5;
94 mapvals.material.highlight = 27.0;
95 mapvals.material.metallic = FALSE;
96
97 mapvals.pixel_threshold = 0.25;
98 mapvals.max_depth = 3.0;
99 mapvals.preview_zoom_factor = 1.0;
100
101 mapvals.bumpmaptype = 0;
102 mapvals.bumpmin = 0.0;
103 mapvals.bumpmax = 0.1;
104
105 mapvals.antialiasing = FALSE;
106 mapvals.create_new_image = FALSE;
107 mapvals.transparent_background = FALSE;
108 mapvals.bump_mapped = FALSE;
109 mapvals.env_mapped = FALSE;
110 mapvals.ref_mapped = FALSE;
111 mapvals.previewquality = FALSE;
112 mapvals.interactive_preview = TRUE;
113
114 mapvals.bumpmap_id = -1;
115 mapvals.envmap_id = -1;
116 }
117
118 static void
check_drawables(void)119 check_drawables (void)
120 {
121 if (mapvals.bump_mapped)
122 {
123 if (mapvals.bumpmap_id != -1 &&
124 gimp_item_get_image (mapvals.bumpmap_id) == -1)
125 {
126 mapvals.bump_mapped = FALSE;
127 mapvals.bumpmap_id = -1;
128 }
129
130 if (gimp_drawable_is_indexed (mapvals.bumpmap_id) ||
131 (gimp_drawable_width (mapvals.drawable_id) !=
132 gimp_drawable_width (mapvals.bumpmap_id)) ||
133 (gimp_drawable_height (mapvals.drawable_id) !=
134 gimp_drawable_height (mapvals.bumpmap_id)))
135 {
136 mapvals.bump_mapped = FALSE;
137 mapvals.bumpmap_id = -1;
138 }
139 }
140
141 if (mapvals.env_mapped)
142 {
143 if (mapvals.envmap_id != -1 &&
144 gimp_item_get_image (mapvals.envmap_id) == -1)
145 {
146 mapvals.env_mapped = FALSE;
147 mapvals.envmap_id = -1;
148 }
149
150 if (gimp_drawable_is_gray (mapvals.envmap_id) ||
151 gimp_drawable_has_alpha (mapvals.envmap_id))
152 {
153 mapvals.env_mapped = FALSE;
154 mapvals.envmap_id = -1;
155 }
156 }
157 }
158
159 static void
query(void)160 query (void)
161 {
162 static const GimpParamDef args[] =
163 {
164 { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
165 { GIMP_PDB_IMAGE, "image", "Input image" },
166 { GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
167 { GIMP_PDB_DRAWABLE, "bumpdrawable", "Bumpmap drawable (set to 0 if disabled)" },
168 { GIMP_PDB_DRAWABLE, "envdrawable", "Environmentmap drawable (set to 0 if disabled)" },
169 { GIMP_PDB_INT32, "dobumpmap", "Enable bumpmapping (TRUE/FALSE)" },
170 { GIMP_PDB_INT32, "doenvmap", "Enable envmapping (TRUE/FALSE)" },
171 { GIMP_PDB_INT32, "bumpmaptype", "Type of mapping (0=linear,1=log, 2=sinusoidal, 3=spherical)" },
172 { GIMP_PDB_INT32, "lighttype", "Type of lightsource (0=point,1=directional,3=spot,4=none)" },
173 { GIMP_PDB_COLOR, "lightcolor", "Lightsource color (r,g,b)" },
174 { GIMP_PDB_FLOAT, "lightposition-x", "Lightsource position (x,y,z)" },
175 { GIMP_PDB_FLOAT, "lightposition-y", "Lightsource position (x,y,z)" },
176 { GIMP_PDB_FLOAT, "lightposition-z", "Lightsource position (x,y,z)" },
177 { GIMP_PDB_FLOAT, "lightdirection-x", "Lightsource direction [x,y,z]" },
178 { GIMP_PDB_FLOAT, "lightdirection-y", "Lightsource direction [x,y,z]" },
179 { GIMP_PDB_FLOAT, "lightdirection-z", "Lightsource direction [x,y,z]" },
180 { GIMP_PDB_FLOAT, "ambient-intensity", "Material ambient intensity (0..1)" },
181 { GIMP_PDB_FLOAT, "diffuse-intensity", "Material diffuse intensity (0..1)" },
182 { GIMP_PDB_FLOAT, "diffuse-reflectivity", "Material diffuse reflectivity (0..1)" },
183 { GIMP_PDB_FLOAT, "specular-reflectivity", "Material specular reflectivity (0..1)" },
184 { GIMP_PDB_FLOAT, "highlight", "Material highlight (0..->), note: it's exponential" },
185 { GIMP_PDB_INT32, "antialiasing", "Apply antialiasing (TRUE/FALSE)" },
186 { GIMP_PDB_INT32, "newimage", "Create a new image (TRUE/FALSE)" },
187 { GIMP_PDB_INT32, "transparentbackground", "Make background transparent (TRUE/FALSE)" }
188 };
189
190 gimp_install_procedure (PLUG_IN_PROC,
191 N_("Apply various lighting effects to an image"),
192 "No help yet",
193 "Tom Bech & Federico Mena Quintero",
194 "Tom Bech & Federico Mena Quintero",
195 "Version 0.2.0, March 15 1998",
196 N_("_Lighting Effects..."),
197 "RGB*",
198 GIMP_PLUGIN,
199 G_N_ELEMENTS (args), 0,
200 args, NULL);
201
202 gimp_plugin_menu_register (PLUG_IN_PROC,
203 "<Image>/Filters/Light and Shadow/Light");
204 }
205
206 static void
run(const gchar * name,gint nparams,const GimpParam * param,gint * nreturn_vals,GimpParam ** return_vals)207 run (const gchar *name,
208 gint nparams,
209 const GimpParam *param,
210 gint *nreturn_vals,
211 GimpParam **return_vals)
212 {
213 static GimpParam values[1];
214 GimpRunMode run_mode;
215 gint32 drawable_id;
216 GimpPDBStatusType status = GIMP_PDB_SUCCESS;
217
218 INIT_I18N ();
219 gegl_init (NULL, NULL);
220
221 *nreturn_vals = 1;
222 *return_vals = values;
223
224 values[0].type = GIMP_PDB_STATUS;
225 values[0].data.d_status = status;
226
227 /* Set default values */
228 /* ================== */
229
230 set_default_settings ();
231
232 /* Possibly retrieve data */
233 /* ====================== */
234
235 gimp_get_data (PLUG_IN_PROC, &mapvals);
236
237 /* Get the specified drawable */
238 /* ========================== */
239
240 run_mode = param[0].data.d_int32;
241 drawable_id = param[2].data.d_drawable;
242
243 mapvals.drawable_id = drawable_id;
244
245 check_drawables ();
246
247 if (status == GIMP_PDB_SUCCESS)
248 {
249 /* Make sure that the drawable is RGBA or RGB color */
250 /* ================================================ */
251
252 if (gimp_drawable_is_rgb (drawable_id))
253 {
254 switch (run_mode)
255 {
256 case GIMP_RUN_INTERACTIVE:
257 if (main_dialog (drawable_id))
258 {
259 compute_image ();
260
261 gimp_set_data (PLUG_IN_PROC,
262 &mapvals, sizeof (LightingValues));
263 gimp_displays_flush ();
264 }
265 break;
266
267 case GIMP_RUN_WITH_LAST_VALS:
268 if (image_setup (drawable_id, FALSE))
269 compute_image ();
270 gimp_displays_flush ();
271 break;
272
273 case GIMP_RUN_NONINTERACTIVE:
274 if (nparams != 24)
275 {
276 status = GIMP_PDB_CALLING_ERROR;
277 }
278 else
279 {
280 mapvals.bumpmap_id = param[3].data.d_drawable;
281 mapvals.envmap_id = param[4].data.d_drawable;
282 mapvals.bump_mapped = (gint) param[5].data.d_int32;
283 mapvals.env_mapped = (gint) param[6].data.d_int32;
284 mapvals.bumpmaptype = (gint) param[7].data.d_int32;
285 mapvals.lightsource[0].type = (LightType) param[8].data.d_int32;
286 mapvals.lightsource[0].color = param[9].data.d_color;
287 mapvals.lightsource[0].position.x = param[10].data.d_float;
288 mapvals.lightsource[0].position.y = param[11].data.d_float;
289 mapvals.lightsource[0].position.z = param[12].data.d_float;
290 mapvals.lightsource[0].direction.x = param[13].data.d_float;
291 mapvals.lightsource[0].direction.y = param[14].data.d_float;
292 mapvals.lightsource[0].direction.z = param[15].data.d_float;
293 mapvals.material.ambient_int = param[16].data.d_float;
294 mapvals.material.diffuse_int = param[17].data.d_float;
295 mapvals.material.diffuse_ref = param[18].data.d_float;
296 mapvals.material.specular_ref = param[19].data.d_float;
297 mapvals.material.highlight = param[20].data.d_float;
298 mapvals.antialiasing = (gint) param[21].data.d_int32;
299 mapvals.create_new_image = (gint) param[22].data.d_int32;
300 mapvals.transparent_background = (gint) param[23].data.d_int32;
301
302 check_drawables ();
303 if (image_setup (drawable_id, FALSE))
304 compute_image ();
305 }
306 default:
307 break;
308 }
309 }
310 else
311 {
312 status = GIMP_PDB_EXECUTION_ERROR;
313 }
314 }
315
316 values[0].data.d_status = status;
317
318 g_free (xpostab);
319 g_free (ypostab);
320 }
321
322 const GimpPlugInInfo PLUG_IN_INFO =
323 {
324 NULL, /* init_proc */
325 NULL, /* quit_proc */
326 query, /* query_proc */
327 run, /* run_proc */
328 };
329
330 MAIN ()
331