home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Resource Library: Graphics
/
graphics-16000.iso
/
msdos
/
raytrace
/
rayshade
/
src
/
surface.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-28
|
3KB
|
154 lines
/*
* surface.c
*
* Copyright (C) 1989, 1991, Craig E. Kolb
* All rights reserved.
*
* This software may be freely copied, modified, and redistributed
* provided that this copyright notice is preserved on all copies.
*
* You may not distribute this software, in whole or in part, as part of
* any commercial product without the express consent of the authors.
*
* There is no warranty or other guarantee of fitness of this software
* for any purpose. It is provided solely "as is".
*
* $Id: surface.c,v 4.0 91/07/17 14:40:55 kolb Exp Locker: kolb $
*
* $Log: surface.c,v $
* Revision 4.0 91/07/17 14:40:55 kolb
* Initial version.
*
*/
#include "atmosphere.h"
#include "surface.h"
#define blend(a, b, p, q) (a * p + b * q)
Color Black = {0., 0., 0.},
White = {1., 1., 1.};
/*
* Create and return pointer to surface with given properties.
*/
Surface *
SurfaceCreate()
{
Surface *stmp;
stmp = (Surface *)RayMalloc(sizeof(Surface));
stmp->amb = stmp->diff = stmp->spec =
stmp->translu = Black;
stmp->body = White;
stmp->srexp = stmp->stexp = DEFAULT_PHONGPOW;
stmp->statten = 1.; /* No attenuation by default */
stmp->reflect = stmp->transp = 0.;
stmp->noshadow = FALSE;
stmp->index = DEFAULT_INDEX;
stmp->name = (char *)NULL;
stmp->next = (Surface *)NULL;
return stmp;
}
Surface *
SurfaceCopy(surf)
Surface *surf;
{
Surface *res;
if (!surf)
return (Surface *)NULL;
res = SurfaceCreate();
*res = *surf;
res->next = (Surface *)NULL;
res->name = (char *)NULL;
return res;
}
/*
* Compute combination of two surfaces. Resulting surface is copied into surf1.
*/
void
SurfaceBlend(surf1, surf2, p, q)
Surface *surf1, *surf2;
Float p, q;
{
/*
* P is weight of surf1. q is weight of surf2.
* Result is placed in surf1.
*/
if (q < EPSILON)
return; /* keep surf1 as-is */
ColorBlend(&surf1->amb, &surf2->amb, p, q);
ColorBlend(&surf1->diff, &surf2->diff, p, q);
ColorBlend(&surf1->spec, &surf2->spec, p, q);
ColorBlend(&surf1->translu, &surf2->translu, p, q);
ColorBlend(&surf1->body, &surf2->body, p, q);
surf1->srexp = blend(surf1->srexp, surf2->srexp, p, q);
surf1->stexp = blend(surf1->stexp, surf2->stexp, p, q);
surf1->reflect = blend(surf1->reflect, surf2->reflect, p, q);
surf1->transp = blend(surf1->transp, surf2->transp, p, q);
surf1->translucency = blend(surf1->translucency, surf2->translucency,
p, q);
/*
* Questionable...
*/
surf1->statten = blend(surf1->statten, surf2->statten, p, q);
surf1->index = blend(surf1->index, surf2->index, p, q);
if (p < EPSILON) {
surf1->noshadow = surf2->noshadow;
} else {
/* else there's a blend of some kind... */
surf1->noshadow = (surf1->noshadow && surf2->noshadow);
}
}
/*
* Blend two colors. Result is placed in color1.
*/
void
ColorBlend(color1, color2, p, q)
Color *color1, *color2;
Float p, q;
{
color1->r = blend(color1->r, color2->r, p, q);
color1->g = blend(color1->g, color2->g, p, q);
color1->b = blend(color1->b, color2->b, p, q);
}
SurfList *
SurfPop(list)
SurfList *list;
{
SurfList *stmp = list->next;
free((voidstar)list);
return stmp;
}
SurfList *
SurfPush(surf, list)
Surface *surf;
SurfList *list;
{
SurfList *stmp;
stmp = (SurfList *)RayMalloc(sizeof(SurfList));
stmp->surf = surf;
stmp->next = list;
return stmp;
}