Headers/SR.h

/******************************************************************************
 **                                                                          **
 **     Module:     SR.h                                                     **
 **                                                                          **
 **                                                                          **
 **     Purpose:    Sample renderer  header                                  **
 **                                                                          **
 **                                                                          **
 **                                                                          **
 **     Copyright (C) 1996 Apple Computer, Inc.  All rights reserved.        **
 **                                                                          **
 **                                                                          **
 *****************************************************************************/
#ifndef SR_h
#define SR_h
 
#include <assert.h>
 
#include "QD3D.h"
#include "QD3DCamera.h"
#include "QD3DStyle.h"
#include "QD3DRenderer.h"
 
#if defined(WINDOW_SYSTEM_MACINTOSH) && WINDOW_SYSTEM_MACINTOSH
 
#include <Quickdraw.h>
 
#elif defined (WINDOW_SYSTEM_WIN32) && WINDOW_SYSTEM_WIN32
 
#include <WINDOWS.h>
 
#endif
 
#include "SR_Math.h"
#include "SR_Marker.h"
 
 
#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus */
 
/******************************************************************************
 **                                                                          **
 **                             Macros                                       **
 **                                                                          **
 *****************************************************************************/
 
/*
 *  Keep the compiler from complaining about unused parameters.
 */
#define UNUSED(x)   x
 
 
/*
 *  For line pipeline, we may be in "polygon" or "polyline" mode. In the
 *  former, we must connect the last vertex with the first; in the latter mode,
 *  we must *not*.
 */
#define DO_POLYLINE 0
#define DO_POLYGON  1
 
 
/*
 * Fast math macros
 */
#define FLOAT_TRUNC_TO_LONG(f)              (long)(f)
#define FLOAT_ROUND_TO_LONG(f)  \
    (((f) >= 0.0) ? (long)((f) + 0.5) : (long)((f) - 0.5))
    
#define FLOAT_ROUND_TO_LONG_POSITIVE(f)     (long)((f) + 0.5)
#define FABS(f)                             (((f) >= 0.0F) ? (f) : -(f))
#define ABS(x)                              (((x) >= 0)    ? (x) : -(x))
 
 
 /*
 *  Pixel-packing macros. 32-bit version assumes Macintosh ordering of
 *  r, g, and b. Other platforms may have these in a different order, in which
 *  case this macro should have the packing reordered. Other bit depths may
 *  be accomodated by adding similar macros, with the appropriate shifts replacing
 *  those found in this macro. Ordering is same on Win95.
 */
#define PACK_RGB_32(_r, _g, _b) (                                               \
    ((unsigned long) 0xFF000000) |                                              \
    ((unsigned long)(FLOAT_ROUND_TO_LONG_POSITIVE((_r) * 255.0) & 0xFF) << 16) |\
    ((unsigned long)(FLOAT_ROUND_TO_LONG_POSITIVE((_g) * 255.0) & 0xFF) << 8)  |\
    ((unsigned long)(FLOAT_ROUND_TO_LONG_POSITIVE((_b) * 255.0) & 0xFF)))
    
#if defined(WINDOW_SYSTEM_MACINTOSH) && WINDOW_SYSTEM_MACINTOSH
 
/*
 *  Convert a (0 - 1) valued RGB specification to a pixel. For 32-
 *  bit pixel, pack in the RGB values; for 8-bit pixels, call the 
 *  QuickDraw function that converts a 16-bit color to a colormap
 *  index. Other platforms may require a different function call
 *  to map the RGB values to a pixel index.
 */
#define COLOR_TO_PIXEL(_result, _drawRegion, _depth, _r, _g, _b)    \
    switch (_depth) {                                               \
        case kQ3XDevicePixelTypeRGB32:                              \
        case kQ3XDevicePixelTypeARGB32:                             \
            _result = PACK_RGB_32(_r, _g, _b);                      \
            break;                                                  \
        case kQ3XDevicePixelTypeIndexed8: {                         \
            RGBColor    _rgbColor;                                  \
                                                                    \
            _rgbColor.red   = _r * 65535;                           \
            _rgbColor.green = _g * 65535;                           \
            _rgbColor.blue  = _b * 65535;                           \
                                                                    \
            _result = Color2Index(&_rgbColor);                      \
            break;                                                  \
        }                                                           \
        default:                                                    \
            assert(0);                                              \
            break;                                                  \
    }
    
