5165 lines
143 KiB
C
5165 lines
143 KiB
C
/******************************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 ptar@sgi.com 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"
|
|
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
|
|
// Vertex flags that should be propagated to polyarray flags
|
|
//
|
|
#define VERTEX_FLAGS_FOR_POLYARRAY (POLYDATA_VERTEX2 | POLYDATA_VERTEX3 | \
|
|
POLYDATA_VERTEX4)
|
|
|
|
#define VERTEX_MATERIAL(pm, pa, pd) (pm->pdMaterial0[pd - pa->pdBuffer0])
|
|
|
|
PDMATERIAL* FASTCALL GetVertexMaterial(POLYARRAY *pa, POLYDATA *pd)
|
|
{
|
|
POLYMATERIAL *pm = GLTEB_CLTPOLYMATERIAL();
|
|
if (!pm)
|
|
{
|
|
PAMatAlloc();
|
|
pm = GLTEB_CLTPOLYMATERIAL();
|
|
if (!pm)
|
|
return NULL;
|
|
}
|
|
return &VERTEX_MATERIAL(pm, pa, pd);
|
|
}
|
|
//------------------------------------------------------------------------
|
|
// Assumes that POLYMATERIAL structure is valid
|
|
//
|
|
PDMATERIAL* FASTCALL GetVertexMaterialSafe(POLYARRAY *pa, POLYDATA *pd)
|
|
{
|
|
POLYMATERIAL *pm = GLTEB_CLTPOLYMATERIAL();
|
|
return &VERTEX_MATERIAL(pm, pa, pd);
|
|
}
|
|
//------------------------------------------------------------------------
|
|
// Copy material changes from src to pd material
|
|
//
|
|
void FASTCALL SetVertexMaterial(POLYARRAY *pa,
|
|
POLYDATA *pd,
|
|
__GLmatChange *src,
|
|
GLint faceOrientation)
|
|
{
|
|
__GLmatChange *pdMat;
|
|
PDMATERIAL *mat;
|
|
|
|
// Get POLYMATERIAL pointer after PAMatAlloc!
|
|
mat = GetVertexMaterial(pa, pd);
|
|
if (!mat)
|
|
return;
|
|
if (faceOrientation == __GL_FRONTFACE)
|
|
{
|
|
mat->front = PAMatAlloc();
|
|
if (!mat->front)
|
|
return;
|
|
pdMat = mat->front;
|
|
}
|
|
else
|
|
{
|
|
mat->back = PAMatAlloc();
|
|
pdMat = mat->back;
|
|
}
|
|
if (pdMat)
|
|
*pdMat = *src;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
// Save shared vertex for a partial primitive
|
|
//
|
|
// We have to save all data applicapable for vertex (all data that can be inside
|
|
// BEGIN END brackets): flags, color, texture, normal, coordinate, material, edge flag.
|
|
// We do not save evaluator data, because it was processed earlier.
|
|
//
|
|
void SaveSharedVertex(SAVEREGION *dst, POLYDATA *src, POLYARRAY *pa)
|
|
{
|
|
dst->pd.flags = src->flags;
|
|
dst->pd.obj = src->obj;
|
|
if (src->flags & POLYDATA_TEXTURE_VALID)
|
|
dst->pd.texture = src->texture;
|
|
if (src->flags & POLYDATA_NORMAL_VALID)
|
|
dst->pd.normal = src->normal;
|
|
if (src->flags & POLYDATA_COLOR_VALID)
|
|
dst->pd.colors[0] = src->colors[0];
|
|
if (src->flags & POLYDATA_MATERIAL_FRONT)
|
|
dst->front = *(GetVertexMaterial(pa, src)->front);
|
|
if (src->flags & POLYDATA_MATERIAL_BACK)
|
|
dst->back = *(GetVertexMaterial(pa, src)->back);
|
|
}
|
|
//
|
|
// dst - POLYDATA
|
|
// src - SAVEREGION
|
|
// pa - POLYARRAY
|
|
//
|
|
#define RESTOREMATERIAL(dst, src, pa) \
|
|
if (dst->flags & POLYDATA_MATERIAL_FRONT) \
|
|
{ \
|
|
SetVertexMaterial(pa, dst, &src->front, __GL_FRONTFACE); \
|
|
} \
|
|
if (dst->flags & POLYDATA_MATERIAL_BACK) \
|
|
{ \
|
|
SetVertexMaterial(pa, dst, &src->back, __GL_BACKFACE); \
|
|
}
|
|
// Restore shared vertex for a partial primitive
|
|
//
|
|
// We have to restore all data applicapable for vertex (all data that can be inside
|
|
// BEGIN END brackets): flags, color, texture, normal, coordinate, material, edge flag.
|
|
// We do not restore evaluator data, because it was processed earlier.
|
|
// We must update POLYARRAY flags and current color, normal, edge flag, texture pointers.
|
|
// We also must intitialize flags for a next vertex.
|
|
//
|
|
void RestoreSharedVertex(POLYDATA *dst, SAVEREGION *src, POLYARRAY *pa)
|
|
{
|
|
dst->flags = src->pd.flags;
|
|
dst->obj = src->pd.obj;
|
|
if (dst->flags & POLYDATA_TEXTURE_VALID)
|
|
{
|
|
dst->texture = src->pd.texture;
|
|
if (src->pd.flags & POLYDATA_EVAL_TEXCOORD)
|
|
pa->pdLastEvalTexture = dst;
|
|
else
|
|
pa->pdCurTexture = dst;
|
|
}
|
|
if (dst->flags & POLYDATA_NORMAL_VALID)
|
|
{
|
|
dst->normal = src->pd.normal;
|
|
if (src->pd.flags & POLYDATA_EVAL_NORMAL)
|
|
pa->pdLastEvalNormal = dst;
|
|
else
|
|
pa->pdCurNormal = dst;
|
|
}
|
|
if (dst->flags & POLYDATA_COLOR_VALID)
|
|
{
|
|
dst->colors[0] = src->pd.colors[0];
|
|
if (src->pd.flags & POLYDATA_EVAL_COLOR)
|
|
pa->pdLastEvalColor = dst;
|
|
else
|
|
pa->pdCurColor = dst;
|
|
}
|
|
if (dst->flags & POLYDATA_EDGEFLAG_VALID)
|
|
pa->pdCurEdgeFlag = dst;
|
|
|
|
RESTOREMATERIAL(dst, src, pa);
|
|
|
|
pa->flags |= (dst->flags & VERTEX_FLAGS_FOR_POLYARRAY);
|
|
(dst+1)->flags = 0; // Initialize flag for a next vertex
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
// Copy data from Graphics Context
|
|
//
|
|
void FASTCALL CopyColorFromGC(__GLcontext *gc, POLYARRAY *pa, POLYDATA *pd)
|
|
{
|
|
__GLcolor scaledUserColor;
|
|
|
|
pd->flags |= POLYDATA_COLOR_VALID;
|
|
if (!gc->modes.colorIndexMode)
|
|
{
|
|
__GL_SCALE_AND_CHECK_CLAMP_RGBA(scaledUserColor.r,
|
|
scaledUserColor.g,
|
|
scaledUserColor.b,
|
|
scaledUserColor.a,
|
|
gc, pa->flags,
|
|
gc->state.current.userColor.r,
|
|
gc->state.current.userColor.g,
|
|
gc->state.current.userColor.b,
|
|
gc->state.current.userColor.a);
|
|
}
|
|
else
|
|
{
|
|
__GL_CHECK_CLAMP_CI(scaledUserColor.r, gc, pa->flags,
|
|
gc->state.current.userColorIndex);
|
|
}
|
|
pd->colors[0] = scaledUserColor;
|
|
}
|
|
|
|
void FASTCALL CopyTextureFromGC(__GLcontext *gc, POLYARRAY *pa, POLYDATA *pd)
|
|
{
|
|
pd->flags |= POLYDATA_TEXTURE_VALID;
|
|
pd->texture = gc->state.current.texture;
|
|
|
|
if (__GL_FLOAT_COMPARE_PONE(pd->texture.w, !=))
|
|
pa->flags |= POLYARRAY_TEXTURE4;
|
|
else if (__GL_FLOAT_NEZ(pd->texture.z))
|
|
pa->flags |= POLYARRAY_TEXTURE3;
|
|
else if (__GL_FLOAT_NEZ(pd->texture.y))
|
|
pa->flags |= POLYARRAY_TEXTURE2;
|
|
else
|
|
pa->flags |= POLYARRAY_TEXTURE1;
|
|
}
|
|
|
|
void FASTCALL CopyEdgeFlagFromGC(__GLcontext *gc, POLYDATA *pd)
|
|
{
|
|
pd->flags |= POLYDATA_EDGEFLAG_VALID;
|
|
if (gc->state.current.edgeTag)
|
|
pd->flags |= POLYDATA_EDGEFLAG_BOUNDARY;
|
|
}
|
|
|
|
void FASTCALL CopyNormalFromGC(__GLcontext *gc, POLYDATA *pd)
|
|
{
|
|
pd->flags |= POLYDATA_NORMAL_VALID;
|
|
pd->normal = gc->state.current.normal;
|
|
}
|
|
//-------------------------------------------------------------------------------
|
|
// Copy material state corresponding to changeBits from GC to mat.
|
|
// face defines front or back material to use.
|
|
//
|
|
void FASTCALL CopyMaterialFromGC(__GLcontext *gc, __GLmatChange *mat,
|
|
GLuint changeBits, GLint face)
|
|
{
|
|
__GLmaterialState *ms;
|
|
|
|
ms = &gc->state.light.front;
|
|
if (face != __GL_FRONTFACE)
|
|
ms = &gc->state.light.back;
|
|
|
|
// Take data from graphics context
|
|
|
|
if (changeBits & __GL_MATERIAL_AMBIENT)
|
|
mat->ambient = ms->ambient;
|
|
|
|
if (changeBits & __GL_MATERIAL_DIFFUSE)
|
|
mat->diffuse = ms->diffuse;
|
|
|
|
if (changeBits & __GL_MATERIAL_SPECULAR)
|
|
mat->specular = ms->specular;
|
|
|
|
if (changeBits & __GL_MATERIAL_EMISSIVE)
|
|
{
|
|
mat->emissive.r = ms->emissive.r * gc->oneOverRedVertexScale;
|
|
mat->emissive.g = ms->emissive.g * gc->oneOverGreenVertexScale;
|
|
mat->emissive.b = ms->emissive.b * gc->oneOverBlueVertexScale;
|
|
mat->emissive.a = ms->emissive.a * gc->oneOverAlphaVertexScale;
|
|
}
|
|
|
|
if (changeBits & __GL_MATERIAL_SHININESS)
|
|
mat->shininess = ms->specularExponent;
|
|
|
|
if (changeBits & __GL_MATERIAL_COLORINDEXES)
|
|
{
|
|
mat->cmapa = ms->cmapa;
|
|
mat->cmapd = ms->cmapd;
|
|
mat->cmaps = ms->cmaps;
|
|
}
|
|
}
|
|
//-------------------------------------------------------------------------------
|
|
// Compute complete vertex state to restore state modified by pdLast vertex.
|
|
//
|
|
// We have to preserve the following state for a vertex:
|
|
// - normal
|
|
// - texture
|
|
// - color
|
|
// - edge flag
|
|
// - material
|
|
//
|
|
// Input:
|
|
// dst - where to copy vertex state
|
|
// pdStart - we go from this vertex to the beginning of a polyarray to find
|
|
// material changes
|
|
// pdLast - we have to update vertex state only if the state is changed by
|
|
// this vertex
|
|
//
|
|
void FASTCALL UpdateVertexState(__GLcontext *gc,
|
|
POLYARRAY *pa,
|
|
SAVEREGION *dst,
|
|
POLYDATA *pdStart,
|
|
POLYDATA *pdLast)
|
|
{
|
|
GLuint flags = dst->pd.flags;
|
|
GLuint flagsLast = pdLast ? pdLast->flags : 0xFFFFFFFF;
|
|
POLYDATA *pd0 = pa->pd0;
|
|
|
|
ASSERTOPENGL(pdStart >= pd0, "Infinite loop possible!");
|
|
|
|
// If last vertex changes normal we have to find nearest previous normal
|
|
// and propagate it to the dst
|
|
if (flagsLast & POLYDATA_NORMAL_VALID && !(flags & POLYDATA_NORMAL_VALID))
|
|
{
|
|
POLYDATA *pd;
|
|
// Find nearest normal
|
|
for (pd = pdStart; pd >= pd0; pd--)
|
|
{
|
|
if (pd->flags & POLYDATA_NORMAL_VALID &&
|
|
!(pd->flags & POLYDATA_EVAL_NORMAL))
|
|
break;
|
|
}
|
|
flags |= POLYDATA_NORMAL_VALID;
|
|
if (pd < pd0)
|
|
// We have not found any normal, so take value from graphics state
|
|
CopyNormalFromGC(gc, &dst->pd);
|
|
else
|
|
dst->pd.normal = pd->normal;
|
|
}
|
|
|
|
// If last vertex changes texture we have to find nearest previous texture
|
|
// and propagate it to the dst
|
|
if (flagsLast & POLYDATA_TEXTURE_VALID && !(flags & POLYDATA_TEXTURE_VALID))
|
|
{
|
|
POLYDATA *pd;
|
|
// Find latest texture
|
|
for (pd = pdStart; pd >= pd0; pd--)
|
|
{
|
|
if (pd->flags & POLYDATA_TEXTURE_VALID &&
|
|
!(pd->flags & POLYDATA_EVAL_TEXCOORD))
|
|
break;
|
|
}
|
|
flags |= POLYDATA_TEXTURE_VALID;
|
|
if (pd < pd0)
|
|
// We have not found any vertex, so take value from graphics state
|
|
CopyTextureFromGC(gc, pa, &dst->pd);
|
|
else
|
|
dst->pd.texture = pd->texture;
|
|
}
|
|
|
|
// If last vertex changes color we have to find nearest previous color
|
|
// and propagate it to the dst
|
|
if (flagsLast & POLYDATA_COLOR_VALID && !(flags & POLYDATA_COLOR_VALID))
|
|
{
|
|
POLYDATA *pd;
|
|
// Find latest color
|
|
for (pd = pdStart; pd >= pd0; pd--)
|
|
{
|
|
if (pd->flags & POLYDATA_COLOR_VALID &&
|
|
!(pd->flags & POLYDATA_EVAL_COLOR))
|
|
break;
|
|
}
|
|
flags |= POLYDATA_COLOR_VALID;
|
|
if (pd < pd0)
|
|
// We have not found any vertex, so take value from graphics state
|
|
CopyColorFromGC(gc, pa, &dst->pd);
|
|
else
|
|
dst->pd.colors[0] = pd->colors[0];
|
|
}
|
|
|
|
if (flagsLast & POLYDATA_EDGEFLAG_VALID && !(flags & POLYDATA_EDGEFLAG_VALID))
|
|
{
|
|
POLYDATA *pd;
|
|
// Find latest edge flag
|
|
for (pd = pdStart; pd >= pd0; pd--)
|
|
{
|
|
if (pd->flags & POLYDATA_EDGEFLAG_VALID)
|
|
break;
|
|
}
|
|
flags |= POLYDATA_EDGEFLAG_VALID;
|
|
if (pd < pd0)
|
|
{
|
|
// We have not found any vertex, so take value from graphics state
|
|
if (gc->state.current.edgeTag)
|
|
flags |= POLYDATA_EDGEFLAG_BOUNDARY;
|
|
}
|
|
else
|
|
flags |= (pd->flags & POLYDATA_EDGEFLAG_BOUNDARY);
|
|
}
|
|
|
|
dst->pd.flags |= flags;
|
|
|
|
// Now we have to update material state
|
|
|
|
if (pdLast->flags & (POLYARRAY_MATERIAL_FRONT | POLYARRAY_MATERIAL_BACK))
|
|
{
|
|
// We have to compute material state for pdLast1, because after the primitive is
|
|
// processed, current material state will have changes from pdLast2 vertex.
|
|
|
|
__GLmatChange *mat;
|
|
__GLmatChange *pdMatLast;
|
|
POLYDATA *pd;
|
|
GLint face;
|
|
GLuint matMask;
|
|
GLuint changeBits;
|
|
|
|
for (face = __GL_BACKFACE, matMask = POLYARRAY_MATERIAL_BACK;
|
|
face >= 0;
|
|
face--, matMask = POLYARRAY_MATERIAL_FRONT
|
|
)
|
|
{
|
|
if (!(pa->flags & matMask))
|
|
continue;
|
|
|
|
// Only reset material data changed by pdLast
|
|
if (face == __GL_FRONTFACE)
|
|
{
|
|
pdMatLast = GetVertexMaterial(pa, pdLast)->front;
|
|
changeBits = pdMatLast->dirtyBits;
|
|
mat = &dst->front;
|
|
// Don't modify color materials if they are in effect!
|
|
changeBits &= ~gc->light.front.colorMaterialChange;
|
|
}
|
|
else
|
|
{
|
|
pdMatLast = GetVertexMaterial(pa, pdLast)->back;
|
|
changeBits = pdMatLast->dirtyBits;
|
|
mat = &dst->back;
|
|
// Don't modify color materials if they are in effect!
|
|
changeBits &= ~gc->light.back.colorMaterialChange;
|
|
}
|
|
|
|
// Don't modify material settings used by this vertex
|
|
changeBits &= ~mat->dirtyBits;
|
|
|
|
if (!changeBits)
|
|
continue;
|
|
|
|
mat->dirtyBits |= changeBits;
|
|
|
|
// Apply changes from vertices
|
|
// We go backwards and apply the latest change
|
|
for (pd = pdStart; pd >= pd0; pd--)
|
|
{
|
|
__GLmatChange *pdMat;
|
|
GLuint dirtyBits;
|
|
if (pd->flags & matMask)
|
|
{
|
|
GLuint dirtyBits;
|
|
|
|
pdMat = GetVertexMaterial(pa, pd)->front + face;
|
|
dirtyBits = pdMat->dirtyBits & changeBits;
|
|
|
|
if (!dirtyBits)
|
|
continue;
|
|
|
|
if (dirtyBits & __GL_MATERIAL_AMBIENT)
|
|
{
|
|
mat->ambient = pdMat->ambient;
|
|
}
|
|
|
|
if (dirtyBits & __GL_MATERIAL_DIFFUSE)
|
|
{
|
|
mat->diffuse = pdMat->diffuse;
|
|
}
|
|
|
|
if (dirtyBits & __GL_MATERIAL_SPECULAR)
|
|
{
|
|
mat->specular = pdMat->specular;
|
|
}
|
|
|
|
if (dirtyBits & __GL_MATERIAL_EMISSIVE)
|
|
{
|
|
mat->emissive = pdMat->emissive;
|
|
}
|
|
|
|
if (dirtyBits & __GL_MATERIAL_SHININESS)
|
|
{
|
|
mat->shininess = pdMat->shininess;
|
|
}
|
|
|
|
if (dirtyBits & __GL_MATERIAL_COLORINDEXES)
|
|
{
|
|
mat->cmapa = pdMat->cmapa;
|
|
mat->cmapd = pdMat->cmapd;
|
|
mat->cmaps = pdMat->cmaps;
|
|
}
|
|
|
|
// Clear processed bits
|
|
changeBits &= ~dirtyBits;
|
|
|
|
if (!changeBits)
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (changeBits)
|
|
CopyMaterialFromGC (gc, mat, changeBits, face);
|
|
|
|
dst->pd.flags |= matMask;
|
|
}
|
|
}
|
|
}
|
|
//-------------------------------------------------------------------------------------
|
|
// Propagate vertex state from GC to the vertex.
|
|
//
|
|
// Already set vertex data should be preserved.
|
|
//
|
|
void FASTCALL UpdateVertexStateUsingGC(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *dst)
|
|
{
|
|
POLYDATA * const pd = &dst->pd;
|
|
if (!(pd->flags & POLYDATA_NORMAL_VALID))
|
|
CopyNormalFromGC(gc, pd);
|
|
|
|
if (!(pd->flags & POLYDATA_TEXTURE_VALID))
|
|
CopyTextureFromGC(gc, pa, pd);
|
|
|
|
if (!(pd->flags & POLYDATA_COLOR_VALID))
|
|
CopyColorFromGC(gc, pa, pd);
|
|
|
|
if (!(pd->flags & POLYDATA_EDGEFLAG_VALID))
|
|
CopyEdgeFlagFromGC(gc, pd);
|
|
|
|
if (pa->flags & (POLYARRAY_MATERIAL_FRONT | POLYARRAY_MATERIAL_BACK))
|
|
{
|
|
// Compute material state for the vertex, using GC
|
|
// Do not override material changes in the vertex
|
|
|
|
__GLmatChange *mat;
|
|
GLint face;
|
|
GLuint matMask;
|
|
GLuint changeBits;
|
|
|
|
for (face = __GL_BACKFACE, matMask = POLYARRAY_MATERIAL_BACK;
|
|
face >= 0;
|
|
face--, matMask = POLYARRAY_MATERIAL_FRONT
|
|
)
|
|
{
|
|
GLuint dirtyBits;
|
|
if (!(pa->flags & matMask))
|
|
continue;
|
|
|
|
// Don't modify color materials if they are in effect or if they are set
|
|
// by pdFirst!
|
|
|
|
changeBits = 0xFFFFFFFF;
|
|
if (face == __GL_FRONTFACE)
|
|
{
|
|
if (pd->flags & matMask)
|
|
changeBits &= ~dst->front.dirtyBits;
|
|
|
|
changeBits &= ~gc->light.front.colorMaterialChange;
|
|
mat = &dst->front;
|
|
}
|
|
else
|
|
{
|
|
if (pd->flags & matMask)
|
|
changeBits &= ~dst->back.dirtyBits;
|
|
changeBits = ~gc->light.back.colorMaterialChange;
|
|
mat = &dst->back;
|
|
}
|
|
|
|
// Apply changes from vertices
|
|
// We go backwards and remember the latest change
|
|
|
|
if (changeBits)
|
|
{
|
|
CopyMaterialFromGC (gc, mat, changeBits, face);
|
|
// Update changes for the vertex
|
|
pd->flags |= matMask;
|
|
mat->dirtyBits |= changeBits;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
#endif // NEW_PARTIAL_PRIM
|
|
|
|
//
|
|
// 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;
|
|
__GL_SETUP();
|
|
DWORD flags = GET_EVALSTATE (gc);
|
|
|
|
|
|
// 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_PTR)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;
|
|
}
|
|
|
|
// if there are any pending API calls that affect the Evaluator state
|
|
// then flush the message buffer
|
|
|
|
if (flags & (__EVALS_AFFECTS_ALL_EVAL|
|
|
__EVALS_AFFECTS_1D_EVAL|
|
|
__EVALS_AFFECTS_2D_EVAL))
|
|
glsbAttention ();
|
|
|
|
// 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 == PA_nextMsgOffset_RESET_VALUE,
|
|
"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->pd0 = pd0;
|
|
pa->primType = mode;
|
|
pa->pdCurColor =
|
|
pa->pdCurNormal =
|
|
pa->pdCurTexture =
|
|
pa->pdCurEdgeFlag = NULL;
|
|
pa->paNext = NULL;
|
|
pa->nIndices = 0;
|
|
pa->aIndices = NULL; // identity mapping
|
|
pa->pdLastEvalColor =
|
|
pa->pdLastEvalNormal =
|
|
pa->pdLastEvalTexture = NULL;
|
|
|
|
// 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 == PA_nextMsgOffset_RESET_VALUE,
|
|
"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->pd0 = pd0;
|
|
pa->primType = mode;
|
|
pa->pdCurColor =
|
|
pa->pdCurNormal =
|
|
pa->pdCurTexture =
|
|
pa->pdCurEdgeFlag = NULL;
|
|
pa->paNext = NULL;
|
|
pa->nIndices = 0;
|
|
pa->aIndices = PA_aIndices_INITIAL_VALUE; // this is updated in End
|
|
|
|
// For consistency
|
|
pa->pdLastEvalColor =
|
|
pa->pdLastEvalNormal =
|
|
pa->pdLastEvalTexture = NULL;
|
|
|
|
// 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;
|
|
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
__GL_SETUP();
|
|
pa = gc->paTeb;
|
|
#else
|
|
pa = GLTEB_CLTPOLYARRAY();
|
|
#endif
|
|
|
|
// 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 there are evaluator calls in this polyarray that also generate
|
|
// color, then too, remove the POLYARRAY_SAME_COLOR_DATA flag
|
|
|
|
if ((pa->pdCurColor != pa->pd0) ||
|
|
((pa->pd0->flags & POLYDATA_COLOR_VALID) &&
|
|
(pa->flags & POLYARRAY_PARTIAL_BEGIN)) ||
|
|
(pa->pdLastEvalColor != NULL))
|
|
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 += (GLint)((ULONG_PTR)(pa->pdNextVertex - pa->pd0));
|
|
/*
|
|
// If there are no vertices and no attributes to propagate to a next
|
|
// primitive, we can remove this polyarray from the batch
|
|
if (pa->nIndices == 0 && pa->pdNextVertex->flags == 0)
|
|
return;
|
|
*/
|
|
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
if (pa->primType == GL_LINE_LOOP)
|
|
{
|
|
if (pa->nIndices > 1)
|
|
{
|
|
// We have to add an additional vertex at the end. It could be
|
|
// - saved vertex if primitive is partial begin OR
|
|
// - first vertex
|
|
// We will change primitive type to GL_LINE_STRIP after we update
|
|
// current color, normal, texture, edge flag in __glim_DrawPolyArray
|
|
//
|
|
POLYDATA *pd = pa->pdNextVertex++;
|
|
SAVEREGION firstVertex;
|
|
SAVEREGION lastVertex;
|
|
SAVEREGION *reg;
|
|
// We have to propagate vertex state for next primitive before we
|
|
// insert the vertex.
|
|
|
|
pa->nIndices++;
|
|
if (pa->flags & POLYARRAY_PARTIAL_BEGIN)
|
|
{ // This is partial primitive
|
|
reg = &gc->vertex.regSaved;
|
|
}
|
|
else
|
|
{ // This is non partial primitive
|
|
SaveSharedVertex(&firstVertex, pa->pd0, pa);
|
|
reg = &firstVertex;
|
|
}
|
|
// Save pdNextVertex before we override it
|
|
SaveSharedVertex(&lastVertex, pd, pa);
|
|
// Insert first vertex at the end
|
|
RestoreSharedVertex(pd, reg, pa);
|
|
// Compute state for last vertex, because we have to override
|
|
// changes made by first vertex.
|
|
UpdateVertexState(gc, pa, &lastVertex, pd-1, pd);
|
|
// pdNextVertex will have state for a next primitive
|
|
RestoreSharedVertex(pa->pdNextVertex, &lastVertex, pa);
|
|
}
|
|
|
|
pa->primType = GL_LINE_STRIP;
|
|
}
|
|
#else // NEW_PARTIAL_PRIM
|
|
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.
|
|
#endif // NEWFLUSH
|
|
|
|
// 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 != PA_aIndices_INITIAL_VALUE),
|
|
"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));
|
|
}
|
|
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
|
|
typedef void (*PFNSAVERESTORE)(__GLcontext*, POLYARRAY*, SAVEREGION*);
|
|
|
|
void FASTCALL SaveFirstVertex(__GLcontext* gc, POLYARRAY* pa)
|
|
{
|
|
if (!(pa->flags & POLYARRAY_PARTIAL_BEGIN))
|
|
{
|
|
GLuint flags = pa->flags & (POLYARRAY_MATERIAL_FRONT | POLYARRAY_MATERIAL_BACK);
|
|
SaveSharedVertex(&gc->vertex.regSaved, pa->pd0, pa);
|
|
// Save vertex state to restore it later
|
|
pa->flags |= (POLYARRAY_MATERIAL_FRONT | POLYARRAY_MATERIAL_BACK);
|
|
UpdateVertexStateUsingGC(gc, pa, &gc->vertex.regSaved);
|
|
// Restore pa flags
|
|
pa->flags &= ~(POLYARRAY_MATERIAL_FRONT | POLYARRAY_MATERIAL_BACK);
|
|
pa->flags |= flags;
|
|
}
|
|
}
|
|
|
|
// This function is used by GL_POINTS, GL_LINES, GL_TRIANGLES, GL_QUADS,
|
|
// because for these cases parts of broken primitive are not connected.
|
|
// We also clear POLYARRAY_PARTIAL_END flag, because in DrawPolyArray we
|
|
// can remove this partial primitive if it is clipped out (we do not have
|
|
// to preserve line stipple for these primitives).
|
|
//
|
|
void SaveEmpty(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *r)
|
|
{
|
|
pa->flags &= ~POLYARRAY_PARTIAL_END;
|
|
}
|
|
|
|
// A line loop is the same as a line strip except that a final segment is
|
|
// added from the final specified vertex to the first vertex. We convert
|
|
// the line loop into a strip here. We have to save first vertex of line
|
|
// loop only if the primitive is not partial begin (i.e. it is not a middle
|
|
// part of a line loop broken into more than two polyarrays).
|
|
// We do not clear POLYARRAY_PARTIAL_END flag, because in DrawPolyArray we
|
|
// can not remove this partial primitive if it is clipped out to preserve
|
|
// line stipple.
|
|
// Index mapping is always indentity for GL_LINE_LOOP.
|
|
// We save first vertex in graphics state, because it will be restored in glcltEnd.
|
|
// We change line loop to line strip here.
|
|
//
|
|
// When the first vertex is saved we have preserve its state to restore it in the next part
|
|
// of partial primitive.
|
|
//
|
|
void SaveLineLoop(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *r)
|
|
{
|
|
POLYDATA* pd;
|
|
|
|
SaveFirstVertex(gc, pa);
|
|
|
|
pd = pa->pdNextVertex-1;
|
|
SaveSharedVertex(r, pd, pa);
|
|
pa->primType = GL_LINE_STRIP;
|
|
}
|
|
|
|
// For GL_LINE_STRIP we save last vertex. We do not clear POLYARRAY_PARTIAL_END flag,
|
|
// because in DrawPolyArray we can not remove this partial primitive if it is clipped
|
|
// out to preserve line stipple.
|
|
// We do not preserve index because it is assumed to be 0 for the next part
|
|
// of the primitive.
|
|
//
|
|
void SaveLineStrip(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *r)
|
|
{
|
|
POLYDATA *pd;
|
|
if (pa->aIndices)
|
|
pd = &pa->pd0[pa->aIndices[pa->nIndices-1]];
|
|
else
|
|
pd = pa->pdNextVertex-1;
|
|
SaveSharedVertex(r, pd, pa);
|
|
}
|
|
|
|
// For GL_TRIANLE_FAN we save first and last vertices. Line stipple is reset for every
|
|
// triangle in a fan, so we can clear POLYARRAY_PARTIAL_END flag
|
|
// We do not preserve indices because they are assumed to be 0 and 1 for the next part
|
|
// of the primitive.
|
|
//
|
|
// When we restore first vertex it must have the same state as when we saved it.
|
|
// But this state should no affect vertex last vertex.
|
|
// So we have to compute vertex state for the first when we save it and compute
|
|
// vertex state for the lase vertex when we restore it.
|
|
// First vertex and its state should be computed only once, even if a primitive is broken
|
|
// several times.
|
|
//
|
|
void SaveTFan(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *r)
|
|
{
|
|
if (pa->aIndices)
|
|
{
|
|
POLYDATA *pd;
|
|
GLubyte *aIndices = pa->aIndices;
|
|
|
|
pd = &pa->pd0[aIndices[0]];
|
|
SaveSharedVertex(&gc->vertex.regSaved, pd, pa);
|
|
|
|
pd = &pa->pd0[aIndices[pa->nIndices-1]];
|
|
SaveSharedVertex(r, pd, pa);
|
|
}
|
|
else
|
|
{
|
|
POLYDATA *pd;
|
|
// Compute state for the first vertex only for the very first part
|
|
// of partial primitive
|
|
SaveFirstVertex(gc, pa);
|
|
|
|
pd = pa->pdNextVertex-1;
|
|
SaveSharedVertex(r, pd, pa);
|
|
}
|
|
pa->flags &= ~POLYARRAY_PARTIAL_END;
|
|
}
|
|
|
|
// This function handles GL_TRIANGLE_STRIP and GL_QUAD_STRIP.
|
|
// We save two last vertices.
|
|
// Line stipple is reset for every triangle (quad) in a strip, so we can clear
|
|
// POLYARRAY_PARTIAL_END flag.
|
|
// We do not preserve indices because they are assumed to be 0 and 1 for the
|
|
// next part of the primitive.
|
|
//
|
|
// We have to save 2 last vertices: v1 and v2 (last vertex).
|
|
// Next part of partial primitive will start with vertex v1.
|
|
// v2 could change vertex state, so we have to compute vertex state for v1 and
|
|
// restore it. This should be done only for non indexed case.
|
|
//
|
|
void SaveTStrip(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *r)
|
|
{
|
|
if (pa->aIndices)
|
|
{
|
|
POLYDATA *pd;
|
|
GLint nIndices = pa->nIndices;
|
|
GLubyte *aIndices = pa->aIndices;
|
|
|
|
pd = &pa->pd0[aIndices[nIndices-2]];
|
|
SaveSharedVertex(r, pd, pa);
|
|
pd = &pa->pd0[aIndices[nIndices-1]];
|
|
SaveSharedVertex(r+1, pd, pa);
|
|
}
|
|
else
|
|
{
|
|
POLYDATA *pd = pa->pdNextVertex-2;
|
|
|
|
SaveSharedVertex(r, pd, pa);
|
|
// Compute vertex state, changed by vertex pd+1
|
|
UpdateVertexState(gc, pa, r, pd-1, pd+1);
|
|
pd++;
|
|
SaveSharedVertex(r+1, pd, pa);
|
|
}
|
|
pa->flags &= ~POLYARRAY_PARTIAL_END;
|
|
}
|
|
|
|
// For GL_POLYGON we first and last two vertices, because we do not know
|
|
// if the last vertex of this part is the last vertex for the primitive. We need this
|
|
// information to compute edge flag for the last vertex.
|
|
// We remove last vertex from the primitive. It will be processed in the next part of
|
|
// the primitive.
|
|
// We need POLYARRAY_PARTIAL_END flag when we compute edge flag in DrawPolyArray.
|
|
//
|
|
void SavePolygon(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *r)
|
|
{
|
|
POLYDATA *pd;
|
|
// Compute state for the first vertex only for the very first part
|
|
// of partial primitive
|
|
SaveFirstVertex(gc, pa);
|
|
|
|
pd = pa->pdNextVertex-2;
|
|
SaveSharedVertex(r, pd, pa);
|
|
|
|
r++;
|
|
pd = pa->pdNextVertex-1;
|
|
SaveSharedVertex(r, pd, pa);
|
|
|
|
// Remove last vertex from the primitive
|
|
pa->nIndices--;
|
|
pa->pdNextVertex--;
|
|
}
|
|
|
|
PFNSAVERESTORE pfnSaveFunc[] =
|
|
{
|
|
SaveEmpty, // GL_POINTS
|
|
SaveEmpty, // GL_LINES
|
|
SaveLineLoop, // GL_LINE_LOOP
|
|
SaveLineStrip, // GL_LINE_STRIP
|
|
SaveEmpty, // GL_TRIANGLES
|
|
SaveTStrip, // GL_TRIANGLE_STRIP
|
|
SaveTFan, // GL_TRIANGLE_FAN
|
|
SaveEmpty, // GL_QUADS
|
|
SaveTStrip, // GL_QUAD_STRIP
|
|
SavePolygon // GL_POLYGON
|
|
};
|
|
|
|
// This function is used by GL_POINTS, GL_LINES, GL_TRIANGLES, GL_QUADS,
|
|
// because for these cases parts of broken primitive are not connected. We
|
|
// also clear POLYARRAY_PARTIAL_BEGIN flag, because in DrawPolyArray we can
|
|
// remove this partial primitive if it is clipped out (we do not have to
|
|
// preserve line stipple for these primitives).
|
|
//
|
|
void RestoreEmpty(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *r)
|
|
{
|
|
pa->flags &= ~POLYARRAY_PARTIAL_BEGIN;
|
|
}
|
|
|
|
// For GL_LINE_LOOP and GL_LINE_STRIP last vertex from previous part will be the first.
|
|
// We will convert line loop into line strip in glcltEnd or PolyArrayFlushPartialPrimitive
|
|
// To preserve line stipple we need POLYARRAY_PARTIAL_BEGIN flag.
|
|
//
|
|
void RestoreLineStrip(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *r)
|
|
{
|
|
POLYDATA *pd = pa->pdNextVertex++;
|
|
|
|
RestoreSharedVertex(pd, r, pa);
|
|
}
|
|
|
|
// For GL_TRIANGLE_STRIP and GL_QUAD_STRIP we have to add two saved
|
|
// vertices at the beginning of primitive.
|
|
// We do not to preserve line stipple, so we clear POLYARRAY_PARTIAL_BEGIN flag.
|
|
//
|
|
void RestoreTStrip(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *r)
|
|
{
|
|
POLYDATA *pd = pa->pdNextVertex++;
|
|
|
|
RestoreSharedVertex(pd, r, pa);
|
|
|
|
r++;
|
|
pd = pa->pdNextVertex++;
|
|
RestoreSharedVertex(pd, r, pa);
|
|
|
|
pa->flags &= ~POLYARRAY_PARTIAL_BEGIN;
|
|
}
|
|
|
|
// For GL_TRIANGLE_FAN we have to add two saved vertices at the beginning
|
|
// of primitive. Last vertex should have a state, not modified by previous vertex.
|
|
// We do not to preserve line stipple, so we clear POLYARRAY_PARTIAL_BEGIN flag.
|
|
//
|
|
void RestoreTFan(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *r)
|
|
{
|
|
POLYDATA *pd = pa->pdNextVertex++;
|
|
|
|
RestoreSharedVertex(pd, &gc->vertex.regSaved, pa);
|
|
|
|
pd = pa->pdNextVertex++;
|
|
if (!pa->aIndices)
|
|
// Compute state for last vertex, because it could be modified
|
|
// by first vertex
|
|
UpdateVertexStateUsingGC(gc, pa, r);
|
|
RestoreSharedVertex(pd, r, pa);
|
|
}
|
|
|
|
// For GL_POLYGON we have to add three saved vertices at the beginning of primitive.
|
|
// We need POLYARRAY_PARTIAL_BEGIN flag to compute edge flag in DrawPolyArray.
|
|
//
|
|
void RestorePolygon(__GLcontext *gc, POLYARRAY *pa, SAVEREGION *r)
|
|
{
|
|
POLYDATA *pd = pa->pdNextVertex++;
|
|
|
|
RestoreSharedVertex(pd, &gc->vertex.regSaved, pa);
|
|
|
|
// Compute state for this vertex, because it could be modified
|
|
// by first vertex
|
|
UpdateVertexStateUsingGC(gc, pa, r);
|
|
pd = pa->pdNextVertex++;
|
|
RestoreSharedVertex(pd, r, pa);
|
|
|
|
r++;
|
|
pd = pa->pdNextVertex++;
|
|
RestoreSharedVertex(pd, r, pa);
|
|
}
|
|
|
|
PFNSAVERESTORE pfnRestoreFunc[] =
|
|
{
|
|
RestoreEmpty, // GL_POINTS
|
|
RestoreEmpty, // GL_LINES
|
|
RestoreLineStrip, // GL_LINE_LOOP
|
|
RestoreLineStrip, // GL_LINE_STRIP
|
|
RestoreEmpty, // GL_TRIANGLES
|
|
RestoreTStrip, // GL_TRIANGLE_STRIP
|
|
RestoreTFan, // GL_TRIANGLE_FAN
|
|
RestoreEmpty, // GL_QUADS
|
|
RestoreTStrip, // GL_QUAD_STRIP
|
|
RestorePolygon // GL_POLYGON
|
|
};
|
|
|
|
#endif // NEW_PARTIAL_PRIM
|
|
|
|
// 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;
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
SAVEREGION savereg[3]; // Temporary storage for vertices, shared between
|
|
#endif // NEW_PARTIAL_PRIM // parts of decomposed primitive
|
|
__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 || (pa->aIndices == PA_aIndices_INITIAL_VALUE),
|
|
"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->pdLastEvalColor != pa->pd0))
|
|
pa->flags &= ~POLYARRAY_SAME_COLOR_DATA;
|
|
|
|
// Save some pa flags for next partial primitive.
|
|
// Need to preserve POLYARRAY_CLAMP_COLOR flag in dlist playback.
|
|
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
// We have to preserve material flags to handle first vertex
|
|
//
|
|
paFlags = pa->flags & (POLYARRAY_SAME_POLYDATA_TYPE |
|
|
POLYARRAY_SAME_COLOR_DATA |
|
|
POLYARRAY_TEXTURE1 |
|
|
POLYARRAY_TEXTURE2 |
|
|
POLYARRAY_TEXTURE3 |
|
|
POLYARRAY_TEXTURE4 |
|
|
POLYARRAY_VERTEX2 |
|
|
POLYARRAY_VERTEX3 |
|
|
POLYARRAY_VERTEX4 |
|
|
POLYDATA_MATERIAL_FRONT |
|
|
POLYDATA_MATERIAL_BACK |
|
|
POLYARRAY_CLAMP_COLOR);
|
|
#else
|
|
paFlags = pa->flags & (POLYARRAY_SAME_POLYDATA_TYPE |
|
|
POLYARRAY_SAME_COLOR_DATA |
|
|
POLYARRAY_CLAMP_COLOR);
|
|
#endif
|
|
// 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 += (GLint)((ULONG_PTR)(pa->pdNextVertex - pa->pd0));
|
|
|
|
// Save states before flushing the batch.
|
|
|
|
mode = pa->primType;
|
|
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
// Save shared vertices for the next part of the partial primitive
|
|
|
|
pfnSaveFunc[mode](gc, pa, savereg);
|
|
#endif // NEW_PARTIAL_PRIM
|
|
|
|
// 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.
|
|
// 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 == PA_nextMsgOffset_RESET_VALUE,
|
|
"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
|
|
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
// Compute the start of the PARTIAL primitive. A partial primitive begins
|
|
// with a POLYARRAY entry followed by vertex entries. We DO NOT not need to
|
|
// reserve additional vertex entries at the beginning for connectivity
|
|
// between decomposed primitives. Because we just add them at the beginning
|
|
|
|
pd0 = pa->pdBufferNext + 1;
|
|
#else
|
|
// 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];
|
|
|
|
#endif // NEW_PARTIAL_PRIM
|
|
|
|
// 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->pd0 = pd0;
|
|
pa->primType = mode;
|
|
pa->paNext = NULL;
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
pa->nIndices = 0; // WE do not reserve any vertices
|
|
#else
|
|
pa->nIndices = nReservedIndicesPartialBegin[mode];
|
|
#endif // NEW_PARTIAL_PRIM
|
|
pa->aIndices = NULL; // identity mapping
|
|
pa->pdCurColor =
|
|
pa->pdCurNormal =
|
|
pa->pdCurTexture =
|
|
pa->pdCurEdgeFlag =
|
|
pa->pdLastEvalColor =
|
|
pa->pdLastEvalNormal =
|
|
pa->pdLastEvalTexture = NULL;
|
|
|
|
|
|
// 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;
|
|
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
// Add saved vertices into the new part of the primitive
|
|
|
|
pfnRestoreFunc[mode](gc, pa, savereg);
|
|
|
|
#endif // NEW_PARTIAL_PRIM
|
|
}
|
|
|
|
// 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;
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
SAVEREGION savereg[3]; // Temporary storage for vertices, shared between
|
|
#endif // NEW_PARTIAL_PRIM // parts of decomposed primitive
|
|
__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 != PA_aIndices_INITIAL_VALUE),
|
|
"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 |
|
|
POLYARRAY_TEXTURE1 |
|
|
POLYARRAY_TEXTURE2 |
|
|
POLYARRAY_TEXTURE3 |
|
|
POLYARRAY_TEXTURE4 |
|
|
POLYARRAY_VERTEX2 |
|
|
POLYARRAY_VERTEX3 |
|
|
POLYARRAY_VERTEX4 |
|
|
POLYARRAY_CLAMP_COLOR);
|
|
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
// Save shared vertices for the next part of partial primitive
|
|
|
|
pfnSaveFunc[mode](gc, pa, savereg);
|
|
|
|
#endif // NEW_PARTIAL_PRIM
|
|
|
|
// 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 == PA_nextMsgOffset_RESET_VALUE,
|
|
"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
|
|
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
// Compute the start of the PARTIAL primitive. A partial primitive begins
|
|
// with a POLYARRAY entry followed by vertex entries. We DO NOT need to
|
|
// reserve additional vertex entries at the beginning for connectivity
|
|
// between decomposed primitives.
|
|
|
|
pd0 = pa->pdBufferNext + 1;
|
|
#else
|
|
// 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];
|
|
#endif
|
|
|
|
// 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->pd0 = pd0;
|
|
pa->primType = mode;
|
|
pa->pdCurColor =
|
|
pa->pdCurNormal =
|
|
pa->pdCurTexture =
|
|
pa->pdCurEdgeFlag = NULL;
|
|
pa->paNext = NULL;
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
pa->nIndices = 0;
|
|
#else
|
|
pa->nIndices = nReservedIndicesPartialBegin[mode];
|
|
#endif // NEW_PARTIAL_PRIM
|
|
pa->aIndices = PA_aIndices_INITIAL_VALUE; // 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;
|
|
|
|
#ifdef NEW_PARTIAL_PRIM
|
|
// Add saved vertices into the new part of the primitive
|
|
|
|
pfnRestoreFunc[mode](gc, pa, savereg);
|
|
|
|
#endif // NEW_PARTIAL_PRIM
|
|
}
|
|
|
|
// 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) \
|
|
{ \
|
|
GLfloat t1; \
|
|
POLYARRAY *pa; \
|
|
POLYDATA *pd, *pd1; \
|
|
ULONG flag1, flag2, flag3; \
|
|
register GLfloat tone; \
|
|
\
|
|
pa = GLTEB_CLTPOLYARRAY(); \
|
|
tone = 1.0; \
|
|
\
|
|
pd1 = pa->pdFlush; \
|
|
flag1 = pa->flags; \
|
|
pd = pa->pdNextVertex; \
|
|
\
|
|
if (flag1 & POLYARRAY_IN_BEGIN) \
|
|
{ \
|
|
flag3 = pd->flags; \
|
|
pa->pdNextVertex++; \
|
|
flag2 = flag1 | POLYARRAY_VERTEX3; \
|
|
flag3 = flag3 | POLYDATA_VERTEX3; \
|
|
\
|
|
pd->obj.x = x1; \
|
|
pd->obj.y = y1; \
|
|
pd->obj.z = z1; \
|
|
pd->obj.w = tone; \
|
|
pa->flags = flag2; \
|
|
pd->flags = flag3; \
|
|
\
|
|
pd[1].flags = 0; \
|
|
\
|
|
if (pd >= pd1) \
|
|
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_RGB(pd->colors[0].r, pd->colors[0].g, pd->colors[0].b, \
|
|
gc, red, green, 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_RGBA(pd->colors[0].r, \
|
|
pd->colors[0].g, \
|
|
pd->colors[0].b, \
|
|
pd->colors[0].a, \
|
|
gc, red, green, blue, 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_RGB(pd->colors[0].r, \
|
|
pd->colors[0].g, \
|
|
pd->colors[0].b, \
|
|
gc, pa->flags, \
|
|
red, green, 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_RGB2(red, green, blue) \
|
|
{ \
|
|
POLYARRAY *pa; \
|
|
POLYDATA *pd; \
|
|
GLfloat sr, sg, sb; \
|
|
ULONG f1, f2, f3, f4, f5, f6; \
|
|
LONG t1, t2, t3; \
|
|
\
|
|
__GL_SETUP(); \
|
|
\
|
|
pa = gc->paTeb; \
|
|
\
|
|
if (pa->flags & POLYARRAY_IN_BEGIN) \
|
|
{ \
|
|
\
|
|
t1 = (LONG) (CASTINT(gc->redVertexScale)); \
|
|
t2 = (LONG) (CASTINT(gc->greenVertexScale)); \
|
|
t3 = (LONG) (CASTINT(gc->blueVertexScale)); \
|
|
\
|
|
pd = pa->pdNextVertex; \
|
|
pa->pdCurColor = pd; \
|
|
\
|
|
sr = red * gc->redVertexScale; \
|
|
sg = green * gc->greenVertexScale; \
|
|
sb = blue * gc->blueVertexScale; \
|
|
\
|
|
f1 = (ULONG) (CASTINT(sr)); \
|
|
f2 = (ULONG) (CASTINT(sg)); \
|
|
f3 = (ULONG) (CASTINT(sb)); \
|
|
\
|
|
f4 = (ULONG) (t1 - CASTINT(sr)); \
|
|
f5 = (ULONG) (t2 - CASTINT(sg)); \
|
|
f6 = (ULONG) (t3 - CASTINT(sb)); \
|
|
\
|
|
f1 = f1 | f2; \
|
|
f3 = f3 | f4; \
|
|
f5 = f5 | f6; \
|
|
\
|
|
pd->colors[0].r = sr; \
|
|
pd->colors[0].g = sg; \
|
|
pd->colors[0].b = sb; \
|
|
\
|
|
f1 = f1 | f3 | f5; \
|
|
\
|
|
pa->flags |= (f1 & 0x80000000); \
|
|
\
|
|
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_RGBA(pd->colors[0].r, \
|
|
pd->colors[0].g, \
|
|
pd->colors[0].b, \
|
|
pd->colors[0].a, \
|
|
gc, pa->flags, \
|
|
red, green, blue, 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_RGBA(pd->colors[0].r,
|
|
pd->colors[0].g,
|
|
pd->colors[0].b,
|
|
pd->colors[0].a,
|
|
gc, pa->flags,
|
|
red, green, blue, 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(x1, y1, z1) \
|
|
{ \
|
|
POLYARRAY *pa; \
|
|
POLYDATA *pd; \
|
|
ULONG flag1, flag2; \
|
|
\
|
|
pa = GLTEB_CLTPOLYARRAY(); \
|
|
\
|
|
pd = pa->pdNextVertex; \
|
|
flag1 = pa->flags; \
|
|
\
|
|
if (flag1 & POLYARRAY_IN_BEGIN) \
|
|
{ \
|
|
flag2 = pd->flags; \
|
|
flag2 |= POLYDATA_NORMAL_VALID; \
|
|
pa->pdCurNormal = pd; \
|
|
pd->normal.x = x1; \
|
|
pd->normal.y = y1; \
|
|
pd->normal.z = z1; \
|
|
pd->flags = flag2; \
|
|
} \
|
|
else \
|
|
{ \
|
|
glcltNormal3f_NotInBegin(pa, x1, y1, z1); \
|
|
} \
|
|
\
|
|
}
|
|
|
|
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]);
|
|
}
|
|
|
|
#ifndef __GL_ASM_GLCLTCOLOR3F_INRGBA
|
|
void APIENTRY
|
|
glcltColor3f_InRGBA ( IN GLfloat red, IN GLfloat green, IN GLfloat blue )
|
|
{
|
|
PA_COLOR_IN_RGB2(red, green, blue);
|
|
}
|
|
#endif // __GL_ASM_GLCLTCOLOR3F_INRGBA
|
|
|
|
#ifndef __GL_ASM_GLCLTCOLOR3FV_INRGBA
|
|
void APIENTRY
|
|
glcltColor3fv_InRGBA ( IN const GLfloat v[3] )
|
|
{
|
|
GLfloat red, green, blue;
|
|
|
|
red = (GLfloat) v[0];
|
|
green = (GLfloat) v[1];
|
|
blue = (GLfloat) v[2];
|
|
|
|
PA_COLOR_IN_RGB2(red, green, blue);
|
|
}
|
|
#endif // __GL_ASM_GLCLTCOLOR3FV_INRGBA
|
|
|
|
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]);
|
|
}
|
|
|
|
#ifndef __GL_ASM_GLCLTCOLOR4F_INRGBA
|
|
void APIENTRY
|
|
glcltColor4f_InRGBA ( IN GLfloat red, IN GLfloat green, IN GLfloat blue, IN GLfloat alpha )
|
|
{
|
|
PA_COLOR_IN_RGBA(red, green, blue, alpha);
|
|
}
|
|
#endif // __GL_ASM_GLCLTCOLOR4F_INRGBA
|
|
|
|
#ifndef __GL_ASM_GLCLTCOLOR4FV_INRGBA
|
|
void APIENTRY
|
|
glcltColor4fv_InRGBA ( IN const GLfloat v[4] )
|
|
{
|
|
PA_COLOR_IN_RGBA(v[0], v[1], v[2], v[3]);
|
|
}
|
|
#endif // __GL_ASM_GLCLTCOLOR4FV_INRGBA
|
|
|
|
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 *) ALLOCZ(
|
|
// 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 *) ALLOC(
|
|
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++)
|
|
{
|
|
FREE(pm->aMat[i]);
|
|
}
|
|
FREE(pm);
|
|
|
|
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, ¶m);
|
|
}
|
|
|
|
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 __GL_ASM_GLCLTNORMAL3F
|
|
void APIENTRY
|
|
glcltNormal3f ( IN GLfloat x, IN GLfloat y, IN GLfloat z )
|
|
{
|
|
PA_NORMAL(x, y, z);
|
|
}
|
|
#endif //__GL_ASM_GLCLTNORMAL3F
|
|
|
|
#ifndef __GL_ASM_GLCLTNORMAL3FV
|
|
void APIENTRY
|
|
glcltNormal3fv ( IN const GLfloat v[3] )
|
|
{
|
|
GLfloat x, y, z;
|
|
|
|
x = v[0];
|
|
y = v[1];
|
|
z = v[2];
|
|
|
|
PA_NORMAL(x, y, z);
|
|
}
|
|
#endif //__GL_ASM_GLCLTNORMAL3FV
|
|
|
|
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 __GL_ASM_GLCLTTEXCOORD2F
|
|
void APIENTRY
|
|
glcltTexCoord2f ( IN GLfloat s, IN GLfloat t )
|
|
{
|
|
PA_TEXTURE2((GLfloat) s, (GLfloat) t);
|
|
}
|
|
#endif //__GL_ASM_GLCLTTEXCOORD2F
|
|
|
|
#ifndef __GL_ASM_GLCLTTEXCOORD2FV
|
|
void APIENTRY
|
|
glcltTexCoord2fv ( IN const GLfloat v[2] )
|
|
{
|
|
PA_TEXTURE2((GLfloat) v[0], (GLfloat) v[1]);
|
|
}
|
|
#endif //__GL_ASM_GLCLTTEXCOORD2FV
|
|
|
|
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 __GL_ASM_GLCLTTEXCOORD3F
|
|
void APIENTRY
|
|
glcltTexCoord3f ( IN GLfloat s, IN GLfloat t, IN GLfloat r )
|
|
{
|
|
PA_TEXTURE3((GLfloat) s, (GLfloat) t, (GLfloat) r);
|
|
}
|
|
#endif //__GL_ASM_GLCLTTEXCOORD3F
|
|
|
|
#ifndef __GL_ASM_GLCLTTEXCOORD3FV
|
|
void APIENTRY
|
|
glcltTexCoord3fv ( IN const GLfloat v[3] )
|
|
{
|
|
PA_TEXTURE3((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2]);
|
|
}
|
|
#endif //__GL_ASM_GLCLTTEXCOORD3FV
|
|
|
|
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]);
|
|
}
|
|
|
|
#ifdef GL_WIN_multiple_textures
|
|
void APIENTRY glcltMultiTexCoord1dWIN
|
|
(GLbitfield mask, GLdouble s)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord1dvWIN
|
|
(GLbitfield mask, const GLdouble *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord1fWIN
|
|
(GLbitfield mask, GLfloat s)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord1fvWIN
|
|
(GLbitfield mask, const GLfloat *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord1iWIN
|
|
(GLbitfield mask, GLint s)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord1ivWIN
|
|
(GLbitfield mask, const GLint *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord1sWIN
|
|
(GLbitfield mask, GLshort s)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord1svWIN
|
|
(GLbitfield mask, const GLshort *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord2dWIN
|
|
(GLbitfield mask, GLdouble s, GLdouble t)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord2dvWIN
|
|
(GLbitfield mask, const GLdouble *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord2fWIN
|
|
(GLbitfield mask, GLfloat s, GLfloat t)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord2fvWIN
|
|
(GLbitfield mask, const GLfloat *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord2iWIN
|
|
(GLbitfield mask, GLint s, GLint t)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord2ivWIN
|
|
(GLbitfield mask, const GLint *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord2sWIN
|
|
(GLbitfield mask, GLshort s, GLshort t)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord2svWIN
|
|
(GLbitfield mask, const GLshort *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord3dWIN
|
|
(GLbitfield mask, GLdouble s, GLdouble t, GLdouble r)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord3dvWIN
|
|
(GLbitfield mask, const GLdouble *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord3fWIN
|
|
(GLbitfield mask, GLfloat s, GLfloat t, GLfloat r)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord3fvWIN
|
|
(GLbitfield mask, const GLfloat *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord3iWIN
|
|
(GLbitfield mask, GLint s, GLint t, GLint r)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord3ivWIN
|
|
(GLbitfield mask, const GLint *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord3sWIN
|
|
(GLbitfield mask, GLshort s, GLshort t, GLshort r)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord3svWIN
|
|
(GLbitfield mask, const GLshort *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord4dWIN
|
|
(GLbitfield mask, GLdouble s, GLdouble t, GLdouble r, GLdouble q)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord4dvWIN
|
|
(GLbitfield mask, const GLdouble *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord4fWIN
|
|
(GLbitfield mask, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord4fvWIN
|
|
(GLbitfield mask, const GLfloat *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord4iWIN
|
|
(GLbitfield mask, GLint s, GLint t, GLint r, GLint q)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord4ivWIN
|
|
(GLbitfield mask, const GLint *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord4sWIN
|
|
(GLbitfield mask, GLshort s, GLshort t, GLshort r, GLshort q)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
|
|
void APIENTRY glcltMultiTexCoord4svWIN
|
|
(GLbitfield mask, const GLshort *v)
|
|
{
|
|
// ATTENTION
|
|
}
|
|
#endif // GL_WIN_multiple_textures
|
|
|
|
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 __GL_ASM_GLCLTVERTEX2F
|
|
void APIENTRY
|
|
glcltVertex2f ( IN GLfloat x, IN GLfloat y )
|
|
{
|
|
PA_VERTEX2((GLfloat) x, (GLfloat) y);
|
|
}
|
|
#endif //__GL_ASM_GLCLTVERTEX2F
|
|
|
|
#ifndef __GL_ASM_GLCLTVERTEX2FV
|
|
void APIENTRY
|
|
glcltVertex2fv ( IN const GLfloat v[2] )
|
|
{
|
|
PA_VERTEX2((GLfloat) v[0], (GLfloat) v[1]);
|
|
}
|
|
#endif //__GL_ASM_GLCLTVERTEX2FV
|
|
|
|
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 __GL_ASM_GLCLTVERTEX3F
|
|
void APIENTRY
|
|
glcltVertex3f ( IN GLfloat x, IN GLfloat y, IN GLfloat z )
|
|
{
|
|
PA_VERTEX3((GLfloat) x, (GLfloat) y, (GLfloat) z);
|
|
}
|
|
#endif //__GL_ASM_GLCLTVERTEX3F
|
|
|
|
#ifndef __GL_ASM_GLCLTVERTEX3FV
|
|
void APIENTRY
|
|
glcltVertex3fv ( IN const GLfloat v[3] )
|
|
{
|
|
GLfloat x1, y1, z1;
|
|
|
|
x1 = (GLfloat) v[0];
|
|
y1 = (GLfloat) v[1];
|
|
z1 = (GLfloat) v[2];
|
|
|
|
PA_VERTEX3(x1, y1, z1);
|
|
|
|
}
|
|
#endif //__GL_ASM_GLCLTVERTEX3FV
|
|
|
|
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 )
|
|
{
|
|
__GL_SETUP();
|
|
|
|
GLCLIENT_BEGIN( Disable, DISABLE )
|
|
pMsg->cap = cap ;
|
|
|
|
// Set the enable flags for the evaluators
|
|
switch (cap)
|
|
{
|
|
case GL_MAP1_COLOR_4:
|
|
case GL_MAP1_INDEX:
|
|
case GL_MAP1_NORMAL:
|
|
case GL_MAP1_TEXTURE_COORD_1:
|
|
case GL_MAP1_TEXTURE_COORD_2:
|
|
case GL_MAP1_TEXTURE_COORD_3:
|
|
case GL_MAP1_TEXTURE_COORD_4:
|
|
case GL_MAP1_VERTEX_3:
|
|
case GL_MAP1_VERTEX_4:
|
|
gc->eval.evalStateFlags |= __EVALS_AFFECTS_1D_EVAL;
|
|
break;
|
|
case GL_MAP2_COLOR_4:
|
|
case GL_MAP2_INDEX:
|
|
case GL_MAP2_NORMAL:
|
|
case GL_MAP2_TEXTURE_COORD_1:
|
|
case GL_MAP2_TEXTURE_COORD_2:
|
|
case GL_MAP2_TEXTURE_COORD_3:
|
|
case GL_MAP2_TEXTURE_COORD_4:
|
|
case GL_MAP2_VERTEX_3:
|
|
case GL_MAP2_VERTEX_4:
|
|
case GL_NORMALIZE:
|
|
case GL_AUTO_NORMAL:
|
|
gc->eval.evalStateFlags |= __EVALS_AFFECTS_2D_EVAL;
|
|
break;
|
|
case GL_LIGHTING:
|
|
gc->eval.evalStateFlags |= __EVALS_AFFECTS_ALL_EVAL;
|
|
break;
|
|
}
|
|
return;
|
|
GLCLIENT_END
|
|
}
|
|
|
|
void APIENTRY
|
|
glcltEnable ( IN GLenum cap )
|
|
{
|
|
__GL_SETUP();
|
|
|
|
GLCLIENT_BEGIN( Enable, ENABLE )
|
|
pMsg->cap = cap ;
|
|
|
|
// Set the enable flags for the evaluators
|
|
switch (cap)
|
|
{
|
|
case GL_MAP1_COLOR_4:
|
|
case GL_MAP1_INDEX:
|
|
case GL_MAP1_NORMAL:
|
|
case GL_MAP1_TEXTURE_COORD_1:
|
|
case GL_MAP1_TEXTURE_COORD_2:
|
|
case GL_MAP1_TEXTURE_COORD_3:
|
|
case GL_MAP1_TEXTURE_COORD_4:
|
|
case GL_MAP1_VERTEX_3:
|
|
case GL_MAP1_VERTEX_4:
|
|
gc->eval.evalStateFlags |= __EVALS_AFFECTS_1D_EVAL;
|
|
break;
|
|
case GL_MAP2_COLOR_4:
|
|
case GL_MAP2_INDEX:
|
|
case GL_MAP2_NORMAL:
|
|
case GL_MAP2_TEXTURE_COORD_1:
|
|
case GL_MAP2_TEXTURE_COORD_2:
|
|
case GL_MAP2_TEXTURE_COORD_3:
|
|
case GL_MAP2_TEXTURE_COORD_4:
|
|
case GL_MAP2_VERTEX_3:
|
|
case GL_MAP2_VERTEX_4:
|
|
case GL_NORMALIZE:
|
|
case GL_AUTO_NORMAL:
|
|
gc->eval.evalStateFlags |= __EVALS_AFFECTS_2D_EVAL;
|
|
break;
|
|
case GL_LIGHTING:
|
|
gc->eval.evalStateFlags |= __EVALS_AFFECTS_ALL_EVAL;
|
|
break;
|
|
}
|
|
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 )
|
|
{
|
|
__GL_SETUP();
|
|
|
|
GLCLIENT_BEGIN( PopAttrib, POPATTRIB )
|
|
if (gc->eval.evalStackState & 0x1)
|
|
{
|
|
gc->eval.evalStateFlags = gc->eval.evalStateFlags |
|
|
__EVALS_AFFECTS_ALL_EVAL |
|
|
__EVALS_POP_EVAL_ATTRIB;
|
|
}
|
|
gc->eval.evalStackState = (gc->eval.evalStackState) >> 1;
|
|
return;
|
|
GLCLIENT_END
|
|
}
|
|
|
|
void APIENTRY
|
|
glcltPushAttrib ( IN GLbitfield mask )
|
|
{
|
|
__GL_SETUP ();
|
|
|
|
// Assert that the stack size is always less than 31 since the
|
|
// bitfield is a DWORD.
|
|
ASSERTOPENGL (gc->constants.maxAttribStackDepth < 31, "Attrib state stack is greater than the size of the bitfield used to track it\n");
|
|
|
|
GLCLIENT_BEGIN( PushAttrib, PUSHATTRIB )
|
|
pMsg->mask = mask ;
|
|
gc->eval.evalStackState = (gc->eval.evalStackState) << 1;
|
|
if (mask & GL_EVAL_BIT)
|
|
{
|
|
gc->eval.evalStateFlags = gc->eval.evalStateFlags |
|
|
__EVALS_AFFECTS_ALL_EVAL |
|
|
__EVALS_PUSH_EVAL_ATTRIB;
|
|
gc->eval.evalStackState = (gc->eval.evalStackState) | 0x1;
|
|
}
|
|
return;
|
|
GLCLIENT_END
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
}
|