/*
 * Copyright (C) 1997-2009, R3vis Corporation.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
 *
 * Original Contributor:
 *   Wes Bethel, R3vis Corporation, Marin County, California
 *   http://www.r3vis.com/
 * Additional Contributor(s):
 *
 * The OpenRM project is located at http://openrm.sourceforge.net/.
 */

/*
 * $Id: rmtypes.h,v 1.20 2008/11/23 15:07:26 wes Exp $
 * Version: $Name: v180-alpha-02 $
 * $Revision: 1.20 $
 * $Log: rmtypes.h,v $
 * Revision 1.20  2008/11/23 15:07:26  wes
 * Changes to RMnode: children pointers are now held/managed in an
 * RMarray rather than an RMnode * inside the node. This change will
 * allow realloc's to occur using a chunking strategy that is part
 * of the RMarray
 *
 * Revision 1.19  2007/05/14 15:32:09  wes
 * RMarray -- changed int counts to size_t's
 *
 * Revision 1.18  2005/06/26 18:47:12  wes
 * Added glAttrib state mask stack to RMpipe to aid in state tracking.
 *
 * Revision 1.17  2005/05/28 16:26:34  wes
 * Added pickEnable attribute to RMnodes, and function prototypes for
 * rmNodeSetPickEnable and rmNodeGetPickEnable
 *
 * Revision 1.16  2005/04/27 03:34:10  wes
 * Fix up declarations for multitexturing functions.
 *
 * Revision 1.15  2005/02/27 19:32:55  wes
 * Added support for application supplied texture object IDs and display lists.
 *
 * Revision 1.14  2005/02/24 16:16:37  wes
 * Added support for fbClears to be set at the RMpipe level. Apps can
 * still set them at the RMnode level if desired for fine-grained control.
 *
 * Revision 1.13  2005/02/19 16:47:24  wes
 * Distro sync and consolidation.
 *
 * Revision 1.12  2005/01/23 17:17:34  wes
 * Copyright update to 2005.
 * Updates to support use of extensions: multitexturing on all platforms,
 * 3d texturing (for volume rendering support) on Win32
 *
 * Revision 1.11  2004/03/10 01:48:27  wes
 * Added prototype for rmIndexedQuadStrip draw routine.
 *
 * Revision 1.10  2004/02/23 03:04:29  wes
 * New primitives: RM_QUAD_STRIP, RM_INDEXED_TRIANGLES, RM_INDEXED_QUADS,
 * RM_INDEXED_TRIANGLE_STRIP.
 *
 * Revision 1.9  2004/01/17 04:06:42  wes
 * Updated Copyright line for 2004.
 *
 * Revision 1.8  2003/12/01 02:13:37  wes
 * Additions to support constate-rate rendering on Unix and Win32.
 *
 * Revision 1.7  2003/11/22 00:53:52  wes
 * Changes to support RMtextures being shared when assigned as scene parameters
 * to properly implement instancing.
 *
 * Revision 1.6  2003/11/05 15:36:54  wes
 * Added RMtime struct.
 *
 * Revision 1.5  2003/04/05 14:15:49  wes
 * Added comments explaining role of some RMpipe fields.
 *
 * Revision 1.4  2003/02/14 00:15:32  wes
 * Added CR-specific structure to the RMpipe, used to hold CR-specific things.
 *
 * Revision 1.3  2003/02/02 17:50:55  wes
 * Added bounding boxes to RMprimitives, as a supplement to node-level bboxes.
 * The RMprimitive level bboxes are needed for the retained-mode CR work.
 *
 * Revision 1.2  2003/02/02 02:07:14  wes
 * Updated copyright to 2003.
 *
 * Revision 1.1.1.1  2003/01/28 02:15:23  wes
 * Manual rebuild of rm150 repository.
 *
 * Revision 1.18  2003/01/27 05:04:27  wes
 * Changes to RMpipe API and initialization sequence to unify GLX, WGL and CR
 * platforms w/o too much disruption to existing apps.
 *
 * Revision 1.17  2003/01/11 18:43:28  wes
 * Added global control over display list use at the RMpipe level with
 * new routines rmPipeSetDisplayListEnable() and rmPipeGetDisplayListEnable().
 *
 * Revision 1.16  2002/12/31 00:56:21  wes
 * Cleaned up arch-specific portions of RMpipe to support Chromium.
 *
 * Revision 1.15  2002/12/04 14:50:30  wes
 * Cleanup SGI compiles.
 *
 * Revision 1.14  2002/09/02 23:49:27  wes
 * Modifications for Win32 to support dynamic object pools.
 *
 * Revision 1.13  2002/08/29 22:21:13  wes
 * Massive upgrade to accommodate dynamic object reallocation within
 * the component manager, and within the context cache. Use the
 * debug #define DEBUG_LEVEL DEBUG_REALLOC_TRACE to get a printf
 * whenever a realloc occurs. With this upgrade, there are no
 * OpenRM limits on the size of the scene graph. There will be external
 * limits, such as the amount of RAM and the amount of space available
 * to your OpenGL implementation.
 *
 * Revision 1.12  2002/08/17 15:18:43  wes
 * Modified node struct to accommodate the render order callback.
 *
 * Revision 1.11  2002/06/02 15:19:23  wes
 * Added RMstateCache code to help eliminate the number of state changes
 * made during the render traversal. The RMstateCache tracks
 * the actual OpenGL rendering state w/o the need for querying OpenGL
 * directly, and  is queried by draw code that then decides if any
 * real state changes are required given the configuration of data
 * within an RMprimitive.
 *
 * Revision 1.10  2002/04/30 19:42:33  wes
 * Updated copyright dates.
 *
 * Revision 1.9  2001/10/15 00:17:38  wes
 * Added two new fog-related fields to the RMstate struct.
 *
 * Revision 1.8  2001/07/15 17:21:20  wes
 * Removed dead code.
 *
 * Revision 1.7  2001/03/31 17:13:59  wes
 * v1.4.0-alpha-2 checkin
 *
 * Revision 1.6  2000/12/03 23:20:22  wes
 * Thread-safety mods.
 *
 * Revision 1.5  2000/09/02 19:26:21  wes
 * Updated comments inside code.
 *
 * Revision 1.4  2000/05/17 14:31:19  wes
 * Added rmPolys() (thanks to Matt and Todd at VRCO).
 *
 * Revision 1.3  2000/04/20 17:41:46  wes
 * Minor CVS tag changes.
 *
 * Revision 1.2  2000/04/20 16:30:24  wes
 * Added copyright info.
 *
 * Revision 1.1.1.1  2000/02/28 21:29:40  wes
 * OpenRM 1.2 Checkin
 *
 * Revision 1.1.1.1  2000/02/28 17:18:48  wes
 * Initial entry - pre-RM120 release, source base for OpenRM 1.2.
 *
 */