#define COLOR_8_TO_INDEX(_result, _drawRegion, _depth, _r, _g, _b)  \
    switch (_depth) {                                               \
        case kQ3XDevicePixelTypeIndexed8: {                         \
            RGBColor    _rgbColor;                                  \
                                                                    \
            _rgbColor.red   = _r << 8;                              \
            _rgbColor.green = _g << 8;                              \
            _rgbColor.blue  = _b << 8;                              \
                                                                    \
            _result = Color2Index(&_rgbColor);                      \
            break;                                                  \
        }                                                           \
        default:                                                    \
            assert(0);                                              \
            break;                                                  \
    }
 
#define COLOR_5_TO_INDEX(_result, _drawRegion, _depth, _r, _g, _b)  \
    switch (_depth) {                                               \
        case kQ3XDevicePixelTypeIndexed8: {                         \
            RGBColor    _rgbColor;                                  \
                                                                    \
            _rgbColor.red   = _r << 11;                             \
            _rgbColor.green = _g << 11;                             \
            _rgbColor.blue  = _b << 11;                             \
                                                                    \
            _result = Color2Index(&_rgbColor);                      \
            break;                                                  \
        }                                                           \
        default:                                                    \
            assert(0);                                              \
            break;                                                  \
    }
 
#elif defined(WINDOW_SYSTEM_WIN32) && WINDOW_SYSTEM_WIN32
 
/*
 *  Convert a (0 - 1) valued RGB specification to a pixel. For 32-
 *  bit pixel, pack in the RGB values; All other formats are
 *  not supported 
 */
 
#define COLOR_TO_PIXEL(_result, _drawRegion, _depth, _r, _g, _b)    \
    switch (_depth) {                                               \
        case kQ3XDevicePixelTypeRGB32:                              \
        case kQ3XDevicePixelTypeARGB32:                             \
            _result = PACK_RGB_32(_r, _g, _b);                      \
            break;                                                  \
        default:                                                    \
            assert(0);                                              \
            break;                                                  \
    }
 
/*
 *  This should never be called on Windows since we never have 
 *  indexed Draw Contexts.
 */
 
#define COLOR_8_TO_INDEX(_result, _drawRegion, _depth, _r, _g, _b)  \
    switch (_depth) {                                               \
        default:                                                    \
            assert(0);                                              \
            break;                                                  \
    }
 
/*
 *  This should never be called on Windows since we never have 
 *  indexed Draw Contexts.
 */
 
#define COLOR_5_TO_INDEX(_result, _drawRegion, _depth, _r, _g, _b)  \
    switch (_depth) {                                               \
        default:                                                    \
            assert(0);                                              \
            break;                                                  \
    }
 
#endif
 
/******************************************************************************
 **                                                                          **
 **                                 Transforms                               **
 **                                                                          **
 *****************************************************************************/
 
typedef struct TSRRenderTransforms {
    TQ3Matrix4x4            localToWorld;
    TQ3Boolean              dirtyLocalToWorld;
    TQ3Boolean              validLocalToWorld;
    
    TQ3Matrix4x4            localToFrustum;
    TQ3Boolean              dirtyLocalToFrustum;
    TQ3Boolean              validLocalToFrustum;
    
    TQ3Matrix4x4            worldToFrustum;
    TQ3Boolean              dirtyWorldToFrustum;
    TQ3Boolean              validWorldToFrustum;
    
    TQ3Matrix4x4            frustumToDC;
    TQ3Boolean              dirtyFrustumToDC;
    TQ3Boolean              validFrustumToDC;
    
    TQ3Matrix4x4            localToDC;
    TQ3Boolean              dirtyLocalToDC;
    TQ3Boolean              validLocalToDC;
} TSRRenderTransforms;
 
 
 
/******************************************************************************
 **                                                                          **
 **                             Clipping Macros                              **
 **                                                                          **
 *****************************************************************************/
 
#define SR_MIN_X        0x01
#define SR_MAX_X        0x02
#define SR_MIN_Y        0x04
#define SR_MAX_Y        0x08
#define SR_MIN_Z        0x10
#define SR_MAX_Z        0x20
#define SR_CLIP_ALL     0x3F
 
#define SR_DRAW_NEXT    0xFF
 
 
/******************************************************************************
 **                                                                          **
 **                             Data Structure                               **
 **                                                                          **
 *****************************************************************************/
                
