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

This is mgribshade.c in view mode; [Download] [Up]

#include "mgP.h"
#include "mgribP.h"
#include "mgribshade.h"
#include "mgribtoken.h"

/*
 * Notes:	Tossed mgrib_material, just use mgrib_appearance
 *		since shaders depend on both appearance and material 
 *		settings. (4/1/93 TMM)
 */
void
mgrib_appearance( struct mgastk *astk, int ap_mask, int mat_mask)
{
    Appearance *ap = &(astk->ap);
    Material *mat = &astk->mat;

    mrti(mr_section, "Interpreting Material", mr_NULL);

    if(mat_mask & MTF_DIFFUSE)
        mrti(mr_color, mr_parray, 3, &mat->diffuse, mr_NULL);

    if( (ap_mask & APF_TRANSP || mat_mask & MTF_ALPHA) && 
       ap->valid & APF_TRANSP && ap->flag & APF_TRANSP) {
        /* presumably, we want this here as well as per vertex opacity
         * specification
	 * 
	 * Actually, if the material alpha override bit is set, we
	 * don't output the per vertex opacity information, which
	 * would take precedence. 4/16/93 TMM
         */
        float alpha = astk->mat.alpha;
	mrti(mr_opacity, mr_array, 3, alpha, alpha, alpha, mr_NULL);
    }

    if(ap_mask & APF_SHADING || 
       (mat_mask & MTF_SPECULAR|MTF_SHININESS|MTF_Kd|MTF_Ka|MTF_Ks)) {

        float roughness = (mat->shininess)? 1.0/mat->shininess : 1.0;
	if(ap->shading == APF_CONSTANT) {
		mrti(mr_surface, mr_constant, mr_NULL);
	} else if(ap->shading == APF_FLAT) {
	    int shader;
	    /* determain shader */
	    if(_mgribc->shader==MG_RIBSTDSHADE) {
		shader = mr_plastic;
	    } else {
	        if(_mgc->space & TM_HYPERBOLIC) shader = mr_hplastic;
		else shader = mr_plastic;
	    }
	    /* define surface */
	    mrti(mr_shadinginterpolation, mr_constant,
		    mr_surface, shader, mr_Ka, mr_float, mat->ka,
		    mr_Kd, mr_float, mat->kd, mr_Ks, mr_float, mat->ks,
		    mr_specularcolor, mr_parray, 3, &(mat->specular),
		    mr_roughness, mr_float, roughness, mr_NULL);
	} else if(ap->shading == APF_SMOOTH) {
	    mrti(mr_shadinginterpolation, mr_string, "smooth",
		    mr_surface, mr_plastic, mr_Ka, mr_float, mat->ka,
		    mr_Kd, mr_float, mat->kd, mr_Ks, mr_float, mat->ks,
		    mr_specularcolor, mr_parray, 3, &(mat->specular),
		    mr_roughness, mr_float, roughness, mr_NULL);
	}
    }	
}

void
mgrib_lighting(struct mgastk *astk, int mask)
{
  LtLight *light;
  LmLighting *li = &astk->lighting;

  if (li->valid & mask & LMF_AMBIENT) {
      mrti(mr_section, "Interpreting Lights", mr_NULL);
      /* output the ambient light */
      mrti(mr_comment, "Ambient Light", mr_NULL);
      mrti(mr_lightsource, mr_ambientlight, mr_int, 0,
	   mr_lightcolor, mr_parray, 3, &(li->ambient), mr_NULL);
    }    
  /* We must be in global coordinate space to place lights correctly. */
  mrti(mr_transformbegin, mr_identity, mr_NULL);
  mgrib_lights( li->lights, astk );
  mrti(mr_transformend, mr_NULL);
}

/* In GL, we want unique light numbers. In RenderMan we want to re-use
light numbers, so we always start with light "1".  In GL, we define
then bind lights. Defining is expensive and we avoid it as much as
possible. In RenderMan, it's a one-step process. Also, once a light is
defined it cannot be deleted. Thus we might need to explicitly turn
off lights if we are replacing more lights with less lights. So we
keep track of how many lights we've used so far, and turn off the
extras when we need to.
1/13/92 TMM */

void mgrib_lights( LtLight *light, struct mgastk *astk ) 
{ 
  int i, lightsused; 
  static int prevused = 0;

  lightsused = 0;
  while (light) {
    ++lightsused;

    if (light->Private == 0) {
      /* this is a new light */
      light->Private = lightsused;
      light->changed = 1;
    }
    if (light->changed) {
      if (light->position.w == 0.0) {
	/* directional light */
	/* We used to output the lights as "to" instead of as "from".
	   This is like negating them, which is why we then did
	   explicitly negate them to get the right result!
	   So, leave the lights alone now. Do NOT negate them.
	   It's NOT about handedness of coordinate systems.
         */
	mrti(mr_comment, "Directional Light",
	     mr_lightsource, mr_distantlight, mr_int, light->Private,
	     mr_intensity, mr_float, light->intensity,
	     mr_lightcolor, mr_parray, 3, &(light->color),
	     mr_string, "to", mr_array, 3, 0.,0.,0., /* aim at origin */
	     mr_string, "from", mr_parray, 3, &(light->globalposition),
	     mr_NULL);
      } else {
	/* point light */
	mrti(mr_lightsource, mr_string, "pointlight", mr_int, light->Private,
	     mr_intensity, mr_float, light->intensity,
	     mr_lightcolor, mr_parray, 3, &(light->color),
	     mr_string, "from", mr_parray, 3, &(light->globalposition),
	     mr_NULL);
      }
      light->changed = 0;
    }
    light = light->next;
  }
  for (i = lightsused +1; i <= prevused; i++)
    mrti(mr_illuminate, mr_int, i, mr_int, 0, mr_NULL);
  if (prevused < lightsused) prevused = lightsused;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.