BRL-CAD
sh_text.c
Go to the documentation of this file.
1 /* S H _ T E X T . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1998-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_text.c
21  *
22  * Texture map lookup
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <stddef.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <ctype.h>
32 
33 #include "vmath.h"
34 #include "raytrace.h"
35 #include "optical.h"
36 
37 
38 #define TXT_NAME_LEN 128
39 struct txt_specific {
40  int tx_transp[3]; /* RGB for transparency */
41  /* char tx_file[TXT_NAME_LEN]; Filename */
42  struct bu_vls tx_name; /* name of object or file (depending on tx_datasrc flag) */
43  int tx_w; /* Width of texture in pixels */
44  int tx_n; /* Number of scanlines */
45  int tx_trans_valid; /* boolean: is tx_transp valid ? */
46  fastf_t tx_scale[2]; /* replication factors in U, V */
47  int tx_mirror; /* flag: repetitions are mirrored */
48 #define TXT_SRC_FILE 'f'
49 #define TXT_SRC_OBJECT 'o'
50 #define TXT_SRC_AUTO 0
51  char tx_datasrc; /* which type of datasource */
52  struct rt_binunif_internal *tx_binunifp; /* db internal object when TXT_SRC_OBJECT */
53  struct bu_mapped_file *tx_mp; /* mapped file when TXT_SRC_FILE */
54 };
55 #define TX_NULL ((struct txt_specific *)0)
56 #define TX_O(m) bu_offsetof(struct txt_specific, m)
57 
58 /* local sp_hook functions */
59 HIDDEN void txt_transp_hook(const struct bu_structparse *, const char *, void *, const char *, void *);
60 HIDDEN void txt_source_hook(const struct bu_structparse *, const char *, void *, const char *, void *);
61 
62 HIDDEN int txt_load_datasource(struct txt_specific *texture, struct db_i *dbInstance, const long unsigned int size);
63 
64 
66  {"%d", 1, "transp", TX_O(tx_transp), txt_transp_hook, NULL, NULL },
67  {"%V", 1, "file", TX_O(tx_name), txt_source_hook, NULL, NULL },
68  {"%V", 1, "obj", TX_O(tx_name), txt_source_hook, NULL, NULL },
69  {"%V", 1, "object", TX_O(tx_name), txt_source_hook, NULL, NULL },
70  {"%V", 1, "texture", TX_O(tx_name), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
71  {"%d", 1, "w", TX_O(tx_w), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
72  {"%d", 1, "n", TX_O(tx_n), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
73  {"%d", 1, "l", TX_O(tx_n), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
74  {"%d", 1, "trans_valid", TX_O(tx_trans_valid), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },/*compat*/
75  {"%d", 1, "t", TX_O(tx_trans_valid), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
76  {"%f", 2, "uv", TX_O(tx_scale), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
77  {"%d", 1, "m", TX_O(tx_mirror), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
78  {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
79 };
80 
81 
82 /* txt_datasource_hook() is used to automatically try to load a default texture
83  * datasource. The type gets set to auto and the datasource is detected. First
84  * the database is searched for a matching object, then a file on disk is
85  * looked up. If neither is found, object name is left null so txt_setup() will
86  * fail.
87  */
88 HIDDEN void
90  const char *name,
91  void *base,
92  const char *UNUSED(value),
93  void *UNUSED(data))
94 {
95  struct txt_specific *textureSpecific = (struct txt_specific *)base;
96  if (bu_strncmp(name, "file", 4) == 0) {
97  textureSpecific->tx_datasrc=TXT_SRC_FILE;
98  } else if (bu_strncmp(name, "obj", 3) == 0) {
99  textureSpecific->tx_datasrc = TXT_SRC_OBJECT;
100  } else {
101  textureSpecific->tx_datasrc = TXT_SRC_AUTO;
102  }
103 }
104 
105 
106 /*
107  * Hooked function, called by bu_structparse
108  */
109 HIDDEN void
110 txt_transp_hook(const struct bu_structparse *sdp,
111  const char *name,
112  void *base,
113  const char *UNUSED(value),
114  void *UNUSED(data))
115 {
116  register struct txt_specific *tp =
117  (struct txt_specific *)base;
118 
119  if (BU_STR_EQUAL(name, txt_parse[0].sp_name) && sdp == txt_parse) {
120  tp->tx_trans_valid = 1;
121  } else {
122  bu_log("file:%s, line:%d txt_transp_hook name:(%s) instead of (%s)\n",
123  __FILE__, __LINE__, name, txt_parse[0].sp_name);
124  }
125 }
126 
127 
128 /*
129  * This is a helper routine used in txt_setup() to load a texture either from
130  * a file or from a db object. The resources are released in txt_free()
131  * (there is no specific unload_datasource function).
132  */
133 HIDDEN int
134 txt_load_datasource(struct txt_specific *texture, struct db_i *dbInstance, const unsigned long int size)
135 {
136  struct directory *dirEntry;
137 
138  RT_CK_DBI(dbInstance);
139 
140  if (texture == (struct txt_specific *)NULL) {
141  bu_bomb("ERROR: txt_load_datasource() received NULL arg (struct txt_specific *)\n");
142  }
143 
144  bu_log("Loading texture %s [%s]...", texture->tx_datasrc==TXT_SRC_AUTO?"from auto-determined datasource":texture->tx_datasrc==TXT_SRC_OBJECT?"from a database object":texture->tx_datasrc==TXT_SRC_FILE?"from a file":"from an unknown source (ERROR)", bu_vls_addr(&texture->tx_name));
145 
146  /* if the source is auto or object, we try to load the object */
147  if ((texture->tx_datasrc==TXT_SRC_AUTO) || (texture->tx_datasrc==TXT_SRC_OBJECT)) {
148 
149  /* see if the object exists */
150  if ((dirEntry=db_lookup(dbInstance, bu_vls_addr(&texture->tx_name), LOOKUP_QUIET)) == RT_DIR_NULL) {
151 
152  /* unable to find the texture object */
153  if (texture->tx_datasrc!=TXT_SRC_AUTO) {
154  return -1;
155  }
156  } else {
157  struct rt_db_internal *dbip;
158 
159  BU_ALLOC(dbip, struct rt_db_internal);
160 
161  RT_DB_INTERNAL_INIT(dbip);
162  RT_CK_DB_INTERNAL(dbip);
163  RT_CK_DIR(dirEntry);
164 
165  /* the object was in the directory, so go get it */
166  if (rt_db_get_internal(dbip, dirEntry, dbInstance, NULL, NULL) <= 0) {
167  /* unable to load/create the texture database record object */
168  return -1;
169  }
170 
171  RT_CK_DB_INTERNAL(dbip);
172  RT_CK_BINUNIF(dbip->idb_ptr);
173 
174  /* keep the binary object pointer */
175  texture->tx_binunifp=(struct rt_binunif_internal *)dbip->idb_ptr; /* make it so */
176 
177  /* release the database instance pointer struct we created */
178  RT_DB_INTERNAL_INIT(dbip);
179  bu_free(dbip, "txt_load_datasource");
180 
181  /* check size of object */
182  if (texture->tx_binunifp->count < size) {
183  bu_log("\nWARNING: %s needs %d bytes, binary object only has %lu\n", bu_vls_addr(&texture->tx_name), size, texture->tx_binunifp->count);
184  } else if (texture->tx_binunifp->count > size) {
185  bu_log("\nWARNING: Binary object is larger than specified texture size\n\tBinary Object: %zu pixels\n\tSpecified Texture Size: %zu pixels\n...continuing to load using image subsection...", texture->tx_binunifp->count);
186  }
187  }
188  }
189 
190  /* if we are auto and we couldn't find a database object match, or if source
191  * is explicitly a file then we load the file.
192  */
193  if (((texture->tx_datasrc==TXT_SRC_AUTO) && (texture->tx_binunifp==NULL)) || (texture->tx_datasrc==TXT_SRC_FILE)) {
194 
195  texture->tx_mp = bu_open_mapped_file_with_path(dbInstance->dbi_filepath, bu_vls_addr(&texture->tx_name), NULL);
196 
197  if (texture->tx_mp==NULL)
198  return -1; /* FAIL */
199 
200  if (texture->tx_mp->buflen < size) {
201  bu_log("\nWARNING: %s needs %d bytes, file only has %lu\n", bu_vls_addr(&texture->tx_name), size, texture->tx_mp->buflen);
202  } else if (texture->tx_mp->buflen > size) {
203  bu_log("\nWARNING: Texture file size is larger than specified texture size\n\tInput File: %zu pixels\n\tSpecified Texture Size: %lu pixels\n...continuing to load using image subsection...", texture->tx_mp->buflen, size);
204  }
205 
206  }
207 
208  bu_log("done.\n");
209 
210  return 0;
211 }
212 
213 
214 /*
215  * Given a u, v coordinate within the texture (0 <= u, v <= 1.0),
216  * return a pointer to the relevant pixel.
217  *
218  * Note that .pix files are stored left-to-right, bottom-to-top,
219  * which works out very naturally for the indexing scheme.
220  */
221 HIDDEN int
222 txt_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
223 {
224  register struct txt_specific *tp =
225  (struct txt_specific *)dp;
226  fastf_t xmin, xmax, ymin, ymax;
227  int dx, dy;
228  register fastf_t r, g, b;
229  struct uvcoord uvc;
230  long tmp;
231  char color_warn = 0;
232 
233  RT_CK_AP(ap);
234  RT_CHECK_PT(pp);
235 
236  uvc = swp->sw_uv;
237 
238  if (rdebug & RDEBUG_SHADE)
239  bu_log("in txt_render(): du=%g, dv=%g\n",
240  uvc.uv_du, uvc.uv_dv);
241 
242  /* take care of scaling U, V coordinates to get the desired amount
243  * of replication of the texture
244  */
245  uvc.uv_u *= tp->tx_scale[X];
246  tmp = uvc.uv_u;
247  uvc.uv_u -= tmp;
248  if (tp->tx_mirror && (tmp & 1))
249  uvc.uv_u = 1.0 - uvc.uv_u;
250 
251  uvc.uv_v *= tp->tx_scale[Y];
252  tmp = uvc.uv_v;
253  uvc.uv_v -= tmp;
254  if (tp->tx_mirror && (tmp & 1))
255  uvc.uv_v = 1.0 - uvc.uv_v;
256 
257  uvc.uv_du /= tp->tx_scale[X];
258  uvc.uv_dv /= tp->tx_scale[Y];
259 
260  /*
261  * If no texture file present, or if
262  * texture isn't and can't be read, give debug colors
263  */
264 
265  if ((bu_vls_strlen(&tp->tx_name) <= 0) || (!tp->tx_mp && !tp->tx_binunifp)) {
266  bu_log("WARNING: texture [%s] could not be read\n", bu_vls_addr(&tp->tx_name));
267  VSET(swp->sw_color, uvc.uv_u, 0, uvc.uv_v);
268  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
269  (void)rr_render(ap, pp, swp);
270  return 1;
271  }
272 
273  /* u is left->right index, v is line number bottom->top */
274  /* Don't filter more than 1/8 of the texture for 1 pixel! */
275  if (uvc.uv_du > 0.125) uvc.uv_du = 0.125;
276  if (uvc.uv_dv > 0.125) uvc.uv_dv = 0.125;
277 
278  if (uvc.uv_du < 0 || uvc.uv_dv < 0) {
279  bu_log("txt_render uv=%g, %g, du dv=%g %g seg=%s\n",
280  uvc.uv_u, uvc.uv_v, uvc.uv_du, uvc.uv_dv,
281  pp->pt_inseg->seg_stp->st_name);
282  uvc.uv_du = uvc.uv_dv = 0;
283  }
284 
285  xmin = uvc.uv_u - uvc.uv_du;
286  xmax = uvc.uv_u + uvc.uv_du;
287  ymin = uvc.uv_v - uvc.uv_dv;
288  ymax = uvc.uv_v + uvc.uv_dv;
289  if (xmin < 0) xmin = 0;
290  if (ymin < 0) ymin = 0;
291  if (xmax > 1) xmax = 1;
292  if (ymax > 1) ymax = 1;
293 
294  if (rdebug & RDEBUG_SHADE)
295  bu_log("footprint in texture space is (%g %g) <-> (%g %g)\n",
296  xmin * (tp->tx_w-1), ymin * (tp->tx_n-1),
297  xmax * (tp->tx_w-1), ymax * (tp->tx_n-1));
298 
299  dx = (int)(xmax * (tp->tx_w-1)) - (int)(xmin * (tp->tx_w-1));
300  dy = (int)(ymax * (tp->tx_n-1)) - (int)(ymin * (tp->tx_n-1));
301 
302  if (rdebug & RDEBUG_SHADE)
303  bu_log("\tdx = %d, dy = %d\n", dx, dy);
304 
305  if (dx == 0 && dy == 0) {
306  /* No averaging necessary */
307 
308  register unsigned char *cp=NULL;
309  unsigned int offset;
310 
311  offset = (int)(ymin * (tp->tx_n-1)) * tp->tx_w * 3 + (int)(xmin * (tp->tx_w-1)) * 3;
312  if (tp->tx_mp) {
313  if (offset >= tp->tx_mp->buflen) {
314  offset %= tp->tx_mp->buflen;
315  color_warn = 1;
316  }
317  cp = ((unsigned char *)(tp->tx_mp->buf)) + offset;
318  } else if (tp->tx_binunifp) {
319  if (offset >= tp->tx_binunifp->count) {
320  offset %= tp->tx_binunifp->count;
321  color_warn = 1;
322  }
323  cp = ((unsigned char *)(tp->tx_binunifp->u.uint8)) + offset;
324  } else {
325  bu_bomb("sh_text.c -- No texture data found\n");
326  }
327  r = *cp++;
328  g = *cp++;
329  b = *cp;
330  } else {
331  /* Calculate weighted average of cells in footprint */
332 
333  fastf_t tot_area = 0.0;
334  fastf_t cell_area;
335  int start_line, stop_line, line;
336  int start_col, stop_col, col;
337  fastf_t xstart, xstop, ystart, ystop;
338  unsigned int max_offset;
339 
340  xstart = xmin * (tp->tx_w-1);
341  xstop = xmax * (tp->tx_w-1);
342  ystart = ymin * (tp->tx_n-1);
343  ystop = ymax * (tp->tx_n-1);
344 
345  start_line = ystart;
346  stop_line = ystop;
347  start_col = xstart;
348  stop_col = xstop;
349 
350  r = g = b = 0.0;
351 
352  if (rdebug & RDEBUG_SHADE) {
353  bu_log("\thit in texture space = (%g %g)\n", uvc.uv_u * (tp->tx_w-1), uvc.uv_v * (tp->tx_n-1));
354  bu_log("\t averaging from (%g %g) to (%g %g)\n", xstart, ystart, xstop, ystop);
355  bu_log("\tcontributions to average:\n");
356  }
357 
358  max_offset = stop_line * tp->tx_w * 3 + (int)(xstart) * 3 + (dx + 1) * 3;
359  if (tp->tx_mp) {
360  if (max_offset > tp->tx_mp->buflen) {
361  color_warn = 1;
362  }
363  } else if (tp->tx_binunifp) {
364  if (max_offset > tp->tx_binunifp->count) {
365  color_warn = 1;
366  }
367  }
368 
369  for (line = start_line; line <= stop_line; line++) {
370  register unsigned char *cp=NULL;
371  fastf_t line_factor;
372  fastf_t line_upper, line_lower;
373  unsigned int offset;
374 
375  line_upper = line + 1.0;
376  if (line_upper > ystop)
377  line_upper = ystop;
378  line_lower = line;
379  if (line_lower < ystart)
380  line_lower = ystart;
381  line_factor = line_upper - line_lower;
382 
383  offset = line * tp->tx_w * 3 + (int)(xstart) * 3;
384  if (tp->tx_mp) {
385  if (offset >= tp->tx_mp->buflen) {
386  offset %= tp->tx_mp->buflen;
387  }
388  cp = ((unsigned char *)(tp->tx_mp->buf)) + offset;
389  } else if (tp->tx_binunifp) {
390  if (offset >= tp->tx_binunifp->count) {
391  offset %= tp->tx_binunifp->count;
392  }
393  cp = ((unsigned char *)(tp->tx_binunifp->u.uint8)) + offset;
394  } else {
395  /* not reachable */
396  bu_bomb("sh_text.c -- Unable to read datasource\n");
397  }
398 
399  for (col = start_col; col <= stop_col; col++) {
400  fastf_t col_upper, col_lower;
401 
402  col_upper = col + 1.0;
403  if (col_upper > xstop) col_upper = xstop;
404  col_lower = col;
405  if (col_lower < xstart) col_lower = xstart;
406 
407  cell_area = line_factor * (col_upper - col_lower);
408  tot_area += cell_area;
409 
410  if (rdebug & RDEBUG_SHADE)
411  bu_log("\t %d %d %d weight=%g (from col=%d line=%d)\n", *cp, *(cp+1), *(cp+2), cell_area, col, line);
412 
413  r += (*cp++) * cell_area;
414  g += (*cp++) * cell_area;
415  b += (*cp++) * cell_area;
416  }
417 
418  }
419  r /= tot_area;
420  g /= tot_area;
421  b /= tot_area;
422  }
423 
424  /*
425  * If the actual image file size is less than the provided size,
426  * warn the user by displaying a color closer to red.
427  */
428  if (color_warn == 1) {
429  r = (r + 255.0) / 2;
430  g /= 2;
431  b /= 2;
432  }
433 
434  if (rdebug & RDEBUG_SHADE)
435  bu_log(" average: %g %g %g\n", r, g, b);
436 
437  if (!tp->tx_trans_valid) {
438  opaque:
439  VSET(swp->sw_color,
440  r / 255.0,
441  g / 255.0,
442  b / 255.0);
443 
444  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
445  (void)rr_render(ap, pp, swp);
446  return 1;
447  }
448  /* This circumlocution needed to keep expression simple for Cray,
449  * and others
450  */
451  if (!EQUAL(r, ((long)tp->tx_transp[0]))) goto opaque;
452  if (!EQUAL(g, ((long)tp->tx_transp[1]))) goto opaque;
453  if (!EQUAL(b, ((long)tp->tx_transp[2]))) goto opaque;
454 
455  /*
456  * Transparency mapping is enabled, and we hit a transparent spot.
457  * Let higher level handle it in reflect/refract code.
458  */
459  swp->sw_transmit = 1.0;
460  swp->sw_reflect = 0.0;
461 
462  bu_log("leaving txt_render()\n");
463 
464  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
465  (void)rr_render(ap, pp, swp);
466  return 1;
467 }
468 
469 
470 /*
471  * Given a u, v coordinate within the texture (0 <= u, v <= 1.0),
472  * return the filtered intensity.
473  *
474  * Note that .bw files are stored left-to-right, bottom-to-top,
475  * which works out very naturally for the indexing scheme.
476  */
477 HIDDEN int
478 bwtxt_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
479 {
480  register struct txt_specific *tp =
481  (struct txt_specific *)dp;
482  fastf_t xmin, xmax, ymin, ymax;
483  int line;
484  int dx, dy;
485  int x, y;
486  register long bw;
487  struct uvcoord uvc;
488  long tmp;
489 
490  uvc = swp->sw_uv;
491 
492  /*
493  * If no texture file present, or if
494  * texture isn't and can't be read, give debug colors
495  */
496  if ((bu_vls_strlen(&tp->tx_name) <= 0) || (!tp->tx_mp && !tp->tx_binunifp)) {
497  VSET(swp->sw_color, uvc.uv_u, 0, uvc.uv_v);
498  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
499  (void)rr_render(ap, pp, swp);
500  return 1;
501  }
502 
503  /* take care of scaling U, V coordinates to get the desired amount
504  * of replication of the texture
505  */
506  uvc.uv_u *= tp->tx_scale[X];
507  tmp = uvc.uv_u;
508  uvc.uv_u -= tmp;
509  if (tp->tx_mirror && (tmp & 1))
510  uvc.uv_u = 1.0 - uvc.uv_u;
511 
512  uvc.uv_v *= tp->tx_scale[Y];
513  tmp = uvc.uv_v;
514  uvc.uv_v -= tmp;
515  if (tp->tx_mirror && (tmp & 1))
516  uvc.uv_v = 1.0 - uvc.uv_v;
517 
518  uvc.uv_du /= tp->tx_scale[X];
519  uvc.uv_dv /= tp->tx_scale[Y];
520 
521 
522  /* u is left->right index, v is line number bottom->top */
523  /* Don't filter more than 1/8 of the texture for 1 pixel! */
524  if (uvc.uv_du > 0.125) uvc.uv_du = 0.125;
525  if (uvc.uv_dv > 0.125) uvc.uv_dv = 0.125;
526 
527  if (uvc.uv_du < 0 || uvc.uv_dv < 0) {
528  bu_log("bwtxt_render uv=%g, %g, du dv=%g %g seg=%s\n",
529  uvc.uv_u, uvc.uv_v, uvc.uv_du, uvc.uv_dv,
530  pp->pt_inseg->seg_stp->st_name);
531  uvc.uv_du = uvc.uv_dv = 0;
532  }
533  xmin = uvc.uv_u - uvc.uv_du;
534  xmax = uvc.uv_u + uvc.uv_du;
535  ymin = uvc.uv_v - uvc.uv_dv;
536  ymax = uvc.uv_v + uvc.uv_dv;
537  if (xmin < 0) xmin = 0;
538  if (ymin < 0) ymin = 0;
539  if (xmax > 1) xmax = 1;
540  if (ymax > 1) ymax = 1;
541  x = xmin * (tp->tx_w-1);
542  y = ymin * (tp->tx_n-1);
543  dx = (xmax - xmin) * (tp->tx_w-1);
544  dy = (ymax - ymin) * (tp->tx_n-1);
545  if (dx < 1) dx = 1;
546  if (dy < 1) dy = 1;
547  bw = 0;
548  for (line = 0; line < dy; line++) {
549  register unsigned char *cp=NULL;
550  register unsigned char *ep;
551 
552  if (tp->tx_mp) {
553  cp = ((unsigned char *)(tp->tx_mp->buf)) +
554  (y+line) * tp->tx_w + x;
555  } else if (tp->tx_binunifp) {
556  cp = ((unsigned char *)(tp->tx_binunifp->u.uint8)) +
557  (y+line) * tp->tx_w + x;
558  } else {
559  /* not reachable */
560  bu_bomb("sh_text.c -- Unable to read datasource\n");
561  }
562 
563  ep = cp + dx;
564  while (cp < ep) {
565  bw += *cp++;
566  }
567  }
568 
569  if (!tp->tx_trans_valid) {
570  opaque:
571  VSETALL(swp->sw_color,
572  (bw / 255.0) / (dx*dy));
573  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
574  (void)rr_render(ap, pp, swp);
575  return 1;
576  }
577  /* This circumlocution needed to keep expression simple for Cray,
578  * and others
579  */
580  if (bw / (dx*dy) != ((long)tp->tx_transp[0])) goto opaque;
581 
582  /*
583  * Transparency mapping is enabled, and we hit a transparent spot.
584  * Let higher level handle it in reflect/refract code.
585  */
586  swp->sw_transmit = 1.0;
587  swp->sw_reflect = 0.0;
588  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
589  (void)rr_render(ap, pp, swp);
590  return 1;
591 }
592 
593 
594 HIDDEN int
595 txt_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)
596 {
597  register struct txt_specific *tp;
598  int pixelbytes = 3;
599 
600  BU_CK_VLS(matparm);
601  BU_GET(tp, struct txt_specific);
602  *dpp = tp;
603 
604  bu_vls_init(&tp->tx_name);
605 
606  /* defaults */
607  tp->tx_w = tp->tx_n = -1;
608  tp->tx_trans_valid = 0;
609  tp->tx_scale[X] = 1.0;
610  tp->tx_scale[Y] = 1.0;
611  tp->tx_mirror = 0;
612  tp->tx_datasrc = 0; /* source is auto-located by default */
613  tp->tx_binunifp = NULL;
614  tp->tx_mp = NULL;
615 
616  /* load given values */
617  if (bu_struct_parse(matparm, txt_parse, (char *)tp, NULL) < 0) {
618  BU_PUT(tp, struct txt_specific);
619  return -1;
620  }
621 
622  /* validate values */
623  if (tp->tx_w < 0) tp->tx_w = 512;
624  if (tp->tx_n < 0) tp->tx_n = tp->tx_w;
625  if (tp->tx_trans_valid) rp->reg_transmit = 1;
626  BU_CK_VLS(&tp->tx_name);
627  if (bu_vls_strlen(&tp->tx_name) <= 0) return -1;
628  /* !?! if (tp->tx_name[0] == '\0') return -1; */ /* FAIL, no file */
629 
630  if (BU_STR_EQUAL(mfp->mf_name, "bwtexture")) pixelbytes = 1;
631 
632  /* load the texture from its datasource */
633  if (txt_load_datasource(tp, rtip->rti_dbip, tp->tx_w * tp->tx_n * pixelbytes)<0) {
634  bu_log("\nERROR: txt_setup() %s %s could not be loaded [source was %s]\n", rp->reg_name, bu_vls_addr(&tp->tx_name), tp->tx_datasrc==TXT_SRC_OBJECT?"object":tp->tx_datasrc==TXT_SRC_FILE?"file":"auto");
635  return -1;
636  }
637 
638 
639  if (rdebug & RDEBUG_SHADE) {
640  bu_log("txt_setup: texture loaded! type=%s name=%s\n", tp->tx_datasrc==TXT_SRC_AUTO?"auto":tp->tx_datasrc==TXT_SRC_OBJECT?"object":tp->tx_datasrc==TXT_SRC_FILE?"file":"unknown", bu_vls_addr(&tp->tx_name));
641  bu_struct_print("texture", txt_parse, (char *)tp);
642  }
643 
644  return 1; /* OK */
645 }
646 
647 
648 HIDDEN void
649 txt_print(register struct region *rp, void *UNUSED(dp))
650 {
651  bu_struct_print(rp->reg_name, txt_parse, (char *)rp->reg_udata);
652 }
653 
654 
655 HIDDEN void
656 txt_free(void *cp)
657 {
658  struct txt_specific *tp = (struct txt_specific *)cp;
659 
660  bu_vls_free(&tp->tx_name);
662  if (tp->tx_mp) bu_close_mapped_file(tp->tx_mp);
663  tp->tx_binunifp = (struct rt_binunif_internal *)NULL; /* sanity */
664  tp->tx_mp = (struct bu_mapped_file *)NULL; /* sanity */
665  BU_PUT(cp, struct txt_specific);
666 }
667 
668 
669 struct ckr_specific {
670  int ckr_a[3]; /* first RGB */
671  int ckr_b[3]; /* second RGB */
672  double ckr_scale;
673 };
674 #define CKR_NULL ((struct ckr_specific *)0)
675 #define CKR_O(m) bu_offsetof(struct ckr_specific, m)
676 
678  {"%d", 3, "a", CKR_O(ckr_a), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
679  {"%d", 3, "b", CKR_O(ckr_b), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
680  {"%g", 1, "s", CKR_O(ckr_scale), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
681  {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
682 };
683 
684 
685 HIDDEN int
686 ckr_render(struct application *ap, const struct partition *pp, register struct shadework *swp, void *dp)
687 {
688  register struct ckr_specific *ckp =
689  (struct ckr_specific *)dp;
690  register int *cp;
691  int u, v;
692 
693  u = swp->sw_uv.uv_u * ckp->ckr_scale;
694  v = swp->sw_uv.uv_v * ckp->ckr_scale;
695 
696  if (((u&1) && (v&1)) || (!(u&1) && !(v&1))) {
697  cp = ckp->ckr_a;
698  } else {
699  cp = ckp->ckr_b;
700  }
701 
702  VSET(swp->sw_color,
703  (unsigned char)cp[0] / 255.0,
704  (unsigned char)cp[1] / 255.0,
705  (unsigned char)cp[2] / 255.0);
706 
707  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
708  (void)rr_render(ap, pp, swp);
709 
710  return 1;
711 }
712 
713 
714 HIDDEN int
715 ckr_setup(register struct region *UNUSED(rp), struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *UNUSED(rtip))
716 /* New since 4.4 release */
717 {
718  register struct ckr_specific *ckp;
719 
720  /* Default will be white and black checkers */
721  BU_GET(ckp, struct ckr_specific);
722  *dpp = ckp;
723  ckp->ckr_a[0] = ckp->ckr_a[1] = ckp->ckr_a[2] = 255;
724  ckp->ckr_b[0] = ckp->ckr_b[1] = ckp->ckr_b[2] = 0;
725  ckp->ckr_scale = 2.0;
726  if (bu_struct_parse(matparm, ckr_parse, (char *)ckp, NULL) < 0) {
727  BU_PUT(ckp, struct ckr_specific);
728  return -1;
729  }
730  ckp->ckr_a[0] &= 0x0ff;
731  ckp->ckr_a[1] &= 0x0ff;
732  ckp->ckr_a[2] &= 0x0ff;
733  ckp->ckr_b[0] &= 0x0ff;
734  ckp->ckr_b[1] &= 0x0ff;
735  ckp->ckr_b[2] &= 0x0ff;
736  return 1;
737 }
738 
739 
740 HIDDEN void
741 ckr_print(register struct region *rp, void *UNUSED(dp))
742 {
743  bu_struct_print(rp->reg_name, ckr_parse, (const char *)rp->reg_udata);
744 }
745 
746 
747 HIDDEN void
748 ckr_free(void *cp)
749 {
750  BU_PUT(cp, struct ckr_specific);
751 }
752 
753 
754 /*
755  * Render a map which varies red with U and blue with V values.
756  * Mostly useful for debugging ft_uv() routines.
757  */
758 HIDDEN int
759 tstm_render(struct application *ap, const struct partition *pp, register struct shadework *swp, void *UNUSED(dp))
760 {
761  VSET(swp->sw_color, swp->sw_uv.uv_u, 0, swp->sw_uv.uv_v);
762 
763  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
764  (void)rr_render(ap, pp, swp);
765 
766  return 1;
767 }
768 
769 
770 static vect_t star_colors[] = {
771  { 0.825769, 0.415579, 0.125303 },
772  { /* 3000 */ 0.671567, 0.460987, 0.258868 },
773  { 0.587580, 0.480149, 0.376395 },
774  { 0.535104, 0.488881, 0.475879 },
775  { 0.497639, 0.493881, 0.556825 },
776  { 0.474349, 0.494836, 0.624460 },
777  { 0.456978, 0.495116, 0.678378 },
778  { 0.446728, 0.493157, 0.727269 },
779  { /* 10000 */ 0.446728, 0.493157, 0.727269 }
780 };
781 
782 
783 HIDDEN int
784 star_render(register struct application *ap, const struct partition *pp, struct shadework *swp, void *UNUSED(dp))
785 {
786  /* Probably want to diddle parameters based on what part of sky */
787  if (bn_rand0to1(ap->a_resource->re_randptr) >= 0.98) {
788  register int i;
789  register fastf_t f;
790  i = (sizeof(star_colors)-1) / sizeof(star_colors[0]);
791 
792  /* "f" used for intermediate result to avoid an SGI compiler error */
794  i = ((double)i) * f;
795 
797  VSCALE(swp->sw_color, star_colors[i], f);
798  } else {
799  VSETALL(swp->sw_color, 0);
800  }
801 
802  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
803  (void)rr_render(ap, pp, swp);
804 
805  return 1;
806 }
807 
808 
809 /*
810  * Given a u, v coordinate within the texture (0 <= u, v <= 1.0),
811  * compute a new surface normal.
812  * For now we come up with a local coordinate system, and
813  * make bump perturbations from the red and blue channels of
814  * an RGB image.
815  *
816  * Note that .pix files are stored left-to-right, bottom-to-top,
817  * which works out very naturally for the indexing scheme.
818  */
819 HIDDEN int
820 bmp_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
821 {
822  register struct txt_specific *tp =
823  (struct txt_specific *)dp;
824  unsigned char *cp=NULL;
825  fastf_t pertU, pertV;
826  vect_t y; /* world coordinate axis vectors */
827  vect_t u, v; /* surface coord system vectors */
828  int i, j; /* bump map pixel indices */
829 
830  /*
831  * If no texture file present, or if
832  * texture isn't and can't be read, give debug color.
833  */
834  if ((bu_vls_strlen(&tp->tx_name) <= 0) || (!tp->tx_mp && !tp->tx_binunifp)) {
835  VSET(swp->sw_color, swp->sw_uv.uv_u, 0, swp->sw_uv.uv_v);
836  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
837  (void)rr_render(ap, pp, swp);
838  return 1;
839  }
840  /* u is left->right index, v is line number bottom->top */
841  if (swp->sw_uv.uv_u < 0 || swp->sw_uv.uv_u > 1 || swp->sw_uv.uv_v < 0 || swp->sw_uv.uv_v > 1) {
842  bu_log("bmp_render: bad u, v=%g, %g du, dv=%g, %g seg=%s\n",
843  swp->sw_uv.uv_u, swp->sw_uv.uv_v,
844  swp->sw_uv.uv_du, swp->sw_uv.uv_dv,
845  pp->pt_inseg->seg_stp->st_name);
846  VSET(swp->sw_color, 0, 1, 0);
847  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
848  (void)rr_render(ap, pp, swp);
849  return 1;
850  }
851 
852  /* Find a local coordinate system */
853  VSET(y, 0, 1, 0);
854  VCROSS(u, y, swp->sw_hit.hit_normal);
855  VUNITIZE(u);
856  VCROSS(v, swp->sw_hit.hit_normal, u);
857 
858  /* Find our RGB value */
859  i = swp->sw_uv.uv_u * (tp->tx_w-1);
860  j = swp->sw_uv.uv_v * (tp->tx_n-1);
861 
862  if (tp->tx_mp) {
863  cp = ((unsigned char *)(tp->tx_mp->buf)) +
864  (j) * tp->tx_w * 3 + i * 3;
865  } else if (tp->tx_binunifp) {
866  cp = ((unsigned char *)(tp->tx_binunifp->u.uint8)) +
867  (j) * tp->tx_w * 3 + i * 3;
868  } else {
869  /* not reachable */
870  bu_bomb("sh_text.c -- Unreachable code reached while reading datasource\n");
871  }
872  pertU = ((fastf_t)(*cp) - 128.0) / 128.0;
873  pertV = ((fastf_t)(*(cp+2)) - 128.0) / 128.0;
874 
875  if (rdebug&RDEBUG_LIGHT) {
876  VPRINT("normal", swp->sw_hit.hit_normal);
877  VPRINT("u", u);
878  VPRINT("v", v);
879  bu_log("cu = %d, cv = %d\n", *cp, *(cp+2));
880  bu_log("pertU = %g, pertV = %g\n", pertU, pertV);
881  }
882  VJOIN2(swp->sw_hit.hit_normal, swp->sw_hit.hit_normal, pertU, u, pertV, v);
883  VUNITIZE(swp->sw_hit.hit_normal);
884  if (rdebug&RDEBUG_LIGHT) {
885  VPRINT("after", swp->sw_hit.hit_normal);
886  }
887 
888  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
889  (void)rr_render(ap, pp, swp);
890 
891  return 1;
892 }
893 
894 
895 HIDDEN int
896 envmap_setup(register struct region *rp, struct bu_vls *matparm, void **UNUSED(dpp), const struct mfuncs *UNUSED(mfp), struct rt_i *rtip)
897 {
898  struct mfuncs *shaders = MF_NULL;
899 
900  BU_CK_VLS(matparm);
901  RT_CK_RTI(rtip);
902 
903  if (env_region.reg_mfuncs) {
904  bu_log("envmap_setup: second environment map ignored\n");
905  return 0; /* drop region */
906  }
907 
908  env_region = *rp; /* struct copy */
909  /* Get copies of, or eliminate, references to dynamic structures */
914  env_region.reg_mfuncs = (char *)0;
916 
917  /* get list of available shaders */
918  if (!shaders) {
919  optical_shader_init(&shaders);
920  }
921  if (mlib_setup(&shaders, &env_region, rtip) < 0)
922  bu_log("envmap_setup() material '%s' failed\n",
924 
925 
926  return 0; /* This region should be dropped */
927 }
928 
929 
930 /*
931  * Regardless of arguments, always return zero.
932  * Useful mostly as a stub print, and/or free routine.
933  */
934 /* VARARGS */
935 int
936 mlib_zero(struct application *UNUSED(a), const struct partition *UNUSED(b), struct shadework *UNUSED(c), void *UNUSED(d))
937 {
938  return 0;
939 }
940 
941 
942 /*
943  * Regardless of arguments, always return one.
944  * Useful mostly as a stub setup routine.
945  */
946 /* VARARGS */
947 int
948 mlib_one(struct region *UNUSED(a), struct bu_vls *UNUSED(b), void **UNUSED(c), const struct mfuncs *UNUSED(d), struct rt_i *UNUSED(e))
949 {
950  return 1;
951 }
952 
953 
954 /* VARARGS */
955 void
956 mlib_void(struct region *UNUSED(a), void *UNUSED(b))
957 {
958 }
959 
960 static void
961 mlib_void2(void *UNUSED(b))
962 {
963 }
964 
965 struct mfuncs txt_mfuncs[] = {
966  {MF_MAGIC, "texture", 0, MFI_UV, 0, txt_setup, txt_render, txt_print, txt_free },
967  {MF_MAGIC, "bwtexture", 0, MFI_UV, 0, txt_setup, bwtxt_render, txt_print, txt_free },
968  {MF_MAGIC, "checker", 0, MFI_UV, 0, ckr_setup, ckr_render, ckr_print, ckr_free },
969  {MF_MAGIC, "testmap", 0, MFI_UV, 0, mlib_one, tstm_render, mlib_void, mlib_void2 },
970  {MF_MAGIC, "fakestar", 0, 0, 0, mlib_one, star_render, mlib_void, mlib_void2 },
971  {MF_MAGIC, "bump", 0, MFI_UV|MFI_NORMAL, 0, txt_setup, bmp_render, txt_print, txt_free },
972  {MF_MAGIC, "envmap", 0, 0, 0, envmap_setup, mlib_zero, mlib_void, mlib_void2 },
973  {0, (char *)0, 0, 0, 0, 0, 0, 0, 0 }
974 };
975 
976 
977 /*
978  * Local Variables:
979  * mode: C
980  * tab-width: 8
981  * indent-tabs-mode: t
982  * c-file-style: "stroustrup"
983  * End:
984  * ex: shiftwidth=4 tabstop=8
985  */
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
Definition: raytrace.h:800
#define RDEBUG_LIGHT
Definition: optical.h:132
HIDDEN int star_render(register struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
Definition: sh_text.c:784
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
int rt_db_get_internal(struct rt_db_internal *ip, const struct directory *dp, const struct db_i *dbip, const mat_t mat, struct resource *resp)
Definition: dir.c:76
void mlib_void(struct region *a, void *b)
Definition: sh_text.c:956
int tx_w
Definition: sh_text.c:43
unsigned char * uint8
Definition: raytrace.h:1009
HIDDEN int ckr_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)
Definition: sh_text.c:715
int ckr_a[3]
Definition: sh_text.c:670
struct bu_structparse txt_parse[]
Definition: sh_text.c:65
#define MF_MAGIC
Definition: magic.h:205
struct bu_structparse ckr_parse[]
Definition: sh_text.c:677
#define RT_CK_RTI(_p)
Definition: raytrace.h:1833
fastf_t uv_u
Range 0..1.
Definition: raytrace.h:341
struct soltab * seg_stp
pointer back to soltab
Definition: raytrace.h:372
Definition: clone.c:90
#define VSET(a, b, c, d)
Definition: color.c:53
#define VSETALL(a, s)
Definition: color.c:54
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
char ** dbi_filepath
search path for aux file opens (convenience var)
Definition: raytrace.h:810
Header file for the BRL-CAD common definitions.
#define TXT_SRC_AUTO
Definition: sh_text.c:50
HIDDEN void txt_free(void *cp)
Definition: sh_text.c:656
const char * reg_name
Identifying string.
Definition: raytrace.h:539
struct mfuncs txt_mfuncs[]
Definition: sh_text.c:965
struct resource * a_resource
dynamic memory resources
Definition: raytrace.h:1591
union rt_binunif_internal::@9 u
HIDDEN int ckr_render(struct application *ap, const struct partition *pp, register struct shadework *swp, void *dp)
Definition: sh_text.c:686
struct region env_region
Definition: init.c:50
int mlib_zero(struct application *a, const struct partition *b, struct shadework *c, void *d)
Definition: sh_text.c:936
fastf_t tx_scale[2]
Definition: sh_text.c:46
#define HIDDEN
Definition: common.h:86
#define RT_CK_BINUNIF(_p)
Definition: raytrace.h:1016
HIDDEN int txt_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
Definition: sh_text.c:222
void bu_struct_print(const char *title, const struct bu_structparse *parsetab, const char *base)
Definition: parse.c:1221
HIDDEN void txt_print(register struct region *rp, void *dp)
Definition: sh_text.c:649
void optical_shader_init(struct mfuncs **headp)
Definition: init.c:61
if(share_geom)
Definition: nmg_mod.c:3829
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
int bu_strncmp(const char *string1, const char *string2, size_t n)
Definition: str.c:191
Definition: color.c:49
COMPLEX data[64]
Definition: fftest.c:34
char tx_datasrc
Definition: sh_text.c:51
#define BU_CK_VLS(_vp)
Definition: vls.h:69
HIDDEN int bwtxt_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
Definition: sh_text.c:478
struct bu_vls tx_name
Definition: sh_text.c:42
#define RT_CK_DB_INTERNAL(_p)
Definition: raytrace.h:207
HIDDEN void txt_source_hook(const struct bu_structparse *, const char *, void *, const char *, void *)
Definition: sh_text.c:89
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
#define RT_CK_DIR(_dp)
Definition: raytrace.h:876
#define RT_DB_INTERNAL_INIT(_p)
Definition: raytrace.h:199
#define LOOKUP_QUIET
Definition: raytrace.h:893
#define RT_CK_AP(_p)
Definition: raytrace.h:1674
fastf_t uv_dv
delta in v
Definition: raytrace.h:344
#define TREE_NULL
Definition: raytrace.h:1181
int tx_trans_valid
Definition: sh_text.c:45
struct bu_list * back
"back", "last"
Definition: list.h:121
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
struct seg * pt_inseg
IN seg ptr (gives stp)
Definition: raytrace.h:576
#define CKR_O(m)
Definition: sh_text.c:675
char * ma_shader
shader name & parms
Definition: raytrace.h:527
int reg_transmit
flag: material transmits light
Definition: raytrace.h:549
HIDDEN int txt_load_datasource(struct txt_specific *texture, struct db_i *dbInstance, const long unsigned int size)
size_t bu_vls_strlen(const struct bu_vls *vp)
Definition: vls.c:189
#define UNUSED(parameter)
Definition: common.h:239
char * bu_vls_strdup(const struct bu_vls *vp)
Definition: vls.c:274
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
void rt_binunif_free(struct rt_binunif_internal *bip)
Definition: db5_bin.c:378
HIDDEN int txt_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)
Definition: sh_text.c:595
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
int tx_mirror
Definition: sh_text.c:47
#define BU_STRUCTPARSE_FUNC_NULL
Definition: parse.h:153
#define TXT_SRC_OBJECT
Definition: sh_text.c:49
HIDDEN void txt_transp_hook(const struct bu_structparse *, const char *, void *, const char *, void *)
Definition: sh_text.c:110
int mlib_one(struct region *a, struct bu_vls *b, void **c, const struct mfuncs *d, struct rt_i *e)
Definition: sh_text.c:948
#define RT_CK_DBI(_p)
Definition: raytrace.h:829
HIDDEN void ckr_print(register struct region *rp, void *dp)
Definition: sh_text.c:741
#define TX_O(m)
Definition: sh_text.c:56
struct mater_info reg_mater
Real material information.
Definition: raytrace.h:546
HIDDEN void ckr_free(void *cp)
Definition: sh_text.c:748
void * idb_ptr
Definition: raytrace.h:195
#define bn_rand0to1(_q)
Definition: rand.h:123
#define RDEBUG_SHADE
Definition: optical.h:130
struct db_i * rti_dbip
prt to Database instance struct
Definition: raytrace.h:1774
int mlib_setup(struct mfuncs **headp, register struct region *rp, struct rt_i *rtip)
Definition: material.c:204
int bu_struct_parse(const struct bu_vls *in_vls, const struct bu_structparse *desc, const char *base, void *data)
Definition: parse.c:878
#define RT_DIR_NULL
Definition: raytrace.h:875
fastf_t uv_du
delta in u
Definition: raytrace.h:343
void bu_close_mapped_file(struct bu_mapped_file *mp)
Definition: mappedfile.c:339
struct rt_binunif_internal * tx_binunifp
Definition: sh_text.c:52
union tree * reg_treetop
Pointer to boolean tree.
Definition: raytrace.h:540
#define TXT_SRC_FILE
Definition: sh_text.c:48
#define BU_LIST_NULL
Definition: list.h:124
HIDDEN int envmap_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)
Definition: sh_text.c:896
double ckr_scale
Definition: sh_text.c:672
HIDDEN int bmp_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
Definition: sh_text.c:820
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
int rr_render(struct application *app, const struct partition *pp, struct shadework *swp)
int tx_transp[3]
Definition: sh_text.c:40
void * reg_udata
User appl. data for material.
Definition: raytrace.h:548
int tx_n
Definition: sh_text.c:44
float * re_randptr
ptr into random number table
Definition: raytrace.h:1457
struct bu_list * forw
"forward", "next"
Definition: list.h:120
#define RT_CHECK_PT(_p)
compat
Definition: raytrace.h:588
Definition: vls.h:56
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
double fastf_t
Definition: defines.h:300
#define VPRINT(a, b)
Definition: raytrace.h:1881
Header file for the BRL-CAD Optical Library, LIBOPTICAL.
void * reg_mfuncs
User appl. funcs for material.
Definition: raytrace.h:547
int ckr_b[3]
Definition: sh_text.c:671
struct bu_mapped_file * tx_mp
Definition: sh_text.c:53
struct bu_list l
magic # and doubly linked list
Definition: raytrace.h:538
int rdebug
Definition: init.c:39
struct bu_mapped_file * bu_open_mapped_file_with_path(char *const *path, const char *name, const char *appl)
Definition: mappedfile.c:430
Definition: color.c:50
fastf_t uv_v
Range 0..1.
Definition: raytrace.h:342
#define bu_strdup(s)
Definition: str.h:71
HIDDEN int tstm_render(struct application *ap, const struct partition *pp, register struct shadework *swp, void *dp)
Definition: sh_text.c:759
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126