typedef TQ3Status (*LineFunction2D)(
    const struct TSRPrivate         *srPrivate, 
    const TQ3Point3D                *pt0,
    const TQ3Point3D                *pt1,
    const TQ3ColorRGB               *lineColor);
 
typedef TQ3Status (*PointFunction2D)(
    const struct TSRPrivate         *srPrivate, 
    const TQ3Point3D                *pt0, 
    const TQ3ColorRGB               *pointColor);
 
typedef TQ3Status (*MarkerFunction2D)(
    const struct TSRPrivate         *srPrivate, 
    const TQ3Point3D                *pt0, 
    const TSRMarkerRasterData       *markerData,
    const TQ3ColorRGB               *pointColorRGB);
 
typedef TQ3Status (*PixmapMarkerFunction2D)(
    const struct TSRPrivate         *srPrivate, 
    const TQ3Point3D                *pt0, 
    const TSRPixmapMarkerRasterData *markerData,
    const TQ3ColorRGB               *highlightColor);
 
typedef struct TSRRasterFunctions {
    LineFunction2D          lineFunction;
    PointFunction2D         pointFunction;
    MarkerFunction2D        markerFunction;
    PixmapMarkerFunction2D  pixmapMarkerFunction;
} TSRRasterFunctions;
 
enum {
    SRcRasterBasic = 0,
    SRcRasterClip  = 1
};
 
 
typedef struct TSRPrivate {
    /*
     *  Styles
     */
    TQ3BackfacingStyle              backfacingStyle;
    TQ3OrientationStyle             orientationStyle;
    TQ3FillStyle                    viewFillStyle;
    
    /*
     *  Highlight attribute set and state (on or off)
     */
    TQ3AttributeSet                 viewHighlightAttributeSet;
    TQ3Boolean                      viewHighlightState;
 
    /*
     *  Current color
     */
    TQ3ColorRGB                     viewDiffuseColor;
 
    /*
     *  Transforms
     */
    TSRRenderTransforms             transforms;
    
    /*
     *  Clipping info in device coordinates
     */
    float                           clipPlanesInDC[6];
        
    /*
     *  Current draw region and draw context
     */
    TQ3XDrawRegion                  drawRegion;
    TQ3DrawContextObject            currentDrawContext;
    
    /*
     *  Raster descriptor and raster base address
     */
    TQ3XDrawRegionDescriptor        *descriptor;
    void                            *image;
    
    /*
     *  Raster functions (clipping and non-clipping).
     */
    TSRRasterFunctions              rasterFunctions[2];
    TSRRasterFunctions              *currentRasterFunctions;
    
    /*
     *  Camera info
     */
    TQ3CameraObject                 camera;
    TQ3ObjectType                   cameraType;
    TQ3CameraPlacement              cameraPlacement;
    
    /*
     *  Eye (camera) info in local and world space
     */
    TQ3RationalPoint4D              eyePointInLocalCoords;
    TSRVector4D                     eyeVectorInLocalCoords;
    TQ3RationalPoint4D              eyePointInWorldCoords;
    TSRVector4D                     eyeVectorInWorldCoords;
    
    /*
     *  Info for dealing with non-affine local-to-world transforms
     */
    unsigned long                   normalLocalToWorldRank;
    TQ3PlaneEquation                flatWorld;
    
    /*
     *  Counter for use in Q3XView_IdleProgress
     */
    unsigned long                   primitiveCount;
    
    /*
     *  Dummy variable for configuration data. A real renderer
     *  would store settings here
     */
     short                          dummyConfigData;
     
} TSRPrivate;
 
 
 
/******************************************************************************
 **                                                                          **
 **                         State Update Routines                            **
 **                                                                          **
 *****************************************************************************/
 
TQ3Status SR_UpdateRasterFunctions(
    TSRPrivate              *srPrivate);
 
/*
 *  Styles
 */
TQ3Status SR_Update_BackfacingStyle(
    TQ3ViewObject           view,
    TSRPrivate              *srPrivate,
    TQ3BackfacingStyle      *backfacingStyle);
 
TQ3Status SR_Update_FillStyle(
    TQ3ViewObject           view,
    TSRPrivate              *srPrivate,
    TQ3FillStyle            *fillStyle);
 
