452 lines
16 KiB
C
452 lines
16 KiB
C
|
#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__ */
|