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

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

#include "mg.h"
#include "mgP.h"
#include "mgribP.h"
#include "mgribshade.h"
#include "mgribtoken.h"
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

mgcontext * mgrib_ctxcreate(int a1, ...);
void	    mgrib_ctxset( int a1, ...  );
int	    mgrib_feature( int feature );
void	    mgrib_ctxdelete( mgcontext *ctx );
int	    mgrib_ctxget( int attr, void* valueptr );
int	    mgrib_ctxselect( mgcontext *ctx );
void	    mgrib_sync( void );
void	    mgrib_worldbegin( void );
void	    mgrib_worldend( void );
void	    mgrib_reshapeviewport( void );
void	    mgrib_identity( void );
void	    mgrib_transform( Transform T );
int	    mgrib_pushtransform( void );
int	    mgrib_poptransform( void );
void	    mgrib_settransform( Transform T );
int	    mgrib_pushappearance( void );
int	    mgrib_popappearance( void );
Appearance  *mgrib_setappearance( Appearance* app, int merge);
Appearance  *mgrib_getappearance( void );
int	    mgrib_setcamera( Camera* cam );
mgribcontext *mgrib_newcontext( mgribcontext *ctx );

extern void  mgrib_polygon();
extern void  mgrib_mesh();
extern void  mgrib_line();
extern void  mgrib_polyline();
extern void  mgrib_polylist();
extern void  mgrib_bezier();

void _mgrib_ctxset(int a1, va_list *alist);

WnWindow *mgribwindow(WnWindow *win);

struct mgfuncs mgribfuncs = {
  MGD_RIB,
  mgdevice_RIB,
  mgrib_feature,
  (mgcontext *(*)())mgrib_ctxcreate,
  mgrib_ctxdelete,
  (void (*)())mgrib_ctxset,
  mgrib_ctxget,
  mgrib_ctxselect,
  mgrib_sync,
  mgrib_worldbegin,
  mgrib_worldend,
  mgrib_reshapeviewport,
  mgrib_settransform,
  mg_gettransform,	/* Generic */
  mgrib_identity,
  mgrib_transform,
  mgrib_pushtransform,
  mgrib_poptransform,
  mgrib_pushappearance,
  mgrib_popappearance,
  mgrib_setappearance,
  mgrib_getappearance,
  mgrib_setcamera,
  mgrib_polygon,
  mgrib_polylist,
  mgrib_mesh,
  mgrib_line,
  mgrib_polyline,
  mg_quads,
  mgrib_bezier
  };

static mgribcontext *MGRIB;	/* For debugging */

