home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / GRAPHICS / rayshade.lzh / texture.c < prev    next >
Text File  |  1990-05-08  |  10KB  |  453 lines

  1. /*
  2.  * texture.c
  3.  *
  4.  * Copyright (C) 1989, Craig E. Kolb
  5.  *
  6.  * This software may be freely copied, modified, and redistributed,
  7.  * provided that this copyright notice is preserved on all copies.
  8.  *
  9.  * There is no warranty or other guarantee of fitness for this software,
  10.  * it is provided solely .  Bug reports or fixes may be sent
  11.  * to the author, who may or may not act on them as he desires.
  12.  *
  13.  * You may not include this software in a program or other software product
  14.  * without supplying the source, or without informing the end-user that the
  15.  * source is available for no extra charge.
  16.  *
  17.  * If you modify this software, you should include a notice giving the
  18.  * name of the person performing the modification, the date of modification,
  19.  * and the reason for such modification.
  20.  *
  21.  * $Id: texture.c,v 3.0.1.4 90/04/04 17:22:39 craig Exp $
  22.  *
  23.  * $Log:    texture.c,v $
  24.  * Revision 3.0.1.4  90/04/04  17:22:39  craig
  25.  * patch5: Added checking for invalid colormap entries.
  26.  * 
  27.  * Revision 3.0.1.3  90/03/07  21:30:22  craig
  28.  * patch4: Fixed thresholding bug in fBmText().
  29.  * patch4: Colormap is now set to NULL in new_texture().
  30.  * patch4: Added gloss texture.
  31.  * 
  32.  * Revision 3.0.1.2  89/12/06  16:33:50  craig
  33.  * patch2: Added calls to new error/warning routines.
  34.  * 
  35.  * Revision 3.0.1.1  89/11/27  18:36:54  craig
  36.  * patch2: Removed hardcoded constants in calculation of ambient
  37.  * patch2: component in several textures.
  38.  * 
  39.  * Revision 3.0  89/10/27  02:06:05  craig
  40.  * Baseline for first official release.
  41.  * 
  42.  */
  43. #include <stdio.h>
  44. #include <math.h>
  45. #include "constants.h"
  46. #include "typedefs.h"
  47. #include "funcdefs.h"
  48. #include "texture.h"
  49.  
  50. /*
  51.  * Array of texturing functions indexed by type.
  52.  */
  53. int (*textures[])() =
  54.     {CheckerText, BlotchText, BumpText, MarbleText, fBmText, fBmBumpText,
  55.      WoodText, GlossText};
  56. extern double Chaos(), Marble(), fBm(), Noise();
  57. Color    *read_colormap();
  58.  
  59. /*
  60.  * Return pointer to new texture structure.
  61.  */
  62. Texture *
  63. new_texture(type)
  64. char type;
  65. {
  66.     Texture *new;
  67.  
  68.     new = (Texture *)Malloc(sizeof(Texture));
  69.     new->type = type;
  70.     new->surf1 = (Surface *)NULL;
  71.     new->next = (Texture *)NULL;
  72.     new->trans = (Trans *)NULL;
  73.     new->colormap = (Color *)NULL;
  74.     return new;
  75. }
  76.  
  77. /*
  78.  * Apply appropriate textures to a surface.
  79.  */
  80. apply_textures(hitinfo, list)
  81. HitInfo *hitinfo;
  82. Texture *list;
  83. {
  84.     Texture *ttmp;
  85.     Vector ptmp;
  86.  
  87.     for (ttmp = list; ttmp; ttmp = ttmp->next) {
  88.         ptmp = hitinfo->pos;
  89.         if (ttmp->trans) {
  90.             /*
  91.              * Transform position and normal to texture space.
  92.              */
  93.             transform_point(&ptmp,&ttmp->trans->world2obj);
  94.             TransformNormal(&hitinfo->norm,&ttmp->trans->obj2world);
  95.         }
  96.         /*
  97.          * Make sure to use a normalized normal.
  98.          */
  99.         (void)normalize(&hitinfo->norm);
  100.         (*textures[(int)ttmp->type])
  101.             (ttmp,&ptmp,&hitinfo->norm,&hitinfo->surf);
  102.         if (ttmp->trans) {
  103.             /*
  104.              * Transform the normal back to world-space.
  105.              */
  106.             TransformNormal(&hitinfo->norm,&ttmp->trans->world2obj);
  107.         }
  108.     }
  109. }
  110.  
  111. Texture *
  112. NewWoodText()
  113. {
  114.     Texture *text;
  115.  
  116.     text = new_texture(WOOD);
  117.     return text;
  118. }
  119.  
  120. /*ARGSUSED*/
  121. WoodText(text, pos, norm, surf)
  122. Texture *text;
  123. Vector *pos, *norm;
  124. Surface *surf;
  125. {
  126.     double red, grn, blu;
  127.     double chaos, brownLayer, greenLayer;
  128.     double perturb, brownPerturb, greenPerturb, grnPerturb;
  129.     double t;
  130.  
  131.     chaos = Chaos(pos, 7);
  132.     t = sin(sin(8.*chaos + 7*pos->x +3.*pos->y));
  133.  
  134.     greenLayer = brownLayer = abs(t);
  135.  
  136.     perturb = fabs(sin(40.*chaos + 50*pos->z));
  137.  
  138.     brownPerturb = .6*perturb + 0.3;
  139.     greenPerturb = .2*perturb + 0.8;
  140.     grnPerturb = .15*perturb + 0.85;
  141.     grn = 0.5 * pow(abs(brownLayer), 0.3);
  142.     brownLayer = pow(0.5 * (brownLayer+1.0), 0.6) * brownPerturb;
  143.     greenLayer = pow(0.5 * (greenLayer+1.0), 0.6) * greenPerturb;
  144.  
  145.     red = (0.5*brownLayer + 0.35*greenLayer)*2.*grn;
  146.     blu = (0.25*brownLayer + 0.35*greenLayer)*2.0*grn;
  147.     grn *= max(brownLayer, greenLayer) * grnPerturb;
  148.  
  149.     surf->diff.r *= red;
  150.     surf->diff.g *= grn;
  151.     surf->diff.b *= blu;
  152.     surf->amb.r *= red;
  153.     surf->amb.g *= grn;
  154.     surf->amb.b *= blu;
  155. }
  156.  
  157. /*
  158.  * Create and return a reference to a "checker" texture.
  159.  */
  160. Texture *
  161. NewCheckText(surf)
  162. char *surf;
  163. {
  164.     Texture *text;
  165.  
  166.     text = new_texture(CHECKER);
  167.     text->surf1 = find_surface(surf);
  168.  
  169.     return text;
  170. }
  171.  
  172. Texture *
  173. NewfBmBumpText(offset, scale, h, lambda, octaves)
  174. double h, lambda, scale, offset;
  175. int octaves;
  176. {
  177.     Texture *text;
  178.  
  179.     text = NewfBmText(offset, scale, h, lambda, octaves, 0., (char *)0);
  180.  
  181.     text->type = FBMBUMP;
  182.  
  183.     return text;
  184. }
  185.  
  186. Texture *
  187. NewfBmText(offset, scale, h, lambda, octaves, thresh, mapname)
  188. double h, lambda, scale, offset, thresh;
  189. int octaves;
  190. char *mapname;
  191. {
  192.     double beta;
  193.     Texture *text;
  194.  
  195.     text = new_texture(FBM);
  196.  
  197.     text->args = (double *)Malloc(5 * sizeof(double));
  198.     beta = 1. + 2 * h;
  199.     text->args[0] = pow(lambda, -0.5 * beta);    /* omega */
  200.     text->args[1] = lambda;
  201.     text->args[2] = scale;
  202.     text->args[3] = offset;
  203.     text->args[4] = thresh;
  204.     text->size = (double)octaves;
  205.     if (mapname != (char *)0)
  206.         text->colormap = read_colormap(mapname);
  207.  
  208.     return text;
  209. }
  210.  
  211. /*
  212.  * Create and return a reference to a "bump" texture.
  213.  */
  214. Texture *
  215. NewBumpText(size)
  216. double size;
  217. {
  218.     Texture *text;
  219.  
  220.     text = new_texture(BUMP);
  221.     text->size = size;
  222.  
  223.     return text;
  224. }
  225.  
  226. /*
  227.  * Create and return a reference to a "blotch" texture.
  228.  */
  229. Texture *
  230. NewBlotchText(scale, surf)
  231. double scale;
  232. char *surf;
  233. {
  234.     Texture *text;
  235.  
  236.     text = new_texture(BLOTCH);
  237.     text->size = scale;
  238.     text->surf1 = find_surface(surf);
  239.  
  240.     return text;
  241. }
  242.  
  243. Texture *
  244. NewMarbleText(mapname)
  245. char *mapname;
  246. {
  247.     Texture *text;
  248.  
  249.     text = new_texture(MARBLE);
  250.     if (mapname)
  251.         text->colormap = read_colormap(mapname);
  252.     return text;
  253. }
  254.  
  255. Texture *
  256. NewGlossText(gloss)
  257. double gloss;
  258. {
  259.     Texture *text;
  260.  
  261.     text = new_texture(GLOSS);
  262.     /*
  263.      * Radius of base of cone to be sampled is 1 - glossiness.
  264.      */
  265.     text->size = 1. - gloss;
  266.     return text;
  267. }
  268.  
  269. /*
  270.  * Apply "blotch" texture.
  271.  */
  272. /*ARGSUSED*/
  273. BlotchText(text, pos, norm, surf)
  274. Texture *text;
  275. Vector *pos, *norm;
  276. Surface *surf;
  277. {
  278.     double val;
  279.  
  280.     /*
  281.      * "size" represents the 'average' noise value at a point.
  282.      */
  283.     val = Noise(pos);
  284.     if (val > text->size) {
  285.         val = (val - text->size) / (1. - text->size);
  286.         blend_surface(surf, text->surf1, 1. - val, val);
  287.     }
  288. }
  289.  
  290. /*ARGSUSED*/
  291. fBmText(text, pos, norm, surf)
  292. Texture *text;
  293. Vector *pos, *norm;
  294. Surface *surf;
  295. {
  296.     double val;
  297.     int index;
  298.  
  299.     val = fBm(pos, text->args[0], text->args[1], (int)text->size);
  300.     if (val < text->args[4])
  301.         val = text->args[3];
  302.     else
  303.         val = text->args[3] + text->args[2] * (val - text->args[4]);
  304.     if (text->colormap) {
  305.         index = 255. * val;
  306.         if (index > 255) index = 255;
  307.         if (index < 0) index = 0;
  308.         surf->diff.r *= text->colormap[index].r;
  309.         surf->diff.g *= text->colormap[index].g;
  310.         surf->diff.b *= text->colormap[index].b;
  311.         surf->amb.r *= text->colormap[index].r;
  312.         surf->amb.g *= text->colormap[index].g;
  313.         surf->amb.b *= text->colormap[index].b;
  314.     } else {
  315.         ScaleColor(val, surf->diff, &surf->diff);
  316.         ScaleColor(val, surf->amb, &surf->amb);
  317.     }
  318. }
  319.  
  320. /*
  321.  * Apply a "checker" texture.
  322.  */
  323. /*ARGSUSED*/
  324. CheckerText(text, pos, norm, surf)
  325. Texture *text;
  326. Vector *pos, *norm;
  327. Surface *surf;
  328. {
  329.     int xp, yp, zp;
  330.  
  331.     xp = pos->x > 0. ? pos->x : 1. - pos->x;
  332.     yp = pos->y > 0. ? pos->y : 1. - pos->y;
  333.     zp = pos->z > 0. ? pos->z : 1. - pos->z;
  334.  
  335.     if ((xp + yp + zp) % 2)
  336.         *surf = *text->surf1;
  337.     /* else surface stays the same. */
  338. }
  339.  
  340. /*ARGSUSED*/
  341. fBmBumpText(text, pos, norm, surf)
  342. Texture *text;
  343. Vector *pos, *norm;
  344. Surface *surf;
  345. {
  346.     Vector disp;
  347.     double w;
  348.  
  349.     VfBm(pos, text->args[0], text->args[1], (int)text->size, &disp);
  350.     w = text->args[2];
  351.     norm->x += text->args[3] + disp.x * w;
  352.     norm->y += text->args[3] + disp.y * w;
  353.     norm->z += text->args[3] + disp.z * w;
  354. }
  355.  
  356. /*
  357.  * Apply a "bump" texture.
  358.  */
  359. /*ARGSUSED*/
  360. BumpText(text, pos, norm, surf)
  361. Texture *text;
  362. Vector *pos, *norm;
  363. Surface *surf;
  364. {
  365.     Vector disp;
  366.  
  367.     DNoise(pos, &disp);
  368.     norm->x += disp.x * text->size;
  369.     norm->y += disp.y * text->size;
  370.     norm->z += disp.z * text->size;
  371.     (void)normalize(norm);
  372. }
  373.  
  374. /*ARGSUSED*/
  375. MarbleText(text, pos, norm, surf)
  376. Texture *text;
  377. Vector *pos, *norm;
  378. Surface *surf;
  379. {
  380.     double val;
  381.     int index;
  382.  
  383.     val = Marble(pos);
  384.     if (text->colormap) {
  385.         index = (int)(255. * val);
  386.         surf->diff.r *= text->colormap[index].r;
  387.         surf->diff.g *= text->colormap[index].g;
  388.         surf->diff.b *= text->colormap[index].b;
  389.         surf->amb.r *= text->colormap[index].r;
  390.         surf->amb.g *= text->colormap[index].g;
  391.         surf->amb.b *= text->colormap[index].b;
  392.     } else {
  393.         ScaleColor(val, surf->amb, &surf->amb);
  394.         ScaleColor(val, surf->diff, &surf->diff);
  395.     }
  396. }
  397.  
  398. /*ARGSUSED*/
  399. GlossText(text, pos, norm, surf)
  400. Texture *text;
  401. Vector *pos, *norm;
  402. Surface *surf;
  403. {
  404.     Vector uaxis, vaxis, point, norminc;
  405.  
  406.     /*
  407.      * Find coordinate system with norm as the Z axis.
  408.      */
  409.     VectCoordSys(norm, &uaxis, &vaxis);
  410.     /*
  411.      * Find point on unit circle.
  412.      */
  413.     unit_circle_point(&point);
  414.     /*
  415.      * Perturb normal appropriately.
  416.      */
  417.     veccomb(text->size * point.x, uaxis,
  418.         text->size * point.y, vaxis,
  419.         &norminc);
  420.     vecadd(*norm, norminc, norm);
  421.     /*
  422.      * Renormalize.
  423.      */
  424.     (void)normalize(norm);
  425. }
  426.  
  427. Color *
  428. read_colormap(filename)
  429. char *filename;
  430. {
  431.     FILE *fp;
  432.     Color *map;
  433.     char buf[BUFSIZ];
  434.     int i, num;
  435.  
  436.     fp = fopen(filename, "r");
  437.     if (fp == (FILE *)NULL)
  438.         yyerror("Cannot open colormap file \"%s\".\n", filename);
  439.  
  440.     map = (Color *)Calloc(256, sizeof(Color));
  441.  
  442.     for (i = 0; fgets(buf,BUFSIZ,fp) != NULL && i < 256; i++) {
  443.         num = sscanf(buf,"%lf %lf %lf",&map[i].r, &map[i].g, &map[i].b);
  444.         if (num != 3) {
  445.             RSerror("%s, line %d:  Bad color specification.\n",
  446.                 filename, i+1);
  447.         }
  448.         ScaleColor(1. / 255., map[i], &map[i]);
  449.     }
  450.     (void)fclose(fp);
  451.     return map;
  452. }
  453.