TQ3Status SR_Update_HighlightStyle(
    TQ3ViewObject           view,
    TSRPrivate              *srPrivate,
    TQ3AttributeSet         *highlightStyle);
 
TQ3Status SR_Update_OrientationStyle(
    TQ3ViewObject           view,
    TSRPrivate              *srPrivate,
    TQ3OrientationStyle     *orientationStyle);
 
/*
 *  Attributes
 */
TQ3Status SR_Update_DiffuseColor(
    TQ3ViewObject           view,
    TSRPrivate              *srPrivate,
    TQ3ColorRGB             *diffuseColor);
 
TQ3Status SR_Update_HighlightState(
    TQ3ViewObject           view,
    TSRPrivate              *srPrivate,
    TQ3Boolean              *highlightSwitch);
 
/*
 *  Matrices
 */
TQ3Status SR_Update_LocalToWorldMatrix(
    TQ3ViewObject           view,
    TSRPrivate              *srPrivate,
    TQ3Matrix4x4            *localToWorld);
 
TQ3Status SR_Update_LocalToFrustumMatrix(
    TQ3ViewObject           view,
    TSRPrivate              *srPrivate,
    TQ3Matrix4x4            *localToFrustum);
    
TQ3Status SR_Update_WorldToFrustumMatrix(
    TQ3ViewObject           view,
    TSRPrivate              *srPrivate,
    TQ3Matrix4x4            *worldToFrustum);
    
/******************************************************************************
 **                                                                          **
 **                     Idle Progress Mechanism                              **
 **                                                                          **
 *****************************************************************************/
 
TQ3Status SR_IdleProgress(
    TQ3ViewObject   view,
    TSRPrivate      *srPrivate);
 
 
/******************************************************************************
 **                                                                          **
 **                     Pipeline Setup Routines                              **
 **                                                                          **
 *****************************************************************************/
 
void SR_SetupPipelineExit(
    TSRPrivate          *srPrivate);
 
TQ3Status SR_SetupRegionDependentTransformations(
    TSRPrivate          *srPrivate);
 
void SR_SetupPipelineInitCamera(
    TSRPrivate          *srPrivate,
    TQ3CameraObject     camera);
 
TQ3Status SR_UpdatePipeline(
    TSRPrivate          *srPrivate);
 
 
/******************************************************************************
 **                                                                          **
 **                         Pipeline Routines                                **
 **                                                                          **
 *****************************************************************************/
 
TQ3Status SR_LinePipe(
    TSRPrivate          *srPrivate,
    TQ3Point3D          *localVertices,
    long                numVertices,
    long                sizeOfLocalVertices,
    TQ3ColorRGB         *color,
    TQ3Vector3D         *normal,
    long                mode);      
 
TQ3Status SR_PointPipe(
    TSRPrivate          *srPrivate,
    TQ3Point3D          *localVertices,
    long                numVertices,
    long                sizeOfLocalVertices,
    TQ3ColorRGB         *color,
    TQ3Vector3D         *normal,
    long                mode);      
 
 
/******************************************************************************
 **                                                                          **
 **                     Entry Points into Renderer                           **
 **                                                                          **
 *****************************************************************************/
 
TQ3Status SR_Geometry_Triangle(
    TQ3ViewObject               view, 
    struct TSRPrivate           *srPrivate,
    TQ3GeometryObject           triangle, 
    const TQ3TriangleData       *triangleData);
        
TQ3Status SR_Geometry_Line(
    TQ3ViewObject               view, 
    struct TSRPrivate           *srPrivate,
    TQ3GeometryObject           line,
    TQ3LineData                 *lineData);
 
TQ3Status SR_Geometry_Point(
    TQ3ViewObject               view, 
    struct TSRPrivate           *srPrivate,
    TQ3GeometryObject           point,
    const TQ3PointData          *pointData);
 
TQ3Status SR_Geometry_Marker(
    TQ3ViewObject               view, 
    struct TSRPrivate           *srPrivate,
    TQ3GeometryObject           marker,
    const TQ3MarkerData         *markerData);
 
TQ3Status SR_Geometry_PixmapMarker(
    TQ3ViewObject               view, 
    struct TSRPrivate           *srPrivate,
    TQ3GeometryObject           pixmapMarker,
    const TQ3PixmapMarkerData   *pixmapMarkerData);
 
#ifdef __cplusplus
}
#endif  /* __cplusplus */
 
#endif  /*  SR_h  */