int
mgdevice_RIB()
{
  _mgf = mgribfuncs;
  if (_mgc != NULL && _mgc->devno != MGD_RIB)
    _mgc = NULL;

  return(0);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_ctxcreate
 * Date:	Thu Jul 18 18:55:18 1991
 * Author:	mbp
 * Notes:	see mg.doc for rest of spec
 */
mgcontext *
mgrib_ctxcreate(int a1, ...)
{
  va_list alist;
  time_t timedate = (time_t)time(0);
    
  _mgc =
    (mgcontext*)(MGRIB = mgrib_newcontext( OOGLNewE(mgribcontext,
    	"mgrib_ctxcreate") ));

  /* Ensure some sensible default Window */
  WnSet(_mgc->win, WN_XSIZE, 300, WN_YSIZE, 200, WN_END);

  /* Default RIB1.0 structure info */
  sprintf(_mgribc->ribscene, "Generic RIB file");
  sprintf(_mgribc->ribcreator, "mgrib driver");
  sprintf(_mgribc->ribfor, getenv("USER"));
  sprintf(_mgribc->ribdate, ctime(&timedate));
  _mgribc->ribdate[24] = '\0'; /* remove the line feed */
  
  va_start(alist, a1);
  _mgrib_ctxset(a1, &alist);
  va_end(alist);
  return _mgc;
}

/*-----------------------------------------------------------------------
 * Function:	_mgrib_ctxset
 * Description:	internal ctxset routine
 * Args:	a1: first attribute
 *		*alist: rest of attribute-value list
 * Returns:	nothing
 * Author:	mbp
 * Date:	Fri Sep 20 11:08:13 1991
 * Notes:	mgrib_ctxcreate() and mgrib_ctxset() call this to actually
 *		parse and interpret the attribute list.
 */
void
_mgrib_ctxset(int a1, va_list *alist)
{
  int attr;

  for (attr = a1; attr != MG_END; attr = va_arg (*alist, int)) {
    switch (attr) {
    case MG_ApSet:
      {
	Appearance *ap;

	ap = _ApSet(NULL, va_arg(*alist, int), alist);
	mgrib_setappearance(ap, MG_MERGE);
	ApDelete(ap);
      }
      break;
    case MG_WnSet:
      _WnSet( _mgc->win, va_arg(*alist, int), alist);
      break;
    case MG_CamSet:
      _CamSet( _mgc->cam, va_arg(*alist, int), alist);
      break;
    case MG_APPEAR:
      mgsetappearance(va_arg(*alist, Appearance *), MG_SET);
      break;
    case MG_WINDOW:
      if (_mgc->win) WnDelete(_mgc->win);
      _mgc->win = va_arg(*alist, WnWindow*);
      RefIncr((Ref*) (_mgc->win));
      break;
    case MG_CAMERA:
      mgrib_setcamera( va_arg(*alist, Camera*) );
      break;
    case MG_SETOPTIONS:
      _mgc->opts |= va_arg(*alist, int);
    case MG_UNSETOPTIONS:
      _mgc->opts &= ~va_arg(*alist, int);
      break;
    case MG_SHOW:
      _mgc->shown = va_arg(*alist, int);
      break;
    case MG_PARENT:
      _mgc->parent = va_arg(*alist, mgcontext*);
      break;
    case MG_BACKGROUND:
      _mgc->background = *va_arg(*alist, ColorA*);
      break;
    case MG_ZNUDGE:
      /* for now, read nothing */
      va_arg(*alist, double);
      break;

    case MG_SPACE:   _mgc->space = va_arg(*alist, int); break;
    case MG_NDINFO:  _mgc->NDinfo = va_arg(*alist, void *); break;
    case MG_NDMAP:   _mgc->NDmap = va_arg(*alist, mgmapfunc); break;


    /* kind of RIB-specific */
    case MG_RIBFILE:
/*        if(_mgribc->rib) fclose(_mgribc->rib); */
	_mgribc->rib = va_arg(*alist, FILE*);
	break;

    /* really RIB-specific */
    case MG_RIBLINEMODE:
	_mgribc->line_mode = va_arg(*alist, int);
	break;
    case MG_RIBFORMAT:
	switch( va_arg(*alist, int) ) {
	case MG_RIBASCII:
	    _mgribc->render_device |= RMD_ASCII;
	    _mgribc->render_device &= ~RMD_BINARY; break;
	case MG_RIBBINARY:
	    _mgribc->render_device |= RMD_BINARY;
	    _mgribc->render_device &= ~RMD_ASCII; break;
	}
	break;
    case MG_RIBFILEPATH:
	if(_mgribc->rib) fclose(_mgribc->rib);
	strcpy(_mgribc->filepath, va_arg(*alist, char*));
	_mgribc->rib = fopen(_mgribc->filepath,"w+");
	break;
    case MG_RIBDISPLAY:
        _mgribc->display = va_arg(*alist, int);
        break;
    case MG_RIBDISPLAYNAME:
	strcpy(_mgribc->displayname, va_arg(*alist, char*));
        break;
    case MG_RIBBACKING:
        _mgribc->backing = va_arg(*alist, int);
	break;
    case MG_RIBSHADER:
        _mgribc->shader = va_arg(*alist, int);
	break;
    case MG_RIBSCENE:
    	strcpy(_mgribc->ribscene, va_arg(*alist, char*));
	break;
    case MG_RIBCREATOR:
    	strcpy(_mgribc->ribcreator, va_arg(*alist, char*));
	break;
    case MG_RIBFOR:
    	strcpy(_mgribc->ribfor, va_arg(*alist, char*));
	break;
    case MG_RIBDATE:
    	strcpy(_mgribc->ribdate, va_arg(*alist, char*));
	break;
    default:
    
    	OOGLError (0, "_mgrib_ctxset: undefined option: %d\n", attr);
    	return;
    	break;
    }
  }

  if (_mgc->shown && !_mgribc->born) {

    /* open the window */
    mgribwindow(_mgc->win);
    /* rib state is *not* in accordance with appearance state:
       don't set the appearance until worldbegin time */
  }
}


/*-----------------------------------------------------------------------
 * Function:	mgrib_ctxget
 * Description:	get a context attribute value
 * Args:	attr: the attribute to get
 *		value: place to write attr's value
 * Returns:	1 for success; -1 if attr is invalid
 * Author:	mbp
 * Date:	Fri Sep 20 11:50:25 1991
 * Notes:
 */
int
mgrib_ctxget(int attr, void* value)
{
#define VALUE(type) ((type*)value)

  switch (attr) {

  /* Attributes common to all MG contexts: */
  case MG_APPEAR:
    *VALUE(Appearance*) = &(_mgc->astk->ap);
    break;
  case MG_CAMERA:
    *VALUE(Camera*) = _mgc->cam;
    break;
  case  MG_WINDOW:
    if(_mgribc->born) {
    /* IT DOESN'T MAKE SENSE TO DO THIS, DOES IT? */
    }
    *VALUE(WnWindow*) = _mgc->win;
    break;
  case MG_PARENT:
    *VALUE(mgcontext*) = _mgc->parent;
    break;
  case MG_SETOPTIONS:
  case MG_UNSETOPTIONS:
    *VALUE(int) = _mgc->opts;
    break;
  case MG_BACKGROUND:
    *VALUE(ColorA) = _mgc->background;
    break;
  case MG_ZNUDGE:
    /* not implemented now */
    *VALUE(int) = 0;
  case MG_SPACE: *VALUE(int) = _mgc->space; break;
  case MG_NDINFO: *VALUE(void *) = _mgc->NDinfo; break;
  case MG_NDMAP:  *VALUE(mgmapfunc) = _mgc->NDmap; break;

  /* Attributes specific to RIB contexts: */
  case MG_RIBWINID:
    *VALUE(int) = _mgribc->win;
    break;
  case MG_RIBFILE:
    *VALUE(FILE*) = _mgribc->rib;
     break;

  /* Attributes really specific to RI contexts: */
  case MG_RIBLINEMODE:
     *VALUE(int) = _mgribc->line_mode;
	 break;
  case MG_RIBFORMAT:
     if(_mgribc->render_device & RMD_ASCII) *VALUE(int) = MG_RIBASCII;
     if(_mgribc->render_device & RMD_BINARY) *VALUE(int) = MG_RIBBINARY;
	 break;
  case MG_RIBFILEPATH:
     *VALUE(char *) = _mgribc->filepath;
	 break;
  case MG_RIBDISPLAY:
     *VALUE(int) = _mgribc->display;
	 break;
  case MG_RIBDISPLAYNAME:
     *VALUE(char *) = _mgribc->displayname;
	 break;
  case MG_RIBBACKING:
     *VALUE(int) = _mgribc->backing;
     break;
  case MG_RIBSHADER:
     *VALUE(int) = _mgribc->shader;
     break;
  case MG_RIBSCENE:
     *VALUE(char *) = _mgribc->ribscene;
     break;
  case MG_RIBCREATOR:
     *VALUE(char *) = _mgribc->ribcreator;
     break;
  case MG_RIBFOR:
     *VALUE(char *) = _mgribc->ribfor;
     break;
  case MG_RIBDATE:
     *VALUE(char *) = _mgribc->ribdate;
     break;
  default:
    OOGLError (0, "mgrib_ctxget: undefined option: %d\n", attr);
    return -1;

  }
  return 1;

#undef VALUE
}

/*-----------------------------------------------------------------------
 * Function:	mgribwindow
 * Description:	create a RIB window
 * Args:	*win: the WnWindow structure to realize
 * Returns:	win if success, NULL if not
 * Author:	wisdom, gunn
 * Date:	Fri Sep 20 11:56:31 1991
 * Notes:	makes the RI calls necessary to create a RIB "window"
 *		which is really a virtual window defining Format, Display,
 *		etc.
 */
WnWindow *
mgribwindow(WnWindow *win)
{
  WnPosition wp;
  int xsize, ysize, flag, reconstrain;
  char *name;
  char gver[80];
  double pxloc, pyloc, pxsize, pysize;
  char fullscene[280], fullcreator[280], fullfor[280], fulldate[280];

    /* RIB 1.0 structure comments */
    sprintf(fullscene,"Scene %s",_mgribc->ribscene);
    sprintf(fullcreator,"Creator %s",_mgribc->ribcreator);
    sprintf(fullfor,"For %s",_mgribc->ribfor);
    sprintf(fulldate,"CreationDate %s",_mgribc->ribdate);
    mrti(mr_header,"RenderMan RIB-Structure 1.0", mr_nl,
    	 mr_header, fullscene, mr_nl,
	 mr_header, fullcreator, mr_nl,
	 mr_header, fulldate, mr_nl,
	 mr_header, fullfor, mr_nl,
	 mr_header, "Frames 1", mr_nl,	/* always 1 frame*/
	 mr_NULL);

    /* options */
    if(_mgribc->shader && _mgribc->shadepath) {
	mrti(mr_header, "CapabilitiesNeeded ShadingLanguage", mr_nl,
	     mr_embed, "version 3.03", mr_nl,
	     mr_option, mr_string, "searchpath", mr_string, "shader",
		mr_nl, mr_embed, "[", mr_string, _mgribc->shadepath,
		mr_embed, "]", mr_nl, mr_nl, mr_NULL);
    } else {
        mrti(mr_embed, "version 3.03", mr_nl, mr_nl, mr_NULL);
    }
        
    /* set display characteristics...*/
    mrti(mr_display, mr_string, _mgribc->displayname, 
         (_mgribc->display == MG_RIBFRAME) ? mr_framebuffer : mr_file, 
         mr_rgb, mr_NULL);

    /* window size */
    WnGet(_mgc->win, WN_CURPOS, &wp);
    xsize = wp.xmax - wp.xmin + 1;
    ysize = wp.ymax - wp.ymin + 1;
    mrti(mr_format, mr_int, xsize, mr_int, ysize, mr_float, 1., mr_NULL);

    _mgribc->born = 1;
    return(win);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_ctxset
 * Description:	set some context attributes
 * Args:	a1, ...: list of attribute-value pairs
 * Returns:	nothing
 * Author:	mbp
 * Date:	Fri Sep 20 12:00:18 1991
 */
void mgrib_ctxset( int a1, ...  )
{
  va_list alist;

  va_start( alist, a1 );
  _mgrib_ctxset(a1, &alist);
  va_end(alist);
}


/*-----------------------------------------------------------------------
 * Function:	mgrib_feature
 * Description:	report whether mgrib device has a particular feature
 * Args:	feature: the feature to report on
 * Returns:	an int giving info about feature
 * Author:	wisdom
 * Date:	Tue Aug  3 15:38:05 CDT 1993
 * Notes:	-1 means the feature is not present.
 *
 */
int mgrib_feature( int feature )
{
  if(feature == MGF_BEZIER) return 1;
  return(-1);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_ctxdelete
 * Description:	delete a GL context
 * Args:	*ctx: context to delete
 * Returns:	nothing
 * Author:	slevy
 * Date:	Tue Nov 12 10:29:04 CST 1991
 * Notes:	Deleting the current context leaves the current-context
 *		pointer set to NULL.
 */
void mgrib_ctxdelete( mgcontext *ctx )
{
/*  if(_mgribc->rib) fclose(_mgribc->rib); */

  if(ctx->devno != MGD_RIB) {
    mgcontext *was = _mgc;
    mgctxselect(ctx);
    mgctxdelete(ctx);
    if(was != ctx)
	mgctxselect(was);
  } else {
    if(((mgribcontext *)ctx)->shadepath)
        free(((mgribcontext *)ctx)->shadepath);
    mg_ctxdelete(ctx);
    if(ctx == _mgc)
	_mgc = NULL;
  }
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_ctxselect
 * Description:	select a RIB context --- make it current
 * Args:	*ctx: the context to become current
 * Returns:	0 (why ???)
 * Author:	mbp, wisdom
 * Date:	Fri Sep 20 12:04:41 1991
 */
int
mgrib_ctxselect( mgcontext *ctx )
{
  if(ctx == NULL || ctx->devno != MGD_RIB) {
    return mg_ctxselect(ctx);
  }

  _mgc = ctx;
  MGRIB = (mgribcontext *)ctx;

  return(0);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_sync
 * Description:	sync
 * Returns:	nothing
 * Author:	wisdom
 * Date:	Mon Aug  2 18:05:41 CDT 1993
 * Notes:	sync with PRMAN not necessary
 */
void
mgrib_sync( void )
{}

/*-----------------------------------------------------------------------
 * Function:	mgrib_worldbegin
 * Description:	prepare to draw a frame
 * Returns:	nothing
 * Author:	wisdom, slevy, gunn
 * Date:	Sat Mar  7 16:28:35 GMT-0600 1992
 */
void
mgrib_worldbegin( void )
{
  static Transform cam2ri = {{1, 0,0,0}, {0,1,0,0}, {0,0,-1,0},{0,0,0,1}};
  int persp;
  float halfxfield, halfyfield, aspect, near, far, fov;
  WnWindow *win;
  int xsize, ysize;
  Transform T;
  WnPosition wp;
  char str[256];
  float focallen;
  HPoint3 look;
  Point3 lookat;

    /* first, check to see if we need to open the default rib file    */
    /* IT'S NOW POSSIBLE THAT THIS WON'T GET SENT TO A FILE (streams) */
    /* IN WHICH CASE IT WOULD BE WRONG TO OPEN A FILE. MOVE THIS!!    */
    if(!_mgribc->rib)
    	_mgribc->rib = fopen(DEFAULT_RIB_FILE, "w+");
	
    /* interpret options...(none exist now) */

    /* this will make sure there's nothing left in the rib file */
    /* we cannot use ftruncate because it generates an error on sgi */
    /*ftruncate(fileno(_mgribc->rib), 0);*/
    if (lseek(1, (off_t)0, 0) == (off_t)0 && ftruncate(1, (off_t)0) == -1)
	perror("ftruncate");
    	 
    mg_worldbegin();
    mg_findcam();

    /* Camera is at (in its own coordinates)  (0,0,0).
     * Looking toward vector (0,0,-1)
     * nominally looking at a point (0,0,-focallen)
     */
    CamGet(_mgc->cam, CAM_FOCUS, &focallen);
    look.x = look.y = 0;  look.z = -focallen;   look.w = 1;
    /* Transform to world coordinates */
    HPt3TransPt3(_mgc->C2W, &look, &lookat);    
    /* Now the camera is at _mgc->cpos (this is a Point3), */
    /* looking at lookat (another Point3) */
   
    /* interpret camera ...*/
    CamGet( _mgc->cam, CAM_NEAR, &near);
    CamGet( _mgc->cam, CAM_FAR, &far);
    mrti(mr_clipping, mr_float, near, mr_float, far, mr_NULL);
    CamGet( _mgc->cam, CAM_PERSPECTIVE, &persp);
    mrti(mr_projection, mr_string, persp?"perspective":"orthographic", mr_NULL);
    CamGet( _mgc->cam, CAM_ASPECT, &aspect );
    CamGet( _mgc->cam, CAM_HALFYFIELD, &halfyfield );
    halfxfield = halfyfield * aspect;
    mrti(mr_screenwindow, mr_float, -halfxfield, mr_float, halfxfield,
    	mr_float, -halfyfield, mr_float, halfyfield, mr_NULL);
    CamGet( _mgc->cam, CAM_FOV, &fov);
    sprintf(str, "Field of view %g", fov);
    mrti(mr_comment, str, mr_NULL);
    mrti(mr_framebegin, mr_int, 1, mr_nl, mr_NULL);
    
    sprintf(str, "CameraOrientation %.4g %.4g %.4g %.4g %.4g %.4g",
    	    _mgc->cpos.x,_mgc->cpos.y,_mgc->cpos.z,
	    lookat.x,lookat.y,lookat.z);
    mrti(mr_header, str, mr_nl, mr_NULL);
    mrti(mr_identity, mr_NULL);
    mgrib_printmatrix(cam2ri);

    mgrib_printmatrix(_mgc->W2C);

    /* Lighting Hack (*WAY* OBSOLETE)
     * mg_globallights(_mgc->astk->lighting.lights, 1);
     * if ( (_mgc->astk->lighting.lights != NULL) &&
     * (_mgc->astk->ap.shading != APF_CONSTANT))
     * mgrib_lights(_mgc->astk->lighting.lights, _mgc->astk);
     */

    /* RiWorldBegin...*/
    mrti(mr_nl, mr_nl, mr_worldbegin, mr_NULL);

    /* if the option is selected, add the background */
    if(_mgribc->backing == MG_RIBDOBG) {
        float halfxbg = far * halfxfield, halfybg = far * halfyfield;
	float farz = -.99 * far;
	Point3 bg[4];

	bg[0].x = -halfxbg; bg[0].y = -halfybg; bg[0].z = farz;
	bg[1].x = -halfxbg; bg[1].y =  halfybg; bg[1].z = farz;
	bg[2].x =  halfxbg; bg[2].y =  halfybg; bg[2].z = farz;
	bg[3].x =  halfxbg; bg[3].y = -halfybg; bg[3].z = farz;
	
	mrti(mr_comment, "simulate background color via polygon", mr_NULL);
	mrti(mr_attributebegin, mr_NULL);
	mgrib_printmatrix(_mgc->C2W);
	mrti(mr_surface, mr_constant, mr_NULL);
	mrti(mr_color, mr_parray, 3, &_mgc->background, mr_NULL);
	mrti(mr_polygon, mr_P, mr_parray, 4*3, bg, mr_NULL);
	mrti(mr_attributeend, mr_NULL);
    }			

    /* bring ri state into accordance with appearance state */
  
    {
      Appearance *ap = ApCopy( &(_mgc->astk->ap), NULL );
      mgrib_setappearance( ap, MG_SET );
      ApDelete(ap);
    }

    /* NOW DONE BY mg_worldbegin()
     *CamView(_mgc->cam, _mgribc->W2S);
     *TmTranslate(T, 1.0, 1.0, 0);
     *TmConcat(_mgribc->W2S,T, _mgribc->W2S);
     */
     

    /* NOW DONE BY mg_worldbegin()
     *mgrib_ctxget(MG_WINDOW, &win);
     *WnGet(_mgc->win, WN_CURPOS, &wp);
     *xsize = wp.xmax - wp.xmin + 1;
     *ysize = wp.ymax - wp.ymin + 1;
     *
     *TmScale(T, (double)xsize*.5, (double)ysize*.5, 1.0);
     *TmConcat(_mgribc->W2S,T, _mgribc->W2S);
     *
     *TmCopy(_mgribc->W2S, _mgribc->O2S);
     */
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_worldend
 * Description:	finish drawing a frame
 * Returns:	nothing
 * Author:	wisdom
 * Date:	Sat Mar  7 14:47:40 GMT-0600 1992
 */
void
mgrib_worldend( void )
{
    unsigned char *buffer = tokenbuffer;
    mrti(mr_worldend, mr_nl, mr_NULL);
    mrti(mr_frameend, mr_nl, mr_NULL);
    /* now flush the buffer, if appropriate */
    /* mgrib_flushbuffer(); NOW DONE AT HIGHER LEVEL */

}

/*-----------------------------------------------------------------------
 * Function:	mgrib_reshapeviewport
 * Description:	adjust to a new window size
 * Returns:	nothing
 * Author:	mbp
 * Date:	Fri Sep 20 12:08:30 1991
 * Notes:	adjusts both GL's internal viewport setting, as well as
 *		MG context WnWindow's current position and camera's
 *		aspect ratio.
 */
void
mgrib_reshapeviewport( void )
{
    WnWindow *win;
    WnPosition wp;
    int xsize, ysize;

    mgrib_ctxget(MG_WINDOW, &win);	/* Get window; force it to ask
					 * NeXTStep how big the window is
					 */
    WnGet(win, WN_CURPOS, &wp);
    xsize = wp.xmax - wp.xmin + 1;
    ysize = wp.ymax - wp.ymin + 1;

    CamSet(_mgc->cam, CAM_ASPECT, (double)xsize/(double)ysize, CAM_END);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_identity
 * Description:	set the current object xform to identity
 * Returns:	nothing
 * Author:
 * Date:
 * Notes:
 *
 */
void
mgrib_identity( void )
{
    mgrib_settransform( TM_IDENTITY );
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_transform
 * Description:	premultiply the object xform by T
 * Args:	T
 * Returns:	nothing
 * Author:	mbp
 * Date:	Fri Sep 20 12:24:57 1991
 * Notes:	We use the GL ModelView matrix stack, not the mgcontext's
 *		stack.
 *
 */
void
mgrib_transform( Transform T )
{
    mg_transform(T);
    mgrib_printmatrix(T);
    TmConcat(_mgc->xstk->T, _mgc->W2S, _mgc->O2S);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_pushtransform
 * Description:	push the object xform stack
 * Returns:	nothing (???)
 * Author:	mbp
 * Date:	Fri Sep 20 12:25:43 1991
 * Notes:	We use the GL ModelView matrix stack, not the mgcontext's
 *		stack.
 *
 *		This assumes we're already in MVIEWING mode.
 */
int
mgrib_pushtransform( void )
{
    mg_pushtransform();
    mrti(mr_transformbegin, mr_NULL);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_popransform
 * Description:	pop the object xform stack
 * Returns:	nothing (???)
 * Author:	mbp
 * Date:	Fri Sep 20 12:25:43 1991
 * Notes:	We use the GL ModelView matrix stack, not the mgcontext's
 *		stack.
 *
 *		This assumes we're already in MVIEWING mode.
 */
int
mgrib_poptransform( void )
{
    mg_poptransform();
    mrti(mr_transformend, mr_NULL);
    TmConcat(_mgc->xstk->T, _mgc->W2S, _mgc->O2S);
}


/*-----------------------------------------------------------------------
 * Function:	mgrib_settransform
 * Description:	set the current object xform to T
 * Args:	T
 * Returns:	nothing
 * Author:	mbp
 * Date:	Fri Sep 20 12:29:43 1991
 * Notes:	
 */
void
mgrib_settransform( Transform T )
{
    mrti(mr_identity, mr_NULL);
    mg_settransform( T );
    TmConcat(_mgc->xstk->T, _mgc->W2S, _mgc->O2S);
    if(T != TM_IDENTITY)
	mgrib_printmatrix(T);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_pushappearance
 * Description:	push the MG context appearance stack
 * Returns:	nothing
 * Author:	mbp
 * Date:	Fri Sep 20 12:54:19 1991
 */
int
mgrib_pushappearance( void )
{
  mg_pushappearance();
  mrti(mr_comment, "push appearance", mr_attributebegin, mr_NULL);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_popappearance
 * Description:	pop the MG context appearance stack
 * Returns:	nothing
 * Author:	
 * Date:	
 * Note:	Note that we do not have to do anything besides
 *		AttributeEnd, because the RenderMan driver retains
 *		the previous state information. 1/13/92 TMM
 */
int
mgrib_popappearance( void )
{
  register struct mgastk *mastk = _mgc->astk;
  register struct mgastk *mastk_next;

  if (! (mastk_next=mastk->next)) {
    OOGLError(0, "mggl_popappearance: appearance stack has only 1 entry.\n");
    return;
  }

  mrti(mr_comment, "pop appearance", mr_attributeend, mr_NULL);
  mg_popappearance();

}

/*-----------------------------------------------------------------------
 * Function:	mgrib_setappearance
 * Author:	munzner, mbp, wisdom
 * Date:	Wed Aug  7 01:08:07 1991
 * Notes:	Tossed mgrib_material, just use mgrib_appearance
 *		since shaders depend on both appearance and material 
 *		settings. (4/1/93 TMM)
 */
Appearance *
mgrib_setappearance( Appearance* ap, int mergeflag )
{
  int changed, mat_changed, lng_changed;
  struct mgastk *mastk = _mgc->astk;
  Appearance *ma;
  static float nullarray[] = { 0.0 };

  ma = &(mastk->ap);

  /* Decide what changes */
  if (mergeflag == MG_MERGE) {
    changed = ap->valid & ~ma->override;
    mat_changed =
      ap->mat ? ap->mat->valid & ~ma->mat->override : 0;
    lng_changed =
      ap->lighting ? ap->lighting->valid & ~ma->lighting->override : 0;
  }
  else {
    changed = ap->valid;
    mat_changed = ap->mat ? ap->mat->valid : 0;
    lng_changed = ap->lighting ? ap->lighting->valid : 0;
  }

  mg_setappearance( ap, mergeflag );

  /* here is where everything gets set (sort of) */

  if(_mgribc->born) {
    mgrib_appearance( mastk, changed, mat_changed);

    /* interpret lights ... */
    mgrib_lighting(_mgc->astk, lng_changed);
  }

}


/*-----------------------------------------------------------------------
 * Function:	mgrib_getappearance
 * Description:	return a ptr to current appearance
 * Returns:	ptr to current appearance
 * Author:	mbp
 * Date:	Fri Sep 20 13:00:41 1991
 * Notes:	Applications should not modify the returned appearance
 *		in any way.
 */
Appearance *
mgrib_getappearance()
{
    return &(_mgc->astk->ap);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_setcamera
 * Description:	set the context's camera (pointer)
 * Args:	*cam: the camera to use
 * Returns:	nothing
 * Author:	mbp
 * Date:	Fri Sep 20 13:07:31 1991
 * Notes:	The context stores a pointer to the camera, not a copy
 *		of it.
 */
int
mgrib_setcamera( Camera* cam )
{
  if (_mgc->cam) CamDelete(_mgc->cam);
  _mgc->cam = cam;
  RefIncr((Ref*) cam);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_newcontext
 * Description:	initialize a new mgricontext structure
 * Args:	*ctx: the struct to initialize
 * Returns:	ctx
 * Author:	mbp
 * Date:	Fri Sep 20 13:11:03 1991
 */
mgribcontext *
mgrib_newcontext( mgribcontext *ctx )
{
  static char stdshaderpaths[] =
	".:shaders:/usr/local/prman/prman/lib/shaders:/NextLibrary/Shaders";

  char *geomdata = getenv("GEOMDATA");

  mg_newcontext(&(ctx->mgctx));
  ctx->mgctx.devfuncs = &mgribfuncs;
  ctx->mgctx.devno = MGD_RIB;
  ctx->mgctx.astk->ap_seq = 1;
  ctx->mgctx.astk->mat_seq = 1;
  ctx->mgctx.astk->light_seq = 1;
  ctx->born = 0;
  ctx->rib = NULL;
  ctx->backing = MG_RIBDOBG;
  ctx->shader = MG_RIBSTDSHADE;
  ctx->shadepath = NULL;		/* should add context field */
  if(geomdata) {
    char path[512];
    sprintf(path, "%s:%s/shaders", stdshaderpaths, geomdata);
    ctx->shadepath = strdup(path);
  }

  /* initalize the token interface */
  if(!tokenbuffer) mrti_init();
  mrti_reset();

  ctx->render_device = RMD_ASCII;
  ctx->line_mode = MG_RIBCYLINDER;

  return ctx;
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_findctx
 * Description: Given a GL window ID, returns the associated mg context.
 * Returns:	mgcontext * for success, NULL if none exists.
 * Author:	slevy
 * Date:	Mon Nov 11 18:33:53 CST 1991
 * Notes:	This is a public routine.
 */
mgcontext *
mgrib_findctx( long winid )
{
  register struct mgcontext *mgc;

  for(mgc = _mgclist; mgc != NULL; mgc = mgc->next) {
    if(mgc->devno == MGD_RIB && ((mgribcontext *)mgc)->win == winid)
	return mgc;
  }
  return NULL;
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_flushbuffer
 * Description: flushed tokens from buffer to a file
 * Returns:	nothing
 * Author:	wisdom
 * Date:	Mon Jul 26 12:35:45 CDT 1993
 * Notes:	This is a public routine, prototyped in mgrib.h
 */
void
mgrib_flushbuffer()
{
    unsigned char *buffer = tokenbuffer;
    /* do we even want a buffer anymore? why? */
    if(!_mgribc->rib)
    	_mgribc->rib = fopen(DEFAULT_RIB_FILE, "w+");
    while(buffer<ptr) putc(*(buffer++), _mgribc->rib);
    fflush(_mgribc->rib);
    mrti_reset(_mgribc->rib);
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_terminatebuffer
 * Description: NULL terminates the tokenbuffer, required to support
 		NeXTs render panel 
 * Returns:	nothing
 * Author:	wisdom
 * Date:	Mon Jul 26 12:35:45 CDT 1993
 * Notes:	This is a public routine, prototyped in mgrib.h
 */
void
mgrib_terminatebuffer()
{
    *(ptr++) = 0;
}

/*-----------------------------------------------------------------------
 * Function:	mgrib_tokenbuffer
 * Description: returns through indirection the tokenbuffer an size 
 * Returns:	char pointer to tokenbuffer
 * Author:	wisdom
 * Date:	Mon Jul 26 12:35:45 CDT 1993
 * Notes:	This is a public routine, prototyped in mgrib.h
 */
void
mgrib_tokenbuffer(char **buffer, int *size)
{
    *buffer = (char *)tokenbuffer;
    *size = ptr - tokenbuffer;
}

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