414 lines
13 KiB
C
414 lines
13 KiB
C
#ifndef __gllighting_h_
|
|
#define __gllighting_h_
|
|
|
|
/*
|
|
** Copyright 1991, 1992, 1993, Silicon Graphics, Inc.
|
|
** All Rights Reserved.
|
|
**
|
|
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
|
|
** the contents of this file may not be disclosed to third parties, copied or
|
|
** duplicated in any form, in whole or in part, without the prior written
|
|
** permission of Silicon Graphics, Inc.
|
|
**
|
|
** RESTRICTED RIGHTS LEGEND:
|
|
** Use, duplication or disclosure by the Government is subject to restrictions
|
|
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
|
|
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
|
|
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
|
|
** rights reserved under the Copyright Laws of the United States.
|
|
*/
|
|
#include "types.h"
|
|
#include "xform.h"
|
|
|
|
/*
|
|
** Light state. Contains all the user controllable lighting state.
|
|
** Most of the colors kept in user state are scaled to match the
|
|
** drawing surfaces color resolution.
|
|
**
|
|
** Exposed to the MCD as MCDMATERIAL.
|
|
*/
|
|
|
|
struct __GLmaterialStateRec {
|
|
__GLcolor ambient; /* unscaled */
|
|
__GLcolor diffuse; /* unscaled */
|
|
__GLcolor specular; /* unscaled */
|
|
__GLcolor emissive; /* scaled */
|
|
__GLfloat specularExponent;
|
|
#ifdef NT
|
|
// SGIBUG align it properly, otherwise GetMateriali returns wrong result!
|
|
__GLfloat cmapa, cmapd, cmaps;
|
|
#else
|
|
__GLfloat cmapa, cmaps, cmapd;
|
|
#endif
|
|
};
|
|
|
|
/*
|
|
** Exposed to the MCD as MCDLIGHTMODEL
|
|
*/
|
|
|
|
struct __GLlightModelStateRec {
|
|
__GLcolor ambient; /* scaled */
|
|
GLboolean localViewer;
|
|
GLboolean twoSided;
|
|
};
|
|
|
|
/*
|
|
** Partially exposed to the MCD as MCDLIGHT
|
|
*/
|
|
|
|
typedef struct {
|
|
__GLcolor ambient; /* scaled */
|
|
__GLcolor diffuse; /* scaled */
|
|
__GLcolor specular; /* scaled */
|
|
__GLcoord position;
|
|
__GLcoord positionEye;
|
|
__GLcoord direction;
|
|
__GLcoord directionEyeNorm;
|
|
__GLfloat spotLightExponent;
|
|
__GLfloat spotLightCutOffAngle;
|
|
__GLfloat constantAttenuation;
|
|
__GLfloat linearAttenuation;
|
|
__GLfloat quadraticAttenuation;
|
|
|
|
/* MCDLIGHT ends */
|
|
|
|
/* Need both directionEyeNorm and directionEye because MCD 2.0 wants
|
|
a normalized direction but glGetLightfv specifies that the value
|
|
returned for spot direction is the pre-normalized eye coordinate
|
|
direction */
|
|
__GLcoord directionEye;
|
|
struct __GLmatrixRec lightMatrix;
|
|
} __GLlightSourceState;
|
|
|
|
typedef struct {
|
|
GLenum colorMaterialFace;
|
|
GLenum colorMaterialParam;
|
|
GLenum shadingModel;
|
|
__GLlightModelState model;
|
|
__GLmaterialState front;
|
|
__GLmaterialState back;
|
|
GLuint dirtyLights;
|
|
__GLlightSourceState *source;
|
|
} __GLlightState;
|
|
|
|
/************************************************************************/
|
|
|
|
/*
|
|
** What bits are affected by color index anti-aliasing. This isn't a
|
|
** really a changeable parameter (it is defined by the spec), but it
|
|
** is useful for documentation instead of a mysterious 4 or 16 sitting
|
|
** around in the code.
|
|
*/
|
|
#define __GL_CI_ANTI_ALIAS_BITS 4
|
|
#define __GL_CI_ANTI_ALIAS_DIVISOR (1 << __GL_CI_ANTI_ALIAS_BITS)
|
|
|
|
/************************************************************************/
|
|
|
|
/*
|
|
** These macros are used to convert incoming color values into the
|
|
** abstract color range from 0.0 to 1.0
|
|
*/
|
|
#ifdef NT
|
|
#define __GL_B_TO_FLOAT(b) (__glByteToFloat[(GLubyte)(b)])
|
|
#define __GL_UB_TO_FLOAT(ub) (__glUByteToFloat[ub])
|
|
#define __GL_S_TO_FLOAT(s) ((((s)<<1) + 1) * __glOneOver65535)
|
|
#define __GL_US_TO_FLOAT(us) ((us) * __glOneOver65535)
|
|
#else
|
|
#define __GL_B_TO_FLOAT(b) ((((b)<<1) + 1) * gc->constants.oneOver255)
|
|
#define __GL_UB_TO_FLOAT(ub) (gc->constants.uByteToFloat[ub])
|
|
#define __GL_S_TO_FLOAT(s) ((((s)<<1) + 1) * gc->constants.oneOver65535)
|
|
#define __GL_US_TO_FLOAT(us) ((us) * gc->constants.oneOver65535)
|
|
#endif
|
|
|
|
/*
|
|
** Not quite 2^31-1 because of possible floating point errors. 4294965000
|
|
** is a much safer number to use.
|
|
*/
|
|
#ifdef NT
|
|
#define __GL_I_TO_FLOAT(i) \
|
|
((((__GLfloat)(i) * (__GLfloat) 2.0) + 1) * \
|
|
__glOneOver4294965000)
|
|
#define __GL_UI_TO_FLOAT(ui) \
|
|
((__GLfloat)(ui) * __glOneOver4294965000)
|
|
#else
|
|
#define __GL_I_TO_FLOAT(i) \
|
|
((((__GLfloat)(i) * (__GLfloat) 2.0) + 1) * \
|
|
gc->constants.oneOver4294965000)
|
|
#define __GL_UI_TO_FLOAT(ui) \
|
|
((__GLfloat)(ui) * gc->constants.oneOver4294965000)
|
|
#endif
|
|
|
|
/*
|
|
** Bloody "round towards 0" convention. We could avoid these floor() calls
|
|
** were it not for that!
|
|
*/
|
|
#ifdef NT
|
|
#define __GL_FLOAT_TO_B(f) \
|
|
((GLbyte) __GL_FLOORF(((f) * __glVal255) * __glHalf))
|
|
#define __GL_FLOAT_TO_UB(f) \
|
|
((GLubyte) ((f) * __glVal255 + __glHalf))
|
|
#define __GL_FLOAT_TO_S(f) \
|
|
((GLshort) __GL_FLOORF(((f) * __glVal65535) * __glHalf))
|
|
#define __GL_FLOAT_TO_US(f) \
|
|
((GLushort) ((f) * __glVal65535 + __glHalf))
|
|
#else
|
|
#define __GL_FLOAT_TO_B(f) \
|
|
((GLbyte) __GL_FLOORF(((f) * gc->constants.val255) * __glHalf))
|
|
#define __GL_FLOAT_TO_UB(f) \
|
|
((GLubyte) ((f) * gc->constants.val255 + __glHalf))
|
|
#define __GL_FLOAT_TO_S(f) \
|
|
((GLshort) __GL_FLOORF(((f) * gc->constants.val65535) * __glHalf))
|
|
#define __GL_FLOAT_TO_US(f) \
|
|
((GLushort) ((f) * gc->constants.val65535 + __glHalf))
|
|
#endif
|
|
|
|
/*
|
|
** Not quite 2^31-1 because of possible floating point errors. 4294965000
|
|
** is a much safer number to use.
|
|
*/
|
|
#ifdef NT
|
|
#define __GL_FLOAT_TO_I(f) \
|
|
((GLint) __GL_FLOORF(((f) * __glVal4294965000) * __glHalf))
|
|
#define __GL_FLOAT_TO_UI(f) \
|
|
((GLuint) ((f) * __glVal4294965000 + __glHalf))
|
|
#else
|
|
#define __GL_FLOAT_TO_I(f) \
|
|
((GLint) __GL_FLOORF(((f) * gc->constants.val4294965000) * __glHalf))
|
|
#define __GL_FLOAT_TO_UI(f) \
|
|
((GLuint) ((f) * gc->constants.val4294965000 + __glHalf))
|
|
#endif
|
|
|
|
/*
|
|
** Mask the incoming color index (in floating point) against the
|
|
** maximum color index value for the color buffers. Keep 4 bits
|
|
** of fractional precision.
|
|
*/
|
|
#define __GL_MASK_INDEXF(gc, val) \
|
|
(((__GLfloat) (((GLint) ((val) * 16)) \
|
|
& (((gc)->frontBuffer.redMax << 4) | 0xf))) \
|
|
/ (__GLfloat)16.0)
|
|
|
|
#define __GL_MASK_INDEXI(gc, val) \
|
|
((val) & (gc)->frontBuffer.redMax)
|
|
|
|
/************************************************************************/
|
|
|
|
/*
|
|
** These two must be the same size, because they cache their tables in the
|
|
** same arena.
|
|
*/
|
|
#define __GL_SPEC_LOOKUP_TABLE_SIZE 256
|
|
#define __GL_SPOT_LOOKUP_TABLE_SIZE __GL_SPEC_LOOKUP_TABLE_SIZE
|
|
|
|
typedef struct {
|
|
GLint refcount;
|
|
__GLfloat threshold, scale, exp;
|
|
__GLfloat table[__GL_SPEC_LOOKUP_TABLE_SIZE];
|
|
} __GLspecLUTEntry;
|
|
|
|
__GLspecLUTEntry *__glCreateSpecLUT(__GLcontext *gc, __GLfloat exp);
|
|
void FASTCALL __glFreeSpecLUT(__GLcontext *gc, __GLspecLUTEntry *lut);
|
|
void FASTCALL __glInitLUTCache(__GLcontext *gc);
|
|
void FASTCALL __glFreeLUTCache(__GLcontext *gc);
|
|
|
|
#define __GL_LIGHT_UPDATE_FRONT_MATERIAL_AMBIENT
|
|
|
|
/*
|
|
** Per light source per material computed state.
|
|
*/
|
|
typedef struct __GLlightSourcePerMaterialMachineRec {
|
|
__GLcolor ambient; /* light ambient times material ambient */
|
|
__GLcolor diffuse; /* light diffuse times material diffuse */
|
|
__GLcolor specular; /* light specular times material specular */
|
|
} __GLlightSourcePerMaterialMachine;
|
|
|
|
/*
|
|
** Per light source computed state.
|
|
*/
|
|
struct __GLlightSourceMachineRec {
|
|
/*
|
|
** ambient, diffuse and specular are each pre-multiplied by the
|
|
** material ambient, material diffuse and material specular.
|
|
** We use the face being lit to pick between the two sets.
|
|
*/
|
|
__GLlightSourcePerMaterialMachine front, back;
|
|
|
|
__GLlightSourceState *state;
|
|
|
|
__GLfloat constantAttenuation;
|
|
__GLfloat linearAttenuation;
|
|
__GLfloat quadraticAttenuation;
|
|
__GLfloat spotLightExponent;
|
|
|
|
/* Position of the light source in eye coordinates */
|
|
__GLcoord position;
|
|
|
|
/* Direction of the light source in eye coordinates, normalize */
|
|
__GLcoord direction;
|
|
|
|
/* Cosine of the spot light cutoff angle */
|
|
__GLfloat cosCutOffAngle;
|
|
|
|
/* Precomputed attenuation, only when k1 and k2 are zero */
|
|
__GLfloat attenuation;
|
|
|
|
/* This will be set when the cut off angle != 180 */
|
|
GLboolean isSpot;
|
|
|
|
/* When possible, the normalized "h" value from the spec is pre-computed */
|
|
__GLcoord hHat;
|
|
|
|
/* Unit vector VPpli pre-computed (only when light is at infinity) */
|
|
__GLcoord unitVPpli;
|
|
|
|
/* sli and dli values pre-computed (color index mode only) */
|
|
__GLfloat sli, dli;
|
|
|
|
/* Link to next active light */
|
|
__GLlightSourceMachine *next;
|
|
|
|
/* Spot light exponent lookup table */
|
|
__GLfloat *spotTable;
|
|
|
|
/* Values used to avoid pow function during spot computations */
|
|
__GLfloat threshold, scale;
|
|
|
|
/* cache entry where this data came from */
|
|
__GLspecLUTEntry *cache;
|
|
|
|
/* Set to GL_TRUE if slow processing path is needed */
|
|
GLboolean slowPath;
|
|
|
|
/* temporary storage for hHat when original hHat is transformed into *
|
|
/* normal space */
|
|
__GLcoord tmpHHat;
|
|
|
|
/* temporary storage for unitVPpli when original is transformed into *
|
|
/* normal space */
|
|
__GLcoord tmpUnitVPpli;
|
|
};
|
|
|
|
/*
|
|
** Per material computed state.
|
|
*/
|
|
struct __GLmaterialMachineRec {
|
|
#ifdef NT
|
|
/*
|
|
** Sum of:
|
|
** invariant material emissive color (with respect to color material)
|
|
** invariant material ambient color * scene ambient color (with
|
|
** respect to color material)
|
|
**
|
|
** This sum is carefully kept scaled.
|
|
*/
|
|
__GLcolor paSceneColor;
|
|
|
|
/*
|
|
** Cached values for the total emissive+ambient for a material, and
|
|
** the clamped version of this value which can be directly applied
|
|
** to backface vertices with no effective specular or diffuse components.
|
|
*/
|
|
|
|
__GLcolor cachedEmissiveAmbient;
|
|
__GLcolor cachedNonLit;
|
|
#else
|
|
/*
|
|
** Sum of:
|
|
** material emissive color
|
|
** material ambient color * scene ambient color
|
|
**
|
|
** This sum is carefully kept scaled.
|
|
*/
|
|
__GLcolor sceneColor;
|
|
#endif
|
|
|
|
/* Specular exponent */
|
|
__GLfloat specularExponent;
|
|
|
|
/* Specular exponent lookup table */
|
|
__GLfloat *specTable;
|
|
|
|
/* Values used to avoid pow function during specular computations */
|
|
__GLfloat threshold, scale;
|
|
|
|
/* cache entry where this data came from */
|
|
__GLspecLUTEntry *cache;
|
|
|
|
/* Scaled and clamped form of material diffuse alpha */
|
|
__GLfloat alpha;
|
|
|
|
#ifdef NT
|
|
/* color material change bits */
|
|
GLuint colorMaterialChange;
|
|
#endif
|
|
};
|
|
|
|
typedef struct {
|
|
__GLlightSourceMachine *source;
|
|
__GLmaterialMachine front, back;
|
|
|
|
/* List of enabled light sources */
|
|
__GLlightSourceMachine *sources;
|
|
|
|
/* Current material color material (iff one material is being updated) */
|
|
__GLmaterialState *cm;
|
|
__GLmaterialMachine *cmm;
|
|
|
|
/* Cache of lookup tables for spot lights and specular highlights */
|
|
struct __GLspecLUTCache_Rec *lutCache;
|
|
} __GLlightMachine;
|
|
|
|
/* Values for cmParam */
|
|
#define __GL_EMISSION 0
|
|
#define __GL_AMBIENT 1
|
|
#define __GL_SPECULAR 2
|
|
#define __GL_AMBIENT_AND_DIFFUSE 3
|
|
#define __GL_DIFFUSE 4
|
|
|
|
extern void FASTCALL __glCopyCIColor(__GLcontext *gc, GLuint faceBit, __GLvertex *v);
|
|
extern void FASTCALL __glCopyRGBColor(__GLcontext *gc, GLuint faceBit, __GLvertex *v);
|
|
|
|
extern void FASTCALL __glClampRGBColor(__GLcontext *gc, __GLcolor *dst,
|
|
const __GLcolor *src);
|
|
extern void FASTCALL __glClampAndScaleColor(__GLcontext *gc);
|
|
|
|
|
|
/* Stuff for converting float colors */
|
|
extern void FASTCALL __glClampAndScaleColorf(__GLcontext *gc, __GLcolor *dst,
|
|
const GLfloat src[4]);
|
|
extern void FASTCALL __glClampColorf(__GLcontext *gc, __GLcolor *dst,
|
|
const GLfloat src[4]);
|
|
extern void FASTCALL __glScaleColorf(__GLcontext *gc, __GLcolor *dst,
|
|
const GLfloat src[4]);
|
|
extern void FASTCALL __glUnScaleColorf(__GLcontext *gc, GLfloat dst[4],
|
|
const __GLcolor *src);
|
|
|
|
/* Stuff for converting integer colors */
|
|
extern void FASTCALL __glClampAndScaleColori(__GLcontext *gc, __GLcolor *dst,
|
|
const GLint src[4]);
|
|
extern void FASTCALL __glClampColori(__GLcontext *gc, __GLcolor *dst,
|
|
const GLint src[4]);
|
|
extern void FASTCALL __glScaleColori(__GLcontext *gc, __GLcolor *dst,
|
|
const GLint src[4]);
|
|
extern void FASTCALL __glUnScaleColori(__GLcontext *gc, GLint dst[4],
|
|
const __GLcolor *src);
|
|
|
|
extern void FASTCALL __glTransformLightDirection(__GLcontext *gc,
|
|
__GLlightSourceState *ls);
|
|
|
|
extern void FASTCALL __glValidateLighting(__GLcontext *gc);
|
|
extern void FASTCALL __glValidateMaterial(__GLcontext *gc, GLint front, GLint back);
|
|
|
|
/* Procs for handling color material changes */
|
|
extern void FASTCALL __glChangeOneMaterialColor(__GLcontext *gc);
|
|
extern void FASTCALL __glChangeBothMaterialColors(__GLcontext *gc);
|
|
|
|
/* Lighting procs */
|
|
extern void FASTCALL __glCalcRGBColor(__GLcontext *gc, GLint face, __GLvertex *vx);
|
|
extern void FASTCALL __glFastCalcRGBColor(__GLcontext *gc, GLint face, __GLvertex *vx);
|
|
extern void FASTCALL __glCalcCIColor(__GLcontext *gc, GLint face, __GLvertex *vx);
|
|
extern void FASTCALL __glFastCalcCIColor(__GLcontext *gc, GLint face, __GLvertex *vx);
|
|
extern void FASTCALL ComputeColorMaterialChange(__GLcontext *gc);
|
|
|
|
#endif /* __gllighting_h_ */
|