#ifndef _rmtypes_h
#define _rmtypes_h

#ifdef RM_WIN
#include <sys/types.h>
/* why can't MS use standard type definitions?? */
typedef _off_t off_t;
#endif

#include <rm/rmthread.h>
#include <rm/rmcmpmgr.h>

#ifndef GLAPIENTRY

#ifdef RM_WIN
#define GLAPIENTRY __stdcall
#endif
#ifdef RM_X
#define GLAPIENTRY
#endif

#endif

/* constants and limits */
#define MAX_VIS_CMAP_ENTRIES	256
#define RMV_DEFAULT_MAP_SIZE	256
#define OBJECT_NAME_LENGTH	64

#ifdef __cplusplus
extern "C" {
#endif

/* color types [4] */
typedef struct RMcolor1D
{
    float lum;
} RMcolor1D;

typedef struct RMcolor2D
{
    float lum, alpha;
} RMcolor2D;

typedef struct RMcolor3D
{
    float r, g, b;
} RMcolor3D;

typedef struct RMcolor4D
{
    float r, g, b, a;
} RMcolor4D;

/* vertex types [3] */
typedef struct RMvertex2D
{
    float x, y;
} RMvertex2D;

typedef struct RMvertex3D
{
    float x, y, z;
} RMvertex3D;

typedef struct RMvertex4D
{
    float x, y, z, w;
} RMvertex4D;

typedef struct RMmatrix
{
    float m[4][4];
} RMmatrix;

typedef struct RMarray
{
    size_t  nItems; 	   /* # of items currently in array */
    size_t  currentArraySize;  /* current size of array. should be >= nItems */
    size_t  elementSize; 	   /* size in bytes of each array element  */
    size_t  chunkSize; 	/* realloc size is chunkSize * elementSize bytes */
    void *data;
} RMarray;

/* 32 bit cache key */
typedef unsigned int RMcacheKey;
#define RM_CACHEKEY_UNINITIALIZED_VALUE (unsigned int)(-1)

#if 0
/* 64 bit cache key */
typedef unsigned long RMcacheKey;
#endif

typedef struct RMinternalMarker2D
{
    int         npts;
    int         gl_begin_flag;
    RMvertex2D *vlist;
} RMinternalMarker2D;

typedef struct RMvisMap
{
    int   nentries;
    float r[MAX_VIS_CMAP_ENTRIES];
    float g[MAX_VIS_CMAP_ENTRIES];
    float b[MAX_VIS_CMAP_ENTRIES];
    float a[MAX_VIS_CMAP_ENTRIES];
    float transfer_min, transfer_max;
} RMvisMap;

typedef struct RMbitmap
{
    int            w, h;
    int            bytes_per_scanline;
    int            pbsize;
    unsigned char *pixeldata;
} RMbitmap;

typedef struct RMimage
{
    /* configuration */
    int    ndims;		/* 2 or 3, set implicitly by user */
    int    w, h, d;		/* set by user */
    RMenum image_format;	/* set by user: RM_IMAGE_RGB, etc. */
    RMenum image_type;		/* set by user: RM_IMAGE_BYTE, etc. */
    float  xzoom, yzoom;	/* for 2d images only, user supplied, default 1.0, 1.0 */

    /* pixel data */
    RMenum copy_flag;		 /* set by user */
    void  *pixeldata;		 /* set by user */
    void (*appfreefunc)(void *); /* set by user */

    /* colormap */
    RMvisMap *vismap;		 /* set by user, default NULL */

    /* scale & bias */
    float scale, bias;

    /* internals, private */
    int          bytes_per_component; /* computed by RM */
    int          bytes_per_scanline;  /* computed by RM */
    int          elements;	      /* computed by RM */
#if 0
    /* display list stuff removed 10/5/2000 */
    int          d1;
    RMenum       dirty_flag;
#endif
    unsigned int pbsize;

    /* internal, component manager */
    int          compListIndx;
    
    /* internal, context cache key */
    RMcacheKey   cacheKey;
} RMimage;

typedef struct RMcamera2D
{
    float xmin, ymin, xmax, ymax;  /* defines extents of camera (like a viewport, but in R2 world coords) */
    float aspect_ratio;
} RMcamera2D;

typedef struct _RMStereoCameraControls
{
    void (*preframe_leftchannel_func)();
    void (*preframe_rightchannel_func)();
} _RMStereoCameraControls;

typedef struct RMcamera3D
{
    /* camera points */
    RMvertex3D eye;
    RMvertex3D at;
    RMvertex3D up;

    float  hither, yon; 		/* near & far */
    float  fov;				/* field of view angle in degrees in the Y direction */
    float  aspect;			/* aspect ratio (width / height) --> field of view angle in X direction */
    RMenum projection;			/* may be RM_PROJECTION_PERSPECTIVE or RM_PROJECTION_ORTHOGRAPHIC */
    RMenum isStereo;			/* flag for stereo (RM_TRUE or RM_FALSE) */
    float  degrees_eye_separation;	/* for stereo cameras only */
    float  focalDistance;		/* for stereo cameras only */
} RMcamera3D;

typedef struct RMtextProps
{
    int    fontEnum;		/* one of RM_FONT_SERIF,RM_FONT_SANS, RM_FONT_MONO, RM_FONT_SYMBOL */
    RMenum    italicEnum;		/* RM_TRUE or RM_FALSE */
    RMenum    boldEnum;		/* RM_TRUE or RM_FALSE */
    int    sizeEnum; 		/* enum of RM_FONT_XXS, RM_FONT_XS, RM_FONT_S, RM_FONT_M, RM_FONT_L, RM_FONT_XL, RM_FONT_XXL */
    RMenum hJustify, vJustify;
    int    listbase;		/* OpenGL dislay list base (computed by RM at runtime) */
    int    listoffset;		/* OpenGL display list stuff (computed by RM at runtime) */
    void  *fontinfo;

    int    compListIndx;
} RMtextProps;

typedef struct _bounding_box
{
    RMvertex3D min;
    RMvertex3D max;
} _bounding_box;

typedef struct RMclipPlane
{
    RMenum     enabled;		/* RM_TRUE, RM_FALSE */
    RMvertex3D point;
    RMvertex3D normal;		/* (point, normal) parametrization */	
   float       a, b, c, d;	/* plane equation */
} RMclipPlane;

typedef struct RMlight
{
   /* individual light ala OpenGL Light (see glLight) */
    RMenum     ltype;			/* RM_LIGHT_POINT, RM_LIGHT_DIRECTIONAL, RM_SPOT */
    RMcolor4D  ambientLightColor;
    RMcolor4D  diffuseLightColor;
    RMcolor4D  specularLightColor;
    RMvertex3D lightXYZ;		/* position for point and spot lights, direction for directional light sources */
    float      spotCutoff;		/* [0.0, 90.0] degrees */
    float      spotExponent;		/* default = 0.0, higher numbers produce more focused spots */
    RMvertex3D spotDirection;
    float      constantAttenuation;
    float      linearAttenuation;
    float      quadraticAttenuation;
    RMenum     enabled;			/* RM_TRUE or RM_FALSE */
} RMlight;

typedef struct RMlightModel
{
    /* light model parms ala OpenGL Light Model (see glLightModel) */
    RMcolor4D globalAmbient;
    GLenum    twoSideEnable;
    GLenum    localViewerEnable;
} RMlightModel;

typedef struct RMtexture
{
    RMimage   *images[RM_MAX_MIPMAPS];
    GLuint    *appTextureID; 	        /* these two could go in a union
					 since both are not simultaneously usable. */

    int       dims;			/* 1, 2 or 3d texture */
    int       nmipmaps;			/* number of mipmaps associated w/this texture */

    /* flags for OpenGL */
    GLenum    mag_filter_mode;		/* for GL_TEXTURE_MAG_FILTER */
    GLenum    min_filter_mode;		/* for GL_TEXTURE_MIN_FILTER */
    GLenum    wrap_mode;		/* applied to each of u, v, w */

    /* OpenGL has extra options for texel storage modes */
    GLenum    *oglTexelFormat;		/* GL_RGBA, GL_RGB, etc. default is GL_RGBA */

    /* environment modes */
    GLenum     envMode;			/* see man glTexEnv */
    RMcolor4D *blendColor;		/* see man glTexEnv */

    int        borderWidth;		/* texture border */

    /* residency status currently not used. */
    RMenum     residency_status;	/* internal: RM_TRUE or RM_FALSE */

    /* for the component manager */
    int        compListIndx;
    
    /* internal, context cache keys for texture IDs and texture data */
    RMcacheKey  cacheKeyID;
    RMcacheKey  cacheKeyData;

    /* reference counting - indicates whether or not a shared texture is
       assigned as a scene parameter to an RMnode */
    int         refCount;
} RMtexture;

typedef struct RMfog
{
    GLenum    fogMode;		/* GL_LINEAR, GL_EXP or GL_EXP2, def GL_LINEAR */
    GLfloat   fogDensity;	/* default = 1.0 */
    GLfloat   fogStart;		/* default is 0.0 */
    GLfloat   fogEnd;		/* default is 1 */
    RMcolor4D fogColor;		/* default is 0,0,0,0 */
} RMfog;

typedef struct RMstate
{
    RMmatrix      model;		/* model transformations */
    RMmatrix      view;			/* viewing transformations */
    RMmatrix      modelView;		/* combined model & view (OGL style) */
    RMmatrix      projection;		/* projection matrix */
    RMmatrix      composite;	        /* model*view*projection */
    RMmatrix      pick;			/* pick matrix */
    RMmatrix      textureMatrix;	/* texture matrix */
    RMmatrix      projection_inverse;	/* inverse of the concatenated view & projection matrices  (?) */
    RMmatrix      vpm;			/* viewport matrix - from NDC to window */
    float         vp[4];		/* (x, y) VP location + (w, h) VP width & height */
    float         aspect_ratio; 
    float         focal_length; 
    int           w, h;			/* window width & height */
    RMenum        rendermode;
    RMenum        renderpass;
    RMenum        renderPassDims;       /* to distinguish between 3D/2D traversals */
    RMenum        which_channel;	/* used */
    RMtexture    *texture;		/* current texture */
    int           texture_mode;		/* if current texture, GL_TEXTURE_2D, etc. */
    int           attrib_stack_depth;	/* current attribute stack depth */
    
    /* material properties */
    RMcolor4D     ambient;
    RMcolor4D     diffuse;
    RMcolor4D     specular;
    RMcolor4D     emissive;
    RMcolor4D     unlit_color;
    float         specular_exponent;
    float         opacity;

    /* line & point style */
    float         pointsize;
    RMenum        linewidth;
    RMenum        linestyle;

    /* render mode parms */
    RMenum        shademodel;
    
    /* polygon face properties */
    RMenum        poly_mode_face;
    RMenum        poly_mode_drawstyle;
    RMenum        cull_mode;		/* cull faces? [RM_CULL_NONE, RM_CULL_FRONT, RM_CULL_BACK, RM_CULL_FRONT_AND_BACK] */
    RMenum        front_face;   	/* vertex winding? [RM_CCW, RM_CW] */

    /* clip planes */
    RMclipPlane  *cp0;
    RMclipPlane  *cp1;
    RMclipPlane  *cp2;
    RMclipPlane  *cp3;
    RMclipPlane  *cp4;
    RMclipPlane  *cp5;

    /* fog */
    RMenum       fogActive;	/* RM_TRUE if fog is active */
    RMfog        fog;		/* rather than creating copies */
    
    /* lighting */
    RMlightModel *lmodel;
    RMlight      *lightSources[RM_MAX_LIGHTS];

    /* text */
    RMtextProps  *textProps;

    int          frameNumber;

    /* internal use only */
    RMenum       colorMaterialActive;
    RMenum       lightingActive;
} RMstate;

typedef struct
{
    RMenum       colorMaterialActive; /* in use */
    RMenum       lightingActive; /* not yet used */
    RMenum       texturingActive; /* not yet used */
} RMstateCache;

typedef struct 
{
    RMcolor4D *ambient_color;
    RMcolor4D *diffuse_color;
    RMcolor4D *specular_color;
    RMcolor4D *unlit_color;
    float     *specular_exponent;
    float     *opacity;
} _surface_properties;
   
typedef struct _rendermode_properties
{
    RMenum *shademodel;			/* shade? [RM_SHADER_SMOOTH, RM_SHADER_FLAT, RM_SHADER_NOLIGHT] */
    RMenum *poly_mode_face;
    RMenum *poly_mode_drawstyle;
    RMenum *cull_mode;			/* cull faces? [RM_CULL_NONE, RM_CULL_FRONT, RM_CULL_BACK, RM_CULL_FRONT_AND_BACK] */
    RMenum *front_face;			/* vertex winding? [RM_CCW, RM_CW] */
    float  *pointsize;
    RMenum *linewidth;
    RMenum *linestyle;
    RMenum *normalizeNormals;
} _rendermode_properties;

typedef struct internals_RMsceneParms
{
    float        *viewport; 		 /* array of length 4: (x, y, w, h) in NDC [0..1], scales to window size */
/*    RMcolor4D    *background_color; moved */
/*    RMimage      *background_image_tile; moved */
    RMcamera3D   *camera3d;
    RMcamera2D   *camera2d;

    /* RMtexture  *texture; modified during multitexturing upgrade 11/11/04 */
    RMtexture    *textures[RM_MAX_MULTITEXTURES+1]; 
    RMenum        haveAnyTextures;

/*    float        *depth_value; moved */
/*    RMimage      *depth_image; moved */
    RMclipPlane  *cp0;
    RMclipPlane  *cp1;
    RMclipPlane  *cp2;
    RMclipPlane  *cp3;
    RMclipPlane  *cp4;
    RMclipPlane  *cp5;
    RMlightModel *lmodel;
    RMlight      *lightSources[RM_MAX_LIGHTS];
    RMtextProps  *textProps;
    RMfog        *fog;
} internals_RMsceneParms;

typedef struct 
{
    RMcolor4D    *bgColor; 
    RMimage      *bgImageTile;
    
    float        *depthValue; 
    RMimage      *depthImage;
} internals_RMfbClear;

typedef struct internals_RMtransformationStruct
{
    /*
     * transformations are applied in this order (left multiplication!):
     *
     * Pre * -C * S * R * S2 * C * T * Post
     */
    RMmatrix   pre;		/* applied before any other transforms */
    RMmatrix   s;		/* pre-rotation scale */
    RMmatrix   r;		/* rotation */
    RMmatrix   s2;		/* post-rotation scale */
    RMvertex3D translate;	/* translation vector */
    RMmatrix   post;		/* applied after other transforms */
    RMenum     transform_mode;  /* RM_TRANSFORM_GEOMETRY, RM_TRANSFORM_TEXTURE, RM_TRANSFORM_CAMERA, RM_TRANSFORM_IGNORE */
} internals_RMtransformationStruct;

typedef struct _object_info
{
    char   name[OBJECT_NAME_LENGTH];

    /* node scheduling for rendering in a multipass/multichannel rendering environment */
    RMenum posted;		/* controls whether or not is rendered */
    RMenum rpass_vdims;		/* 2D or 3D coords? */
    RMenum rpass_opacity;	/* RM_RENDERPASS_OPAQUE, RM_RENDERPASS_TRANSPARENT */
    RMenum channel;		/* RM_LEFT_CHANNEL, RM_RIGHT_CHANNEL, RM_ALL_CHANNELS */
    RMenum pickEnable;		/* when RM_TRUE, the node will be traversed
				 during pick operations. Default is RM_TRUE */
} _object_info;

typedef struct RMnode
{
    /* scene graph topology */
    struct RMnode  *parent;

    RMarray *childrenArray; 		/* new in 1.8.0 */
#if 0
    int             nchildren;
    struct RMnode **children;
#endif

    /* here's the geometry */
    int             nprims;
    void          **prims;

    /* properties */
    _surface_properties    *sprops;
    _rendermode_properties *rprops;
    internals_RMsceneParms *scene_parms;

    /* fb clear control */
    internals_RMfbClear    *fbClear;

    /* bounding box info */
    _bounding_box           bbox;
    RMvertex3D              center;

    /* transformation info */
    internals_RMtransformationStruct *transforms;

    /* misc scheduling info about the object */
    _object_info object_info;

    /* callbacks */
    int (*viewPretraverseCallback)    (const struct RMnode *, const RMstate *);
    int (*viewPosttraverseCallback)   (const struct RMnode *, const RMstate *);

    int (*renderPretraverseCallback)    (const struct RMnode *, const RMstate *);
    int (*renderPosttraverseCallback)   (const struct RMnode *, const RMstate *);
    int (*viewSwitchCallback) (const struct RMnode *, const RMstate *);
    /*
     * 7/22/02. added view (stage) render order callback. note that the
     * switch callback and renderOrder callbacks are (or should be)
     * mutually-exclusive. such mutual-exclusivity is not reflected in
     * the data structure or in the API at this time.
     */
    int (*viewRenderOrderCallback) (const struct RMnode *, const RMstate *, int *orderIndices, int nChildren);

    /* client data stuff - not multistage safe! (1/2001) */
    void  *clientData;
    void (*clientDataFreeFunc) (struct RMnode *, void *);

    int  refcount;

    /* attribute mask */
    GLuint   attribMask;

    /* optional mutex */
    RMmutex *nodeMutex;
    
    /* internal, component manager */
    int          compListIndx;
} RMnode;

typedef struct RMfontRegistry /* PRIVATE */
{
    int   initialized;
    int   refcount;
    int   listbase;
    int   listoffset;
    int   listCount;
    void *fontinfo;
} RMfontRegistry;

/*
 * context cache structure - used internally by RM to hold OpenGL
 * display list IDs, texture IDs, etc.
 *
 * 8/28/02 - added num*CacheKeys fields to this struct in conjunction
 * with dynamic object pools.
 */
typedef struct RMcontextCache
{
    /* for RMprimitives */
    GLuint      *primDisplayListIDs;
    RMcacheKey  *primCacheKeys;
    int          numPrimDisplayListIDs;
    int          numPrimCacheKeys;

    /* for RMimages */
    GLuint      *imgDisplayListIDs;
    RMcacheKey  *imgCacheKeys;
    int          numImgDisplayListIDs;
    int          numImgCacheKeys;

    /* for RMtextures */
    GLuint      *textureIDs;
    RMcacheKey  *textureIDCacheKeys; /* textureID management */
    RMcacheKey  *textureDataCacheKeys; /* texture image data status */
    int          numTextureIDs;
    int          numTextureIDCacheKeys;
    int          numTextureDataCacheKeys;

    /* need to add this stuff VVVV  */
    
    /* RM-built display lists for quadrics objects */
    GLuint      *sphereIDs;
    GLuint      *coneIDs, *flipConeIDs;
    GLuint      *cylinderIDs, *flipCylinderIDs;
    
    /* pre-rendered bitmap font glyph display list IDs  */
    RMfontRegistry *pipeFontRegistry;
    
} RMcontextCache;

#ifdef RM_CR
typedef struct
{
  crCreateContextProc glCreateContextCR;
  crMakeCurrentProc   glMakeCurrentCR;
  crSwapBuffersProc   glSwapBuffersCR;

  glChromiumParametervCRProc glChromiumParametervCR;
  glChromiumParameteriCRProc glChromiumParameteriCR;
  glGetChromiumParametervCRProc glGetChromiumParametervCR;
  glBarrierCreateCRProc glBarrierCreateCR;
  glBarrierExecCRProc   glBarrierExecCR;
} RMpipeCRvariables;
#endif

typedef struct RMtime /* niki */
{
    long sec;
    long usec;
} RMtime;

/* 
 * new in RM 1.6.0: obtain & use special capabilities of the OpenGL 
 * implementation. 
*/
typedef struct
{
    /* ---------- multitexturing stuff ----------- */
    /* does this OpenGL support multitexturing? */
    RMenum haveMultiTexturing;
    int    numTextureUnits;
    /* dynamically obtain multitexturing func pointers */
    void   (GLAPIENTRY * activeTextureARB)(GLenum target); 
    void   (GLAPIENTRY * multiTexCoord1fvARB)(GLenum target, float *s);
    void   (GLAPIENTRY * multiTexCoord2fvARB)(GLenum target, float *s);
    void   (GLAPIENTRY * multiTexCoord3fvARB)(GLenum target, float *s);

    /* ---------- 3d textures stuff ------------- */
    /* does this OpenGL support 3D textures? */
    RMenum have3DTextures;

    void (GLAPIENTRY * rm_glTexImage3D) (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
    void (GLAPIENTRY * rm_glTexSubImage3D) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); 

} RMpipeOGLCapabilities;

typedef struct RMpipe
{
    /* stuff common to all environments/OpenGL implementations */
    RMenum       offscreen; /* RM_TRUE for offscreen formats, RM_FALSE otherwise */
    RMenum       processingMode;
    
    RMenum       channel_format;
    int          xwindow_width, xwindow_height;
    int          xflags;
    RMenum       opaque3DEnable, transparent3DEnable, opaque2DEnable;
    RMenum       initMatrixStack;	/* RM_TRUE or RM_FALSE */
    int          frameNumber;

    /* global control over use of display lists */
    RMenum       displayListEnableBool;

    /* Context Cache stuff */
    RMcontextCache *contextCache; /* the context cache */
    
    void *displayLists;     /* multistage rendering buffers. Note: these are
			     NOT OpenGL display lists!! This buffer contains
			     structures generated by the view-stage traversal
			     that are consumed by the draw-stage traversal */
    
    void *mtControl;        /* multistage process/thread control structure */

#ifdef RM_X
    /* stuff specific to X */
    Display     *xdisplay; 
    XVisualInfo *xvisual;
    Window       xdrawable;
    GLXContext   glxcontext;
    Colormap     xcolormap;
#endif

#ifdef RM_WIN
    /* stuff specific to Win32 */
    HDC    hdc;
    HWND   hwnd;
    HGLRC  hRC;
#endif

#ifdef RM_CR
    /* stuff specific to Chromium */
    int    contextCR;
    RMpipeCRvariables *crStuff;  /* see rmcr.c */
#endif

    int myRank, globalNPE;
    RMenum targetPlatform;

    /* pipe callbacks, all platforms */
    /* 1. render function */
    void (*channel_render_func)(RMnode *t, struct RMpipe *p);

    /*
     * 2. optional app callback invoked after rendering, but before
     * the "swapbuffers" call. can be used to perform synchronization
     * between multiple rendering engines.
     */
    void (*postRenderBarrierFunc)(struct RMpipe *p);

    /* 3. color and depth buffer acquisition, swap buffer function */
    void (*postrenderfunc)(const RMimage *, RMenum whichBufferEnum);
    void (*postrender_depthbufferfunc)(const RMimage *, RMenum whichBufferEnum);
    /* 4. swap buffers func */
    RMenum (*swapBuffersFunc)(const struct RMpipe *);

    /* 5. shutdown function */
    void (*shutdownFunc)(struct RMpipe *);

    /*
     * 12/26/02 - specialized barrier functions added during Chromium work.
     * for now, these funcs are added outside of the RM_CR def to minimize
     * the amount of arch-specific stuff.
     */
    void (*postFBClearBarrierFunc)(const struct RMpipe *p);

    /*
     * context creation function - a per-platform thing
     */
    RMenum (*createContextFunc)(struct RMpipe *p);

    /*
     * stuff related to constant time rendering
     */
#define MAX_FRAME_SAMPLES 6
    int          targetFrameRate; /* frames per sec, set by user */
    RMtime       timePerFrame;    /* fps converted to sec/usec */
    double       timePerFrameMS;  /* ms per frame */
    RMtime       lastTimeStart;        /* when was last frame started? */
    RMtime       lastRenderTime;  /* elapsed time for last rendering */

    /* the timeSyncFunc is used as a post-render, pre-swapbuffers
       rendezvous point */
    void         (*timeSyncFunc)(struct RMpipe *p);

    /* 
     * new in 1.6.0 - special capabilities of the OpenGL implementation.
     */
    RMpipeOGLCapabilities *caps;

    /* new in 1.6.0 - RMpipe-level framebuffer clear controls. We use a
     SG node to hold the RMpipe-level fbclear parameters as a roundabout
     way of providing internal structure consistency for the routines that
     generate PS output to avoid having yet another table of structs
     for the fbclear objects. The extra level of indirection is something
     of a PITA, but is less so than doing yet another managed table. */
    RMnode        *fbClearNode;

    /*
     * Each pipe has stack used to hold the attrib masks associated with
     * each attrib push/pop. In some cases, we need to twiddle our local
     * state tracker cache on pops to reflect changes to the actual
     * OpenGL state that occur on push/pops. The local stack allows us to
     * do so w/o having to query OpenGL, which would add some small cost.
     *
     * The MAX_MASK_STACK_DEPTH value of 64 is >> the usual OpenGL
     * attrib stack depth, which is usually around 8 or 16.
     */

#define MAX_MASK_STACK_DEPTH 64
    GLuint localMaskStack[MAX_MASK_STACK_DEPTH];
    int localMaskStackTop;
} RMpipe;


typedef struct RMprimitiveDataBlob
{
    void  *ptr;			/* pointer to the stuff */
    RMenum copyflag;
    int    nthings;		/* how many things there are */
    int    blobtype;		/* what kind of blob? */
    int    stride;		/* size of individual thing */
    int    veclen;		/* vector length of data supplied */
    void (*appfreefunc)(void *);/* the app-supplied free function for when the copy-flag is set to RM_DONT_COPY_DATA */
} RMprimitiveDataBlob;

#define OGLPRIMPARMLIST() (struct RMprimitive *p, RMnode *r, RMstate *s, RMpipe *renderPipe, RMstateCache *rsc)

typedef struct RMprimitive
{
    RMenum               type;
    RMprimitiveDataBlob *blobs; /* verts, colors, norms, texture coords, etc. */
    /* Feb 2005 - add support for multitextures */
    RMprimitiveDataBlob *multiTextureCoordBlobs; /* only multitexture coords */
    int multiTextureCoordBlobsMask;
    int numMultiTextureCoordBlobs;

    /* methods, data, flags */
    void (*renderfunc)  OGLPRIMPARMLIST();	/* RMprimitive stores a pointer to the primitive draw method */
    void  *clientData;
    void (*clientDataFreeFunc) (struct RMprimitive *p, void *cd);
    void  *p1;					/* stuff that doesn't really fit into blobs */

    /* misc stuff - usage depends upon app */
    unsigned int flags1;
    unsigned int model_flag;
    int          display_list_enable;

    /* old stuff for compatibility */
    int    utility;

    /* internal, component manager */
    int          compListIndx;

    /* internal, context cache key */
    RMcacheKey   cacheKey;

    /* used by some primitives to track state of textures, etc. */
    RMcacheKey   utilCacheKey;

    /* bounding box stuff */
    RMvertex3D   *bmin, *bmax;
    RMenum       (*primitiveComputeBoundingBoxFunc)(struct RMprimitive *);

} RMprimitive;



/* RM-supplied primitive rendering functions */
void rmAppDisplayList		OGLPRIMPARMLIST();
void rmBitmap			OGLPRIMPARMLIST();
void rmBox2d			OGLPRIMPARMLIST();
void rmBox3d			OGLPRIMPARMLIST();
void rmBox3dWire	    	OGLPRIMPARMLIST();
void rmCircle2d			OGLPRIMPARMLIST();
void rmCones			OGLPRIMPARMLIST();
void rmCylinders		OGLPRIMPARMLIST();
void rmEllipse2d		OGLPRIMPARMLIST();
void rmIndexedBitmap		OGLPRIMPARMLIST();
void rmIndexedQuads		OGLPRIMPARMLIST();
void rmIndexedQuadStrip		OGLPRIMPARMLIST();
void rmIndexedText		OGLPRIMPARMLIST();
void rmIndexedTriangleFan	OGLPRIMPARMLIST();
void rmIndexedTriangles	        OGLPRIMPARMLIST();
void rmIndexedTriangleStrip     OGLPRIMPARMLIST();
void rmLineStrip		OGLPRIMPARMLIST();
void rmLinesDisjoint		OGLPRIMPARMLIST();
void rmMarkers2D	     	OGLPRIMPARMLIST();
void rmOctmesh			OGLPRIMPARMLIST();
void rmPoints			OGLPRIMPARMLIST();
void rmPolys			OGLPRIMPARMLIST();
void rmQuadmesh			OGLPRIMPARMLIST();
void rmQuads			OGLPRIMPARMLIST();
void rmQuadStrip		OGLPRIMPARMLIST();
void rmSpheres			OGLPRIMPARMLIST();
void rmSprite			OGLPRIMPARMLIST();
void rmText			OGLPRIMPARMLIST();
void rmTrianglesDisjoint	OGLPRIMPARMLIST();
void rmTriangleFan		OGLPRIMPARMLIST();
void rmTrianglesConnected	OGLPRIMPARMLIST();


/* structure returned when picking */
typedef struct RMpick
{
    RMnode      *node;
    float        zval;		/* NDC z-value */
    unsigned int index;		/* object index */
    unsigned int prim_index;	/* primitive index */
} RMpick;

#ifdef RM_X
#include "rmx.h"
#endif

#ifdef __cplusplus
}
#endif

#endif /* _rmtypes_h */
/* EOF */
