This is mgrishade.c in view mode; [Download] [Up]
#include "mgP.h"
#include "mgriP.h"
#include "mgrishade.h"
/*-----------------------------------------------------------------------
* Function: mgri_material
* Description: bind a material. define it if it's not yet defined.
* Args: *mat: Material to bind.
* mask: Bitmask telling which material fields are valid.
* Passed into mgri_materialdef.
* Returns:
* Author: gunn, wisdom
* Date: Tue Jul 21 14:34:09 CDT 1992
*/
void
mgri_material(struct mgastk *astk, int mask)
{
Material *mat = &astk->mat;
float roughness = (mat->shininess)? 1.0/mat->shininess : 1.0;
if (mat == NULL) return;
if(mask & ((MTF_EMISSION|MTF_AMBIENT|MTF_SPECULAR
|MTF_SHININESS|MTF_Kd|MTF_Ka|MTF_Ks/*|MTF_ALPHA*/))) {
if(astk->useshader || !IS_SHADED(astk->ap.shading)) {
RiSurface(RI_CONSTANT, RI_NULL);
} else {
RiSurface("plastic", RI_KA, &mat->ka, RI_KD,&mat->kd,
RI_KS, &mat->ks, RI_SPECULARCOLOR, &mat->specular,
RI_ROUGHNESS, &roughness, RI_NULL);
}
}
// WHAT'S THE PURPOSE OF KEEPING THIS AROUND? THIS FUNCTION
// SHOULD BE RIPPED OUT, OR?
if(mask & MTF_DIFFUSE)
RiColor((float *)&mat->diffuse);
}
mgri_appearance( struct mgastk *astk, int mask )
{
Appearance *ap = &(astk->ap);
Material *mat = &(astk->mat);
if(mask & APF_TRANSP) {
float alpha = astk->mat.alpha;
/* Quick RenderMan does not (yet) support opacity */
}
if(ap->flag & APF_FACEDRAW && _mgric->drawsfaces == 0) {
_mgric->drawsfaces = 1;
}
if(_mgric->drawsfaces) RiGeometricRepresentation("primitive");
/*
* We set surface properties here. This is not done in mgri_material
* because that function doesn't know if the surface should be constant
* flat or smooth. This needn't be done lower down in mgridraw because
* the surface properties will override surface normal information.
*/
if(mask & APF_SHADING) {
RiShadingInterpolation( IS_SMOOTH(ap->shading) ? RI_SMOOTH : RI_CONSTANT );
astk->useshader = (astk->shader != NULL) && IS_SHADED(ap->shading);
mgri_material(astk, ~0);
}
/*
* Following are handled at draw time
*
* APF_FACEDRAW
* APF_EDGEDRAW
*
* WE WILL NEED TO HANDLE THE CASE OF APF_EVERT. Normally, this
* would be done in a shader. QuickRenderMan does not utilize
* programmable shaders. How can we handle this?
*/
}
void mgri_lighting(struct mgastk *astk, int mask)
{
LtLight *light;
LmLighting *li = &astk->lighting;
char lightlabel[8];
sprintf(lightlabel,"0");
RiLightSource(lightlabel, RI_AMBIENTLIGHT, RI_LIGHTCOLOR,
&(li->ambient), RI_NULL);
/* We must be in global coordinate space to place lights correctly */
RiTransformBegin();
RiIdentity(); /* wont work if we use on to twisted identity in worldbegin? */
/* or is it the case that since camera transform is 'locked */
/* into place' after world begin, that an identity at this */
/* point gives us the same transform as we have at wrld bgn? */
RiConcatTransform(cam2ri); /* cam2ri^-1 = cam2ri, we invert back for qrman */
mgri_lights( li->lights, astk );
RiTransformEnd();
}
void
mgri_lights( LtLight *light, struct mgastk *astk )
{
int i, lightsused=0;
int baselight = -1;
char lightlabel[8];
static int prevused = 0;
while (light) {
++lightsused;
/* Don't use the private or changed fields: we don't care. 1/14/92 TMM */
if (light->Private == 0) {
/* this is a new light */
light->Private = lightsused;
light->changed = 1; /* RenderMan doesn't care, since it has
to spit out the light no matter what... */
}
/* string label for qrman light definitions */
sprintf(lightlabel,"%d",light->Private);
if (light->changed) {
if (light->position.w == 0.0) {
RtPoint lightTo = {0.0, 0.0, 0.0};
RtPoint lightFrom =
{light->position.x, light->position.y, -light->position.z};
/* we are accomodating for a right handed coordinate */
/* system? - lights exist outside the world space */
/* directional light */
RiLightSource(lightlabel, RI_DISTANTLIGHT, RI_INTENSITY,
&(light->intensity), RI_LIGHTCOLOR, &(light->color),
RI_FROM, lightFrom, RI_TO, lightTo, RI_NULL);
} else {
/* point light */
RtPoint frompoint;
mgri_normalize(&light->position, frompoint);
frompoint[2] *= -1; /* flip z coord to compensate for z-flip */
RiLightSource(lightlabel, RI_POINTLIGHT, RI_INTENSITY,
&light->intensity, RI_LIGHTCOLOR, &(light->color),
RI_FROM, &frompoint,RI_NULL);
}
light->changed = 0;
}
light = light->next;
}
/* turn off extra lights */
for (i = lightsused +1; i <= prevused; i++) {
sprintf(lightlabel,"%d",i); /* This may not work - I may need to */
/* collect the tokens returned from */
/* from RiLightSource in a static */
/* array or something like that -smw */
RiIlluminate(lightlabel, RI_FALSE);
}
if (prevused < lightsused) prevused = lightsused;
}
mgri_setshader(mgshadefunc shader)
{
_mgc->astk->shader = shader;
mgri_appearance(_mgc->astk, APF_SHADING);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.