Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

4484 lines
116 KiB

/******************************Module*Header*******************************\
* Module Name: glcltgs.c
*
* Routines to batch function calls and primitives
*
* Copyright (c) 1993-1996 Microsoft Corporation
\**************************************************************************/
/*
** Copyright 1991-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.
*/
/*
* AUTOMATICALLY UPDATED OR GENERATED BY SGI: DO NOT EDIT
* IF YOU MUST MODIFY THIS FILE, PLEASE CONTACT [email protected] 415-390-1483
*/
#include "precomp.h"
#pragma hdrstop
/* Generic OpenGL Client using subbatching. */
#include <string.h>
#include "imports.h"
#include "types.h"
#include "glsbmsg.h"
#include "glsbmsgh.h"
#include "glsrvspt.h"
#include "subbatch.h"
#include "batchinf.h"
#include "glteb.h"
#include "glsbcltu.h"
#include "glclt.h"
#include "compsize.h"
#include "context.h"
#include "global.h"
#include "parray.h"
#include "glarray.h"
#include "lighting.h"
#include "imfuncs.h"
#include "..\dlist\dlistopt.h"
//
// extension apis these are not exported
//
void APIENTRY
glAddSwapHintRectWIN(IN GLint x, IN GLint y, IN GLint width, IN GLint height)
{
PLRC plrc = GLTEB_CLTCURRENTRC();
if (plrc == NULL || plrc->dhrc != 0) {
// this api should only be called if there is a generic rc
// currently selected.
return;
}
GLCLIENT_BEGIN( AddSwapHintRectWIN, ADDSWAPHINTRECTWIN )
pMsg->xs = x;
pMsg->ys = y;
pMsg->xe = x + width;
pMsg->ye = y + height;
return;
GLCLIENT_END
}
#ifdef PRIMITIVE_TRACK
static ULONG prim_entries;
static ULONG prim_total = 0;
static ULONG prim_count = 0;
#endif
// Polyarray begin flags. Reset line stipple for new line loop,
// line strip, and polygon.
// Assume that all vertices have the same color.
GLuint aPolyArrayBeginFlags[] =
{
POLYARRAY_IN_BEGIN | POLYARRAY_SAME_COLOR_DATA, // GL_POINTS
POLYARRAY_IN_BEGIN | POLYARRAY_SAME_COLOR_DATA, // GL_LINES
POLYARRAY_IN_BEGIN | POLYARRAY_SAME_COLOR_DATA | POLYARRAY_RESET_STIPPLE, // GL_LINE_LOOP
POLYARRAY_IN_BEGIN | POLYARRAY_SAME_COLOR_DATA | POLYARRAY_RESET_STIPPLE, // GL_LINE_STRIP
POLYARRAY_IN_BEGIN | POLYARRAY_SAME_COLOR_DATA, // GL_TRIANGLES
POLYARRAY_IN_BEGIN | POLYARRAY_SAME_COLOR_DATA, // GL_TRIANGLE_STRIP
POLYARRAY_IN_BEGIN | POLYARRAY_SAME_COLOR_DATA, // GL_TRIANGLE_FAN
POLYARRAY_IN_BEGIN | POLYARRAY_SAME_COLOR_DATA, // GL_QUADS
POLYARRAY_IN_BEGIN | POLYARRAY_SAME_COLOR_DATA, // GL_QUAD_STRIP
POLYARRAY_IN_BEGIN | POLYARRAY_SAME_COLOR_DATA | POLYARRAY_RESET_STIPPLE // GL_POLYGON
};
// If you modify this function, you need to also modify VA_DrawElementsBegin.
void APIENTRY
glcltBegin ( IN GLenum mode )
{
POLYARRAY *pa;
POLYDATA *pd0, *pdFlush;
GLMSG_DRAWPOLYARRAY *pMsgDrawPolyArray;
// The invalid functions within begin/end are detected in glsbAttention.
pa = GLTEB_CLTPOLYARRAY();
// The vertex buffer is used as follows. The first entry contains the
// POLYARRAY structure. The incoming vertices will be saved beginning
// at a following entry. As an optimization, the POLYARRAY structure is
// kept in the TEB. When glEnd is called, it will be copied to the
// vertex buffer.
#ifndef _WIN95_
ASSERTOPENGL(sizeof(POLYARRAY) <= sizeof(NtCurrentTeb()->glReserved1),
"POLYARRAY and TEB sizes mismatch!");
#endif
ASSERTOPENGL(sizeof(POLYDATA) == sizeof(__GLvertex),
"POLYDATA and __GLvertex sizes mismatch!");
ASSERTOPENGL(sizeof(POLYARRAY) <= sizeof(POLYDATA),
"POLYARRAY and POLYDATA sizes mismatch!");
// Keep vertex structure a multiple of 4 bytes (or 8 bytes).
// The vertex buffer must be 4-byte aligned.
ASSERTOPENGL(!(sizeof(POLYDATA) & 0x3), "bad POLYDATA size!");
ASSERTOPENGL(!((ULONG)pa->pdBuffer0 & 0x3), "POLYDATA should be aligned!\n");
// If we are already in the begin/end bracket, return an error.
if (pa->flags & POLYARRAY_IN_BEGIN)
{
GLSETERROR(GL_INVALID_OPERATION);
return;
}
if ((GLuint) mode > GL_POLYGON)
{
GLSETERROR(GL_INVALID_ENUM);
return;
}
// Flush the command buffer if the vertex buffer is nearly full.
// Otherwise, just continue with the next available vertex buffer entry.
if (pa->pdBufferNext > pa->pdBufferMax - MIN_POLYDATA_BATCH_SIZE)
{
#ifdef PRIMITIVE_TRACK
DbgPrint("* Min-not-present flush\n");
#endif
glsbAttention(); // it resets pdBufferNext pointer too
ASSERTOPENGL(pa->nextMsgOffset == -1, "bad nextMsgOffset\n");
}
// Batch POLYARRAY command in the command buffer.
// We want to leave enough room to accomodate at least one invalid command
// that may be batched in the begin/end bracket. When glsbAttention,
// glsbAttentionAlt, or glcltEnd is called, we will remove these invalid
// commands.
//
// Combine adjacent DrawPolyArray commands into one command.
// request DRAWPOLYARRAY_LARGE structure to make room for invalid commands
GLCLIENT_BEGIN(DrawPolyArray, DRAWPOLYARRAY_LARGE)
// need msg pointer to update pa later
pMsgDrawPolyArray = (GLMSG_DRAWPOLYARRAY *) pMsg;
if (pa->nextMsgOffset == CurrentOffset)
{
// rewind command buffer pointer
pMsgBatchInfo->NextOffset = CurrentOffset;
((BYTE *) pMsgDrawPolyArray) -=
GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY));
// chain adjacent DrawPolyArray commands
((POLYARRAY *) pMsgDrawPolyArray->paLast)->paNext
= (POLYARRAY *) pa->pdBufferNext;
((POLYARRAY *) pMsgDrawPolyArray->paLast)
= (POLYARRAY *) pa->pdBufferNext;
}
else
{
// resize the msg to the real size
pMsgBatchInfo->NextOffset = CurrentOffset
+ GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY));
// remember the end of the primitive command
pa->nextMsgOffset = pMsgBatchInfo->NextOffset;
// start of a new chain
pMsgDrawPolyArray->pa0 =
pMsgDrawPolyArray->paLast = (PVOID) pa->pdBufferNext;
}
GLCLIENT_END
// Compute the start of the primitive. A new primitive always begins with a
// POLYARRAY entry immediately followed by vertex entries.
pd0 = pa->pdBufferNext + 1;
// Initialize first polydata.
pd0->flags = 0;
ASSERTOPENGL(pd0->color == &pd0->colors[__GL_FRONTFACE],
"bad color pointer!\n");
// Initialize the polyarray structure in the TEB.
pa->flags = aPolyArrayBeginFlags[mode];
pa->pdNextVertex =
pa->pdCurColor =
pa->pdCurNormal =
pa->pdCurTexture =
pa->pdCurEdgeFlag =
pa->pd0 = pd0;
pa->primType = mode;
pa->paNext = NULL;
pa->nIndices = 0;
pa->aIndices = NULL; // identity mapping
// Compute the flush vertex for this primitive. When the flush vertex is
// reached, we will have accumulated enough vertices to render a partially
// composed primitive.
pdFlush = pa->pdBufferMax;
switch (mode)
{
case GL_POINTS:
case GL_LINE_STRIP:
case GL_TRIANGLE_FAN:
break;
case GL_LINE_LOOP:
// Line loop reserves an additional end vertex to close the loop.
pdFlush--;
break;
case GL_POLYGON:
// The polygon decomposer can only handle up to
// __GL_MAX_POLYGON_CLIP_SIZE vertices.
if (pdFlush > pd0 + __GL_MAX_POLYGON_CLIP_SIZE - 1);
pdFlush = pd0 + __GL_MAX_POLYGON_CLIP_SIZE - 1;
break;
case GL_LINES:
case GL_TRIANGLE_STRIP:
case GL_QUAD_STRIP:
// number of vertices must be a multiple of 2
if ((pdFlush - pd0 + 1) % 2)
pdFlush--;
break;
case GL_TRIANGLES:
// number of vertices must be a multiple of 3
switch ((pdFlush - pd0 + 1) % 3)
{
case 2: pdFlush--; // fall through
case 1: pdFlush--;
}
break;
case GL_QUADS:
// number of vertices must be a multiple of 4
switch ((pdFlush - pd0 + 1) % 4)
{
case 3: pdFlush--; // fall through
case 2: pdFlush--; // fall through
case 1: pdFlush--;
}
break;
}
pa->pdFlush = pdFlush;
#ifdef PRIMITIVE_TRACK
DbgPrint("glcltBegin with %3d space left\n", pdFlush-pd0+1);
prim_entries = 0;
#endif
}
// Special version of Begin for DrawElements.
// If you modify this function, you need to also modify glcltBegin.
void FASTCALL VA_DrawElementsBegin(POLYARRAY *pa, GLenum mode, GLsizei count)
{
POLYDATA *pd0;
GLMSG_DRAWPOLYARRAY *pMsgDrawPolyArray;
GLint maxVertexCount;
// The vertex buffer is used as follows. The first entry contains the
// POLYARRAY structure. The incoming vertices will be saved beginning
// at a following entry. As an optimization, the POLYARRAY structure is
// kept in the TEB. When VA_DrawElementsEnd is called, it will be copied
// to the vertex buffer.
// We don't handle Points, Line Loop, and Polygon here. They should
// have been sent to Begin/End.
ASSERTOPENGL(mode != GL_POINTS && mode != GL_LINE_LOOP && mode != GL_POLYGON,
"Primitive type not handled\n");
// Flush the command buffer if the vertex buffer will overflow.
// Otherwise, just continue with the next available vertex buffer entry.
// Maximum number of vertex entries that we will handle in next batch
maxVertexCount = min(count,VA_DRAWELEM_MAP_SIZE)
// Add maximum number of entries used for index map
+ (VA_DRAWELEM_INDEX_SIZE + sizeof(POLYDATA) - 1) / sizeof(POLYDATA)
// Reserve an extra vertex entry to prevent calling
// PolyArrayFlushPartialPrimitive in the Vertex routines.
// It should call VA_DrawElementsFlushPartialPrimitive instead.
+ 1
// Add an entry for POLYARRAY
+ 1
// Add a few more entries to be safe
+ 4;
if (pa->pdBufferNext > pa->pdBufferMax - maxVertexCount + 1)
{
#ifdef PRIMITIVE_TRACK
DbgPrint("* Min-not-present flush\n");
#endif
glsbAttention(); // it resets pdBufferNext pointer too
ASSERTOPENGL(pa->nextMsgOffset == -1, "bad nextMsgOffset\n");
}
// The vertex buffer must have at least maxVertexCount (currently <= 277)
// entries.
ASSERTOPENGL(maxVertexCount <= pa->pdBufferMax - pa->pdBuffer0 + 1,
"vertex buffer is too small!\n");
// Batch POLYARRAY command in the command buffer.
// Combine adjacent DrawPolyArray commands into one command.
GLCLIENT_BEGIN(DrawPolyArray, DRAWPOLYARRAY)
// need msg pointer to update pa later
pMsgDrawPolyArray = pMsg;
if (pa->nextMsgOffset == CurrentOffset)
{
// rewind command buffer pointer
pMsgBatchInfo->NextOffset = CurrentOffset;
((BYTE *) pMsgDrawPolyArray) -=
GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY));
// chain adjacent DrawPolyArray commands
((POLYARRAY *) pMsgDrawPolyArray->paLast)->paNext
= (POLYARRAY *) pa->pdBufferNext;
((POLYARRAY *) pMsgDrawPolyArray->paLast)
= (POLYARRAY *) pa->pdBufferNext;
}
else
{
// remember the end of the primitive command
pa->nextMsgOffset = pMsgBatchInfo->NextOffset;
// start of a new chain
pMsgDrawPolyArray->pa0 =
pMsgDrawPolyArray->paLast = (PVOID) pa->pdBufferNext;
}
GLCLIENT_END
// Compute the start of the primitive. A new primitive always begins with a
// POLYARRAY entry immediately followed by vertex entries.
pd0 = pa->pdBufferNext + 1;
// Initialize first polydata.
pd0->flags = 0;
ASSERTOPENGL(pd0->color == &pd0->colors[__GL_FRONTFACE],
"bad color pointer!\n");
// Initialize the polyarray structure in the TEB.
pa->flags = aPolyArrayBeginFlags[mode] | POLYARRAY_SAME_POLYDATA_TYPE;
pa->pdNextVertex =
pa->pdCurColor =
pa->pdCurNormal =
pa->pdCurTexture =
pa->pdCurEdgeFlag =
pa->pd0 = pd0;
pa->primType = mode;
pa->paNext = NULL;
pa->nIndices = 0;
pa->aIndices = (GLubyte *) -1; // this is updated in End
// The flush vertex for this primitive should never be reached. We have
// reserved enough room for a vertex batch. Set it to maximum and assert
// that we never reach the vertex in PolyArrayFlushPartialPrimitive!
pa->pdFlush = pa->pdBufferMax;
#ifdef PRIMITIVE_TRACK
DbgPrint("VA_DrawElementsBegin with %3d space left\n", pa->pdBufferMax-pd0+1);
#endif
return;
}
void APIENTRY
glcltEnd ( void )
{
POLYARRAY *pa;
GLMSG_DRAWPOLYARRAY *pMsgDrawPolyArray;
pa = GLTEB_CLTPOLYARRAY();
// Flush invalid commands accumulated in the command buffer if there is any.
glsbAttention();
// If we are not in the begin/end bracket, return an error.
if (!(pa->flags & POLYARRAY_IN_BEGIN))
{
GLSETERROR(GL_INVALID_OPERATION);
return;
}
// Clear the POLYARRAY_IN_BEGIN flag in the TEB. We are now out of
// the begin/end bracket.
pa->flags &= ~POLYARRAY_IN_BEGIN;
// Clear POLYARRAY_SAME_COLOR_DATA flag if the primitive uses more than
// one color. Also clear the flag if an evaluator is used. We cannot
// tell if an evaluator modifies the color on the client side.
if ((pa->pdCurColor != pa->pd0) ||
((pa->pd0->flags & POLYDATA_COLOR_VALID) &&
(pa->flags & POLYARRAY_PARTIAL_BEGIN)) ||
(pa->flags & (POLYARRAY_EVALCOORD1 | POLYARRAY_EVALCOORD2 |
POLYARRAY_EVALPOINT1 | POLYARRAY_EVALPOINT2)))
pa->flags &= ~POLYARRAY_SAME_COLOR_DATA;
// Compute nIndices. It is the final number of vertices passed to the low
// level render routines and is different from the number of polydata's
// accumulated. The final number includes the reserved vertices and the
// accumulated vertices.
pa->nIndices += pa->pdNextVertex - pa->pd0;
if (pa->primType == GL_LINE_LOOP)
pa->nIndices++; // add one extra vertex when a line loop is closed.
// It's okay not to advance pdBufferNext since we
// don't need attributes after they've been
// processed.
// Save the POLYARRAY structure in the batch.
pMsgDrawPolyArray = (GLMSG_DRAWPOLYARRAY *)
((BYTE *) pa->pMsgBatchInfo + pa->nextMsgOffset -
GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY)));
*(POLYARRAY *) pMsgDrawPolyArray->paLast = *pa;
#ifdef PRIMITIVE_TRACK
prim_entries += pa->pdNextVertex-pa->pd0;
prim_total += prim_entries;
prim_count++;
DbgPrint("glcltEnd with %3d polydata entries, %3d now, avg %d\n",
prim_entries, pa->pdNextVertex-pa->pd0, prim_total/prim_count);
#endif
// Advance polyarray batch pointer.
// Skip a vertex because it may contain attributes for the current batch.
pa->pdBufferNext = pa->pdNextVertex + 1;
}
void FASTCALL VA_DrawElementsEnd(POLYARRAY *pa)
{
GLMSG_DRAWPOLYARRAY *pMsgDrawPolyArray;
ASSERTOPENGL(pa->flags & POLYARRAY_IN_BEGIN, "not in begin\n");
ASSERTOPENGL(pa->aIndices && pa->aIndices != (GLubyte *) -1,
"no output index array!\n");
// Clear the POLYARRAY_IN_BEGIN flag in the TEB. We are now out of
// the begin/end bracket.
pa->flags &= ~POLYARRAY_IN_BEGIN;
// Clear POLYARRAY_SAME_COLOR_DATA flag if the primitive uses more than
// one color.
if (pa->pdCurColor != pa->pd0)
pa->flags &= ~POLYARRAY_SAME_COLOR_DATA;
// Save the POLYARRAY structure in the batch.
pMsgDrawPolyArray = (GLMSG_DRAWPOLYARRAY *)
((BYTE *) pa->pMsgBatchInfo + pa->nextMsgOffset -
GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY)));
*(POLYARRAY *) pMsgDrawPolyArray->paLast = *pa;
#ifdef PRIMITIVE_TRACK
prim_count++;
DbgPrint("VA_DrawElementsEnd called\n");
#endif
// Advance polyarray batch pointer.
pa->pdBufferNext = (POLYDATA *) (pa->aIndices +
(pa->nIndices + sizeof(POLYDATA) - 1) / sizeof(POLYDATA) * sizeof(POLYDATA));
}
// Number of reserved vertices for partial Begin.
GLint nReservedIndicesPartialBegin[] =
{
0, // GL_POINTS
0, // GL_LINES
1, // GL_LINE_LOOP
1, // GL_LINE_STRIP
0, // GL_TRIANGLES
2, // GL_TRIANGLE_STRIP
2, // GL_TRIANGLE_FAN
0, // GL_QUADS
2, // GL_QUAD_STRIP
3 // GL_POLYGON
};
// If you modify this function, you need to also modify
// VA_DrawElementsFlushPartialPrimitive.
void FASTCALL PolyArrayFlushPartialPrimitive()
{
POLYARRAY *pa;
POLYDATA *pd0, *pdFlush;
GLenum mode;
GLMSG_DRAWPOLYARRAY *pMsgDrawPolyArray;
GLuint paFlags;
__GL_SETUP();
pa = gc->paTeb;
#ifdef PRIMITIVE_TRACK
prim_entries += pa->pdNextVertex-pa->pd0;
DbgPrint("* Flush partial primitive with %d polydata entries\n",
pa->pdNextVertex-pa->pd0);
#endif
ASSERTOPENGL(pa->flags & POLYARRAY_IN_BEGIN, "not in begin\n");
ASSERTOPENGL(!pa->aIndices, "Flushing DrawElements unexpected!\n");
// Flush invalid commands accumulated in the command buffer if there is any.
glsbAttention();
// Clear the POLYARRAY_IN_BEGIN flag in the TEB. We are now out of
// the begin/end bracket temporarily. glsbAttention does not flush
// unless the flag is clear.
pa->flags &= ~POLYARRAY_IN_BEGIN;
// Mark it as a partially completed primitive batch.
pa->flags |= POLYARRAY_PARTIAL_END;
// Clear POLYARRAY_SAME_COLOR_DATA flag if the primitive uses more than
// one color. Also clear the flag if an evaluator is used. We cannot
// tell if an evaluator modifies the color on the client side.
if ((pa->pdCurColor != pa->pd0) ||
((pa->pd0->flags & POLYDATA_COLOR_VALID) &&
(pa->flags & POLYARRAY_PARTIAL_BEGIN)) ||
(pa->flags & (POLYARRAY_EVALCOORD1 | POLYARRAY_EVALCOORD2 |
POLYARRAY_EVALPOINT1 | POLYARRAY_EVALPOINT2)))
pa->flags &= ~POLYARRAY_SAME_COLOR_DATA;
// Save some pa flags for next partial primitive.
// Need to preserve POLYARRAY_CLAMP_COLOR flag in dlist playback.
paFlags = pa->flags & (POLYARRAY_SAME_POLYDATA_TYPE |
POLYARRAY_SAME_COLOR_DATA |
POLYARRAY_CLAMP_COLOR);
// Compute nIndices. It is the final number of vertices passed to the low
// level render routines and is different from the number of polydata's
// accumulated. The final number includes the reserved vertices and the
// accumulated vertices.
pa->nIndices += pa->pdNextVertex - pa->pd0;
// Save the POLYARRAY structure in the batch.
pMsgDrawPolyArray = (GLMSG_DRAWPOLYARRAY *)
((BYTE *) pa->pMsgBatchInfo + pa->nextMsgOffset -
GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY)));
*(POLYARRAY *) pMsgDrawPolyArray->paLast = *pa;
// Save states before flushing the batch.
mode = pa->primType;
// Flush the command buffer and reset pointer for the next batch.
// If we are compiling poly array primitive in dlist, record the last poly
// data record.
if (gc->dlist.beginRec)
{
// Record the poly data.
__glDlistCompilePolyData(gc, GL_FALSE);
// We just recorded this vertex, don't record it in the compile
// code again!
gc->dlist.skipPolyData = GL_TRUE;
if (gc->dlist.mode == GL_COMPILE_AND_EXECUTE)
glsbAttention(); // reset pdBufferNext pointer too!
else
glsbResetBuffers(TRUE); // reset pointers but no execution
}
else
{
glsbAttention(); // reset pdBufferNext pointer too!
}
ASSERTOPENGL(pa->nextMsgOffset == -1, "bad nextMsgOffset\n");
// Batch new POLYARRAY command in the command buffer.
GLCLIENT_BEGIN(DrawPolyArray, DRAWPOLYARRAY)
// need msg pointer to update pa later
pMsgDrawPolyArray = pMsg;
// start of a new chain
pMsgDrawPolyArray->pa0 =
pMsgDrawPolyArray->paLast = (PVOID) pa->pdBufferNext;
// remember the end of the primitive command
pa->nextMsgOffset = pMsgBatchInfo->NextOffset;
GLCLIENT_END
// Compute the start of the PARTIAL primitive. A partial primitive begins
// with a POLYARRAY entry followed by vertex entries. We need to
// reserve additional vertex entries at the beginning for connectivity
// between decomposed primitives.
pd0 = pa->pdBufferNext + 1 + nReservedIndicesPartialBegin[mode];
// Initialize first polydata.
pd0->flags = 0;
ASSERTOPENGL(pd0->color == &pd0->colors[__GL_FRONTFACE],
"bad color pointer!\n");
// Initialize the polyarray structure in the TEB.
pa->flags = POLYARRAY_IN_BEGIN | POLYARRAY_PARTIAL_BEGIN | paFlags;
pa->pdNextVertex =
pa->pdCurColor =
pa->pdCurNormal =
pa->pdCurTexture =
pa->pdCurEdgeFlag =
pa->pd0 = pd0;
pa->primType = mode;
pa->paNext = NULL;
pa->nIndices = nReservedIndicesPartialBegin[mode];
pa->aIndices = NULL; // identity mapping
// Compute the flush vertex for this primitive. When the flush vertex is
// reached, we will have accumulated enough vertices to render a partially
// composed primitive.
pdFlush = pa->pdBufferMax;
switch (mode)
{
case GL_POINTS:
case GL_LINE_STRIP:
case GL_TRIANGLE_FAN:
break;
case GL_LINE_LOOP:
// Line loop reserves an additional end vertex to close the loop.
pdFlush--;
break;
case GL_POLYGON:
// The polygon decomposer can only handle up to
// __GL_MAX_POLYGON_CLIP_SIZE vertices. We also need to give
// allowance for 3 vertices in the decomposed polygons.
if (pdFlush > (pd0 - 3) + __GL_MAX_POLYGON_CLIP_SIZE - 1)
pdFlush = (pd0 - 3) + __GL_MAX_POLYGON_CLIP_SIZE - 1;
ASSERTOPENGL(nReservedIndicesPartialBegin[GL_POLYGON] == 3,
"bad reserved size!\n");
break;
case GL_LINES:
case GL_TRIANGLE_STRIP:
case GL_QUAD_STRIP:
// number of vertices must be a multiple of 2
if ((pdFlush - pd0 + 1) % 2)
pdFlush--;
break;
case GL_TRIANGLES:
// number of vertices must be a multiple of 3
switch ((pdFlush - pd0 + 1) % 3)
{
case 2: pdFlush--; // fall through
case 1: pdFlush--;
}
break;
case GL_QUADS:
// number of vertices must be a multiple of 4
switch ((pdFlush - pd0 + 1) % 4)
{
case 3: pdFlush--; // fall through
case 2: pdFlush--; // fall through
case 1: pdFlush--;
}
break;
}
pa->pdFlush = pdFlush;
}
// Special version of Flush for DrawElements.
// If you modify this function, you need to also modify
// PolyArrayFlushPartialPrimitive.
void FASTCALL VA_DrawElementsFlushPartialPrimitive(POLYARRAY *pa, GLenum mode)
{
POLYDATA *pd0;
GLMSG_DRAWPOLYARRAY *pMsgDrawPolyArray;
GLuint paFlags;
__GL_SETUP();
#ifdef PRIMITIVE_TRACK
DbgPrint("VA_DrawElementsFlushPartialPrimitive called\n");
#endif
// We don't handle Points, Line Loop, and Polygon here. They should
// have been sent to Begin/End.
ASSERTOPENGL(mode != GL_POINTS && mode != GL_LINE_LOOP && mode != GL_POLYGON,
"Primitive type not handled\n");
ASSERTOPENGL(pa->flags & POLYARRAY_IN_BEGIN, "not in begin\n");
ASSERTOPENGL(pa->aIndices && pa->aIndices != (GLubyte *) -1,
"no output index array!\n");
// Clear the POLYARRAY_IN_BEGIN flag in the TEB. We are now out of
// the begin/end bracket temporarily. glsbAttention does not flush
// unless the flag is clear.
pa->flags &= ~POLYARRAY_IN_BEGIN;
// Mark it as a partially completed primitive batch.
pa->flags |= POLYARRAY_PARTIAL_END;
// Clear POLYARRAY_SAME_COLOR_DATA flag if the primitive uses more than
// one color.
if (pa->pdCurColor != pa->pd0)
pa->flags &= ~POLYARRAY_SAME_COLOR_DATA;
// Save some pa flags for next partial primitive.
paFlags = pa->flags & POLYARRAY_SAME_COLOR_DATA;
// Save the POLYARRAY structure in the batch.
pMsgDrawPolyArray = (GLMSG_DRAWPOLYARRAY *)
((BYTE *) pa->pMsgBatchInfo + pa->nextMsgOffset -
GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY)));
*(POLYARRAY *) pMsgDrawPolyArray->paLast = *pa;
// Flush the command buffer and reset pointer for the next batch.
ASSERTOPENGL(!gc->dlist.beginRec
|| gc->dlist.mode == GL_COMPILE_AND_EXECUTE,
"dlist complilation unexpected!\n");
glsbAttention(); // reset pdBufferNext pointer too!
ASSERTOPENGL(pa->nextMsgOffset == -1, "bad nextMsgOffset\n");
// Batch new POLYARRAY command in the command buffer.
GLCLIENT_BEGIN(DrawPolyArray, DRAWPOLYARRAY)
// need msg pointer to update pa later
pMsgDrawPolyArray = pMsg;
// start of a new chain
pMsgDrawPolyArray->pa0 =
pMsgDrawPolyArray->paLast = (PVOID) pa->pdBufferNext;
// remember the end of the primitive command
pa->nextMsgOffset = pMsgBatchInfo->NextOffset;
GLCLIENT_END
// Compute the start of the PARTIAL primitive. A partial primitive begins
// with a POLYARRAY entry followed by vertex entries. We need to
// reserve additional vertex entries at the beginning for connectivity
// between decomposed primitives.
pd0 = pa->pdBufferNext + 1 + nReservedIndicesPartialBegin[mode];
// Initialize first polydata.
pd0->flags = 0;
ASSERTOPENGL(pd0->color == &pd0->colors[__GL_FRONTFACE],
"bad color pointer!\n");
// Initialize the polyarray structure in the TEB.
pa->flags = POLYARRAY_IN_BEGIN | POLYARRAY_PARTIAL_BEGIN |
POLYARRAY_SAME_POLYDATA_TYPE | paFlags;
pa->pdNextVertex =
pa->pdCurColor =
pa->pdCurNormal =
pa->pdCurTexture =
pa->pdCurEdgeFlag =
pa->pd0 = pd0;
pa->primType = mode;
pa->paNext = NULL;
pa->nIndices = nReservedIndicesPartialBegin[mode];
pa->aIndices = (GLubyte *) -1; // this is updated in End
// The flush vertex for this primitive should never be reached. The call
// to glsbAttention in this function has left enough room for a vertex batch.
// Set it to maximum and assert that we never reach the vertex in
// PolyArrayFlushPartialPrimitive!
pa->pdFlush = pa->pdBufferMax;
}
// The vertex functions are called in begin/end only.
#define PA_VERTEX2(x1,y1) \
\
POLYARRAY *pa; \
POLYDATA *pd; \
\
pa = GLTEB_CLTPOLYARRAY(); \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pa->flags |= POLYARRAY_VERTEX2; \
\
pd = pa->pdNextVertex++; \
pd->flags |= POLYDATA_VERTEX2; \
pd->obj.x = x1; \
pd->obj.y = y1; \
pd->obj.z = __glZero; \
pd->obj.w = __glOne; \
\
pd[1].flags = 0; \
\
if (pd >= pa->pdFlush) \
PolyArrayFlushPartialPrimitive(); \
}
#define PA_VERTEX3(x1,y1,z1) \
\
POLYARRAY *pa; \
POLYDATA *pd; \
\
pa = GLTEB_CLTPOLYARRAY(); \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pa->flags |= POLYARRAY_VERTEX3; \
\
pd = pa->pdNextVertex++; \
pd->flags |= POLYDATA_VERTEX3; \
pd->obj.x = x1; \
pd->obj.y = y1; \
pd->obj.z = z1; \
pd->obj.w = __glOne; \
\
pd[1].flags = 0; \
\
if (pd >= pa->pdFlush) \
PolyArrayFlushPartialPrimitive(); \
}
#define PA_VERTEX4(x1,y1,z1,w1) \
\
POLYARRAY *pa; \
POLYDATA *pd; \
\
pa = GLTEB_CLTPOLYARRAY(); \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pa->flags |= POLYARRAY_VERTEX4; \
\
pd = pa->pdNextVertex++; \
pd->flags |= POLYDATA_VERTEX4; \
pd->obj.x = x1; \
pd->obj.y = y1; \
pd->obj.z = z1; \
pd->obj.w = w1; \
\
pd[1].flags = 0; \
\
if (pd >= pa->pdFlush) \
PolyArrayFlushPartialPrimitive(); \
}
#define PA_COLOR_IN_RGBA_NO_CLAMP1(red,green,blue) \
POLYARRAY *pa; \
POLYDATA *pd; \
__GL_SETUP(); \
\
pa = gc->paTeb; \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pd = pa->pdNextVertex; \
pa->pdCurColor = pd; \
\
__GL_SCALE_R(pd->colors[0].r, gc, red); \
__GL_SCALE_G(pd->colors[0].g, gc, green); \
__GL_SCALE_B(pd->colors[0].b, gc, blue); \
pd->colors[0].a = gc->alphaVertexScale; \
\
pd->flags |= POLYDATA_COLOR_VALID; \
} \
else \
{ \
glcltColor4f_InRGBA_NotInBegin(gc, pa, \
POLYDATA_COLOR_VALID, red, green, blue, __glOne); \
}
#define PA_COLOR_IN_RGBA_NO_CLAMP(red,green,blue,alpha) \
POLYARRAY *pa; \
POLYDATA *pd; \
__GL_SETUP(); \
\
pa = gc->paTeb; \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pd = pa->pdNextVertex; \
pa->pdCurColor = pd; \
\
__GL_SCALE_R(pd->colors[0].r, gc, red); \
__GL_SCALE_G(pd->colors[0].g, gc, green); \
__GL_SCALE_B(pd->colors[0].b, gc, blue); \
__GL_SCALE_A(pd->colors[0].a, gc, alpha); \
\
pd->flags |= POLYDATA_COLOR_VALID | POLYDATA_DLIST_COLOR_4; \
} \
else \
{ \
glcltColor4f_InRGBA_NotInBegin(gc, pa, \
POLYDATA_COLOR_VALID | POLYDATA_DLIST_COLOR_4, red, green, blue, alpha);\
}
#define PA_COLOR_IN_RGB1(red,green,blue) \
POLYARRAY *pa; \
POLYDATA *pd; \
__GL_SETUP(); \
\
pa = gc->paTeb; \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pd = pa->pdNextVertex; \
pa->pdCurColor = pd; \
\
__GL_SCALE_AND_CHECK_CLAMP_R(pd->colors[0].r, gc, pa->flags, red); \
__GL_SCALE_AND_CHECK_CLAMP_G(pd->colors[0].g, gc, pa->flags, green);\
__GL_SCALE_AND_CHECK_CLAMP_B(pd->colors[0].b, gc, pa->flags, blue); \
pd->colors[0].a = gc->alphaVertexScale; \
\
pd->flags |= POLYDATA_COLOR_VALID; \
} \
else \
{ \
glcltColor4f_InRGBA_NotInBegin(gc, pa, \
POLYDATA_COLOR_VALID, red, green, blue, __glOne); \
}
#define PA_COLOR_IN_RGBA(red,green,blue,alpha) \
POLYARRAY *pa; \
POLYDATA *pd; \
__GL_SETUP(); \
\
pa = gc->paTeb; \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pd = pa->pdNextVertex; \
pa->pdCurColor = pd; \
\
__GL_SCALE_AND_CHECK_CLAMP_R(pd->colors[0].r, gc, pa->flags, red); \
__GL_SCALE_AND_CHECK_CLAMP_G(pd->colors[0].g, gc, pa->flags, green);\
__GL_SCALE_AND_CHECK_CLAMP_B(pd->colors[0].b, gc, pa->flags, blue); \
__GL_SCALE_AND_CHECK_CLAMP_A(pd->colors[0].a, gc, pa->flags, alpha);\
\
pd->flags |= POLYDATA_COLOR_VALID | POLYDATA_DLIST_COLOR_4; \
} \
else \
{ \
glcltColor4f_InRGBA_NotInBegin(gc, pa, \
POLYDATA_COLOR_VALID | POLYDATA_DLIST_COLOR_4, red, green, blue, alpha);\
}
#define PA_COLOR_IN_CI(red,green,blue,alpha) \
\
POLYARRAY *pa; \
\
pa = GLTEB_CLTPOLYARRAY(); \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pa->flags |= POLYARRAY_OTHER_COLOR; \
/* need only record the latest values */ \
/* otherColor in the TEB may not be aligned at 16-byte boundary */ \
pa->otherColor.r = red; \
pa->otherColor.g = green; \
pa->otherColor.b = blue; \
pa->otherColor.a = alpha; \
} \
else \
{ \
glcltColor4f_NotInBegin(red, green, blue, alpha); \
}
void FASTCALL glcltColor4f_NotInBegin(GLfloat red, GLfloat green,
GLfloat blue, GLfloat alpha)
{
GLCLIENT_BEGIN( Color4fv, COLOR4FV )
pMsg->v[0] = red;
pMsg->v[1] = green;
pMsg->v[2] = blue;
pMsg->v[3] = alpha;
GLCLIENT_END
}
void FASTCALL glcltColor4f_InRGBA_NotInBegin(__GLcontext *gc, POLYARRAY *pa,
GLuint pdFlags, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
POLYDATA *pd;
GLMSGBATCHINFO *pMsgBatchInfo;
GLMSG_DRAWPOLYARRAY *pMsgDrawPolyArray;
pMsgBatchInfo = (GLMSGBATCHINFO *) pa->pMsgBatchInfo;
// If the last command is DrawPolyArray, add it to the command.
// This allows us to chain primitives separated by the attribute.
if (pMsgBatchInfo->NextOffset == pa->nextMsgOffset)
{
pMsgDrawPolyArray = (GLMSG_DRAWPOLYARRAY *)
((BYTE *) pMsgBatchInfo + pMsgBatchInfo->NextOffset -
GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY)));
pa = (POLYARRAY *) pMsgDrawPolyArray->paLast;
pd = pa->pdNextVertex;
pa->pdCurColor = pd;
__GL_SCALE_AND_CHECK_CLAMP_R(pd->colors[0].r, gc, pa->flags, red);
__GL_SCALE_AND_CHECK_CLAMP_G(pd->colors[0].g, gc, pa->flags, green);
__GL_SCALE_AND_CHECK_CLAMP_B(pd->colors[0].b, gc, pa->flags, blue);
__GL_SCALE_AND_CHECK_CLAMP_A(pd->colors[0].a, gc, pa->flags, alpha);
pd->flags |= pdFlags;
}
else
{
glcltColor4f_NotInBegin(red, green, blue, alpha);
}
}
#define PA_INDEX_IN_RGBA(i) \
\
POLYARRAY *pa; \
\
pa = GLTEB_CLTPOLYARRAY(); \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pa->flags |= POLYARRAY_OTHER_COLOR; \
/* need only record the latest value */ \
pa->otherColor.r = i; \
} \
else \
{ \
glcltIndexf_NotInBegin(i); \
}
#define PA_INDEX_IN_CI(i) \
\
POLYARRAY *pa; \
POLYDATA *pd; \
__GL_SETUP(); \
\
pa = gc->paTeb; \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pd = pa->pdNextVertex; \
pa->pdCurColor = pd; \
__GL_CHECK_CLAMP_CI(pd->colors[0].r, gc, pa->flags, i); \
pd->flags |= POLYDATA_COLOR_VALID; \
} \
else \
{ \
glcltIndexf_InCI_NotInBegin(gc, pa, i); \
}
void FASTCALL glcltIndexf_NotInBegin(GLfloat c)
{
GLCLIENT_BEGIN( Indexf, INDEXF )
pMsg->c = c;
GLCLIENT_END
}
void FASTCALL glcltIndexf_InCI_NotInBegin(__GLcontext *gc, POLYARRAY *pa, GLfloat c)
{
POLYDATA *pd;
GLMSGBATCHINFO *pMsgBatchInfo;
GLMSG_DRAWPOLYARRAY *pMsgDrawPolyArray;
pMsgBatchInfo = (GLMSGBATCHINFO *) pa->pMsgBatchInfo;
// If the last command is DrawPolyArray, add it to the command.
// This allows us to chain primitives separated by the attribute.
if (pMsgBatchInfo->NextOffset == pa->nextMsgOffset)
{
pMsgDrawPolyArray = (GLMSG_DRAWPOLYARRAY *)
((BYTE *) pMsgBatchInfo + pMsgBatchInfo->NextOffset -
GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY)));
pa = (POLYARRAY *) pMsgDrawPolyArray->paLast;
pd = pa->pdNextVertex;
pa->pdCurColor = pd;
__GL_CHECK_CLAMP_CI(pd->colors[0].r, gc, pa->flags, c);
pd->flags |= POLYDATA_COLOR_VALID;
}
else
{
glcltIndexf_NotInBegin(c);
}
}
#define PA_TEXTURE1(s1) \
\
POLYARRAY *pa; \
POLYDATA *pd; \
\
pa = GLTEB_CLTPOLYARRAY(); \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pa->flags |= POLYARRAY_TEXTURE1; \
\
pd = pa->pdNextVertex; \
pa->pdCurTexture = pd; \
pd->flags |= POLYDATA_TEXTURE_VALID | POLYDATA_DLIST_TEXTURE1; \
pd->texture.x = s1; \
pd->texture.y = __glZero; \
pd->texture.z = __glZero; \
pd->texture.w = __glOne; \
} \
else \
{ \
glcltTexCoord4f_NotInBegin(pa, POLYARRAY_TEXTURE1, \
s1, __glZero, __glZero, __glOne); \
}
#define PA_TEXTURE2(s1,t1) \
\
POLYARRAY *pa; \
POLYDATA *pd; \
\
pa = GLTEB_CLTPOLYARRAY(); \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pa->flags |= POLYARRAY_TEXTURE2; \
\
pd = pa->pdNextVertex; \
pa->pdCurTexture = pd; \
pd->flags |= POLYDATA_TEXTURE_VALID | POLYDATA_DLIST_TEXTURE2; \
pd->texture.x = s1; \
pd->texture.y = t1; \
pd->texture.z = __glZero; \
pd->texture.w = __glOne; \
} \
else \
{ \
glcltTexCoord4f_NotInBegin(pa, POLYARRAY_TEXTURE2, \
s1, t1, __glZero, __glOne); \
}
#define PA_TEXTURE3(s1,t1,r1) \
\
POLYARRAY *pa; \
POLYDATA *pd; \
\
pa = GLTEB_CLTPOLYARRAY(); \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pa->flags |= POLYARRAY_TEXTURE3; \
\
pd = pa->pdNextVertex; \
pa->pdCurTexture = pd; \
pd->flags |= POLYDATA_TEXTURE_VALID | POLYDATA_DLIST_TEXTURE3; \
pd->texture.x = s1; \
pd->texture.y = t1; \
pd->texture.z = r1; \
pd->texture.w = __glOne; \
} \
else \
{ \
glcltTexCoord4f_NotInBegin(pa, POLYARRAY_TEXTURE3, \
s1, t1, r1, __glOne); \
}
#define PA_TEXTURE4(s1,t1,r1,q1) \
\
POLYARRAY *pa; \
POLYDATA *pd; \
\
pa = GLTEB_CLTPOLYARRAY(); \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pa->flags |= POLYARRAY_TEXTURE4; \
\
pd = pa->pdNextVertex; \
pa->pdCurTexture = pd; \
pd->flags |= POLYDATA_TEXTURE_VALID | POLYDATA_DLIST_TEXTURE4; \
pd->texture.x = s1; \
pd->texture.y = t1; \
pd->texture.z = r1; \
pd->texture.w = q1; \
} \
else \
{ \
glcltTexCoord4f_NotInBegin(pa, POLYARRAY_TEXTURE4, \
s1, t1, r1, q1); \
}
void FASTCALL glcltTexCoord4f_NotInBegin(POLYARRAY *pa, GLuint paFlags,
GLfloat s, GLfloat t, GLfloat r, GLfloat q)
{
POLYDATA *pd;
GLMSGBATCHINFO *pMsgBatchInfo;
GLMSG_DRAWPOLYARRAY *pMsgDrawPolyArray;
pMsgBatchInfo = (GLMSGBATCHINFO *) pa->pMsgBatchInfo;
// If the last command is DrawPolyArray, add it to the command.
// This allows us to chain primitives separated by the attribute.
if (pMsgBatchInfo->NextOffset == pa->nextMsgOffset)
{
pMsgDrawPolyArray = (GLMSG_DRAWPOLYARRAY *)
((BYTE *) pMsgBatchInfo + pMsgBatchInfo->NextOffset -
GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY)));
pa = (POLYARRAY *) pMsgDrawPolyArray->paLast;
pa->flags |= paFlags;
pd = pa->pdNextVertex;
pa->pdCurTexture = pd;
pd->flags |= POLYDATA_TEXTURE_VALID | paFlags;
pd->texture.x = s;
pd->texture.y = t;
pd->texture.z = r;
pd->texture.w = q;
}
else
{
GLCLIENT_BEGIN( TexCoord4fv, TEXCOORD4FV )
pMsg->v[0] = s;
pMsg->v[1] = t;
pMsg->v[2] = r;
pMsg->v[3] = q;
GLCLIENT_END
}
}
#define PA_NORMAL(nx,ny,nz) \
\
POLYARRAY *pa; \
POLYDATA *pd; \
\
pa = GLTEB_CLTPOLYARRAY(); \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pd = pa->pdNextVertex; \
pa->pdCurNormal = pd; \
pd->flags |= POLYDATA_NORMAL_VALID; \
pd->normal.x = nx; \
pd->normal.y = ny; \
pd->normal.z = nz; \
} \
else \
{ \
glcltNormal3f_NotInBegin(pa, nx, ny, nz); \
}
void FASTCALL glcltNormal3f_NotInBegin(POLYARRAY *pa, GLfloat nx, GLfloat ny, GLfloat nz)
{
POLYDATA *pd;
GLMSGBATCHINFO *pMsgBatchInfo;
GLMSG_DRAWPOLYARRAY *pMsgDrawPolyArray;
pMsgBatchInfo = (GLMSGBATCHINFO *) pa->pMsgBatchInfo;
// If the last command is DrawPolyArray, add it to the command.
// This allows us to chain primitives separated by the attribute.
if (pMsgBatchInfo->NextOffset == pa->nextMsgOffset)
{
pMsgDrawPolyArray = (GLMSG_DRAWPOLYARRAY *)
((BYTE *) pMsgBatchInfo + pMsgBatchInfo->NextOffset -
GLMSG_ALIGN(sizeof(GLMSG_DRAWPOLYARRAY)));
pa = (POLYARRAY *) pMsgDrawPolyArray->paLast;
pd = pa->pdNextVertex;
pa->pdCurNormal = pd;
pd->flags |= POLYDATA_NORMAL_VALID;
pd->normal.x = nx;
pd->normal.y = ny;
pd->normal.z = nz;
}
else
{
GLCLIENT_BEGIN( Normal3fv, NORMAL3FV )
pMsg->v[ 0] = nx;
pMsg->v[ 1] = ny;
pMsg->v[ 2] = nz;
GLCLIENT_END
}
}
#define PA_EDGEFLAG(edgeflag) \
\
POLYARRAY *pa; \
POLYDATA *pd; \
\
pa = GLTEB_CLTPOLYARRAY(); \
\
if (pa->flags & POLYARRAY_IN_BEGIN) \
{ \
pd = pa->pdNextVertex; \
pa->pdCurEdgeFlag = pd; \
if (edgeflag) \
pd->flags |= POLYDATA_EDGEFLAG_VALID|POLYDATA_EDGEFLAG_BOUNDARY;\
else \
{ \
/* must clear POLYDATA_EDGEFLAG_BOUNDARY flag here since */ \
/* there may have been a previous edge flag for this same */ \
/* vertex! */ \
pd->flags &= ~POLYDATA_EDGEFLAG_BOUNDARY; \
pd->flags |= POLYDATA_EDGEFLAG_VALID; \
} \
} \
else \
{ \
glcltEdgeFlag_NotInBegin(edgeflag); \
}
void FASTCALL glcltEdgeFlag_NotInBegin(GLboolean flag)
{
GLCLIENT_BEGIN( EdgeFlag, EDGEFLAG )
pMsg->flag = flag;
GLCLIENT_END
}
void APIENTRY
glcltColor3b_InRGBA ( IN GLbyte red, IN GLbyte green, IN GLbyte blue )
{
PA_COLOR_IN_RGB1(__GL_B_TO_FLOAT(red), __GL_B_TO_FLOAT(green),
__GL_B_TO_FLOAT(blue));
}
void APIENTRY
glcltColor3bv_InRGBA ( IN const GLbyte v[3] )
{
PA_COLOR_IN_RGB1(__GL_B_TO_FLOAT(v[0]), __GL_B_TO_FLOAT(v[1]),
__GL_B_TO_FLOAT(v[2]));
}
void APIENTRY
glcltColor3d_InRGBA ( IN GLdouble red, IN GLdouble green, IN GLdouble blue )
{
PA_COLOR_IN_RGB1((GLfloat) red, (GLfloat) green,
(GLfloat) blue);
}
void APIENTRY
glcltColor3dv_InRGBA ( IN const GLdouble v[3] )
{
PA_COLOR_IN_RGB1((GLfloat) v[0], (GLfloat) v[1],
(GLfloat) v[2]);
}
void APIENTRY
glcltColor3f_InRGBA ( IN GLfloat red, IN GLfloat green, IN GLfloat blue )
{
#if _X86NOT_
// This is currently disable since I don't see any improvements in the
// timings!
// Need rewrite if used.
POLYARRAY *pa;
__GL_SETUP();
pa = gc->paTeb;
__asm{
mov eax, pa
mov ebx, [OFFSET(POLYARRAY.flags)][eax]
test ebx, POLYARRAY_IN_BEGIN
jne in_begin
}
glcltColor4f_InRGBA_NotInBegin(gc, pa, POLYARRAY_COLOR3F,
red, green, blue, __glOne);
return;
__asm{
in_begin:
mov edi, [OFFSET(POLYARRAY.pdNextVertex)][eax]
or ebx, POLYARRAY_COLOR3F
mov ecx, gc
mov [OFFSET(POLYARRAY.flags)][eax], ebx
mov edx, [OFFSET(POLYDATA.flags)][edi]
mov [OFFSET(POLYARRAY.pdCurColor)][eax], edi
or edx, POLYDATA_COLOR_VALID | POLYARRAY_COLOR3F
mov [OFFSET(POLYDATA.flags)][edi], edx
fld DWORD PTR red
mov eax, [OFFSET(__GLcontext.redClampTable)][ecx]
fmul DWORD PTR [OFFSET(__GLcontext.redVertexScale)][ecx]
mov edx, 0x3f800000
shr eax, 31
sub edx, [OFFSET(__GLcontext.redClampTable)][ecx]
shr edx, 31
fstp [OFFSET(__GLcontext.redClampTable)][ecx]
lea eax, [edx + 2*eax]
fld DWORD PTR green
mov ebx, [OFFSET(__GLcontext.greenClampTable)][ecx]
fmul DWORD PTR [OFFSET(__GLcontext.greenVertexScale)][ecx]
mov edx, 0x3f800000
shr ebx, 31
sub edx, [OFFSET(__GLcontext.greenClampTable)][ecx]
shr edx, 31
fstp [OFFSET(__GLcontext.redClampTable)][ecx]
lea ebx, [edx + 2*ebx]
mov edx, [OFFSET(__GLcontext.redClampTable)][ecx][eax]
mov DWORD PTR [OFFSET(POLYDATA.colors)][edi], edx
mov eax, [OFFSET(__GLcontext.redClampTable)][ecx][ebx]
mov DWORD PTR [OFFSET(POLYDATA.colors) + 4][edi], eax
fld DWORD PTR blue
mov eax, [OFFSET(__GLcontext.blueClampTable)][ecx]
fmul DWORD PTR [OFFSET(__GLcontext.blueVertexScale)][ecx]
mov edx, 0x3f800000
shr eax, 31
sub edx, [OFFSET(__GLcontext.blueClampTable)][ecx]
shr edx, 31
fstp [OFFSET(__GLcontext.blueClampTable)][ecx]
lea eax, [edx + 2*eax]
mov ebx, [OFFSET(__GLcontext.alphaVertexScale)][ecx]
mov DWORD PTR [OFFSET(POLYDATA.colors) + 12][edi], ebx
mov edx, [OFFSET(__GLcontext.blueClampTable)][ecx][eax]
mov DWORD PTR [OFFSET(POLYDATA.colors) + 8][edi], edx
}
#else
PA_COLOR_IN_RGB1(red, green, blue);
#endif
}
void APIENTRY
glcltColor3fv_InRGBA ( IN const GLfloat v[3] )
{
PA_COLOR_IN_RGB1(v[0], v[1], v[2]);
}
void APIENTRY
glcltColor3i_InRGBA ( IN GLint red, IN GLint green, IN GLint blue )
{
PA_COLOR_IN_RGB1(__GL_I_TO_FLOAT(red), __GL_I_TO_FLOAT(green),
__GL_I_TO_FLOAT(blue));
}
void APIENTRY
glcltColor3iv_InRGBA ( IN const GLint v[3] )
{
PA_COLOR_IN_RGB1(__GL_I_TO_FLOAT(v[0]), __GL_I_TO_FLOAT(v[1]),
__GL_I_TO_FLOAT(v[2]));
}
void APIENTRY
glcltColor3s_InRGBA ( IN GLshort red, IN GLshort green, IN GLshort blue )
{
PA_COLOR_IN_RGB1(__GL_S_TO_FLOAT(red), __GL_S_TO_FLOAT(green),
__GL_S_TO_FLOAT(blue));
}
void APIENTRY
glcltColor3sv_InRGBA ( IN const GLshort v[3] )
{
PA_COLOR_IN_RGB1(__GL_S_TO_FLOAT(v[0]), __GL_S_TO_FLOAT(v[1]),
__GL_S_TO_FLOAT(v[2]));
}
void APIENTRY
glcltColor3ub_InRGBA ( IN GLubyte red, IN GLubyte green, IN GLubyte blue )
{
PA_COLOR_IN_RGBA_NO_CLAMP1(__GL_UB_TO_FLOAT(red), __GL_UB_TO_FLOAT(green),
__GL_UB_TO_FLOAT(blue));
}
void APIENTRY
glcltColor3ubv_InRGBA ( IN const GLubyte v[3] )
{
PA_COLOR_IN_RGBA_NO_CLAMP1(__GL_UB_TO_FLOAT(v[0]), __GL_UB_TO_FLOAT(v[1]),
__GL_UB_TO_FLOAT(v[2]));
}
void APIENTRY
glcltColor3ui_InRGBA ( IN GLuint red, IN GLuint green, IN GLuint blue )
{
PA_COLOR_IN_RGB1(__GL_UI_TO_FLOAT(red), __GL_UI_TO_FLOAT(green),
__GL_UI_TO_FLOAT(blue));
}
void APIENTRY
glcltColor3uiv_InRGBA ( IN const GLuint v[3] )
{
PA_COLOR_IN_RGB1(__GL_UI_TO_FLOAT(v[0]), __GL_UI_TO_FLOAT(v[1]),
__GL_UI_TO_FLOAT(v[2]));
}
void APIENTRY
glcltColor3us_InRGBA ( IN GLushort red, IN GLushort green, IN GLushort blue )
{
PA_COLOR_IN_RGBA_NO_CLAMP1(__GL_US_TO_FLOAT(red), __GL_US_TO_FLOAT(green),
__GL_US_TO_FLOAT(blue));
}
void APIENTRY
glcltColor3usv_InRGBA ( IN const GLushort v[3] )
{
PA_COLOR_IN_RGBA_NO_CLAMP1(__GL_US_TO_FLOAT(v[0]), __GL_US_TO_FLOAT(v[1]),
__GL_US_TO_FLOAT(v[2]));
}
void APIENTRY
glcltColor4b_InRGBA ( IN GLbyte red, IN GLbyte green, IN GLbyte blue, IN GLbyte alpha )
{
PA_COLOR_IN_RGBA(__GL_B_TO_FLOAT(red), __GL_B_TO_FLOAT(green),
__GL_B_TO_FLOAT(blue), __GL_B_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4bv_InRGBA ( IN const GLbyte v[4] )
{
PA_COLOR_IN_RGBA(__GL_B_TO_FLOAT(v[0]), __GL_B_TO_FLOAT(v[1]),
__GL_B_TO_FLOAT(v[2]), __GL_B_TO_FLOAT(v[3]));
}
void APIENTRY
glcltColor4d_InRGBA ( IN GLdouble red, IN GLdouble green, IN GLdouble blue, IN GLdouble alpha )
{
PA_COLOR_IN_RGBA((GLfloat) red, (GLfloat) green,
(GLfloat) blue, (GLfloat) alpha);
}
void APIENTRY
glcltColor4dv_InRGBA ( IN const GLdouble v[4] )
{
PA_COLOR_IN_RGBA((GLfloat) v[0], (GLfloat) v[1],
(GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltColor4f_InRGBA ( IN GLfloat red, IN GLfloat green, IN GLfloat blue, IN GLfloat alpha )
{
PA_COLOR_IN_RGBA(red, green, blue, alpha);
}
void APIENTRY
glcltColor4fv_InRGBA ( IN const GLfloat v[4] )
{
PA_COLOR_IN_RGBA(v[0], v[1], v[2], v[3]);
}
void APIENTRY
glcltColor4i_InRGBA ( IN GLint red, IN GLint green, IN GLint blue, IN GLint alpha )
{
PA_COLOR_IN_RGBA(__GL_I_TO_FLOAT(red), __GL_I_TO_FLOAT(green),
__GL_I_TO_FLOAT(blue), __GL_I_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4iv_InRGBA ( IN const GLint v[4] )
{
PA_COLOR_IN_RGBA(__GL_I_TO_FLOAT(v[0]), __GL_I_TO_FLOAT(v[1]),
__GL_I_TO_FLOAT(v[2]), __GL_I_TO_FLOAT(v[3]));
}
void APIENTRY
glcltColor4s_InRGBA ( IN GLshort red, IN GLshort green, IN GLshort blue, IN GLshort alpha )
{
PA_COLOR_IN_RGBA(__GL_S_TO_FLOAT(red), __GL_S_TO_FLOAT(green),
__GL_S_TO_FLOAT(blue), __GL_S_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4sv_InRGBA ( IN const GLshort v[4] )
{
PA_COLOR_IN_RGBA(__GL_S_TO_FLOAT(v[0]), __GL_S_TO_FLOAT(v[1]),
__GL_S_TO_FLOAT(v[2]), __GL_S_TO_FLOAT(v[3]));
}
void APIENTRY
glcltColor4ub_InRGBA ( IN GLubyte red, IN GLubyte green, IN GLubyte blue, IN GLubyte alpha )
{
PA_COLOR_IN_RGBA_NO_CLAMP(__GL_UB_TO_FLOAT(red), __GL_UB_TO_FLOAT(green),
__GL_UB_TO_FLOAT(blue), __GL_UB_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4ubv_InRGBA ( IN const GLubyte v[4] )
{
PA_COLOR_IN_RGBA_NO_CLAMP(__GL_UB_TO_FLOAT(v[0]), __GL_UB_TO_FLOAT(v[1]),
__GL_UB_TO_FLOAT(v[2]), __GL_UB_TO_FLOAT(v[3]));
}
void APIENTRY
glcltColor4ui_InRGBA ( IN GLuint red, IN GLuint green, IN GLuint blue, IN GLuint alpha )
{
PA_COLOR_IN_RGBA(__GL_UI_TO_FLOAT(red), __GL_UI_TO_FLOAT(green),
__GL_UI_TO_FLOAT(blue), __GL_UI_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4uiv_InRGBA ( IN const GLuint v[4] )
{
PA_COLOR_IN_RGBA(__GL_UI_TO_FLOAT(v[0]), __GL_UI_TO_FLOAT(v[1]),
__GL_UI_TO_FLOAT(v[2]), __GL_UI_TO_FLOAT(v[3]));
}
void APIENTRY
glcltColor4us_InRGBA ( IN GLushort red, IN GLushort green, IN GLushort blue, IN GLushort alpha )
{
PA_COLOR_IN_RGBA_NO_CLAMP(__GL_US_TO_FLOAT(red), __GL_US_TO_FLOAT(green),
__GL_US_TO_FLOAT(blue), __GL_US_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4usv_InRGBA ( IN const GLushort v[4] )
{
PA_COLOR_IN_RGBA_NO_CLAMP(__GL_US_TO_FLOAT(v[0]), __GL_US_TO_FLOAT(v[1]),
__GL_US_TO_FLOAT(v[2]), __GL_US_TO_FLOAT(v[3]));
}
void APIENTRY
glcltColor3b_InCI ( IN GLbyte red, IN GLbyte green, IN GLbyte blue )
{
PA_COLOR_IN_CI(__GL_B_TO_FLOAT(red), __GL_B_TO_FLOAT(green),
__GL_B_TO_FLOAT(blue), __glOne);
}
void APIENTRY
glcltColor3bv_InCI ( IN const GLbyte v[3] )
{
PA_COLOR_IN_CI(__GL_B_TO_FLOAT(v[0]), __GL_B_TO_FLOAT(v[1]),
__GL_B_TO_FLOAT(v[2]), __glOne);
}
void APIENTRY
glcltColor3d_InCI ( IN GLdouble red, IN GLdouble green, IN GLdouble blue )
{
PA_COLOR_IN_CI((GLfloat) red, (GLfloat) green,
(GLfloat) blue, __glOne);
}
void APIENTRY
glcltColor3dv_InCI ( IN const GLdouble v[3] )
{
PA_COLOR_IN_CI((GLfloat) v[0], (GLfloat) v[1],
(GLfloat) v[2], __glOne);
}
void APIENTRY
glcltColor3f_InCI ( IN GLfloat red, IN GLfloat green, IN GLfloat blue )
{
PA_COLOR_IN_CI(red, green, blue, __glOne);
}
void APIENTRY
glcltColor3fv_InCI ( IN const GLfloat v[3] )
{
PA_COLOR_IN_CI(v[0], v[1], v[2], __glOne);
}
void APIENTRY
glcltColor3i_InCI ( IN GLint red, IN GLint green, IN GLint blue )
{
PA_COLOR_IN_CI(__GL_I_TO_FLOAT(red), __GL_I_TO_FLOAT(green),
__GL_I_TO_FLOAT(blue), __glOne);
}
void APIENTRY
glcltColor3iv_InCI ( IN const GLint v[3] )
{
PA_COLOR_IN_CI(__GL_I_TO_FLOAT(v[0]), __GL_I_TO_FLOAT(v[1]),
__GL_I_TO_FLOAT(v[2]), __glOne);
}
void APIENTRY
glcltColor3s_InCI ( IN GLshort red, IN GLshort green, IN GLshort blue )
{
PA_COLOR_IN_CI(__GL_S_TO_FLOAT(red), __GL_S_TO_FLOAT(green),
__GL_S_TO_FLOAT(blue), __glOne);
}
void APIENTRY
glcltColor3sv_InCI ( IN const GLshort v[3] )
{
PA_COLOR_IN_CI(__GL_S_TO_FLOAT(v[0]), __GL_S_TO_FLOAT(v[1]),
__GL_S_TO_FLOAT(v[2]), __glOne);
}
void APIENTRY
glcltColor3ub_InCI ( IN GLubyte red, IN GLubyte green, IN GLubyte blue )
{
PA_COLOR_IN_CI(__GL_UB_TO_FLOAT(red), __GL_UB_TO_FLOAT(green),
__GL_UB_TO_FLOAT(blue), __glOne);
}
void APIENTRY
glcltColor3ubv_InCI ( IN const GLubyte v[3] )
{
PA_COLOR_IN_CI(__GL_UB_TO_FLOAT(v[0]), __GL_UB_TO_FLOAT(v[1]),
__GL_UB_TO_FLOAT(v[2]), __glOne);
}
void APIENTRY
glcltColor3ui_InCI ( IN GLuint red, IN GLuint green, IN GLuint blue )
{
PA_COLOR_IN_CI(__GL_UI_TO_FLOAT(red), __GL_UI_TO_FLOAT(green),
__GL_UI_TO_FLOAT(blue), __glOne);
}
void APIENTRY
glcltColor3uiv_InCI ( IN const GLuint v[3] )
{
PA_COLOR_IN_CI(__GL_UI_TO_FLOAT(v[0]), __GL_UI_TO_FLOAT(v[1]),
__GL_UI_TO_FLOAT(v[2]), __glOne);
}
void APIENTRY
glcltColor3us_InCI ( IN GLushort red, IN GLushort green, IN GLushort blue )
{
PA_COLOR_IN_CI(__GL_US_TO_FLOAT(red), __GL_US_TO_FLOAT(green),
__GL_US_TO_FLOAT(blue), __glOne);
}
void APIENTRY
glcltColor3usv_InCI ( IN const GLushort v[3] )
{
PA_COLOR_IN_CI(__GL_US_TO_FLOAT(v[0]), __GL_US_TO_FLOAT(v[1]),
__GL_US_TO_FLOAT(v[2]), __glOne);
}
void APIENTRY
glcltColor4b_InCI ( IN GLbyte red, IN GLbyte green, IN GLbyte blue, IN GLbyte alpha )
{
PA_COLOR_IN_CI(__GL_B_TO_FLOAT(red), __GL_B_TO_FLOAT(green),
__GL_B_TO_FLOAT(blue), __GL_B_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4bv_InCI ( IN const GLbyte v[4] )
{
PA_COLOR_IN_CI(__GL_B_TO_FLOAT(v[0]), __GL_B_TO_FLOAT(v[1]),
__GL_B_TO_FLOAT(v[2]), __GL_B_TO_FLOAT(v[3]));
}
void APIENTRY
glcltColor4d_InCI ( IN GLdouble red, IN GLdouble green, IN GLdouble blue, IN GLdouble alpha )
{
PA_COLOR_IN_CI((GLfloat) red, (GLfloat) green,
(GLfloat) blue, (GLfloat) alpha);
}
void APIENTRY
glcltColor4dv_InCI ( IN const GLdouble v[4] )
{
PA_COLOR_IN_CI((GLfloat) v[0], (GLfloat) v[1],
(GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltColor4f_InCI ( IN GLfloat red, IN GLfloat green, IN GLfloat blue, IN GLfloat alpha )
{
PA_COLOR_IN_CI(red, green, blue, alpha);
}
void APIENTRY
glcltColor4fv_InCI ( IN const GLfloat v[4] )
{
PA_COLOR_IN_CI(v[0], v[1], v[2], v[3]);
}
void APIENTRY
glcltColor4i_InCI ( IN GLint red, IN GLint green, IN GLint blue, IN GLint alpha )
{
PA_COLOR_IN_CI(__GL_I_TO_FLOAT(red), __GL_I_TO_FLOAT(green),
__GL_I_TO_FLOAT(blue), __GL_I_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4iv_InCI ( IN const GLint v[4] )
{
PA_COLOR_IN_CI(__GL_I_TO_FLOAT(v[0]), __GL_I_TO_FLOAT(v[1]),
__GL_I_TO_FLOAT(v[2]), __GL_I_TO_FLOAT(v[3]));
}
void APIENTRY
glcltColor4s_InCI ( IN GLshort red, IN GLshort green, IN GLshort blue, IN GLshort alpha )
{
PA_COLOR_IN_CI(__GL_S_TO_FLOAT(red), __GL_S_TO_FLOAT(green),
__GL_S_TO_FLOAT(blue), __GL_S_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4sv_InCI ( IN const GLshort v[4] )
{
PA_COLOR_IN_CI(__GL_S_TO_FLOAT(v[0]), __GL_S_TO_FLOAT(v[1]),
__GL_S_TO_FLOAT(v[2]), __GL_S_TO_FLOAT(v[3]));
}
void APIENTRY
glcltColor4ub_InCI ( IN GLubyte red, IN GLubyte green, IN GLubyte blue, IN GLubyte alpha )
{
PA_COLOR_IN_CI(__GL_UB_TO_FLOAT(red), __GL_UB_TO_FLOAT(green),
__GL_UB_TO_FLOAT(blue), __GL_UB_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4ubv_InCI ( IN const GLubyte v[4] )
{
PA_COLOR_IN_CI(__GL_UB_TO_FLOAT(v[0]), __GL_UB_TO_FLOAT(v[1]),
__GL_UB_TO_FLOAT(v[2]), __GL_UB_TO_FLOAT(v[3]));
}
void APIENTRY
glcltColor4ui_InCI ( IN GLuint red, IN GLuint green, IN GLuint blue, IN GLuint alpha )
{
PA_COLOR_IN_CI(__GL_UI_TO_FLOAT(red), __GL_UI_TO_FLOAT(green),
__GL_UI_TO_FLOAT(blue), __GL_UI_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4uiv_InCI ( IN const GLuint v[4] )
{
PA_COLOR_IN_CI(__GL_UI_TO_FLOAT(v[0]), __GL_UI_TO_FLOAT(v[1]),
__GL_UI_TO_FLOAT(v[2]), __GL_UI_TO_FLOAT(v[3]));
}
void APIENTRY
glcltColor4us_InCI ( IN GLushort red, IN GLushort green, IN GLushort blue, IN GLushort alpha )
{
PA_COLOR_IN_CI(__GL_US_TO_FLOAT(red), __GL_US_TO_FLOAT(green),
__GL_US_TO_FLOAT(blue), __GL_US_TO_FLOAT(alpha));
}
void APIENTRY
glcltColor4usv_InCI ( IN const GLushort v[4] )
{
PA_COLOR_IN_CI(__GL_US_TO_FLOAT(v[0]), __GL_US_TO_FLOAT(v[1]),
__GL_US_TO_FLOAT(v[2]), __GL_US_TO_FLOAT(v[3]));
}
// Allocate a __GLmatChange structure.
//
// The POLYMATERIAL structure contains pointers to __GLmatChange arrays.
// These __GLmatChange structures are used to record material changes to
// vertices in the vertex buffer.
//
// To reduce memory requirement, the POLYMATERIAL structure keeps an array
// of pointers to __GLmatChange arrays. Each __GLmatChange array 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.
__GLmatChange * FASTCALL PAMatAlloc()
{
POLYMATERIAL *pm;
GLuint iArray, iMat;
#if DBG
__GL_SETUP();
#endif
pm = GLTEB_CLTPOLYMATERIAL();
// Allocate a POLYMATERIAL structure for this thread if one does not exist.
if (!pm)
{
GLuint nv, aMatSize;
__GL_SETUP();
nv = gc->vertex.pdBufSize;
aMatSize = nv * 2 / POLYMATERIAL_ARRAY_SIZE + 1;
if (!(pm = (POLYMATERIAL *) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
// Base size
sizeof(POLYMATERIAL) - sizeof(__GLmatChange *) +
// array of pointers to __GLmatChange arrays
aMatSize * sizeof(__GLmatChange *) +
// the PDMATERIAL array
nv * sizeof(PDMATERIAL))))
{
GLSETERROR(GL_OUT_OF_MEMORY);
return NULL;
}
pm->aMatSize = aMatSize;
// Initialize pointer to the PDMATERIAL array
pm->pdMaterial0 = (PDMATERIAL *) &pm->aMat[aMatSize];
GLTEB_SET_CLTPOLYMATERIAL(pm);
}
// Sanity check that pdBufSize has not changed.
ASSERTOPENGL
(
pm->aMatSize == gc->vertex.pdBufSize * 2 / POLYMATERIAL_ARRAY_SIZE + 1,
"vertex buffer size has changed!\n"
);
// Find the material array from which to allocate the material change structure.
iMat = pm->iMat;
iArray = iMat / POLYMATERIAL_ARRAY_SIZE;
iMat = iMat % POLYMATERIAL_ARRAY_SIZE;
ASSERTOPENGL(iArray < pm->aMatSize, "iArray exceeds range!\n");
// Allocate the material array if it has not been allocated.
if (!(pm->aMat[iArray]))
{
if (!(pm->aMat[iArray] = (__GLmatChange *) LocalAlloc(LMEM_FIXED,
sizeof(__GLmatChange) * POLYMATERIAL_ARRAY_SIZE)))
{
GLSETERROR(GL_OUT_OF_MEMORY);
return NULL;
}
}
// Advance next available material pointer.
pm->iMat++;
ASSERTOPENGL(pm->iMat <= gc->vertex.pdBufSize * 2,
"too many material changes!\n");
// Return the material change.
return (&pm->aMat[iArray][iMat]);
}
// Free polymaterial for current thread.
void FASTCALL FreePolyMaterial(void)
{
POLYMATERIAL *pm = GLTEB_CLTPOLYMATERIAL();
GLuint i;
if (pm)
{
for (i = 0; i < pm->aMatSize && pm->aMat[i]; i++)
{
if (LocalFree((PVOID) pm->aMat[i]))
RIP("LocalFree failed\n");
}
if (LocalFree((PVOID) pm))
RIP("LocalFree failed\n");
GLTEB_SET_CLTPOLYMATERIAL(NULL);
}
}
#if !((POLYARRAY_MATERIAL_FRONT == POLYDATA_MATERIAL_FRONT) \
&& (POLYARRAY_MATERIAL_BACK == POLYDATA_MATERIAL_BACK))
#error "bad material mask\n"
#endif
void APIENTRY
glcltMaterialfv ( IN GLenum face, IN GLenum pname, IN const GLfloat params[] )
{
POLYARRAY *pa;
POLYDATA *pd;
GLuint i, pdFlags, dirtyBits, matMask;
POLYMATERIAL *pm;
pa = GLTEB_CLTPOLYARRAY();
if (pa->flags & POLYARRAY_IN_BEGIN)
{
switch (pname)
{
case GL_SHININESS:
if (params[0] < (GLfloat) 0 || params[0] > (GLfloat) 128)
{
GLSETERROR(GL_INVALID_VALUE);
return;
}
dirtyBits = __GL_MATERIAL_SHININESS;
break;
case GL_EMISSION:
dirtyBits = __GL_MATERIAL_EMISSIVE;
break;
case GL_AMBIENT:
dirtyBits = __GL_MATERIAL_AMBIENT;
break;
case GL_DIFFUSE:
dirtyBits = __GL_MATERIAL_DIFFUSE;
break;
case GL_SPECULAR:
dirtyBits = __GL_MATERIAL_SPECULAR;
break;
case GL_AMBIENT_AND_DIFFUSE:
dirtyBits = __GL_MATERIAL_AMBIENT | __GL_MATERIAL_DIFFUSE;
break;
case GL_COLOR_INDEXES:
dirtyBits = __GL_MATERIAL_COLORINDEXES;
break;
default:
GLSETERROR(GL_INVALID_ENUM);
return;
}
switch (face)
{
case GL_FRONT:
pdFlags = POLYDATA_MATERIAL_FRONT;
break;
case GL_BACK:
pdFlags = POLYDATA_MATERIAL_BACK;
break;
case GL_FRONT_AND_BACK:
pdFlags = POLYDATA_MATERIAL_FRONT | POLYDATA_MATERIAL_BACK;
break;
default:
GLSETERROR(GL_INVALID_ENUM);
return;
}
// Update pa flags POLYARRAY_MATERIAL_FRONT and POLYARRAY_MATERIAL_BACK.
pa->flags |= pdFlags;
// Do front and back material for this vertex
// Overwrite the previous material changes for this vertex if they exist since
// only the last material changes matter.
pd = pa->pdNextVertex;
for (i = 0, matMask = POLYDATA_MATERIAL_FRONT;
i < 2;
i++, matMask = POLYDATA_MATERIAL_BACK)
{
__GLmatChange *pdMat;
if (!(pdFlags & matMask))
continue;
// allocate __GLmatChange structure if this vertex hasn't got one
if (!(pd->flags & matMask))
{
if (!(pdMat = PAMatAlloc()))
return;
// Get POLYMATERIAL pointer after PAMatAlloc!
pm = GLTEB_CLTPOLYMATERIAL();
if (matMask == POLYDATA_MATERIAL_FRONT)
pm->pdMaterial0[pd - pa->pdBuffer0].front = pdMat;
else
pm->pdMaterial0[pd - pa->pdBuffer0].back = pdMat;
pdMat->dirtyBits = dirtyBits;
}
else
{
pm = GLTEB_CLTPOLYMATERIAL();
if (matMask == POLYDATA_MATERIAL_FRONT)
pdMat = pm->pdMaterial0[pd - pa->pdBuffer0].front;
else
pdMat = pm->pdMaterial0[pd - pa->pdBuffer0].back;
pdMat->dirtyBits |= dirtyBits;
}
if (dirtyBits & __GL_MATERIAL_SHININESS)
{
pdMat->shininess = params[0];
}
else if (dirtyBits & __GL_MATERIAL_COLORINDEXES)
{
pdMat->cmapa = params[0];
pdMat->cmapd = params[1];
pdMat->cmaps = params[2];
}
else if (dirtyBits & __GL_MATERIAL_EMISSIVE)
{
pdMat->emissive.r = params[0];
pdMat->emissive.g = params[1];
pdMat->emissive.b = params[2];
pdMat->emissive.a = params[3];
}
else if (dirtyBits & __GL_MATERIAL_SPECULAR)
{
pdMat->specular.r = params[0];
pdMat->specular.g = params[1];
pdMat->specular.b = params[2];
pdMat->specular.a = params[3];
}
else
{
// ambient and/or diffuse
if (dirtyBits & __GL_MATERIAL_AMBIENT)
{
pdMat->ambient.r = params[0];
pdMat->ambient.g = params[1];
pdMat->ambient.b = params[2];
pdMat->ambient.a = params[3];
}
if (dirtyBits & __GL_MATERIAL_DIFFUSE)
{
pdMat->diffuse.r = params[0];
pdMat->diffuse.g = params[1];
pdMat->diffuse.b = params[2];
pdMat->diffuse.a = params[3];
}
}
}
// Finally, update pd flags
pd->flags |= pdFlags;
}
else
{
int cArgs;
switch (pname)
{
case GL_SHININESS:
if (params[0] < (GLfloat) 0 || params[0] > (GLfloat) 128)
{
GLSETERROR(GL_INVALID_VALUE);
return;
}
cArgs = 1;
break;
case GL_EMISSION:
case GL_AMBIENT:
case GL_DIFFUSE:
case GL_SPECULAR:
case GL_AMBIENT_AND_DIFFUSE:
cArgs = 4;
break;
case GL_COLOR_INDEXES:
cArgs = 3;
break;
default:
GLSETERROR(GL_INVALID_ENUM);
return;
}
switch (face)
{
case GL_FRONT:
case GL_BACK:
case GL_FRONT_AND_BACK:
break;
default:
GLSETERROR(GL_INVALID_ENUM);
return;
}
GLCLIENT_BEGIN( Materialfv, MATERIALFV )
pMsg->face = face;
pMsg->pname = pname;
while (--cArgs >= 0)
pMsg->params[cArgs] = params[cArgs];
GLCLIENT_END
}
}
void APIENTRY
glcltMaterialf ( IN GLenum face, IN GLenum pname, IN GLfloat param )
{
if (pname != GL_SHININESS)
{
GLSETERROR(GL_INVALID_ENUM);
return;
}
glcltMaterialfv(face, pname, &param);
}
void APIENTRY
glcltMateriali ( IN GLenum face, IN GLenum pname, IN GLint param )
{
GLfloat fParams[1];
if (pname != GL_SHININESS)
{
GLSETERROR(GL_INVALID_ENUM);
return;
}
fParams[0] = (GLfloat) param;
glcltMaterialfv(face, pname, fParams);
}
void APIENTRY
glcltMaterialiv ( IN GLenum face, IN GLenum pname, IN const GLint params[] )
{
GLfloat fParams[4];
switch (pname)
{
case GL_EMISSION:
case GL_AMBIENT:
case GL_DIFFUSE:
case GL_SPECULAR:
case GL_AMBIENT_AND_DIFFUSE:
fParams[0] = __GL_I_TO_FLOAT(params[0]);
fParams[1] = __GL_I_TO_FLOAT(params[1]);
fParams[2] = __GL_I_TO_FLOAT(params[2]);
fParams[3] = __GL_I_TO_FLOAT(params[3]);
break;
case GL_COLOR_INDEXES:
fParams[2] = (GLfloat) params[2];
fParams[1] = (GLfloat) params[1];
case GL_SHININESS:
fParams[0] = (GLfloat) params[0];
break;
}
glcltMaterialfv(face, pname, fParams);
}
void APIENTRY
glcltEdgeFlag ( IN GLboolean flag )
{
PA_EDGEFLAG(flag);
}
void APIENTRY
glcltEdgeFlagv ( IN const GLboolean flag[1] )
{
PA_EDGEFLAG(flag[0]);
}
void APIENTRY
glcltIndexd_InCI ( IN GLdouble c )
{
PA_INDEX_IN_CI((GLfloat) c);
}
void APIENTRY
glcltIndexdv_InCI ( IN const GLdouble c[1] )
{
PA_INDEX_IN_CI((GLfloat) c[0]);
}
void APIENTRY
glcltIndexf_InCI ( IN GLfloat c )
{
PA_INDEX_IN_CI((GLfloat) c);
}
void APIENTRY
glcltIndexfv_InCI ( IN const GLfloat c[1] )
{
PA_INDEX_IN_CI((GLfloat) c[0]);
}
void APIENTRY
glcltIndexi_InCI ( IN GLint c )
{
PA_INDEX_IN_CI((GLfloat) c);
}
void APIENTRY
glcltIndexiv_InCI ( IN const GLint c[1] )
{
PA_INDEX_IN_CI((GLfloat) c[0]);
}
void APIENTRY
glcltIndexs_InCI ( IN GLshort c )
{
PA_INDEX_IN_CI((GLfloat) c);
}
void APIENTRY
glcltIndexsv_InCI ( IN const GLshort c[1] )
{
PA_INDEX_IN_CI((GLfloat) c[0]);
}
void APIENTRY
glcltIndexub_InCI ( IN GLubyte c )
{
PA_INDEX_IN_CI((GLfloat) c);
}
void APIENTRY
glcltIndexubv_InCI ( IN const GLubyte c[1] )
{
PA_INDEX_IN_CI((GLfloat) c[0]);
}
void APIENTRY
glcltIndexd_InRGBA ( IN GLdouble c )
{
PA_INDEX_IN_RGBA((GLfloat) c);
}
void APIENTRY
glcltIndexdv_InRGBA ( IN const GLdouble c[1] )
{
PA_INDEX_IN_RGBA((GLfloat) c[0]);
}
void APIENTRY
glcltIndexf_InRGBA ( IN GLfloat c )
{
PA_INDEX_IN_RGBA((GLfloat) c);
}
void APIENTRY
glcltIndexfv_InRGBA ( IN const GLfloat c[1] )
{
PA_INDEX_IN_RGBA((GLfloat) c[0]);
}
void APIENTRY
glcltIndexi_InRGBA ( IN GLint c )
{
PA_INDEX_IN_RGBA((GLfloat) c);
}
void APIENTRY
glcltIndexiv_InRGBA ( IN const GLint c[1] )
{
PA_INDEX_IN_RGBA((GLfloat) c[0]);
}
void APIENTRY
glcltIndexs_InRGBA ( IN GLshort c )
{
PA_INDEX_IN_RGBA((GLfloat) c);
}
void APIENTRY
glcltIndexsv_InRGBA ( IN const GLshort c[1] )
{
PA_INDEX_IN_RGBA((GLfloat) c[0]);
}
void APIENTRY
glcltIndexub_InRGBA ( IN GLubyte c )
{
PA_INDEX_IN_RGBA((GLfloat) c);
}
void APIENTRY
glcltIndexubv_InRGBA ( IN const GLubyte c[1] )
{
PA_INDEX_IN_RGBA((GLfloat) c[0]);
}
/******************************************************************/
void APIENTRY
glcltNormal3b ( IN GLbyte nx, IN GLbyte ny, IN GLbyte nz )
{
PA_NORMAL(__GL_B_TO_FLOAT(nx), __GL_B_TO_FLOAT(ny), __GL_B_TO_FLOAT(nz));
}
void APIENTRY
glcltNormal3bv ( IN const GLbyte v[3] )
{
PA_NORMAL(__GL_B_TO_FLOAT(v[0]), __GL_B_TO_FLOAT(v[1]), __GL_B_TO_FLOAT(v[2]));
}
void APIENTRY
glcltNormal3d ( IN GLdouble nx, IN GLdouble ny, IN GLdouble nz )
{
PA_NORMAL((GLfloat) nx, (GLfloat) ny, (GLfloat) nz);
}
void APIENTRY
glcltNormal3dv ( IN const GLdouble v[3] )
{
PA_NORMAL((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
}
#ifndef _X86_
void APIENTRY
glcltNormal3f ( IN GLfloat nx, IN GLfloat ny, IN GLfloat nz )
{
PA_NORMAL(nx, ny, nz);
}
void APIENTRY
glcltNormal3fv ( IN const GLfloat v[3] )
{
PA_NORMAL(v[0], v[1], v[2]);
}
#endif
void APIENTRY
glcltNormal3i ( IN GLint nx, IN GLint ny, IN GLint nz )
{
PA_NORMAL(__GL_I_TO_FLOAT(nx), __GL_I_TO_FLOAT(ny), __GL_I_TO_FLOAT(nz));
}
void APIENTRY
glcltNormal3iv ( IN const GLint v[3] )
{
PA_NORMAL(__GL_I_TO_FLOAT(v[0]), __GL_I_TO_FLOAT(v[1]), __GL_I_TO_FLOAT(v[2]));
}
void APIENTRY
glcltNormal3s ( IN GLshort nx, IN GLshort ny, IN GLshort nz )
{
PA_NORMAL(__GL_S_TO_FLOAT(nx), __GL_S_TO_FLOAT(ny), __GL_S_TO_FLOAT(nz));
}
void APIENTRY
glcltNormal3sv ( IN const GLshort v[3] )
{
PA_NORMAL(__GL_S_TO_FLOAT(v[0]), __GL_S_TO_FLOAT(v[1]), __GL_S_TO_FLOAT(v[2]));
}
void APIENTRY
glcltRasterPos2d ( IN GLdouble x, IN GLdouble y )
{
glcltRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) 0.0, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos2dv ( IN const GLdouble v[2] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) 0.0, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos2f ( IN GLfloat x, IN GLfloat y )
{
glcltRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) 0.0, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos2fv ( IN const GLfloat v[2] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) 0.0, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos2i ( IN GLint x, IN GLint y )
{
glcltRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) 0.0, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos2iv ( IN const GLint v[2] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) 0.0, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos2s ( IN GLshort x, IN GLshort y )
{
glcltRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) 0.0, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos2sv ( IN const GLshort v[2] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) 0.0, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos3d ( IN GLdouble x, IN GLdouble y, IN GLdouble z )
{
glcltRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos3dv ( IN const GLdouble v[3] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos3f ( IN GLfloat x, IN GLfloat y, IN GLfloat z )
{
glcltRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos3fv ( IN const GLfloat v[3] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos3i ( IN GLint x, IN GLint y, IN GLint z )
{
glcltRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos3iv ( IN const GLint v[3] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos3s ( IN GLshort x, IN GLshort y, IN GLshort z )
{
glcltRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos3sv ( IN const GLshort v[3] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) 1.0);
}
void APIENTRY
glcltRasterPos4d ( IN GLdouble x, IN GLdouble y, IN GLdouble z, IN GLdouble w )
{
glcltRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
}
void APIENTRY
glcltRasterPos4dv ( IN const GLdouble v[4] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltRasterPos4f ( IN GLfloat x, IN GLfloat y, IN GLfloat z, IN GLfloat w )
{
GLCLIENT_BEGIN( RasterPos4fv, RASTERPOS4FV )
pMsg->v[0] = x;
pMsg->v[1] = y;
pMsg->v[2] = z;
pMsg->v[3] = w;
return;
GLCLIENT_END
}
void APIENTRY
glcltRasterPos4fv ( IN const GLfloat v[4] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltRasterPos4i ( IN GLint x, IN GLint y, IN GLint z, IN GLint w )
{
glcltRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
}
void APIENTRY
glcltRasterPos4iv ( IN const GLint v[4] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltRasterPos4s ( IN GLshort x, IN GLshort y, IN GLshort z, IN GLshort w )
{
glcltRasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
}
void APIENTRY
glcltRasterPos4sv ( IN const GLshort v[4] )
{
glcltRasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltRectd ( IN GLdouble x1, IN GLdouble y1, IN GLdouble x2, IN GLdouble y2 )
{
glcltRectf((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2);
}
void APIENTRY
glcltRectdv ( IN const GLdouble v1[2], IN const GLdouble v2[2] )
{
glcltRectf((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]);
}
void APIENTRY
glcltRectf ( IN GLfloat x1, IN GLfloat y1, IN GLfloat x2, IN GLfloat y2 )
{
POLYARRAY *pa;
// Not allowed in begin/end.
pa = GLTEB_CLTPOLYARRAY();
if (pa->flags & POLYARRAY_IN_BEGIN)
{
GLSETERROR(GL_INVALID_OPERATION);
return;
}
// Call Begin/End to do polyarray correctly. Note that by calling these
// functions, we allow poly array to be batched correctly.
// Note also that we use quad strip instead of quad to force edge flag to be on.
//!!! Conformance fails if we use QUAD_STRIP!
//glcltBegin(GL_QUAD_STRIP);
glcltBegin(GL_QUADS);
pa->flags |= POLYARRAY_SAME_POLYDATA_TYPE;
glcltVertex2f(x1, y1);
glcltVertex2f(x2, y1);
glcltVertex2f(x2, y2);
glcltVertex2f(x1, y2);
glcltEnd();
}
void APIENTRY
glcltRectfv ( IN const GLfloat v1[2], IN const GLfloat v2[2] )
{
glcltRectf((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]);
}
void APIENTRY
glcltRecti ( IN GLint x1, IN GLint y1, IN GLint x2, IN GLint y2 )
{
glcltRectf((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2);
}
void APIENTRY
glcltRectiv ( IN const GLint v1[2], IN const GLint v2[2] )
{
glcltRectf((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]);
}
void APIENTRY
glcltRects ( IN GLshort x1, IN GLshort y1, IN GLshort x2, IN GLshort y2 )
{
glcltRectf((GLfloat) x1, (GLfloat) y1, (GLfloat) x2, (GLfloat) y2);
}
void APIENTRY
glcltRectsv ( IN const GLshort v1[2], IN const GLshort v2[2] )
{
glcltRectf((GLfloat) v1[0], (GLfloat) v1[1], (GLfloat) v2[0], (GLfloat) v2[1]);
}
void APIENTRY
glcltTexCoord1d ( IN GLdouble s )
{
PA_TEXTURE1((GLfloat) s);
}
void APIENTRY
glcltTexCoord1dv ( IN const GLdouble v[1] )
{
PA_TEXTURE1((GLfloat) v[0]);
}
void APIENTRY
glcltTexCoord1f ( IN GLfloat s )
{
PA_TEXTURE1((GLfloat) s);
}
void APIENTRY
glcltTexCoord1fv ( IN const GLfloat v[1] )
{
PA_TEXTURE1((GLfloat) v[0]);
}
void APIENTRY
glcltTexCoord1i ( IN GLint s )
{
PA_TEXTURE1((GLfloat) s);
}
void APIENTRY
glcltTexCoord1iv ( IN const GLint v[1] )
{
PA_TEXTURE1((GLfloat) v[0]);
}
void APIENTRY
glcltTexCoord1s ( IN GLshort s )
{
PA_TEXTURE1((GLfloat) s);
}
void APIENTRY
glcltTexCoord1sv ( IN const GLshort v[1] )
{
PA_TEXTURE1((GLfloat) v[0]);
}
void APIENTRY
glcltTexCoord2d ( IN GLdouble s, IN GLdouble t )
{
PA_TEXTURE2((GLfloat) s, (GLfloat) t);
}
void APIENTRY
glcltTexCoord2dv ( IN const GLdouble v[2] )
{
PA_TEXTURE2((GLfloat) v[0], (GLfloat) v[1]);
}
#ifndef _X86_
void APIENTRY
glcltTexCoord2f ( IN GLfloat s, IN GLfloat t )
{
PA_TEXTURE2((GLfloat) s, (GLfloat) t);
}
void APIENTRY
glcltTexCoord2fv ( IN const GLfloat v[2] )
{
PA_TEXTURE2((GLfloat) v[0], (GLfloat) v[1]);
}
#endif
void APIENTRY
glcltTexCoord2i ( IN GLint s, IN GLint t )
{
PA_TEXTURE2((GLfloat) s, (GLfloat) t);
}
void APIENTRY
glcltTexCoord2iv ( IN const GLint v[2] )
{
PA_TEXTURE2((GLfloat) v[0], (GLfloat) v[1]);
}
void APIENTRY
glcltTexCoord2s ( IN GLshort s, IN GLshort t )
{
PA_TEXTURE2((GLfloat) s, (GLfloat) t);
}
void APIENTRY
glcltTexCoord2sv ( IN const GLshort v[2] )
{
PA_TEXTURE2((GLfloat) v[0], (GLfloat) v[1]);
}
void APIENTRY
glcltTexCoord3d ( IN GLdouble s, IN GLdouble t, IN GLdouble r )
{
PA_TEXTURE3((GLfloat) s, (GLfloat) t, (GLfloat) r);
}
void APIENTRY
glcltTexCoord3dv ( IN const GLdouble v[3] )
{
PA_TEXTURE3((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
}
#ifndef _X86_
void APIENTRY
glcltTexCoord3f ( IN GLfloat s, IN GLfloat t, IN GLfloat r )
{
PA_TEXTURE3((GLfloat) s, (GLfloat) t, (GLfloat) r);
}
void APIENTRY
glcltTexCoord3fv ( IN const GLfloat v[3] )
{
PA_TEXTURE3((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
}
#endif
void APIENTRY
glcltTexCoord3i ( IN GLint s, IN GLint t, IN GLint r )
{
PA_TEXTURE3((GLfloat) s, (GLfloat) t, (GLfloat) r);
}
void APIENTRY
glcltTexCoord3iv ( IN const GLint v[3] )
{
PA_TEXTURE3((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
}
void APIENTRY
glcltTexCoord3s ( IN GLshort s, IN GLshort t, IN GLshort r )
{
PA_TEXTURE3((GLfloat) s, (GLfloat) t, (GLfloat) r);
}
void APIENTRY
glcltTexCoord3sv ( IN const GLshort v[3] )
{
PA_TEXTURE3((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
}
void APIENTRY
glcltTexCoord4d ( IN GLdouble s, IN GLdouble t, IN GLdouble r, IN GLdouble q )
{
PA_TEXTURE4((GLfloat) s, (GLfloat) t, (GLfloat) r, (GLfloat) q);
}
void APIENTRY
glcltTexCoord4dv ( IN const GLdouble v[4] )
{
PA_TEXTURE4((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltTexCoord4f ( IN GLfloat s, IN GLfloat t, IN GLfloat r, IN GLfloat q )
{
PA_TEXTURE4((GLfloat) s, (GLfloat) t, (GLfloat) r, (GLfloat) q);
}
void APIENTRY
glcltTexCoord4fv ( IN const GLfloat v[4] )
{
PA_TEXTURE4((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltTexCoord4i ( IN GLint s, IN GLint t, IN GLint r, IN GLint q )
{
PA_TEXTURE4((GLfloat) s, (GLfloat) t, (GLfloat) r, (GLfloat) q);
}
void APIENTRY
glcltTexCoord4iv ( IN const GLint v[4] )
{
PA_TEXTURE4((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltTexCoord4s ( IN GLshort s, IN GLshort t, IN GLshort r, IN GLshort q )
{
PA_TEXTURE4((GLfloat) s, (GLfloat) t, (GLfloat) r, (GLfloat) q);
}
void APIENTRY
glcltTexCoord4sv ( IN const GLshort v[4] )
{
PA_TEXTURE4((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltVertex2d ( IN GLdouble x, IN GLdouble y )
{
PA_VERTEX2((GLfloat) x, (GLfloat) y);
}
void APIENTRY
glcltVertex2dv ( IN const GLdouble v[2] )
{
PA_VERTEX2((GLfloat) v[0], (GLfloat) v[1]);
}
#ifndef _X86_
void APIENTRY
glcltVertex2f ( IN GLfloat x, IN GLfloat y )
{
PA_VERTEX2((GLfloat) x, (GLfloat) y);
}
void APIENTRY
glcltVertex2fv ( IN const GLfloat v[2] )
{
PA_VERTEX2((GLfloat) v[0], (GLfloat) v[1]);
}
#endif
void APIENTRY
glcltVertex2i ( IN GLint x, IN GLint y )
{
PA_VERTEX2((GLfloat) x, (GLfloat) y);
}
void APIENTRY
glcltVertex2iv ( IN const GLint v[2] )
{
PA_VERTEX2((GLfloat) v[0], (GLfloat) v[1]);
}
void APIENTRY
glcltVertex2s ( IN GLshort x, IN GLshort y )
{
PA_VERTEX2((GLfloat) x, (GLfloat) y);
}
void APIENTRY
glcltVertex2sv ( IN const GLshort v[2] )
{
PA_VERTEX2((GLfloat) v[0], (GLfloat) v[1]);
}
void APIENTRY
glcltVertex3d ( IN GLdouble x, IN GLdouble y, IN GLdouble z )
{
PA_VERTEX3((GLfloat) x, (GLfloat) y, (GLfloat) z);
}
void APIENTRY
glcltVertex3dv ( IN const GLdouble v[3] )
{
PA_VERTEX3((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
}
#ifndef _X86_
void APIENTRY
glcltVertex3f ( IN GLfloat x, IN GLfloat y, IN GLfloat z )
{
PA_VERTEX3((GLfloat) x, (GLfloat) y, (GLfloat) z);
}
void APIENTRY
glcltVertex3fv ( IN const GLfloat v[3] )
{
PA_VERTEX3((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
}
#endif
void APIENTRY
glcltVertex3i ( IN GLint x, IN GLint y, IN GLint z )
{
PA_VERTEX3((GLfloat) x, (GLfloat) y, (GLfloat) z);
}
void APIENTRY
glcltVertex3iv ( IN const GLint v[3] )
{
PA_VERTEX3((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
}
void APIENTRY
glcltVertex3s ( IN GLshort x, IN GLshort y, IN GLshort z )
{
PA_VERTEX3((GLfloat) x, (GLfloat) y, (GLfloat) z);
}
void APIENTRY
glcltVertex3sv ( IN const GLshort v[3] )
{
PA_VERTEX3((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
}
void APIENTRY
glcltVertex4d ( IN GLdouble x, IN GLdouble y, IN GLdouble z, IN GLdouble w )
{
PA_VERTEX4((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
}
void APIENTRY
glcltVertex4dv ( IN const GLdouble v[4] )
{
PA_VERTEX4((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltVertex4f ( IN GLfloat x, IN GLfloat y, IN GLfloat z, IN GLfloat w )
{
PA_VERTEX4((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
}
void APIENTRY
glcltVertex4fv ( IN const GLfloat v[4] )
{
PA_VERTEX4((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltVertex4i ( IN GLint x, IN GLint y, IN GLint z, IN GLint w )
{
PA_VERTEX4((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
}
void APIENTRY
glcltVertex4iv ( IN const GLint v[4] )
{
PA_VERTEX4((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltVertex4s ( IN GLshort x, IN GLshort y, IN GLshort z, IN GLshort w )
{
PA_VERTEX4((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
}
void APIENTRY
glcltVertex4sv ( IN const GLshort v[4] )
{
PA_VERTEX4((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
}
void APIENTRY
glcltClipPlane ( IN GLenum plane, IN const GLdouble equation[4] )
{
GLCLIENT_BEGIN( ClipPlane, CLIPPLANE )
pMsg->plane = plane ;
pMsg->equation[ 0] = equation[ 0];
pMsg->equation[ 1] = equation[ 1];
pMsg->equation[ 2] = equation[ 2];
pMsg->equation[ 3] = equation[ 3];
return;
GLCLIENT_END
}
void APIENTRY
glcltColorMaterial ( IN GLenum face, IN GLenum mode )
{
GLCLIENT_BEGIN( ColorMaterial, COLORMATERIAL )
pMsg->face = face ;
pMsg->mode = mode ;
return;
GLCLIENT_END
}
void APIENTRY
glcltCullFace ( IN GLenum mode )
{
GLCLIENT_BEGIN( CullFace, CULLFACE )
pMsg->mode = mode ;
return;
GLCLIENT_END
}
void APIENTRY
glcltFrontFace ( IN GLenum mode )
{
GLCLIENT_BEGIN( FrontFace, FRONTFACE )
pMsg->mode = mode ;
return;
GLCLIENT_END
}
void APIENTRY
glcltHint ( IN GLenum target, IN GLenum mode )
{
GLCLIENT_BEGIN( Hint, HINT )
pMsg->target = target ;
pMsg->mode = mode ;
return;
GLCLIENT_END
}
void APIENTRY
glcltLineStipple ( IN GLint factor, IN GLushort pattern )
{
GLCLIENT_BEGIN( LineStipple, LINESTIPPLE )
pMsg->factor = factor ;
pMsg->pattern = pattern ;
return;
GLCLIENT_END
}
void APIENTRY
glcltLineWidth ( IN GLfloat width )
{
GLCLIENT_BEGIN( LineWidth, LINEWIDTH )
pMsg->width = width ;
return;
GLCLIENT_END
}
void APIENTRY
glcltPointSize ( IN GLfloat size )
{
GLCLIENT_BEGIN( PointSize, POINTSIZE )
pMsg->size = size ;
return;
GLCLIENT_END
}
void APIENTRY
glcltPolygonMode ( IN GLenum face, IN GLenum mode )
{
GLCLIENT_BEGIN( PolygonMode, POLYGONMODE )
pMsg->face = face ;
pMsg->mode = mode ;
return;
GLCLIENT_END
}
void APIENTRY
glcltScissor ( IN GLint x, IN GLint y, IN GLsizei width, IN GLsizei height )
{
GLCLIENT_BEGIN( Scissor, SCISSOR )
pMsg->x = x ;
pMsg->y = y ;
pMsg->width = width ;
pMsg->height = height ;
return;
GLCLIENT_END
}
void APIENTRY
glcltShadeModel ( IN GLenum mode )
{
GLCLIENT_BEGIN( ShadeModel, SHADEMODEL )
pMsg->mode = mode ;
return;
GLCLIENT_END
}
void APIENTRY
glcltInitNames ( void )
{
GLCLIENT_BEGIN( InitNames, INITNAMES )
return;
GLCLIENT_END
}
void APIENTRY
glcltLoadName ( IN GLuint name )
{
GLCLIENT_BEGIN( LoadName, LOADNAME )
pMsg->name = name ;
return;
GLCLIENT_END
}
void APIENTRY
glcltPassThrough ( IN GLfloat token )
{
GLCLIENT_BEGIN( PassThrough, PASSTHROUGH )
pMsg->token = token ;
return;
GLCLIENT_END
}
void APIENTRY
glcltPopName ( void )
{
GLCLIENT_BEGIN( PopName, POPNAME )
return;
GLCLIENT_END
}
void APIENTRY
glcltPushName ( IN GLuint name )
{
GLCLIENT_BEGIN( PushName, PUSHNAME )
pMsg->name = name ;
return;
GLCLIENT_END
}
void APIENTRY
glcltDrawBuffer ( IN GLenum mode )
{
// We're doing something special here. By doing a glsbAttention after
// putting a glDrawBuffer in the batch, we are guaranteeing that all
// drawing done in the batch is in the same drawing mode and that the
// drawing mode cannot change until the end of the batch. This allows
// the server to sample the current drawing mode at the beginning of
// batch and to assume that it is constant for the entire batch.
//
// The server might be able to take advantage of the fact, for example,
// that all drawing in a batch is only to the back buffer.
GLCLIENT_BEGIN( DrawBuffer, DRAWBUFFER )
pMsg->mode = mode ;
glsbAttention();
return;
GLCLIENT_END
}
void APIENTRY
glcltClear ( IN GLbitfield mask )
{
GLCLIENT_BEGIN( Clear, CLEAR )
pMsg->mask = mask ;
return;
GLCLIENT_END
}
void APIENTRY
glcltClearAccum ( IN GLfloat red, IN GLfloat green, IN GLfloat blue, IN GLfloat alpha )
{
GLCLIENT_BEGIN( ClearAccum, CLEARACCUM )
pMsg->red = red ;
pMsg->green = green ;
pMsg->blue = blue ;
pMsg->alpha = alpha ;
return;
GLCLIENT_END
}
void APIENTRY
glcltClearIndex ( IN GLfloat c )
{
GLCLIENT_BEGIN( ClearIndex, CLEARINDEX )
pMsg->c = c ;
return;
GLCLIENT_END
}
void APIENTRY
glcltClearColor ( IN GLclampf red, IN GLclampf green, IN GLclampf blue, IN GLclampf alpha )
{
GLCLIENT_BEGIN( ClearColor, CLEARCOLOR )
pMsg->red = red ;
pMsg->green = green ;
pMsg->blue = blue ;
pMsg->alpha = alpha ;
return;
GLCLIENT_END
}
void APIENTRY
glcltClearStencil ( IN GLint s )
{
GLCLIENT_BEGIN( ClearStencil, CLEARSTENCIL )
pMsg->s = s ;
return;
GLCLIENT_END
}
void APIENTRY
glcltClearDepth ( IN GLclampd depth )
{
GLCLIENT_BEGIN( ClearDepth, CLEARDEPTH )
pMsg->depth = depth ;
return;
GLCLIENT_END
}
void APIENTRY
glcltStencilMask ( IN GLuint mask )
{
GLCLIENT_BEGIN( StencilMask, STENCILMASK )
pMsg->mask = mask ;
return;
GLCLIENT_END
}
void APIENTRY
glcltColorMask ( IN GLboolean red, IN GLboolean green, IN GLboolean blue, IN GLboolean alpha )
{
GLCLIENT_BEGIN( ColorMask, COLORMASK )
pMsg->red = red ;
pMsg->green = green ;
pMsg->blue = blue ;
pMsg->alpha = alpha ;
return;
GLCLIENT_END
}
void APIENTRY
glcltDepthMask ( IN GLboolean flag )
{
GLCLIENT_BEGIN( DepthMask, DEPTHMASK )
pMsg->flag = flag ;
return;
GLCLIENT_END
}
void APIENTRY
glcltIndexMask ( IN GLuint mask )
{
GLCLIENT_BEGIN( IndexMask, INDEXMASK )
pMsg->mask = mask ;
return;
GLCLIENT_END
}
void APIENTRY
glcltAccum ( IN GLenum op, IN GLfloat value )
{
GLCLIENT_BEGIN( Accum, ACCUM )
pMsg->op = op ;
pMsg->value = value ;
return;
GLCLIENT_END
}
void APIENTRY
glcltDisable ( IN GLenum cap )
{
GLCLIENT_BEGIN( Disable, DISABLE )
pMsg->cap = cap ;
return;
GLCLIENT_END
}
void APIENTRY
glcltEnable ( IN GLenum cap )
{
GLCLIENT_BEGIN( Enable, ENABLE )
pMsg->cap = cap ;
return;
GLCLIENT_END
}
void APIENTRY
glcltFinish ( void )
{
// This function is invalid between glBegin and glEnd.
// This is detected in glsbAttention.
glsbAttention();
}
void APIENTRY
glcltFlush ( void )
{
// This function is invalid between glBegin and glEnd.
// This is detected in glsbAttention.
glsbAttention();
}
void APIENTRY
glcltPopAttrib ( void )
{
GLCLIENT_BEGIN( PopAttrib, POPATTRIB )
return;
GLCLIENT_END
}
void APIENTRY
glcltPushAttrib ( IN GLbitfield mask )
{
GLCLIENT_BEGIN( PushAttrib, PUSHATTRIB )
pMsg->mask = mask ;
return;
GLCLIENT_END
}
void APIENTRY
glcltMapGrid1d ( IN GLint un, IN GLdouble u1, IN GLdouble u2 )
{
glcltMapGrid1f(un, (GLfloat) u1, (GLfloat) u2);
}
void APIENTRY
glcltMapGrid1f ( IN GLint un, IN GLfloat u1, IN GLfloat u2 )
{
GLCLIENT_BEGIN( MapGrid1f, MAPGRID1F )
pMsg->un = un ;
pMsg->u1 = u1 ;
pMsg->u2 = u2 ;
return;
GLCLIENT_END
}
void APIENTRY
glcltMapGrid2d ( IN GLint un, IN GLdouble u1, IN GLdouble u2, IN GLint vn, IN GLdouble v1, IN GLdouble v2 )
{
glcltMapGrid2f(un, (GLfloat) u1, (GLfloat) u2, vn, (GLfloat) v1, (GLfloat) v2);
}
void APIENTRY
glcltMapGrid2f ( IN GLint un, IN GLfloat u1, IN GLfloat u2, IN GLint vn, IN GLfloat v1, IN GLfloat v2 )
{
GLCLIENT_BEGIN( MapGrid2f, MAPGRID2F )
pMsg->un = un ;
pMsg->u1 = u1 ;
pMsg->u2 = u2 ;
pMsg->vn = vn ;
pMsg->v1 = v1 ;
pMsg->v2 = v2 ;
return;
GLCLIENT_END
}
void APIENTRY
glcltEvalCoord1f ( IN GLfloat u )
{
POLYARRAY *pa;
POLYDATA *pd;
// This call has no effect outside begin/end (unless it is being compiled).
// We cannot evaluate the map on the client side since we do not have access
// to the latest gc states (e.g. map definitions, enables) without flushing
// the batch. Instead, we will insert a record into poly array for evaluation
// on the server side.
// This code is similar to glcltVertex.
pa = GLTEB_CLTPOLYARRAY();
if (pa->flags & POLYARRAY_IN_BEGIN)
{
pa->flags |= POLYARRAY_EVALCOORD1;
pd = pa->pdNextVertex++;
pd->flags |= POLYDATA_EVALCOORD1;
pd->obj.x = u;
pd[1].flags = 0;
if (pd >= pa->pdFlush)
PolyArrayFlushPartialPrimitive();
}
}
void APIENTRY
glcltEvalCoord1d ( IN GLdouble u )
{
glcltEvalCoord1f((GLfloat) u);
}
void APIENTRY
glcltEvalCoord1dv ( IN const GLdouble u[1] )
{
glcltEvalCoord1f((GLfloat) u[0]);
}
void APIENTRY
glcltEvalCoord1fv ( IN const GLfloat u[1] )
{
glcltEvalCoord1f((GLfloat) u[0]);
}
void APIENTRY
glcltEvalCoord2f ( IN GLfloat u, IN GLfloat v )
{
POLYARRAY *pa;
POLYDATA *pd;
// This call has no effect outside begin/end (unless it is being compiled).
// We cannot evaluate the map on the client side since we do not have access
// to the latest gc states (e.g. map definitions, enables) without flushing
// the batch. Instead, we will insert a record into poly array for evaluation
// on the server side.
// This code is similar to glcltVertex.
pa = GLTEB_CLTPOLYARRAY();
if (pa->flags & POLYARRAY_IN_BEGIN)
{
pa->flags |= POLYARRAY_EVALCOORD2;
pd = pa->pdNextVertex++;
pd->flags |= POLYDATA_EVALCOORD2;
pd->obj.x = u;
pd->obj.y = v;
pd[1].flags = 0;
if (pd >= pa->pdFlush)
PolyArrayFlushPartialPrimitive();
}
}
void APIENTRY
glcltEvalCoord2d ( IN GLdouble u, IN GLdouble v )
{
glcltEvalCoord2f((GLfloat) u, (GLfloat) v);
}
void APIENTRY
glcltEvalCoord2dv ( IN const GLdouble u[2] )
{
glcltEvalCoord2f((GLfloat) u[0], (GLfloat) u[1]);
}
void APIENTRY
glcltEvalCoord2fv ( IN const GLfloat u[2] )
{
glcltEvalCoord2f((GLfloat) u[0], (GLfloat) u[1]);
}
void APIENTRY
glcltEvalPoint1 ( IN GLint i )
{
POLYARRAY *pa;
POLYDATA *pd;
GLint *pi;
// This call has no effect outside begin/end (unless it is being compiled).
// We cannot evaluate the map on the client side since we do not have access
// to the latest gc states (e.g. map definitions, enables) without flushing
// the batch. Instead, we will insert a record into poly array for evaluation
// on the server side.
// This code is similar to glcltVertex.
pa = GLTEB_CLTPOLYARRAY();
if (pa->flags & POLYARRAY_IN_BEGIN)
{
pa->flags |= POLYARRAY_EVALPOINT1;
pd = pa->pdNextVertex++;
pd->flags |= POLYDATA_EVALPOINT1;
pi = (GLint *) &pd->obj;
pi[0] = i;
pd[1].flags = 0;
if (pd >= pa->pdFlush)
PolyArrayFlushPartialPrimitive();
}
}
void APIENTRY
glcltEvalPoint2 ( IN GLint i, IN GLint j )
{
POLYARRAY *pa;
POLYDATA *pd;
GLint *pi;
// This call has no effect outside begin/end (unless it is being compiled).
// We cannot evaluate the map on the client side since we do not have access
// to the latest gc states (e.g. map definitions, enables) without flushing
// the batch. Instead, we will insert a record into poly array for evaluation
// on the server side.
// This code is similar to glcltVertex.
pa = GLTEB_CLTPOLYARRAY();
if (pa->flags & POLYARRAY_IN_BEGIN)
{
pa->flags |= POLYARRAY_EVALPOINT2;
pd = pa->pdNextVertex++;
pd->flags |= POLYDATA_EVALPOINT2;
pi = (GLint *) &pd->obj;
pi[0] = i;
pi[1] = j;
pd[1].flags = 0;
if (pd >= pa->pdFlush)
PolyArrayFlushPartialPrimitive();
}
}
void APIENTRY
glcltEvalMesh1 ( IN GLenum mode, IN GLint u1, IN GLint u2 )
{
POLYARRAY *pa;
GLenum primType;
GLint i;
// Not allowed in begin/end.
pa = GLTEB_CLTPOLYARRAY();
if (pa->flags & POLYARRAY_IN_BEGIN)
{
GLSETERROR(GL_INVALID_OPERATION);
return;
}
switch(mode)
{
case GL_LINE:
primType = GL_LINE_STRIP;
break;
case GL_POINT:
primType = GL_POINTS;
break;
default:
GLSETERROR(GL_INVALID_ENUM);
return;
}
// Call Begin/End to do polyarray correctly. Note that by calling these
// functions, we allow poly array to be batched correctly.
glcltBegin(primType);
pa->flags |= POLYARRAY_SAME_POLYDATA_TYPE;
for (i = u1; i <= u2; i++)
glcltEvalPoint1(i);
glcltEnd();
}
#define MV_VERTEX3 0x0001
#define MV_VERTEX4 0x0002
#define MV_NORMAL 0x0004
#define MV_COLOR 0x0008
#define MV_INDEX 0x0010
// Assumption: U is moving, left to right. V is moving top to bottom
#define MV_TOP 0x0001
#define MV_LEFT 0x0002
typedef struct {
__GLcoord vertex;
__GLcoord normal;
__GLcoord texture;
__GLcolor color;
} MESHVERTEX;
#define MAX_MESH_VERTICES MAX_U_SIZE*MAX_V_SIZE
#define MAX_U_SIZE 16
#define MAX_V_SIZE 16
GLubyte *dBufFill; //fill only
GLuint totFillPts;
GLubyte *dBufTopLeft; //for mv_left
GLuint totTopLeftPts;
GLubyte *dBufTopRight; //for non mv_left
GLuint totTopRightPts;
int FASTCALL genMeshElts (GLenum mode, GLuint sides, GLint nu, GLint nv,
GLubyte *buff)
{
GLint start;
GLint i, j, k;
// Compute the DrawElements Indices
switch(mode) {
case GL_LINE :
// Draw lines along U direction
start = 1;
k = 0;
if (sides & MV_TOP)
start = 0 ;
for (i=start; i<nv; i++)
for(j=0; j<nu-1; j++) {
buff[k++] = i*nu+j;
buff[k++] = i*nu+j+1;
}
// Draw lines along V direction
start = 1 ;
if (sides & MV_LEFT)
start = 0;
for (i=start; i<nu; i++)
for (j=0; j<nv-1; j++) {
buff[k++] = j*nu+i;
buff[k++] = (j+1)*nu+i;
}
break ;
case GL_FILL :
for (i=0, k=0; i<nv-1; i++)
for (j=0; j<nu-1; j++) {
buff[k++] = i*nu+j;
buff[k++] = (i+1)*nu+j;
buff[k++] = (i+1)*nu+j+1;
buff[k++] = i*nu+j+1;
}
break ;
}
return k; //the total number of points
}
void FASTCALL PA_EvalMesh2Fast(__GLcontext *gc, GLint u1, GLint u2, GLint v1,
GLint v2, GLint meshSize, GLenum mode,
GLuint sides)
{
GLint i, j, k, nu, nv;
POLYARRAY polyArray;
POLYDATA polyData;
__GLcolor currentColor;
__GLcoord currentNormal, currentTexture;
GLboolean currentEdgeFlag;
MESHVERTEX *mv, mvBuf[MAX_U_SIZE*MAX_V_SIZE];
GLuint mflags;
GLuint stride;
GLubyte *disBuf;
__GLvertexArray currentVertexInfo;
GLuint texSize = 0, start, totalPts;
GLubyte dBufSmall[4*MAX_U_SIZE*MAX_V_SIZE]; //small
// Initialize polyarray structure.
// The PADoEval2 function sets polyArray.flags only.
polyArray.flags = 0;
// Initialize polydata structure.
polyData.flags = POLYDATA_EVALPOINT2;
// Now build the mesh vertex array [0..u2-u1, 0..v2-v1]
mv = &mvBuf[0];
nu = u2 - u1 + 1;
nv = v2 - v1 + 1;
for (i = 0; i < nv; i++) { //along U
for (j = 0; j < nu; j++) { //along V
GLint *pi = (GLint *) &polyData.obj;
pi[0] = u1 + j;
pi[1] = v1 + i;
PADoEval2(gc, &polyArray, &polyData, FALSE);
// save the vertex data
mv->vertex = polyData.obj;
mv->normal = polyData.normal;
mv->texture = polyData.texture;
mv->color = polyData.colors[0];
mv++;
}
}
if ((nv != MAX_V_SIZE) || (nu != MAX_U_SIZE)) {
disBuf = dBufSmall;
totalPts = genMeshElts (mode, sides, nu, nv, disBuf);
} else {
if (mode == GL_FILL) {
disBuf = dBufFill;
totalPts = totFillPts;
} else
switch (sides) {
case (MV_TOP | MV_LEFT):
disBuf = dBufTopLeft;
totalPts = totTopLeftPts;
break;
case (MV_TOP):
disBuf = dBufTopRight;
totalPts = totTopRightPts;
break;
case (MV_LEFT):
disBuf = &dBufTopLeft [(MAX_U_SIZE - 1) * 2];
totalPts = totTopLeftPts - (MAX_U_SIZE - 1) * 2;
break;
default : //NONE
disBuf = &dBufTopRight [(MAX_V_SIZE - 1) * 2];
totalPts = totTopRightPts - (MAX_V_SIZE - 1) * 2;
break;
}
}
// Compute mesh valid flags.
mflags = 0;
if (polyData.flags & POLYDATA_VERTEX3)
mflags |= MV_VERTEX3;
else
{
ASSERTOPENGL(polyData.flags & POLYDATA_VERTEX4, "bad vertex flag!\n");
mflags |= MV_VERTEX4;
}
if (polyData.flags & POLYDATA_NORMAL_VALID)
mflags |= MV_NORMAL;
if (polyData.flags & POLYDATA_COLOR_VALID)
{
if (gc->modes.colorIndexMode)
mflags |= MV_INDEX;
else
mflags |= MV_COLOR;
}
if (polyArray.flags & POLYARRAY_TEXTURE1)
texSize = 1;
else if (polyArray.flags & POLYARRAY_TEXTURE2)
texSize = 2;
else if (polyArray.flags & POLYARRAY_TEXTURE3)
texSize = 3;
else if (polyArray.flags & POLYARRAY_TEXTURE4)
texSize = 4;
// Save current values.
if (mflags & MV_NORMAL)
currentNormal = gc->state.current.normal;
if (mflags & MV_INDEX)
currentColor.r = gc->state.current.userColorIndex;
else if (mflags & MV_COLOR)
currentColor = gc->state.current.userColor;
if (texSize)
currentTexture = gc->state.current.texture;
// Always force edge flag on in GL_FILL mode. The spec uses QUAD_STRIP
// which implies that edge flag is on for the evaluated mesh.
currentEdgeFlag = gc->state.current.edgeTag;
gc->state.current.edgeTag = GL_TRUE;
currentVertexInfo = gc->vertexArray;
//Enable the appropriate arrays
// Disable the arrays followed by enabling each individual array.
gc->vertexArray.flags |= __GL_VERTEX_ARRAY_DIRTY;
gc->vertexArray.mask &= ~(VAMASK_VERTEX_ENABLE_MASK |
VAMASK_NORMAL_ENABLE_MASK |
VAMASK_COLOR_ENABLE_MASK |
VAMASK_INDEX_ENABLE_MASK |
VAMASK_TEXCOORD_ENABLE_MASK |
VAMASK_EDGEFLAG_ENABLE_MASK);
stride = sizeof(MESHVERTEX);
if (mflags & MV_NORMAL) {
gc->vertexArray.mask |= VAMASK_NORMAL_ENABLE_MASK;
glcltNormalPointer(GL_FLOAT, stride, &(mvBuf[0].normal.x));
}
if (mflags & MV_INDEX) {
gc->vertexArray.mask |= VAMASK_INDEX_ENABLE_MASK;
glcltIndexPointer(GL_FLOAT, stride, &(mvBuf[0].color.r));
} else if (mflags & MV_COLOR) {
gc->vertexArray.mask |= VAMASK_COLOR_ENABLE_MASK;
glcltColorPointer(3, GL_FLOAT, stride, &(mvBuf[0].color.r));
}
if (texSize) {
glcltTexCoordPointer(texSize, GL_FLOAT, stride, &(mvBuf[0].texture.x));
gc->vertexArray.mask |= VAMASK_TEXCOORD_ENABLE_MASK;
}
if (mflags & MV_VERTEX3)
glcltVertexPointer(3, GL_FLOAT, stride, &(mvBuf[0].vertex.x));
else
glcltVertexPointer(4, GL_FLOAT, stride, &(mvBuf[0].vertex.x));
gc->vertexArray.mask |= VAMASK_VERTEX_ENABLE_MASK;
if (mode == GL_FILL)
glcltDrawElements(GL_QUADS, totalPts,
GL_UNSIGNED_BYTE, disBuf);
else
glcltDrawElements(GL_LINES, totalPts,
GL_UNSIGNED_BYTE, disBuf);
// Execute the command now. Otherwise, the current states will be messed up.
glsbAttention();
// Restore current values.
if (mflags & MV_NORMAL)
__glim_Normal3fv(&currentNormal.x);
if (mflags & MV_INDEX)
__glim_Indexf(currentColor.r);
else if (mflags & MV_COLOR)
__glim_Color4fv(&currentColor.r);
if (texSize)
__glim_TexCoord4fv(&currentTexture.x);
gc->state.current.edgeTag = currentEdgeFlag;
gc->vertexArray = currentVertexInfo ;
}
void APIENTRY
glcltEvalMesh2 ( IN GLenum mode, IN GLint u1, IN GLint u2, IN GLint v1, IN GLint v2 )
{
POLYARRAY *pa;
GLint i, j, meshSize;
__GL_SETUP();
GLboolean done_v, done_u;
GLint v_beg, v_end, u_beg, u_end, u_len;
GLuint sides;
// Flush the command buffer before we start. We need to access the
// latest evaluator states in this function.
glsbAttention();
// Not allowed in begin/end.
pa = gc->paTeb;
if (pa->flags & POLYARRAY_IN_BEGIN)
{
GLSETERROR(GL_INVALID_OPERATION);
return;
}
// If vertex map is not enabled, this is a noop.
if (!(gc->state.enables.eval2 & (__GL_MAP2_VERTEX_4_ENABLE |
__GL_MAP2_VERTEX_3_ENABLE)))
return;
// Make sure that the mesh is not empty.
if (u1 > u2 || v1 > v2)
return;
// Call Begin/End to do polyarray correctly. Note that by calling these
// functions, we allow poly array to be batched correctly.
// In fill or line modes, we use vertex array for best performance.
if (mode == GL_FILL && dBufFill == NULL) {
if (!(dBufFill = (GLubyte *) LocalAlloc (LMEM_FIXED,
4 * MAX_U_SIZE * MAX_V_SIZE * sizeof (GLubyte)))) {
GLSETERROR(GL_OUT_OF_MEMORY);
return;
}
totFillPts = genMeshElts (GL_FILL, MV_TOP | MV_LEFT, MAX_U_SIZE,
MAX_V_SIZE, dBufFill);
}
if (mode == GL_LINE && dBufTopLeft == NULL) {
if (!(dBufTopLeft = (GLubyte *) LocalAlloc (LMEM_FIXED,
2 * 4 * MAX_U_SIZE * MAX_V_SIZE * sizeof (GLubyte)))) {
GLSETERROR(GL_OUT_OF_MEMORY);
return;
}
dBufTopRight = &dBufTopLeft[4 * MAX_U_SIZE * MAX_V_SIZE];
totTopLeftPts = genMeshElts (GL_LINE, MV_TOP | MV_LEFT, MAX_U_SIZE,
MAX_V_SIZE, dBufTopLeft);
totTopRightPts = genMeshElts (GL_LINE, MV_TOP, MAX_U_SIZE, MAX_V_SIZE,
dBufTopRight);
}
switch(mode)
{
case GL_POINT:
glcltBegin(GL_POINTS);
pa->flags |= POLYARRAY_SAME_POLYDATA_TYPE;
for (i = v1; i <= v2; i++)
for (j = u1; j <= u2; j++)
glcltEvalPoint2(j, i);
glcltEnd();
break ;
case GL_LINE:
case GL_FILL: // the sides argument in the fastcall is ignored
meshSize = (u2 - u1 + 1)*(v2 - v1 + 1);
if (meshSize <= MAX_MESH_VERTICES)
PA_EvalMesh2Fast(gc, u1, u2, v1, v2, meshSize, mode,
(GLubyte) 15);
else {
u_beg = u1;
u_end = u_beg + MAX_U_SIZE - 1;
done_u = GL_FALSE;
while (!done_u) { //Along U side
if(u_end >= u2) {
u_end = u2;
done_u = GL_TRUE;
}
u_len = u_end - u_beg + 1;
v_beg = v1;
v_end = v_beg + MAX_V_SIZE - 1;
done_v = GL_FALSE;
while(!done_v) { //Along V side
if(v_end >= v2) {
v_end = v2;
done_v = GL_TRUE;
}
meshSize = u_len*(v_end - v_beg + 1);
sides = 0;
if (u_beg == u1)
sides |= MV_LEFT;
if (v_beg == v1)
sides |= MV_TOP;
PA_EvalMesh2Fast(gc, u_beg, u_end,
v_beg, v_end, meshSize, mode, sides);
v_beg = v_end;
v_end = v_beg+MAX_V_SIZE-1;
}
u_beg = u_end;
u_end = u_beg + MAX_U_SIZE - 1;
}
}
break ;
default:
GLSETERROR(GL_INVALID_ENUM);
return;
}
}
void APIENTRY
glcltAlphaFunc ( IN GLenum func, IN GLclampf ref )
{
GLCLIENT_BEGIN( AlphaFunc, ALPHAFUNC )
pMsg->func = func ;
pMsg->ref = ref ;
return;
GLCLIENT_END
}
void APIENTRY
glcltBlendFunc ( IN GLenum sfactor, IN GLenum dfactor )
{
GLCLIENT_BEGIN( BlendFunc, BLENDFUNC )
pMsg->sfactor = sfactor ;
pMsg->dfactor = dfactor ;
return;
GLCLIENT_END
}
void APIENTRY
glcltLogicOp ( IN GLenum opcode )
{
GLCLIENT_BEGIN( LogicOp, LOGICOP )
pMsg->opcode = opcode ;
return;
GLCLIENT_END
}
void APIENTRY
glcltStencilFunc ( IN GLenum func, IN GLint ref, IN GLuint mask )
{
GLCLIENT_BEGIN( StencilFunc, STENCILFUNC )
pMsg->func = func ;
pMsg->ref = ref ;
pMsg->mask = mask ;
return;
GLCLIENT_END
}
void APIENTRY
glcltStencilOp ( IN GLenum fail, IN GLenum zfail, IN GLenum zpass )
{
GLCLIENT_BEGIN( StencilOp, STENCILOP )
pMsg->fail = fail ;
pMsg->zfail = zfail ;
pMsg->zpass = zpass ;
return;
GLCLIENT_END
}
void APIENTRY
glcltDepthFunc ( IN GLenum func )
{
GLCLIENT_BEGIN( DepthFunc, DEPTHFUNC )
pMsg->func = func ;
return;
GLCLIENT_END
}
void APIENTRY
glcltPixelZoom ( IN GLfloat xfactor, IN GLfloat yfactor )
{
GLCLIENT_BEGIN( PixelZoom, PIXELZOOM )
pMsg->xfactor = xfactor ;
pMsg->yfactor = yfactor ;
return;
GLCLIENT_END
}
void APIENTRY
glcltPixelTransferf ( IN GLenum pname, IN GLfloat param )
{
GLCLIENT_BEGIN( PixelTransferf, PIXELTRANSFERF )
pMsg->pname = pname ;
pMsg->param = param ;
return;
GLCLIENT_END
}
void APIENTRY
glcltPixelTransferi ( IN GLenum pname, IN GLint param )
{
GLCLIENT_BEGIN( PixelTransferi, PIXELTRANSFERI )
pMsg->pname = pname ;
pMsg->param = param ;
return;
GLCLIENT_END
}
void APIENTRY
glcltPixelStoref ( IN GLenum pname, IN GLfloat param )
{
GLCLIENT_BEGIN( PixelStoref, PIXELSTOREF )
pMsg->pname = pname ;
pMsg->param = param ;
return;
GLCLIENT_END
}
void APIENTRY
glcltPixelStorei ( IN GLenum pname, IN GLint param )
{
GLCLIENT_BEGIN( PixelStorei, PIXELSTOREI )
pMsg->pname = pname ;
pMsg->param = param ;
return;
GLCLIENT_END
}
void APIENTRY
glcltPixelMapfv ( IN GLenum map, IN GLint mapsize, IN const GLfloat values[] )
{
GLCLIENT_BEGIN_LARGE_SET( PixelMapfv, PIXELMAPFV, values, ulSize, valuesOff )
pMsg->map = map ;
pMsg->mapsize = mapsize ;
GLCLIENT_END_LARGE_SET
return;
}
void APIENTRY
glcltPixelMapuiv ( IN GLenum map, IN GLint mapsize, IN const GLuint values[] )
{
GLCLIENT_BEGIN_LARGE_SET( PixelMapuiv, PIXELMAPUIV, values, ulSize, valuesOff )
pMsg->map = map ;
pMsg->mapsize = mapsize ;
GLCLIENT_END_LARGE_SET
return;
}
void APIENTRY
glcltPixelMapusv ( IN GLenum map, IN GLint mapsize, IN const GLushort values[] )
{
GLCLIENT_BEGIN_LARGE_SET( PixelMapusv, PIXELMAPUSV, values, ulSize, valuesOff )
pMsg->map = map ;
pMsg->mapsize = mapsize ;
GLCLIENT_END_LARGE_SET
return;
}
void APIENTRY
glcltReadBuffer ( IN GLenum mode )
{
GLCLIENT_BEGIN( ReadBuffer, READBUFFER )
pMsg->mode = mode ;
glsbAttention();
return;
GLCLIENT_END
}
void APIENTRY
glcltCopyPixels ( IN GLint x, IN GLint y, IN GLsizei width, IN GLsizei height, IN GLenum type )
{
GLCLIENT_BEGIN( CopyPixels, COPYPIXELS )
pMsg->x = x ;
pMsg->y = y ;
pMsg->width = width ;
pMsg->height = height ;
pMsg->type = type ;
return;
GLCLIENT_END
}
void APIENTRY
glcltGetClipPlane ( IN GLenum plane, OUT GLdouble equation[4] )
{
GLCLIENT_BEGIN( GetClipPlane, GETCLIPPLANE )
pMsg->plane = plane ;
pMsg->equation = equation;
glsbAttention();
return;
GLCLIENT_END
}
GLenum APIENTRY
glcltGetError ( void )
{
GLCLIENT_BEGIN( GetError, GETERROR )
GLTEB_RETURNVALUE() = GL_INVALID_OPERATION; // assume error
glsbAttention();
return((GLenum)GLTEB_RETURNVALUE());
GLCLIENT_END
}
void APIENTRY
glcltGetMapdv ( IN GLenum target, IN GLenum query, OUT GLdouble v[] )
{
GLCLIENT_BEGIN_LARGE_GET( GetMapdv, GETMAPDV, v, ulSize, vOff )
pMsg->target = target ;
pMsg->query = query ;
GLCLIENT_END_LARGE_GET
return;
}
void APIENTRY
glcltGetMapfv ( IN GLenum target, IN GLenum query, OUT GLfloat v[] )
{
GLCLIENT_BEGIN_LARGE_GET( GetMapfv, GETMAPFV, v, ulSize, vOff )
pMsg->target = target ;
pMsg->query = query ;
GLCLIENT_END_LARGE_GET
return;
}
void APIENTRY
glcltGetMapiv ( IN GLenum target, IN GLenum query, OUT GLint v[] )
{
GLCLIENT_BEGIN_LARGE_GET( GetMapiv, GETMAPIV, v, ulSize, vOff )
pMsg->target = target ;
pMsg->query = query ;
GLCLIENT_END_LARGE_GET
return;
}
void APIENTRY
glcltGetPixelMapfv ( IN GLenum map, OUT GLfloat values[] )
{
GLCLIENT_BEGIN_LARGE_GET( GetPixelMapfv, GETPIXELMAPFV, values, ulSize, valuesOff )
pMsg->map = map ;
GLCLIENT_END_LARGE_GET
return;
}
void APIENTRY
glcltGetPixelMapuiv ( IN GLenum map, OUT GLuint values[] )
{
GLCLIENT_BEGIN_LARGE_GET( GetPixelMapuiv, GETPIXELMAPUIV, values, ulSize, valuesOff )
pMsg->map = map ;
GLCLIENT_END_LARGE_GET
return;
}
void APIENTRY
glcltGetPixelMapusv ( IN GLenum map, OUT GLushort values[] )
{
GLCLIENT_BEGIN_LARGE_GET( GetPixelMapusv, GETPIXELMAPUSV, values, ulSize, valuesOff )
pMsg->map = map ;
GLCLIENT_END_LARGE_GET
return;
}
GLboolean APIENTRY
glcltIsEnabled ( IN GLenum cap )
{
GLCLIENT_BEGIN( IsEnabled, ISENABLED )
pMsg->cap = cap ;
GLTEB_RETURNVALUE() = 0; // assume error
glsbAttention();
return((GLboolean)GLTEB_RETURNVALUE());
GLCLIENT_END
}
void APIENTRY
glcltDepthRange ( IN GLclampd zNear, IN GLclampd zFar )
{
GLCLIENT_BEGIN( DepthRange, DEPTHRANGE )
pMsg->zNear = zNear ;
pMsg->zFar = zFar ;
return;
GLCLIENT_END
}
void APIENTRY
glcltFrustum ( IN GLdouble left, IN GLdouble right, IN GLdouble bottom, IN GLdouble top, IN GLdouble zNear, IN GLdouble zFar )
{
GLCLIENT_BEGIN( Frustum, FRUSTUM )
pMsg->left = left ;
pMsg->right = right ;
pMsg->bottom = bottom ;
pMsg->top = top ;
pMsg->zNear = zNear ;
pMsg->zFar = zFar ;
return;
GLCLIENT_END
}
void APIENTRY
glcltLoadIdentity ( void )
{
GLCLIENT_BEGIN( LoadIdentity, LOADIDENTITY )
return;
GLCLIENT_END
}
void APIENTRY
glcltLoadMatrixf ( IN const GLfloat m[16] )
{
GLCLIENT_BEGIN( LoadMatrixf, LOADMATRIXF )
pMsg->m[ 0] = m[ 0];
pMsg->m[ 1] = m[ 1];
pMsg->m[ 2] = m[ 2];
pMsg->m[ 3] = m[ 3];
pMsg->m[ 4] = m[ 4];
pMsg->m[ 5] = m[ 5];
pMsg->m[ 6] = m[ 6];
pMsg->m[ 7] = m[ 7];
pMsg->m[ 8] = m[ 8];
pMsg->m[ 9] = m[ 9];
pMsg->m[10] = m[10];
pMsg->m[11] = m[11];
pMsg->m[12] = m[12];
pMsg->m[13] = m[13];
pMsg->m[14] = m[14];
pMsg->m[15] = m[15];
return;
GLCLIENT_END
}
void APIENTRY
glcltLoadMatrixd ( IN const GLdouble m[16] )
{
// Call LoadMatrixf instead
GLCLIENT_BEGIN( LoadMatrixf, LOADMATRIXF )
pMsg->m[ 0] = (GLfloat) m[ 0];
pMsg->m[ 1] = (GLfloat) m[ 1];
pMsg->m[ 2] = (GLfloat) m[ 2];
pMsg->m[ 3] = (GLfloat) m[ 3];
pMsg->m[ 4] = (GLfloat) m[ 4];
pMsg->m[ 5] = (GLfloat) m[ 5];
pMsg->m[ 6] = (GLfloat) m[ 6];
pMsg->m[ 7] = (GLfloat) m[ 7];
pMsg->m[ 8] = (GLfloat) m[ 8];
pMsg->m[ 9] = (GLfloat) m[ 9];
pMsg->m[10] = (GLfloat) m[10];
pMsg->m[11] = (GLfloat) m[11];
pMsg->m[12] = (GLfloat) m[12];
pMsg->m[13] = (GLfloat) m[13];
pMsg->m[14] = (GLfloat) m[14];
pMsg->m[15] = (GLfloat) m[15];
return;
GLCLIENT_END
}
void APIENTRY
glcltMatrixMode ( IN GLenum mode )
{
GLCLIENT_BEGIN( MatrixMode, MATRIXMODE )
pMsg->mode = mode ;
return;
GLCLIENT_END
}
void APIENTRY
glcltMultMatrixf ( IN const GLfloat m[16] )
{
GLCLIENT_BEGIN( MultMatrixf, MULTMATRIXF )
pMsg->m[ 0] = m[ 0];
pMsg->m[ 1] = m[ 1];
pMsg->m[ 2] = m[ 2];
pMsg->m[ 3] = m[ 3];
pMsg->m[ 4] = m[ 4];
pMsg->m[ 5] = m[ 5];
pMsg->m[ 6] = m[ 6];
pMsg->m[ 7] = m[ 7];
pMsg->m[ 8] = m[ 8];
pMsg->m[ 9] = m[ 9];
pMsg->m[10] = m[10];
pMsg->m[11] = m[11];
pMsg->m[12] = m[12];
pMsg->m[13] = m[13];
pMsg->m[14] = m[14];
pMsg->m[15] = m[15];
return;
GLCLIENT_END
}
void APIENTRY
glcltMultMatrixd ( IN const GLdouble m[16] )
{
// Call MultMatrixf instead
GLCLIENT_BEGIN( MultMatrixf, MULTMATRIXF )
pMsg->m[ 0] = (GLfloat) m[ 0];
pMsg->m[ 1] = (GLfloat) m[ 1];
pMsg->m[ 2] = (GLfloat) m[ 2];
pMsg->m[ 3] = (GLfloat) m[ 3];
pMsg->m[ 4] = (GLfloat) m[ 4];
pMsg->m[ 5] = (GLfloat) m[ 5];
pMsg->m[ 6] = (GLfloat) m[ 6];
pMsg->m[ 7] = (GLfloat) m[ 7];
pMsg->m[ 8] = (GLfloat) m[ 8];
pMsg->m[ 9] = (GLfloat) m[ 9];
pMsg->m[10] = (GLfloat) m[10];
pMsg->m[11] = (GLfloat) m[11];
pMsg->m[12] = (GLfloat) m[12];
pMsg->m[13] = (GLfloat) m[13];
pMsg->m[14] = (GLfloat) m[14];
pMsg->m[15] = (GLfloat) m[15];
return;
GLCLIENT_END
}
void APIENTRY
glcltOrtho ( IN GLdouble left, IN GLdouble right, IN GLdouble bottom, IN GLdouble top, IN GLdouble zNear, IN GLdouble zFar )
{
GLCLIENT_BEGIN( Ortho, ORTHO )
pMsg->left = left ;
pMsg->right = right ;
pMsg->bottom = bottom ;
pMsg->top = top ;
pMsg->zNear = zNear ;
pMsg->zFar = zFar ;
return;
GLCLIENT_END
}
void APIENTRY
glcltPopMatrix ( void )
{
GLCLIENT_BEGIN( PopMatrix, POPMATRIX )
return;
GLCLIENT_END
}
void APIENTRY
glcltPushMatrix ( void )
{
GLCLIENT_BEGIN( PushMatrix, PUSHMATRIX )
return;
GLCLIENT_END
}
void APIENTRY
glcltRotated ( IN GLdouble angle, IN GLdouble x, IN GLdouble y, IN GLdouble z )
{
// Call Rotatef instead
glcltRotatef((GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z);
}
void APIENTRY
glcltRotatef ( IN GLfloat angle, IN GLfloat x, IN GLfloat y, IN GLfloat z )
{
GLCLIENT_BEGIN( Rotatef, ROTATEF )
pMsg->angle = angle ;
pMsg->x = x ;
pMsg->y = y ;
pMsg->z = z ;
return;
GLCLIENT_END
}
void APIENTRY
glcltScaled ( IN GLdouble x, IN GLdouble y, IN GLdouble z )
{
// Call Scalef instead
glcltScalef((GLfloat) x, (GLfloat) y, (GLfloat) z);
}
void APIENTRY
glcltScalef ( IN GLfloat x, IN GLfloat y, IN GLfloat z )
{
GLCLIENT_BEGIN( Scalef, SCALEF )
pMsg->x = x ;
pMsg->y = y ;
pMsg->z = z ;
return;
GLCLIENT_END
}
void APIENTRY
glcltTranslated ( IN GLdouble x, IN GLdouble y, IN GLdouble z )
{
// Call Translatef instead
glcltTranslatef((GLfloat) x, (GLfloat) y, (GLfloat) z);
}
void APIENTRY
glcltTranslatef ( IN GLfloat x, IN GLfloat y, IN GLfloat z )
{
GLCLIENT_BEGIN( Translatef, TRANSLATEF )
pMsg->x = x ;
pMsg->y = y ;
pMsg->z = z ;
return;
GLCLIENT_END
}
void APIENTRY
glcltViewport ( IN GLint x, IN GLint y, IN GLsizei width, IN GLsizei height )
{
GLCLIENT_BEGIN( Viewport, VIEWPORT )
pMsg->x = x ;
pMsg->y = y ;
pMsg->width = width ;
pMsg->height = height ;
return;
GLCLIENT_END
}