|
|
#ifndef __PARRAY_H__
#define __PARRAY_H__
#include "phong.h"
// Number of polydata entries in the context. Must be at least 32.
// It includes room for the polyarray entry and others.
// It's currently based on POLYDATA_BUFFER_SIZE+1 vertices of size 128
// fitting in 64K, which yields 511
#define POLYDATA_BUFFER_SIZE 511
// DrawElements expects at least this many vertices in the vertex buffer.
// It is the sum of the following (currently sum is 278):
// Number of vertex entries in a batch
// Number of entries used for index map
// An extra vertex entry to prevent calling PolyArrayFlushPartialPrimitive
// in the Vertex routines.
// An entry for POLYARRAY
// 4 spare entries to be safe
// It is given by
// VA_DRAWELEM_MAP_SIZE +
// (VA_DRAWELEM_INDEX_SIZE + sizeof(POLYDATA) - 1) / sizeof(POLYDATA) +
// 1 + 1 + 4
#define MINIMUM_POLYDATA_BUFFER_SIZE 300
// Minimun number of polydata entries required before processing a primitive.
// Must be at least 16.
#define MIN_POLYDATA_BATCH_SIZE 68
#if !((MIN_POLYDATA_BATCH_SIZE <= MINIMUM_POLYDATA_BUFFER_SIZE) && \
(MINIMUM_POLYDATA_BUFFER_SIZE <= POLYDATA_BUFFER_SIZE) \ ) #error "bad sizes\n"
#endif
// Maximun number of vertices handled by the polygon decomposer.
// It allocates stack space based on this constant. It must be at least 6.
#define __GL_MAX_POLYGON_CLIP_SIZE 256
// The POLYMATERIAL structure contains an index to the next available
// __GLmatChange structure, an array of pointers to __GLmatChange arrays,
// and a pointer to an array of PDMATERIAL structures each containing
// pointers to the front and back material changes for each POLYDATA
// elements in vertex buffer.
//
// The __GLmatChange structures are used to record material changes to
// vertices in the vertex buffer. Since there can be up to two material
// changes per vertex, we need up to (POLYDATA_BUFFER_SIZE * 2) material
// changes per rendering thread.
//
// The PDMATERIAL array is part of the POLYMATERIAL structure and follows
// the aMat field immediately. Its elements correspond to the POLYDATA
// elements in the vertex buffer.
//
// To reduce memory requirement, the POLYMATERIAL structure keeps an array
// of pointers to __GLmatChange arrays. Each __GLmatChange array of up to
// 4K size is allocated as needed.
//
// An iMat index is used to keep track of the next free __GLmatChange
// entry. When the poly array buffer is flushed in glsbAttention, iMat
// is reset to 0.
//
// The POLYMATERIAL structure and its __GLmatChange arrays are part of
// a thread local storage and are freed when the thread exits.
#define POLYMATERIAL_ARRAY_SIZE (4096 / sizeof(__GLmatChange))
// This structure is shared with MCD as MCDMATERIALCHANGE.
typedef struct __GLmatChangeRec { GLuint dirtyBits; __GLcolor ambient; __GLcolor diffuse; __GLcolor specular; __GLcolor emissive; __GLfloat shininess; __GLfloat cmapa, cmapd, cmaps; } __GLmatChange;
// Pointers to front and back material change structures. They are
// valid only when the POLYDATA_MATERIAL_FRONT or POLYDATA_MATERIAL_BACK
// flag of the corresponding POLYDATA in the vertex buffer is set.
//
// This structure is shared with MCD as MCDMATERIALCHANGES.
typedef struct { __GLmatChange *front; // pointer to the front material changes
__GLmatChange *back; // pointer to the back material changes
} PDMATERIAL;
typedef struct _POLYMATERIAL { GLuint iMat; // next available material structure for this command batch
PDMATERIAL *pdMaterial0; // pointer to the PDMATERIAL array
GLuint aMatSize; // number of aMat entries
__GLmatChange *aMat[1]; // array of array of __GLmatChange structures
} POLYMATERIAL;
#ifdef GL_WIN_phong_shading
#define __GL_PHONG_FRONT_FIRST_VALID 0x00000001
#define __GL_PHONG_BACK_FIRST_VALID 0x00000002
#define __GL_PHONG_FRONT_TRAIL_VALID 0x00000004
#define __GL_PHONG_BACK_TRAIL_VALID 0x00000008
#define __GL_PHONG_FRONT_FIRST 0
#define __GL_PHONG_BACK_FIRST 1
#define __GL_PHONG_FRONT_TRAIL 2
#define __GL_PHONG_BACK_TRAIL 3
typedef struct __GLphongMaterialDataRec { GLuint flags; __GLmatChange matChange[4]; } __GLphongMaterialData;
#endif //GL_WIN_phong_shading
/*
** Vertex structure. Each vertex contains enough state to properly ** render the active primitive. It is used by the front-end geometry ** and back-end rasterization pipelines. ** ** NOTE: Same as __GLvertex structure! ** NOTE: This structure is used by RasterPos and evaluator too! ** ** To minimize storage requirement, some front-end storage (e.g. obj and normal) ** is shared with back-end storage. */ typedef struct _POLYDATA { /*
** Keep this data structure aligned: have all vectors start on ** 4-word boundary, and sizeof this struct should be kept at ** a multiple of 4 words. Also helps to bunch together most ** frequently used items, helps cache. */
/*
** Bits are set in this indicating which fields of the vertex are ** valid. This field is shared with the back-end has field! */ GLuint flags;
/*
** Moved up here to keep GLcoords aligned. */ __GLcolor *color;
/*
** Clipping code mask. One bit is set for each clipping plane that ** the vertex is out on. */ GLuint clipCode;
/*
** Fog value for the vertex. This is only filled when doing cheap ** fogging. */ __GLfloat fog;
/*
** Coordinates straight from client. These fields may not be ** set depending on the active modes. The normal and texture ** coordinate are used by lighting and texturing. These cells ** may be overwritten by the eyeNormal and the generated texture ** coordinate, depending on the active modes. */ /*
** Projected eye coodinate. This field is filled in when the users ** eye coordinate has been multiplied by the projection matrix. */ union { __GLcoord obj; __GLcoord clip; };
/*
** Window coordinate. This field is filled in when the eye coordinate ** is converted to a drawing surface relative "window" coordinate. ** NOTE: the window.w coordinate contains 1/clip.w. */ __GLcoord window;
__GLcoord texture; __GLcoord normal; /*
** Colors. colors[0] is the "front" color, colors[1] is the "back" color. ** The color pointer points to which color is current for this ** vertex. Verticies can have more than one color when two sided ** lighting is enabled. (note color pointer moved up top). */ __GLcolor colors[2];
/*
** Eye coordinate. This field is filled in when the object coordinate ** has been multiplied by the model-view matrix. If no eye coordinate ** was needed then this field contains undefined values. */ union { __GLcoord eye; struct { __GLfloat eyeX; __GLfloat eyeZ; __GLfloat eyeY; union { __GLfloat eyeW; __GLcolor *lastColor; }; }; };
/*
** On Win64 the POLYARRAY structure is larger than the POLYDATA ** structure since the later contains several pointers which are ** 8 bytes on the 64-bit system. Therefore, this structure must ** be padded to be the same size as the POLYARRAY structure. ** ** N.B. Since the structure must be the same size as the __GLvertex ** structure, then that structure must also be padded. ** */
#if defined(_WIN64)
PVOID Filler[7];
#endif
} POLYDATA;
// This structure is used by RasterPos and evaluator too!
// This structure is also in the TEB!
typedef struct _POLYARRAY { // Flags for this batch. Keep it first!
GLuint flags;
// Pointer to the next vertex in this batch.
POLYDATA *pdNextVertex;
// Pointer to the last vertex modifying the current color, RGBA or CI
// depending on color mode, in this batch.
POLYDATA *pdCurColor;
// Pointer to the last vertex modifying normal coordinates in this batch.
POLYDATA *pdCurNormal;
// Pointer to the last vertex modifying texture coordinates in this batch.
POLYDATA *pdCurTexture;
// Pointer to the last vertex modifying edge flag in this batch.
POLYDATA *pdCurEdgeFlag;
// Pointer to the first vertex of this batch.
// (pd0-1) points to this batch's POLYARRAY structure.
POLYDATA *pd0;
// Pointer to the flush vertex of this batch.
POLYDATA *pdFlush;
// Pointer to the vertex buffer entry in the gc for the next batch.
POLYDATA *pdBufferNext;
// Pointer to the first vertex buffer entry in the gc.
POLYDATA *pdBuffer0;
// Pointer to the last vertex buffer entry in the gc.
POLYDATA *pdBufferMax;
// In RGBA mode, otherColor.r is the last modified color index value in
// this batch. In CI mode, otherColor is the last modified RGBA color in
// this batch. Keep this field aligned!
__GLcolor otherColor;
// Primitive type.
GLenum primType;
// Or result of all vertex clipCode's in this batch.
GLuint orClipCodes;
// Pointer to the next message offset in the batching command buffer.
// We use this offset to determine if 2 POLYARRAY's can be linked in
// a DrawPolyArray command.
ULONG nextMsgOffset;
// Linear pointer to this thread's TEB POLYARRAY, kept here
// so the current POLYARRAY pointer can be retrieved from the
// TEB with a single instruction
struct _POLYARRAY *paTeb;
// This is used to form a linked list of POLYARRAY data to be
// processed in the DrawPolyArray command.
struct _POLYARRAY *paNext;
// Number of vertices in this primitive.
GLint nIndices;
// Index map array defining vertex drawing order. If NULL, the
// vertex order starts from pd0 through (pdNextVertex-1).
GLubyte *aIndices;
// Fast pointer access to the shared command message buffer.
PVOID pMsgBatchInfo;
// MCD Driver-private texture handle, or key
DWORD textureKey;
// And result of all vertex clipCode's in this batch.
GLuint andClipCodes;
// Currently unused but space is reserved in the TEB for it
#ifdef GL_WIN_phong_shading
// anankan: Using it to store a ptr to the Phong data store.
__GLphongMaterialData *phong; #else
ULONG ulUnused[1]; #endif //GL_WIN_phong_shading
POLYDATA *pdLastEvalColor; POLYDATA *pdLastEvalNormal; POLYDATA *pdLastEvalTexture; } POLYARRAY;
// Special values for POLYARRAY members
// Initial value for aIndices
#define PA_aIndices_INITIAL_VALUE ((GLubyte *) -1)
// Reset value for nextMsgOffset
#define PA_nextMsgOffset_RESET_VALUE ((ULONG) -1)
/*
** Edge tag. When POLYDATA_EDGEFLAG_BOUNDARY is set, this vertex and the next ** form a boundary edge on the primitive (polygon, tstrip, tfan, qstrip). */ #define POLYDATA_EDGEFLAG_BOUNDARY 0x00000001 // must be 1, same as
// __GL_HAS_EDGEFLAG_BOUNDARY
#define POLYDATA_EDGEFLAG_VALID 0x00000002
#define POLYDATA_COLOR_VALID 0x00000004
#define POLYDATA_NORMAL_VALID 0x00000008
#define POLYDATA_TEXTURE_VALID 0x00000010
#define POLYDATA_VERTEX2 0x00000020 // same as POLYARRAY_
#define POLYDATA_VERTEX3 0x00000040 // same as POLYARRAY_
#define POLYDATA_VERTEX4 0x00000080 // same as POLYARRAY_
/* flags for evaluators */ #define POLYDATA_EVALCOORD 0x00000100 // same as POLYARRAY_
#define POLYDATA_EVAL_TEXCOORD 0x00000200 // same as POLYARRAY_
#define POLYDATA_EVAL_NORMAL 0x00000400 // same as POLYARRAY_
#define POLYDATA_EVAL_COLOR 0x00000800 // same as POLYARRAY_
#define POLYDATA_DLIST_COLOR_4 0x00002000 // client side dlist flag
#define POLYDATA_FOG_VALID 0x00004000 // same as __GL_HAS_FOG
// 0x00008000 // reserved
#define POLYDATA_DLIST_TEXTURE1 0x00100000 // client side dlist flag
#define POLYDATA_DLIST_TEXTURE2 0x00200000 // client side dlist flag
#define POLYDATA_DLIST_TEXTURE3 0x00400000 // client side dlist flag
#define POLYDATA_DLIST_TEXTURE4 0x00800000 // client side dlist flag
#define POLYDATA_MATERIAL_FRONT 0x10000000 // same as POLYARRAY_
#define POLYDATA_MATERIAL_BACK 0x20000000 // same as POLYARRAY_
//
// This flag is valid when POLYARRAY_HAS_CULLED_VERTEX is set only.
// We have to process vertex when this flag set
//
#ifdef GL_EXT_cull_vertex
#define POLYDATA_VERTEX_USED 0x01000000
#endif //GL_EXT_cull_vertex
#define POLYARRAY_IN_BEGIN 0x00000001
#define POLYARRAY_EYE_PROCESSED 0x00000002
#define POLYARRAY_OTHER_COLOR 0x00000004
#define POLYARRAY_PARTIAL_BEGIN 0x00000008
#define POLYARRAY_PARTIAL_END 0x00000010
#define POLYARRAY_VERTEX2 0x00000020 // same as POLYDATA_
#define POLYARRAY_VERTEX3 0x00000040 // same as POLYDATA_
#define POLYARRAY_VERTEX4 0x00000080 // same as POLYDATA_
/* Recycling these flags for evaluators */ #define POLYARRAY_EVALCOORD 0x00000100 // same as POLYDATA_
#define POLYARRAY_EVAL_TEXCOORD 0x00000200 // same as POLYDATA_
#define POLYARRAY_EVAL_NORMAL 0x00000400 // same as POLYDATA_
#define POLYARRAY_EVAL_COLOR 0x00000800 // same as POLYDATA_
#define POLYARRAY_REMOVE_PRIMITIVE 0x00001000
//
// This flag is set when one of vertices has been culled by dot product
// between normal at the vertex and eye direction
//
#ifdef GL_EXT_cull_vertex
#define POLYARRAY_HAS_CULLED_VERTEX 0x02000000
#endif //GL_EXT_cull_vertex
#ifdef GL_WIN_phong_shading
#define POLYARRAY_PHONG_DATA_VALID 0x00002000
#endif //GL_WIN_phong_shading
#define POLYARRAY_RESET_STIPPLE 0x00004000
#define POLYARRAY_RENDER_PRIMITIVE 0x00008000
#define POLYARRAY_SAME_POLYDATA_TYPE 0x00010000
#define POLYARRAY_RASTERPOS 0x00020000
#define POLYARRAY_SAME_COLOR_DATA 0x00040000
#define POLYARRAY_TEXTURE1 0x00100000 // same as POLYDATA_DLIST_
#define POLYARRAY_TEXTURE2 0x00200000 // same as POLYDATA_DLIST_
#define POLYARRAY_TEXTURE3 0x00400000 // same as POLYDATA_DLIST_
#define POLYARRAY_TEXTURE4 0x00800000 // same as POLYDATA_DLIST_
#define POLYARRAY_MATERIAL_FRONT 0x10000000 // same as POLYDATA_
#define POLYARRAY_MATERIAL_BACK 0x20000000 // same as POLYDATA_
#define POLYARRAY_CLAMP_COLOR 0x80000000 // must be 0x80000000
/************************************************************************/
GLuint FASTCALL PAClipCheckFrustum(__GLcontext *gc, POLYARRAY *pa, POLYDATA *pdLast); GLuint FASTCALL PAClipCheckFrustum2D(__GLcontext *gc, POLYARRAY *pa, POLYDATA *pdLast); GLuint FASTCALL PAClipCheckAll(__GLcontext *gc, POLYARRAY *pa, POLYDATA *pdLast);
typedef void (FASTCALL *PFN_POLYARRAYCALCCOLORSKIP) (__GLcontext *, POLYARRAY *, GLint); typedef void (FASTCALL *PFN_POLYARRAYCALCCOLOR) (__GLcontext *, GLint, POLYARRAY *, POLYDATA *, POLYDATA *); typedef void (FASTCALL *PFN_POLYARRAYAPPLYCHEAPFOG) (__GLcontext *gc, POLYARRAY *pa);
void FASTCALL PolyArrayFillIndex0(__GLcontext *gc, POLYARRAY *pa, GLint face); void FASTCALL PolyArrayFillColor0(__GLcontext *gc, POLYARRAY *pa, GLint face);
#ifdef GL_WIN_phong_shading
void FASTCALL PolyArrayPhongPropagateColorNormal(__GLcontext *gc, POLYARRAY *pa); #endif //GL_WIN_phong_shading
void FASTCALL PolyArrayCalcRGBColor(__GLcontext *gc, GLint face, POLYARRAY *pa, POLYDATA *pd1, POLYDATA *pd2); void FASTCALL PolyArrayFastCalcRGBColor(__GLcontext *gc, GLint face, POLYARRAY *pa, POLYDATA *pd1, POLYDATA *pd2); void FASTCALL PolyArrayZippyCalcRGBColor(__GLcontext *gc, GLint face, POLYARRAY *pa, POLYDATA *pd1, POLYDATA *pd2); void FASTCALL PolyArrayCalcCIColor(__GLcontext *gc, GLint face, POLYARRAY *pa, POLYDATA *pd1, POLYDATA *pd2); void FASTCALL PolyArrayFastCalcCIColor(__GLcontext *gc, GLint face, POLYARRAY *pa, POLYDATA *pd1, POLYDATA *pd2); void FASTCALL PolyArrayCheapFogRGBColor(__GLcontext *gc, POLYARRAY *pa); void FASTCALL PolyArrayCheapFogCIColor(__GLcontext *gc, POLYARRAY *pa); void FASTCALL PolyArrayFlushPartialPrimitive(void); __GLmatChange * FASTCALL PAMatAlloc(void); void FASTCALL FreePolyMaterial(void); GLboolean FASTCALL PolyArrayAllocBuffer(__GLcontext *gc, GLuint nVertices); GLvoid FASTCALL PolyArrayFreeBuffer(__GLcontext *gc); GLvoid FASTCALL PolyArrayResetBuffer(__GLcontext *gc); GLvoid FASTCALL PolyArrayRestoreColorPointer(POLYARRAY *pa);
#endif /* __PARRAY_H__ */
|