ftp.nice.ch/pub/next/graphics/3d/geomview.1.4.1.s.tar.gz#/Geomview/src/lib/mg/ri/mgrishade.c

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.