1 /* Copyright (C) 1992-1998 The Geometry Center
2 * Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips
3 * Copyright (C) 2007 Claus-Justus Heine
4 *
5 * This file is part of Geomview.
6 *
7 * Geomview is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * Geomview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Geomview; see the file COPYING. If not, write
19 * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
20 * USA, or visit http://www.gnu.org.
21 */
22
23 #if HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #if 0
28 static char copyright[] = "Copyright (C) 1992-1998 The Geometry Center\n\
29 Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips";
30 #endif
31
32 #include "mgP.h"
33 #include "mgribP.h"
34 #include "mgribshade.h"
35 #include "mgribtoken.h"
36
37 /*
38 * Notes: Tossed mgrib_material, just use mgrib_appearance
39 * since shaders depend on both appearance and material
40 * settings. (4/1/93 TMM)
41 */
42 void
mgrib_appearance(struct mgastk * astk,int ap_mask,int mat_mask)43 mgrib_appearance( struct mgastk *astk, int ap_mask, int mat_mask)
44 {
45 Appearance *ap = &(astk->ap);
46 Material *mat = &astk->mat;
47
48 mrti(mr_section, "Interpreting Material", mr_NULL);
49
50 if (mat_mask & MTF_DIFFUSE)
51 mrti(mr_color, mr_parray, 3, &mat->diffuse, mr_NULL);
52
53 if ((ap_mask & APF_TRANSP || mat_mask & MTF_ALPHA) &&
54 ap->valid & APF_TRANSP && ap->flag & APF_TRANSP) {
55 /* presumably, we want this here as well as per vertex opacity
56 * specification
57 *
58 * Actually, if the material alpha override bit is set, we
59 * don't output the per vertex opacity information, which
60 * would take precedence. 4/16/93 TMM
61 */
62 float alpha = astk->mat.diffuse.a;
63 mrti(mr_opacity, mr_array, 3, alpha, alpha, alpha, mr_NULL);
64 }
65
66 if ( (ap_mask & (APF_SHADING|APF_TEXTURE))
67 || (mat_mask & (MTF_SPECULAR|MTF_SHININESS|MTF_Kd|MTF_Ka|MTF_Ks))
68 || ( (ap->tex != NULL)
69 && (ap->flag & APF_TEXTURE)
70 && (ap->tex != astk->next->ap.tex) )
71 ) {
72 #if 1 /* cH: I'm not so sure 'bout the following anymore */
73 /* NOTE: the factor "8.0" is to compensate for some of the
74 * usual rib shaders, i.e. BMRT, aqsis etc.. Don't know
75 * why they started this affair, but without the output
76 * from rendrib or aqsis is just _very_ different from
77 * that what is displayed on the screen -- cH.
78 *
79 */
80 float roughness = (mat->shininess)? 8.0/mat->shininess : 8.0/1.0;
81 #else
82 float roughness = (mat->shininess)? 1.0/mat->shininess : 1.0/1.0;
83 #endif
84 enum tokentype shader = mr_plastic;
85
86 if (ap->shading == APF_CONSTANT || ap->shading == APF_CSMOOTH) {
87 if (_mgribc->shader == MG_RIBSTDSHADE) {
88 shader = mr_constant;
89 } else if ((ap->flag & APF_TEXTURE) && ap->tex != NULL) {
90 switch (ap->tex->apply) {
91 case TXF_MODULATE: shader = mr_GVmodulateconstant; break;
92 case TXF_DECAL: shader = mr_GVdecalconstant; break;
93 case TXF_BLEND: shader = mr_GVblendconstant; break;
94 case TXF_REPLACE: shader = mr_GVreplaceconstant; break;
95 }
96 }
97 mrti(mr_shadinginterpolation,
98 mr_string, ap->shading == APF_CONSTANT ? "constant" : "smooth",
99 mr_surface, shader, mr_NULL);
100 } else {
101 /* determine shader */
102 if (_mgribc->shader == MG_RIBSTDSHADE) {
103 if ((ap->flag & APF_TEXTURE) && ap->tex != NULL) {
104 shader = mr_paintedplastic;
105 } else {
106 shader = mr_plastic;
107 }
108 } else {
109 if (_mgc->space & TM_HYPERBOLIC) {
110 shader = mr_hplastic;
111 } else if ((ap->flag & APF_TEXTURE) && ap->tex != NULL) {
112 switch (ap->tex->apply) {
113 case TXF_MODULATE: shader = mr_GVmodulateplastic; break;
114 case TXF_DECAL: shader = mr_GVdecalplastic; break;
115 case TXF_BLEND: shader = mr_GVblendplastic; break;
116 case TXF_REPLACE: shader = mr_GVreplaceplastic; break;
117 }
118 } else {
119 shader = mr_plastic;
120 }
121 }
122
123 /* define surface */
124 if (!IS_SMOOTH(ap->shading)) {
125 mrti(mr_shadinginterpolation, mr_constant,
126 mr_surface, shader, mr_Ka, mr_float, mat->ka,
127 mr_Kd, mr_float, mat->kd, mr_Ks, mr_float, mat->ks,
128 mr_specularcolor, mr_parray, 3, &(mat->specular),
129 mr_roughness, mr_float, roughness, mr_NULL);
130 } else {
131 mrti(mr_shadinginterpolation, mr_string, "smooth",
132 mr_surface, shader, mr_Ka, mr_float, mat->ka,
133 mr_Kd, mr_float, mat->kd, mr_Ks, mr_float, mat->ks,
134 mr_specularcolor, mr_parray, 3, &(mat->specular),
135 mr_roughness, mr_float, roughness, mr_NULL);
136 }
137 }
138
139 /* define texture if appropriate */
140 if ((ap->flag & APF_TEXTURE) &&
141 ap->tex != NULL && ap->tex->image != NULL) {
142 char txtxname[PATH_MAX];
143 char tifftxname[PATH_MAX];
144 char filter[PATH_MAX];
145 int i;
146 unsigned chmask = 0;
147
148 if (_mgribc->shader == MG_RIBSTDSHADE) {
149 static bool was_here = false;
150
151 if (!was_here) {
152 OOGLWarn("textures with apply != modulate will not work "
153 "when using the standard shaders.\n");
154 was_here = true;
155 }
156 }
157
158 for (i = 0; i < _mgribc->n_tximg; i++) {
159 if (_mgribc->tx[i]->image == ap->tex->image &&
160 (_mgribc->tx[i]->flags & (TXF_SCLAMP|TXF_TCLAMP))
161 ==
162 (ap->tex->flags & (TXF_SCLAMP|TXF_TCLAMP))) {
163 break;
164 }
165 }
166
167 mgrib_mktexname(txtxname, i, _mgribc->tmppath, "tiff.tx");
168
169 if (i == _mgribc->n_tximg) {
170 if (_mgribc->n_tximg % 10 == 0) {
171 _mgribc->tx = OOGLRenewNE(Texture *,
172 _mgribc->tx,
173 _mgribc->n_tximg + 10,
174 "New RIB texture images");
175 }
176 _mgribc->tx[i] = ap->tex;
177 _mgribc->n_tximg++;
178 /* try to dump the image to disk */
179 mgrib_mktexname(tifftxname, i, _mgribc->displaypath, "tiff");
180 #ifdef HAVE_PAMTOTIFF
181 chmask = (1 << ap->tex->image->channels) - 1;
182 sprintf(filter, "pamtotiff -lzw -truecolor > %s 2> /dev/null",
183 tifftxname);
184 #else
185 chmask = ap->tex->image->channels > 2 ? 0x7 : 0x1;
186 sprintf(filter, "pnmtotiff -lzw -truecolor > %s 2> /dev/null",
187 tifftxname);
188 #endif
189 if (!ImgWriteFilter(ap->tex->image, chmask, filter)) {
190 _mgribc->tx[i] = NULL;
191 --_mgribc->n_tximg;
192 }
193 mgrib_mktexname(tifftxname, i, NULL, "tiff");
194 mrti_makecurrent(&_mgribc->txbuf);
195 mrti(mr_maketexture, mr_string, tifftxname, mr_string, txtxname,
196 mr_string,
197 ap->tex->flags & TXF_SCLAMP ? "clamp" : "periodic",
198 mr_string,
199 ap->tex->flags & TXF_TCLAMP ? "clamp" : "periodic",
200 mr_string, "gaussian", mr_float, 2.0, mr_float, 2.0,
201 mr_NULL);
202 mrti_makecurrent(&_mgribc->worldbuf);
203 }
204 if (i < _mgribc->n_tximg) {
205 mrti(mr_texturename, mr_string, txtxname, mr_NULL);
206 }
207 if (ap->tex->apply == TXF_BLEND) {
208 mrti(mr_string, "bgcolor",
209 mr_parray, 3, &(ap->tex->background), mr_NULL);
210 }
211 if (ap->tex->apply != TXF_DECAL) {
212 mrti(mr_string, "At",
213 mr_float, (ap->flag & APF_TRANSP) ? 1.0 : 0.0, mr_NULL);
214 }
215 }
216 }
217 }
218
219 void
mgrib_lighting(struct mgastk * astk,int mask)220 mgrib_lighting(struct mgastk *astk, int mask)
221 {
222 LmLighting *lm = &astk->lighting;
223
224 if (lm->valid & mask & LMF_AMBIENT) {
225 mrti(mr_section, "Interpreting Lights", mr_NULL);
226 /* output the ambient light */
227 mrti(mr_comment, "Ambient Light", mr_NULL);
228 mrti(mr_lightsource, mr_ambientlight, mr_int, 0,
229 mr_lightcolor, mr_parray, 3, &(lm->ambient), mr_NULL);
230 }
231 /* We must be in global coordinate space to place lights correctly. */
232 mrti(mr_transformbegin, mr_identity, mr_NULL);
233 mgrib_lights( lm, astk );
234 mrti(mr_transformend, mr_NULL);
235 }
236
237 /* In GL, we want unique light numbers. In RenderMan we want to re-use
238 light numbers, so we always start with light "1". In GL, we define
239 then bind lights. Defining is expensive and we avoid it as much as
240 possible. In RenderMan, it's a one-step process. Also, once a light is
241 defined it cannot be deleted. Thus we might need to explicitly turn
242 off lights if we are replacing more lights with less lights. So we
243 keep track of how many lights we've used so far, and turn off the
244 extras when we need to.
245 1/13/92 TMM */
246
mgrib_lights(LmLighting * lm,struct mgastk * astk)247 void mgrib_lights( LmLighting *lm, struct mgastk *astk )
248 {
249 int i, lightsused;
250 LtLight *light, **lp;
251 static int prevused = 0;
252
253 lightsused = 0;
254 LM_FOR_ALL_LIGHTS(lm, i,lp) {
255 light = *lp;
256 ++lightsused;
257
258 if (light->Private == 0) {
259 /* this is a new light */
260 light->Private = lightsused;
261 light->changed = 1;
262 }
263 if (light->changed) {
264 if (light->position.w == 0.0) {
265 /* directional light */
266 /* We used to output the lights as "to" instead of as "from".
267 This is like negating them, which is why we then did
268 explicitly negate them to get the right result!
269 So, leave the lights alone now. Do NOT negate them.
270 It's NOT about handedness of coordinate systems.
271 */
272 mrti(mr_comment, "Directional Light",
273 mr_lightsource, mr_distantlight, mr_int, light->Private,
274 mr_intensity, mr_float, light->intensity,
275 mr_lightcolor, mr_parray, 3, &(light->color),
276 mr_string, "from", mr_parray, 3, &(light->globalposition),
277 mr_string, "to", mr_array, 3, 0.,0.,0., /* aim at origin */
278 mr_NULL);
279 } else {
280 /* point light */
281 mrti(mr_lightsource, mr_string, "pointlight", mr_int, light->Private,
282 mr_intensity, mr_float, light->intensity,
283 mr_lightcolor, mr_parray, 3, &(light->color),
284 mr_string, "from", mr_parray, 3, &(light->globalposition),
285 mr_NULL);
286 }
287 light->changed = 0;
288 }
289 }
290 for (i = lightsused +1; i <= prevused; i++)
291 mrti(mr_illuminate, mr_int, i, mr_int, 0, mr_NULL);
292 if (prevused < lightsused) prevused = lightsused;
293 }
294
295 /*
296 * Local Variables: ***
297 * mode: c ***
298 * c-basic-offset: 4 ***
299 * End: ***
300 */
301