BRL-CAD
sh_flat.c
Go to the documentation of this file.
1 /* S H _ F L A T . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @file liboptical/sh_flat.c
21  *
22  * Notes -
23  * This is a basic flat shader. It will display an object with a set color
24  * without taking any effects such as curvature, emission, reflection, etc.
25  * into consideration. It simply shades an object constantly with either
26  * (in order of reverse priority) 1) the default flat color (white),
27  * 2) its set region color, 2) the specified flat shader color (given via
28  * the color attribute).
29  *
30  * Optionally a transparency value may be shown as well. With transparency
31  * turned on, the background objects will blend through depending on the
32  * transparency attribute. Masking may be specified for each RGB color
33  * channel (e.g. perhaps only lets red light through). This is potentially
34  * useful to see background objects through foreground objects, as well as
35  * in certain signal analyses as a filter.
36  *
37  * See the flat_parse_tab structure for details on the symantics of other
38  * attribute shorthands/alternatives.
39  *
40  */
41 
42 #include "common.h"
43 
44 #include <stddef.h>
45 #include <stdio.h>
46 #include <math.h>
47 #include <string.h> /* for memcpy */
48 
49 #include "vmath.h"
50 #include "raytrace.h"
51 #include "optical.h"
52 
53 
54 HIDDEN int flat_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip);
55 HIDDEN int flat_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp);
56 HIDDEN void flat_print(register struct region *rp, void *dp);
57 HIDDEN void flat_free(void *cp);
58 
59 /* local sp_hook functions */
60 /* these are two helper functions to process input color and transparency values */
61 void normalizedInput_hook(const struct bu_structparse *, const char *, void *, const char *, void *);
62 void singleNormalizedInput_hook(const struct bu_structparse *, const char *, void *, const char *, void *);
63 
64 /*
65  * the shader specific structure contains all variables which are unique
66  * to any particular use of the shader.
67  */
68 struct flat_specific {
69  uint32_t magic; /* magic # for memory validity check, must come 1st */
70  point_t color; /* overriding flat color */
71  point_t transparency; /* how transparent the object is per rgb channel*/
72 };
73 #define FLAT_MAGIC 0x464c4154 /* magic number is "FLAT" in hex */
74 #define CK_FLAT_SP(_p) BU_CKMAG(_p, FLAT_MAGIC, "flat_specific")
75 
76 /* The default values for the variables in the shader specific structure */
77 static const
78 struct flat_specific flat_defaults = {
79  FLAT_MAGIC,
80  VINITALL(1.0), /* full white */
81  VINIT_ZERO /* completely opaque (no transparency)*/
82 };
83 
84 
85 #define SHDR_FLAT ((struct flat_specific *)0)
86 #define SHDR_O(m) bu_offsetof(struct flat_specific, m)
87 
88 /* description of how to parse/print the arguments to the shader
89  * There is at least one line here for each variable in the shader specific
90  * structure above.
91  *
92  * color := is a 0.0 to 1.0 or 0.0 to 255.0 color intensity triplet
93  * representing the RGB color values.
94  * rgb := the same as color, just shorter (and implies 0 to 255)
95  * bright := sets all three color channels to the same single given intensity.
96  * e.g. a grey value (bright==.2 => color=={.2 .2 .2}==rgb
97  * transparency := a color intensity triplet mask to indicate how much of
98  * background object light are visible through this object.
99  * alpha := similar to bright, sets this object's alpha transparency to a
100  * single mask value that gets set for each channel. e.g. 40% opaque
101  * is alpha==.4 which is equiv to transparency=={.4 .4 .4}).
102  */
104  { "%f", 3, "color", SHDR_O(color), normalizedInput_hook, NULL, NULL }, /* for 0->1 color values */
105  { "%f", 3, "rgb", SHDR_O(color), normalizedInput_hook, NULL, NULL }, /* for 0->255 color values */
106  { "%f", 1, "bright", SHDR_O(color), singleNormalizedInput_hook, NULL, NULL }, /* for luminosity gray value */
107  { "%f", 3, "transparency", SHDR_O(transparency), normalizedInput_hook, NULL, NULL }, /* for rgb 0->1 transparency */
108  { "%f", 1, "alpha", SHDR_O(transparency), singleNormalizedInput_hook, NULL, NULL }, /* for single channel alpha transparency */
109  { "", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
110 };
111 
112 
113 /* The "mfuncs" structure defines the external interface to the shader.
114  * Note that more than one shader "name" can be associated with a given
115  * shader by defining more than one mfuncs struct in this array.
116  * See sh_phong.c for an example of building more than one shader "name"
117  * from a set of source functions. There you will find that "glass" "mirror"
118  * and "plastic" are all names for the same shader with different default
119  * values for the parameters.
120  */
121 struct mfuncs flat_mfuncs[] = {
122  {MF_MAGIC, "flat", 0, MFI_HIT, 0, /* !!! try to set to 0 */
124  {0, (char *)0, 0, 0, 0,
125  0, 0, 0, 0 }
126 };
127 
128 
129 /* normalizedInput_hook
130  *
131  * Used as a hooked function for input of values normalized to 1.0.
132  *
133  * sdp == structure description
134  * name == struct member name
135  * base == beginning of structure
136  * value == string containing value
137  */
138 void
140  const char *UNUSED(name),
141  void *base,
142  const char *UNUSED(value),
143  void *UNUSED(data))
144 {
145  register double *p = (double *)((char *)base + sdp->sp_offset);
146  size_t i;
147  int ok;
148 
149  /* if all the values are in the range [0..1] there's nothing to do */
150  for (ok = 1, i = 0; i < sdp->sp_count; i++, p++) {
151  if ((*p > 1.0) || (*p < 0.0)) ok = 0;
152  }
153  if (ok) return;
154 
155  /* user specified colors in the range [0..255] (or negative) so we need to
156  * map those into [0..1]
157  */
158  p = (double *)((char *)base + sdp->sp_offset);
159  for (i = 0; i < sdp->sp_count; i++, p++) {
160  *p /= 255.0;
161  }
162 
163  for (ok = 1, i = 0; i < sdp->sp_count; i++, p++) {
164  if ((*p > 1.0) || (*p < 0.0)) ok = 0;
165  }
166  if (ok) bu_log ("User specified values are out of range (0.0 to either 1.0 or 255.0)");
167 }
168 
169 
170 /* singleNormalizedInput_hook
171  *
172  * same as normalizedInput_hook (in fact it calls it) except that only one input
173  * is expected from user input. the hook takes the single input value, and sets
174  * it three times. the value is normalized from 0.0 to 1.0
175  */
176 void
178  const char *name,
179  void *base,
180  const char *value,
181  void *data)
182 {
183 
184  register double *p = (double *)((char *)base + sdp->sp_offset);
185 
186  normalizedInput_hook(sdp, name, base, value, data);
187 
188  /* copy the first value into the next two locations */
189  *(p+1) = *p;
190  *(p+2) = *p;
191 }
192 
193 
194 /*
195  * This routine is called (at prep time) once for each region which uses this
196  * shader. The shader specific flat_specific structure is allocated and
197  * default values are set. Then any user-given values override.
198  */
199 HIDDEN int
200 flat_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *rtip)
201 {
202 
203  register struct flat_specific *flat_sp;
204 
205  /* check the arguments */
206  RT_CHECK_RTI(rtip);
207  BU_CK_VLS(matparm);
208  RT_CK_REGION(rp);
209 
210  if (rdebug&RDEBUG_SHADE)
211  bu_log("flat_setup(%s)\n", rp->reg_name);
212 
213  /* Get memory for the shader parameters and shader-specific data */
214  BU_GET(flat_sp, struct flat_specific);
215  *dpp = flat_sp;
216 
217  /* color priority:
218  *
219  * priority goes first to the flat shader's color parameter
220  * second priority is to the material color value
221  * third priority is to the flat shader's default color (white)
222  */
223 
224  /* initialize the default values for the shader */
225  memcpy(flat_sp, &flat_defaults, sizeof(struct flat_specific));
226 
227  /* load the material color if it was set */
228  if (rp->reg_mater.ma_color_valid) {
229  VMOVE(flat_sp->color, rp->reg_mater.ma_color);
230  }
231 
232  /* parse the user's arguments for this use of the shader. */
233  if (bu_struct_parse(matparm, flat_parse_tab, (char *)flat_sp, NULL) < 0)
234  return -1;
235 
236  if (rdebug&RDEBUG_SHADE) {
237  bu_struct_print(" Parameters:", flat_parse_tab, (char *)flat_sp);
238  }
239 
240  return 1;
241 }
242 
243 
244 /*
245  * This is called (from viewshade() in shade.c) once for each hit point
246  * to be shaded. The purpose here is to fill in values in the shadework
247  * structure.
248  *
249  * The flat shader is probably the second most simple shader (second to
250  * the null/invisible shader -- it does nothing). It shades an object
251  * a constant color. The only complexity comes into play when a
252  * transparency value is set. Then we get the color value behind the
253  * one we are shading and blend accordingly with the flat color.
254  */
255 int
256 flat_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
257 {
258 
259  register struct flat_specific *flat_sp = (struct flat_specific *)dp;
260  const point_t unit = {1.0, 1.0, 1.0};
261  point_t intensity;
262 
263  /* check the validity of the arguments we got */
264  RT_AP_CHECK(ap);
265  RT_CHECK_PT(pp);
266  CK_FLAT_SP(flat_sp);
267 
268  if (rdebug&RDEBUG_SHADE)
269  bu_struct_print("flat_render Parameters:", flat_parse_tab, (char *)flat_sp);
270 
271  /* do the actual flat color shading for the flat object. if the object is
272  * not transparent, just put the color. if the object is transparent, do
273  * a little more work determining the background pixel, and then blend with
274  * the flat foreground object.
275  */
276  if (VNEAR_ZERO(flat_sp->transparency, SMALL_FASTF)) {
277 
278  /* just put the flat value */
279  VMOVE(swp->sw_color, flat_sp->color);
280  } else {
281 
282  /* this gets the background pixel value, if the transparency is not 0 */
283  swp->sw_transmit = 1.0; /*!!! try to remove */
284  VMOVE(swp->sw_basecolor, flat_sp->transparency);
285  (void)rr_render(ap, pp, swp);
286 
287  /* now blend with the foreground object being shaded */
288  VSUB2(intensity, unit, flat_sp->transparency); /* inverse transparency is how much we want */
289  VELMUL(intensity, intensity, flat_sp->color); /* ??? is there a way to merge this mul->add step? */
290  VADD2(swp->sw_color, swp->sw_color, intensity);
291  }
292 
293  return 1;
294 }
295 
296 
297 HIDDEN void
298 flat_print(register struct region *rp, void *dp)
299 {
300  bu_struct_print(rp->reg_name, flat_parse_tab, (char *)dp);
301 }
302 
303 
304 HIDDEN void
305 flat_free(void *cp)
306 {
307  BU_PUT(cp, struct flat_specific);
308 }
309 
310 
311 /*
312  * Local Variables:
313  * mode: C
314  * tab-width: 8
315  * indent-tabs-mode: t
316  * c-file-style: "stroustrup"
317  * End:
318  * ex: shiftwidth=4 tabstop=8
319  */
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define MF_MAGIC
Definition: magic.h:205
Definition: clone.c:90
#define CK_FLAT_SP(_p)
Definition: sh_flat.c:74
#define SMALL_FASTF
Definition: defines.h:342
Header file for the BRL-CAD common definitions.
uint32_t magic
Definition: sh_flat.c:69
struct bu_structparse flat_parse_tab[]
Definition: sh_flat.c:103
const char * reg_name
Identifying string.
Definition: raytrace.h:539
char ma_color_valid
non-0 ==> ma_color is non-default
Definition: raytrace.h:524
HIDDEN void flat_free(void *cp)
Definition: sh_flat.c:305
#define RT_CK_REGION(_p)
Definition: raytrace.h:559
#define HIDDEN
Definition: common.h:86
void bu_struct_print(const char *title, const struct bu_structparse *parsetab, const char *base)
Definition: parse.c:1221
#define RT_AP_CHECK(_ap)
Definition: raytrace.h:1685
void singleNormalizedInput_hook(const struct bu_structparse *, const char *, void *, const char *, void *)
Definition: sh_flat.c:177
COMPLEX data[64]
Definition: fftest.c:34
#define BU_CK_VLS(_vp)
Definition: vls.h:69
HIDDEN int flat_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)
Definition: sh_flat.c:200
#define RT_CHECK_RTI(_p)
Definition: raytrace.h:1832
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
#define SHDR_O(m)
Definition: sh_flat.c:86
HIDDEN void flat_print(register struct region *rp, void *dp)
Definition: sh_flat.c:298
#define UNUSED(parameter)
Definition: common.h:239
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
size_t sp_offset
Definition: parse.h:141
#define FLAT_MAGIC
Definition: sh_flat.c:73
#define BU_STRUCTPARSE_FUNC_NULL
Definition: parse.h:153
float ma_color[3]
explicit color: 0..1
Definition: raytrace.h:522
struct mater_info reg_mater
Real material information.
Definition: raytrace.h:546
#define RDEBUG_SHADE
Definition: optical.h:130
void normalizedInput_hook(const struct bu_structparse *, const char *, void *, const char *, void *)
Definition: sh_flat.c:139
size_t sp_count
Definition: parse.h:139
int bu_struct_parse(const struct bu_vls *in_vls, const struct bu_structparse *desc, const char *base, void *data)
Definition: parse.c:878
point_t transparency
Definition: sh_flat.c:71
HIDDEN int flat_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
Definition: sh_flat.c:256
point_t color
Definition: sh_flat.c:70
int rr_render(struct application *app, const struct partition *pp, struct shadework *swp)
#define RT_CHECK_PT(_p)
compat
Definition: raytrace.h:588
Definition: vls.h:56
Header file for the BRL-CAD Optical Library, LIBOPTICAL.
int rdebug
Definition: init.c:39
struct mfuncs flat_mfuncs[]
Definition: sh_flat.c:121