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.