windows-nt/Source/XPSP1/NT/multimedia/opengl/server/soft/so_attri.c
2020-09-26 16:20:57 +08:00

2151 lines
61 KiB
C

/*
** Copyright 1991, 1992, 1993, Silicon Graphics, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of Silicon Graphics, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
*/
#include "precomp.h"
#pragma hdrstop
#include "lighting.h"
#ifdef unix
#include <GL/glxproto.h>
#endif
void APIPRIVATE __glim_AlphaFunc(GLenum af, GLfloat ref)
{
__GL_SETUP_NOT_IN_BEGIN();
if ((af < GL_NEVER) || (af > GL_ALWAYS)) {
__glSetError(GL_INVALID_ENUM);
return;
}
if (__GL_FLOAT_LTZ (ref)) ref = __glZero;
if (__GL_FLOAT_COMPARE_PONE (ref, >)) ref = __glOne;
if ((gc->state.raster.alphaFunction != af) ||
__GL_FLOAT_NE (gc->state.raster.alphaReference, ref)) {
gc->state.raster.alphaFunction = af;
gc->state.raster.alphaReference = ref;
__GL_DELAY_VALIDATE(gc);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, ALPHATEST);
#endif
gc->validateMask |= __GL_VALIDATE_ALPHA_FUNC;
}
}
void APIPRIVATE __glim_BlendFunc(GLenum sf, GLenum df)
{
__GL_SETUP_NOT_IN_BEGIN();
switch (sf) {
case GL_ZERO:
case GL_ONE:
case GL_DST_COLOR:
case GL_ONE_MINUS_DST_COLOR:
case GL_SRC_ALPHA:
case GL_ONE_MINUS_SRC_ALPHA:
case GL_DST_ALPHA:
case GL_ONE_MINUS_DST_ALPHA:
case GL_SRC_ALPHA_SATURATE:
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
switch (df) {
case GL_ZERO:
case GL_ONE:
case GL_SRC_COLOR:
case GL_ONE_MINUS_SRC_COLOR:
case GL_SRC_ALPHA:
case GL_ONE_MINUS_SRC_ALPHA:
case GL_DST_ALPHA:
case GL_ONE_MINUS_DST_ALPHA:
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
if ((gc->state.raster.blendSrc != sf) ||
(gc->state.raster.blendDst != df)) {
gc->state.raster.blendSrc = sf;
gc->state.raster.blendDst = df;
__GL_DELAY_VALIDATE(gc);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, BLEND);
#endif
}
}
void APIPRIVATE __glim_ClearAccum(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
__GLfloat minusOne;
__GLfloat one;
__GL_SETUP_NOT_IN_BEGIN();
minusOne = __glMinusOne;
one = __glOne;
if (r < minusOne) r = minusOne;
if (r > one) r = one;
if (g < minusOne) g = minusOne;
if (g > one) g = one;
if (b < minusOne) b = minusOne;
if (b > one) b = one;
if (a < minusOne) a = minusOne;
if (a > one) a = one;
if (__GL_FLOAT_NE (gc->state.accum.clear.r, r) ||
__GL_FLOAT_NE (gc->state.accum.clear.g, g) ||
__GL_FLOAT_NE (gc->state.accum.clear.b, b) ||
__GL_FLOAT_NE (gc->state.accum.clear.a, a))
{
gc->state.accum.clear.r = r;
gc->state.accum.clear.g = g;
gc->state.accum.clear.b = b;
gc->state.accum.clear.a = a;
__GL_DELAY_VALIDATE(gc);
}
}
void APIPRIVATE __glim_ClearColor (GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
__GLfloat zero;
__GLfloat one;
__GL_SETUP_NOT_IN_BEGIN();
zero = (__GLfloat)__glZero;
one = (__GLfloat)__glOne;
if (__GL_FLOAT_LTZ(r)) r = zero;
if (__GL_FLOAT_COMPARE_PONE (r, >)) r = one;
if (__GL_FLOAT_LTZ(g)) g = zero;
if (__GL_FLOAT_COMPARE_PONE (g, >)) g = one;
if (__GL_FLOAT_LTZ(b)) b = zero;
if (__GL_FLOAT_COMPARE_PONE (b, >)) b = one;
if (__GL_FLOAT_LTZ(a)) a = zero;
if (__GL_FLOAT_COMPARE_PONE (a, >)) a = one;
#if 0
if (__GL_FLOAT_NE (gc->state.raster.clear.r, r) ||
__GL_FLOAT_NE (gc->state.raster.clear.g, g) ||
__GL_FLOAT_NE (gc->state.raster.clear.b, b) ||
__GL_FLOAT_NE (gc->state.raster.clear.a, a))
{
#endif
gc->state.raster.clear.r = r;
gc->state.raster.clear.g = g;
gc->state.raster.clear.b = b;
gc->state.raster.clear.a = a;
#ifdef _MCD_
MCD_STATE_DIRTY(gc, FBUFCTRL);
#endif
//}
}
void APIPRIVATE __glim_ClearDepth(GLdouble z)
{
__GL_SETUP_NOT_IN_BEGIN();
if (z < (GLdouble) 0) z = (GLdouble)0;
if (z > (GLdouble) 1) z = (GLdouble)1;
if (gc->state.depth.clear != z) {
gc->state.depth.clear = z;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_DEPTH);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, FBUFCTRL);
#endif
}
}
void APIPRIVATE __glim_ClearIndex(GLfloat val)
{
__GL_SETUP_NOT_IN_BEGIN();
val = __GL_MASK_INDEXF(gc, val);
gc->state.raster.clearIndex = val;
#ifdef _MCD_
MCD_STATE_DIRTY(gc, FBUFCTRL);
#endif
}
void APIPRIVATE __glim_ClearStencil(GLint s)
{
__GL_SETUP_NOT_IN_BEGIN();
if (gc->state.stencil.clear != (GLshort) (s & __GL_MAX_STENCIL_VALUE)) {
gc->state.stencil.clear = (GLshort) (s & __GL_MAX_STENCIL_VALUE);
__GL_DELAY_VALIDATE(gc);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, FBUFCTRL);
#endif
}
}
void APIPRIVATE __glim_ColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a)
{
__GL_SETUP_NOT_IN_BEGIN();
if ((gc->state.raster.rMask != r) || (gc->state.raster.gMask != g) ||
(gc->state.raster.bMask != b) || (gc->state.raster.aMask != a)) {
gc->state.raster.rMask = r;
gc->state.raster.gMask = g;
gc->state.raster.bMask = b;
gc->state.raster.aMask = a;
__GL_DELAY_VALIDATE(gc);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, FBUFCTRL);
#endif
}
}
void APIPRIVATE __glim_ColorMaterial(GLenum face, GLenum p)
{
__GL_SETUP_NOT_IN_BEGIN();
switch (face) {
case GL_FRONT:
case GL_BACK:
case GL_FRONT_AND_BACK:
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
switch (p) {
case GL_EMISSION:
case GL_SPECULAR:
case GL_AMBIENT:
case GL_DIFFUSE:
case GL_AMBIENT_AND_DIFFUSE:
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
gc->state.light.colorMaterialFace = face;
gc->state.light.colorMaterialParam = p;
if (gc->state.enables.general & __GL_COLOR_MATERIAL_ENABLE) {
#ifdef NT
ComputeColorMaterialChange(gc);
#endif
(*gc->procs.pickColorMaterialProcs)(gc);
(*gc->procs.applyColor)(gc);
}
MCD_STATE_DIRTY(gc, COLORMATERIAL);
}
void APIPRIVATE __glim_CullFace(GLenum cfm)
{
__GL_SETUP_NOT_IN_BEGIN();
switch (cfm) {
case GL_FRONT:
case GL_BACK:
case GL_FRONT_AND_BACK:
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
if (gc->state.polygon.cull != cfm) {
gc->state.polygon.cull = cfm;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POLYGON);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, POLYDRAW);
#endif
}
}
void APIPRIVATE __glim_DepthFunc(GLenum zf)
{
__GL_SETUP_NOT_IN_BEGIN();
if ((zf < GL_NEVER) || (zf > GL_ALWAYS)) {
__glSetError(GL_INVALID_ENUM);
return;
}
if (gc->modes.depthBits != 0)
gc->state.depth.testFunc = zf;
else
gc->state.depth.testFunc = GL_ALWAYS;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_DEPTH);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, DEPTHTEST);
#endif
}
void APIPRIVATE __glim_DepthMask(GLboolean enabled)
{
__GL_SETUP_NOT_IN_BEGIN();
if (gc->state.depth.writeEnable != enabled) {
gc->state.depth.writeEnable = enabled;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_DEPTH);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, FBUFCTRL);
#endif
}
}
void APIPRIVATE __glim_DrawBuffer(GLenum mode)
{
GLint i;
__GL_SETUP_NOT_IN_BEGIN();
switch (mode) {
case GL_NONE:
gc->state.raster.drawBuffer = GL_NONE;
break;
case GL_FRONT_RIGHT:
case GL_BACK_RIGHT:
case GL_RIGHT:
not_supported_in_this_implementation:
__glSetError(GL_INVALID_OPERATION);
return;
case GL_FRONT:
case GL_FRONT_LEFT:
gc->state.raster.drawBuffer = GL_FRONT;
break;
case GL_FRONT_AND_BACK:
case GL_LEFT:
if (!gc->modes.doubleBufferMode) {
gc->state.raster.drawBuffer = GL_FRONT;
} else {
gc->state.raster.drawBuffer = GL_FRONT_AND_BACK;
}
break;
case GL_BACK:
case GL_BACK_LEFT:
if (!gc->modes.doubleBufferMode) {
goto not_supported_in_this_implementation;
}
gc->state.raster.drawBuffer = GL_BACK;
break;
case GL_AUX0:
case GL_AUX1:
case GL_AUX2:
case GL_AUX3:
i = mode - GL_AUX0;
if (i >= gc->modes.maxAuxBuffers) {
goto not_supported_in_this_implementation;
}
gc->state.raster.drawBuffer = mode;
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
if (gc->state.raster.drawBufferReturn != mode) {
gc->state.raster.drawBufferReturn = mode;
__GL_DELAY_VALIDATE(gc);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, FBUFCTRL);
#endif
}
}
void APIPRIVATE __glim_Fogfv(GLenum p, const GLfloat pv[])
{
__GL_SETUP_NOT_IN_BEGIN();
switch (p) {
case GL_FOG_COLOR:
__glClampAndScaleColorf(gc, &gc->state.fog.color, pv);
#ifdef NT
if (gc->state.fog.color.r == gc->state.fog.color.g
&& gc->state.fog.color.r == gc->state.fog.color.b)
gc->state.fog.flags |= __GL_FOG_GRAY_RGB;
else
gc->state.fog.flags &= ~__GL_FOG_GRAY_RGB;
#endif
break;
case GL_FOG_DENSITY:
if (pv[0] < __glZero) {
__glSetError(GL_INVALID_VALUE);
return;
}
gc->state.fog.density = pv[0];
#ifdef NT
gc->state.fog.density2neg = -(pv[0] * pv[0]);
#endif
break;
case GL_FOG_END:
gc->state.fog.end = pv[0];
break;
case GL_FOG_START:
gc->state.fog.start = pv[0];
break;
case GL_FOG_INDEX:
gc->state.fog.index = __GL_MASK_INDEXF(gc, pv[0]);
break;
case GL_FOG_MODE:
switch ((GLenum) pv[0]) {
case GL_EXP:
case GL_EXP2:
case GL_LINEAR:
gc->state.fog.mode = (GLenum) pv[0];
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
/*
** Recompute cached 1/(end - start) value for linear fogging.
*/
if (gc->state.fog.mode == GL_LINEAR) {
if (gc->state.fog.start != gc->state.fog.end) {
gc->state.fog.oneOverEMinusS =
__glOne / (gc->state.fog.end - gc->state.fog.start);
} else {
/*
** Use zero as the undefined value.
*/
gc->state.fog.oneOverEMinusS = __glZero;
}
}
__GL_DELAY_VALIDATE(gc);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, FOG);
#endif
}
void APIPRIVATE __glim_FrontFace(GLenum dir)
{
__GL_SETUP_NOT_IN_BEGIN();
switch (dir) {
case GL_CW:
case GL_CCW:
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
if (gc->state.polygon.frontFaceDirection != dir) {
gc->state.polygon.frontFaceDirection = dir;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POLYGON);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, POLYDRAW);
#endif
}
}
void APIPRIVATE __glim_Hint(GLenum target, GLenum mode)
{
__GLhintState *hs;
__GL_SETUP_NOT_IN_BEGIN();
hs = &gc->state.hints;
switch (mode) {
case GL_DONT_CARE:
case GL_FASTEST:
case GL_NICEST:
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
switch (target) {
case GL_PERSPECTIVE_CORRECTION_HINT:
if (hs->perspectiveCorrection == mode) return;
hs->perspectiveCorrection = mode;
break;
case GL_POINT_SMOOTH_HINT:
if (hs->pointSmooth == mode) return;
hs->pointSmooth = mode;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POINT);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, HINTS);
#endif
return;
case GL_LINE_SMOOTH_HINT:
if (hs->lineSmooth == mode) return;
hs->lineSmooth = mode;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_LINE);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, HINTS);
#endif
return;
case GL_POLYGON_SMOOTH_HINT:
if (hs->polygonSmooth == mode) return;
hs->polygonSmooth = mode;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POLYGON);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, HINTS);
#endif
return;
case GL_FOG_HINT:
if (hs->fog == mode) return;
hs->fog = mode;
break;
#ifdef GL_WIN_phong_shading
case GL_PHONG_HINT_WIN:
if (hs->phong == mode) return;
hs->phong = mode;
break;
#endif //GL_WIN_phong_shading
default:
__glSetError(GL_INVALID_ENUM);
return;
}
__GL_DELAY_VALIDATE(gc);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, HINTS);
#endif
}
void APIPRIVATE __glim_IndexMask(GLuint i)
{
__GL_SETUP_NOT_IN_BEGIN();
i = __GL_MASK_INDEXI(gc, i);
if (gc->state.raster.writeMask != (GLint) i) {
gc->state.raster.writeMask = (GLint) i;
__GL_DELAY_VALIDATE(gc);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, FBUFCTRL);
#endif
}
}
void FASTCALL __glTransformLightDirection(__GLcontext *gc, __GLlightSourceState *lss)
{
__GLcoord dir;
__GLfloat q;
GLint target = (GLint)((ULONG_PTR)(lss - &gc->state.light.source[0]));
__GLtransform *tr;
dir.x = lss->direction.x;
dir.y = lss->direction.y;
dir.z = lss->direction.z;
#ifdef NT
ASSERTOPENGL(lss->direction.w == __glOne, "Direction with invalid w\n");
q = -(dir.x * lss->position.x + dir.y * lss->position.y +
dir.z * lss->position.z);
#else
if (lss->position.w != __glZero) {
q = -(dir.x * lss->position.x + dir.y * lss->position.y +
dir.z * lss->position.z) / lss->position.w;
} else {
q = __glZero;
}
#endif // NT
dir.w = q;
tr = gc->transform.modelView;
if (tr->flags & XFORM_UPDATE_INVERSE) {
__glComputeInverseTranspose(gc, tr);
}
(*tr->inverseTranspose.xf4)(&lss->directionEye, &dir.x,
&tr->inverseTranspose);
__glNormalize(&lss->directionEyeNorm.x, &lss->directionEye.x);
gc->light.source[target].direction = lss->directionEyeNorm;
}
void APIPRIVATE __glim_Lightfv(GLenum light, GLenum p, const GLfloat pv[])
{
__GLlightSourceState *lss;
__GLmatrix *m;
__GL_SETUP_NOT_IN_BEGIN();
light -= GL_LIGHT0;
#ifdef NT
// light is unsigned!
if (light >= (GLenum) gc->constants.numberOfLights) {
#else
if ((light < 0) || (light >= gc->constants.numberOfLights)) {
#endif // NT
bad_enum:
__glSetError(GL_INVALID_ENUM);
return;
}
lss = &gc->state.light.source[light];
switch (p) {
case GL_AMBIENT:
__glScaleColorf(gc, &lss->ambient, pv);
break;
case GL_DIFFUSE:
__glScaleColorf(gc, &lss->diffuse, pv);
break;
case GL_SPECULAR:
__glScaleColorf(gc, &lss->specular, pv);
break;
case GL_POSITION:
lss->position.x = pv[0];
lss->position.y = pv[1];
lss->position.z = pv[2];
lss->position.w = pv[3];
/*
** Transform light position into eye space
*/
m = &gc->transform.modelView->matrix;
(*m->xf4)(&lss->positionEye, &lss->position.x, m);
//
// Grab a copy of the matrix so we can do this again later for
// infinite lighting (avoiding normal transformations):
//
lss->lightMatrix = gc->transform.modelView->matrix;
break;
case GL_SPOT_DIRECTION:
lss->direction.x = pv[0];
lss->direction.y = pv[1];
lss->direction.z = pv[2];
lss->direction.w = __glOne;
__glTransformLightDirection(gc, lss);
break;
case GL_SPOT_EXPONENT:
if ((pv[0] < (__GLfloat) 0) || (pv[0] > (__GLfloat) 128)) {
bad_value:
__glSetError(GL_INVALID_VALUE);
return;
}
lss->spotLightExponent = pv[0];
break;
case GL_SPOT_CUTOFF:
if ((pv[0] != (__GLfloat) 180) && ((pv[0] < (__GLfloat) 0) || (pv[0] > (__GLfloat) 90))) {
goto bad_value;
}
lss->spotLightCutOffAngle = pv[0];
break;
case GL_CONSTANT_ATTENUATION:
if (pv[0] < __glZero) {
goto bad_value;
}
lss->constantAttenuation = pv[0];
break;
case GL_LINEAR_ATTENUATION:
if (pv[0] < __glZero) {
goto bad_value;
}
lss->linearAttenuation = pv[0];
break;
case GL_QUADRATIC_ATTENUATION:
if (pv[0] < __glZero) {
goto bad_value;
}
lss->quadraticAttenuation = pv[0];
break;
default:
goto bad_enum;
}
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_LIGHTING);
gc->state.light.dirtyLights |= 1 << light;
MCD_STATE_DIRTY(gc, LIGHTS);
}
void APIPRIVATE __glim_LightModelfv(GLenum p, const GLfloat pv[])
{
__GLlightModelState *model;
__GL_SETUP_NOT_IN_BEGIN();
model = &gc->state.light.model;
switch (p) {
case GL_LIGHT_MODEL_AMBIENT:
__glScaleColorf(gc, &model->ambient, pv);
break;
case GL_LIGHT_MODEL_LOCAL_VIEWER:
model->localViewer = pv[0] != __glZero;
break;
case GL_LIGHT_MODEL_TWO_SIDE:
model->twoSided = pv[0] != __glZero;
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_LIGHTING);
MCD_STATE_DIRTY(gc, LIGHTMODEL);
}
void APIPRIVATE __glim_LineStipple(GLint factor, GLushort stipple)
{
__GL_SETUP_NOT_IN_BEGIN();
if (factor < 1) {
factor = 1;
}
if (factor > 255) {
factor = 255;
}
if ((gc->state.line.stippleRepeat != (GLshort) factor) ||
(gc->state.line.stipple != stipple)) {
gc->state.line.stippleRepeat = (GLshort) factor;
gc->state.line.stipple = stipple;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_LINE);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, LINEDRAW);
#endif
}
}
static GLint RoundWidth(__GLfloat size)
{
if (size < (__GLfloat) 1.0)
return 1;
return size + (__GLfloat) 0.5;
}
static __GLfloat ClampWidth(__GLcontext *gc, __GLfloat size)
{
__GLfloat minSize = gc->constants.lineWidthMinimum;
__GLfloat maxSize = gc->constants.lineWidthMaximum;
__GLfloat gran = gc->constants.lineWidthGranularity;
GLint i;
if (size <= minSize) return minSize;
if (size >= maxSize) return maxSize;
/* choose closest fence post */
i = (GLint)(((size - minSize) / gran) + __glHalf);
return minSize + i * gran;
}
void APIPRIVATE __glim_LineWidth(GLfloat width)
{
__GL_SETUP_NOT_IN_BEGIN();
if (width <= 0) {
__glSetError(GL_INVALID_VALUE);
return;
}
if (gc->state.line.requestedWidth == width) return;
gc->state.line.requestedWidth = width;
gc->state.line.aliasedWidth = RoundWidth(width);
gc->state.line.smoothWidth = ClampWidth(gc, width);
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_LINE);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, LINEDRAW);
#endif
}
void APIPRIVATE __glim_LogicOp(GLenum op)
{
__GL_SETUP_NOT_IN_BEGIN();
if ((op < GL_CLEAR) || (op > GL_SET)) {
__glSetError(GL_INVALID_ENUM);
return;
}
if (gc->state.raster.logicOp != op) {
gc->state.raster.logicOp = op;
__GL_DELAY_VALIDATE(gc);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, LOGICOP);
#endif
}
}
static GLint ApplyParameterF(__GLcontext *gc, __GLmaterialState *ms,
GLenum p, const GLfloat pv[])
{
switch (p) {
case GL_COLOR_INDEXES:
ms->cmapa = pv[0];
ms->cmapd = pv[1];
ms->cmaps = pv[2];
return __GL_MATERIAL_COLORINDEXES;
case GL_EMISSION:
__glScaleColorf(gc, &ms->emissive, pv);
return __GL_MATERIAL_EMISSIVE;
case GL_SPECULAR:
ms->specular.r = pv[0];
ms->specular.g = pv[1];
ms->specular.b = pv[2];
ms->specular.a = pv[3];
return __GL_MATERIAL_SPECULAR;
case GL_SHININESS:
ms->specularExponent = pv[0];
return __GL_MATERIAL_SHININESS;
case GL_AMBIENT:
ms->ambient.r = pv[0];
ms->ambient.g = pv[1];
ms->ambient.b = pv[2];
ms->ambient.a = pv[3];
return __GL_MATERIAL_AMBIENT;
case GL_DIFFUSE:
ms->diffuse.r = pv[0];
ms->diffuse.g = pv[1];
ms->diffuse.b = pv[2];
ms->diffuse.a = pv[3];
return __GL_MATERIAL_DIFFUSE;
case GL_AMBIENT_AND_DIFFUSE:
ms->ambient.r = pv[0];
ms->ambient.g = pv[1];
ms->ambient.b = pv[2];
ms->ambient.a = pv[3];
ms->diffuse = ms->ambient;
return __GL_MATERIAL_DIFFUSE | __GL_MATERIAL_AMBIENT;
}
return 0;
}
#ifdef SGI
GLenum __glErrorCheckMaterial(GLenum face, GLenum p, GLfloat pv0)
{
switch (face) {
case GL_FRONT:
case GL_BACK:
case GL_FRONT_AND_BACK:
break;
default:
return GL_INVALID_ENUM;
}
switch (p) {
case GL_COLOR_INDEXES:
case GL_EMISSION:
case GL_SPECULAR:
case GL_AMBIENT:
case GL_DIFFUSE:
case GL_AMBIENT_AND_DIFFUSE:
break;
case GL_SHININESS:
if (pv0 < (GLfloat) 0 || pv0 > (GLfloat) 128) {
return GL_INVALID_VALUE;
}
break;
default:
return GL_INVALID_ENUM;
}
return GL_NO_ERROR;
}
#endif
//!!! can we 'batch' these calls up until begin is called?
void APIPRIVATE __glim_Materialfv(GLenum face, GLenum p, const GLfloat pv[])
{
GLenum error;
GLint frontChange, backChange;
__GL_SETUP();
switch (face) {
case GL_FRONT:
frontChange = ApplyParameterF(gc, &gc->state.light.front, p, pv);
backChange = 0;
break;
case GL_BACK:
backChange = ApplyParameterF(gc, &gc->state.light.back, p, pv);
frontChange = 0;
break;
case GL_FRONT_AND_BACK:
backChange = ApplyParameterF(gc, &gc->state.light.back, p, pv);
frontChange = ApplyParameterF(gc, &gc->state.light.front, p, pv);
break;
}
if (p != GL_COLOR_INDEXES) {
__glValidateMaterial(gc, frontChange, backChange);
}
if (gc->state.enables.general & __GL_COLOR_MATERIAL_ENABLE) {
(*gc->procs.applyColor)(gc);
}
MCD_STATE_DIRTY(gc, MATERIAL);
}
static GLint RoundSize(__GLfloat size)
{
if (size < (__GLfloat) 1.0)
return 1;
return size + (__GLfloat) 0.5;
}
static __GLfloat ClampSize(__GLcontext *gc, __GLfloat size)
{
__GLfloat minSize = gc->constants.pointSizeMinimum;
__GLfloat maxSize = gc->constants.pointSizeMaximum;
__GLfloat gran = gc->constants.pointSizeGranularity;
GLint i;
if (size <= minSize) return minSize;
if (size >= maxSize) return maxSize;
/* choose closest fence post */
i = (GLint)(((size - minSize) / gran) + __glHalf);
return minSize + i * gran;
}
void APIPRIVATE __glim_PointSize(GLfloat f)
{
__GL_SETUP_NOT_IN_BEGIN();
if (f <= __glZero) {
__glSetError(GL_INVALID_VALUE);
return;
}
if (gc->state.point.requestedSize != f) {
gc->state.point.requestedSize = f;
gc->state.point.aliasedSize = RoundSize(f);
gc->state.point.smoothSize = ClampSize(gc, f);
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POINT);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, POINTDRAW);
#endif
}
}
void APIPRIVATE __glim_PolygonMode(GLenum face, GLenum mode)
{
__GL_SETUP_NOT_IN_BEGIN();
switch (mode) {
case GL_FILL:
break;
case GL_POINT:
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POINT);
break;
case GL_LINE:
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_LINE);
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
switch (face) {
case GL_FRONT:
gc->state.polygon.frontMode = mode;
break;
case GL_BACK:
gc->state.polygon.backMode = mode;
break;
case GL_FRONT_AND_BACK:
gc->state.polygon.frontMode = mode;
gc->state.polygon.backMode = mode;
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POLYGON);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, POLYDRAW);
#endif
}
#ifdef NT
void APIPRIVATE __glim_PolygonStipple(const GLubyte *mask, GLboolean _IsDlist)
#else
void APIPRIVATE __glim_PolygonStipple(const GLubyte *mask)
#endif
{
GLubyte *stipple;
__GL_SETUP_NOT_IN_BEGIN();
#ifdef NT
if (_IsDlist)
{
const GLubyte *bits = mask;
/*
** Just copy bits into stipple, convertPolygonStipple() will do the rest
*/
__GL_MEMCOPY(&gc->state.polygonStipple.stipple[0], bits,
sizeof(gc->state.polygonStipple.stipple));
}
else
{
#endif
stipple = &gc->state.polygonStipple.stipple[0];
__glFillImage(gc, 32, 32, GL_COLOR_INDEX, GL_BITMAP, mask, stipple);
#ifdef NT
}
#endif
(*gc->procs.convertPolygonStipple)(gc);
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POLYGON);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, POLYDRAW);
#endif
}
void APIPRIVATE __glim_ShadeModel(GLenum sm)
{
__GL_SETUP_NOT_IN_BEGIN();
#ifdef GL_WIN_phong_shading
if (!((sm == GL_FLAT) || (sm == GL_SMOOTH) || (sm == GL_PHONG_WIN)))
#else
if ((sm < GL_FLAT) || (sm > GL_SMOOTH))
#endif
{
__glSetError(GL_INVALID_ENUM);
return;
}
if (gc->state.light.shadingModel != sm)
{
gc->state.light.shadingModel = sm;
__GL_DELAY_VALIDATE(gc);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, SHADEMODEL);
#endif
}
}
void APIPRIVATE __glim_StencilMask(GLuint sm)
{
__GL_SETUP_NOT_IN_BEGIN();
if (gc->state.stencil.writeMask !=
(GLshort)(sm & __GL_MAX_STENCIL_VALUE)) {
gc->state.stencil.writeMask = (GLshort) (sm & __GL_MAX_STENCIL_VALUE);
__GL_DELAY_VALIDATE(gc);
gc->validateMask |= __GL_VALIDATE_STENCIL_FUNC;
#ifdef _MCD_
MCD_STATE_DIRTY(gc, FBUFCTRL);
#endif
}
}
void APIPRIVATE __glim_StencilFunc(GLenum func, GLint ref, GLuint mask)
{
__GL_SETUP_NOT_IN_BEGIN();
if ((func < GL_NEVER) || (func > GL_ALWAYS)) {
__glSetError(GL_INVALID_ENUM);
return;
}
if (ref < 0) ref = 0;
if (ref > __GL_MAX_STENCIL_VALUE) ref = __GL_MAX_STENCIL_VALUE;
if ((gc->state.stencil.testFunc != func) ||
(gc->state.stencil.reference != (GLshort) ref) ||
(gc->state.stencil.mask = (GLshort)(mask & __GL_MAX_STENCIL_VALUE))) {
gc->state.stencil.testFunc = func;
gc->state.stencil.reference = (GLshort) ref;
gc->state.stencil.mask = (GLshort) (mask & __GL_MAX_STENCIL_VALUE);
__GL_DELAY_VALIDATE(gc);
gc->validateMask |= __GL_VALIDATE_STENCIL_FUNC;
#ifdef _MCD_
MCD_STATE_DIRTY(gc, STENCILTEST);
#endif
}
}
void APIPRIVATE __glim_StencilOp(GLenum fail, GLenum depthFail, GLenum depthPass)
{
__GL_SETUP_NOT_IN_BEGIN();
switch (fail) {
case GL_KEEP: case GL_ZERO: case GL_REPLACE:
case GL_INCR: case GL_DECR: case GL_INVERT:
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
switch (depthFail) {
case GL_KEEP: case GL_ZERO: case GL_REPLACE:
case GL_INCR: case GL_DECR: case GL_INVERT:
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
switch (depthPass) {
case GL_KEEP: case GL_ZERO: case GL_REPLACE:
case GL_INCR: case GL_DECR: case GL_INVERT:
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
if ((gc->state.stencil.fail != fail) ||
(gc->state.stencil.depthFail != depthFail) ||
(gc->state.stencil.depthPass != depthPass) ) {
gc->state.stencil.fail = fail;
gc->state.stencil.depthFail = depthFail;
gc->state.stencil.depthPass = depthPass;
__GL_DELAY_VALIDATE(gc);
gc->validateMask |= __GL_VALIDATE_STENCIL_OP;
#ifdef _MCD_
MCD_STATE_DIRTY(gc, STENCILTEST);
#endif
}
}
/************************************************************************/
/*
** Copy context information from src to dst. Mark dst for validation
** when done.
*/
GLboolean FASTCALL __glCopyContext(__GLcontext *dst, const __GLcontext *src, GLuint mask)
{
const __GLattribute *sp;
GLboolean rv = GL_TRUE;
sp = &src->state;
if (dst == GLTEB_SRVCONTEXT()) {
return GL_FALSE;
}
/*
** In order for a context copy to be successful, the source
** and destination color scales must match. We make the
** destination context match the source context, since it isn't
** currently the current one, and will be automatically rescaled
** when it next made current.
**
*/
/* set the new destination context scale factors */
dst->frontBuffer.redScale = src->frontBuffer.redScale;
dst->frontBuffer.greenScale = src->frontBuffer.greenScale;
dst->frontBuffer.blueScale = src->frontBuffer.blueScale;
dst->frontBuffer.alphaScale = src->frontBuffer.alphaScale;
dst->redVertexScale = src->redVertexScale;
dst->greenVertexScale = src->greenVertexScale;
dst->blueVertexScale = src->blueVertexScale;
dst->alphaVertexScale = src->alphaVertexScale;
/* rescale the destination context with the new scale factors */
__glContextSetColorScales(dst);
if (mask & GL_ACCUM_BUFFER_BIT) {
dst->state.accum = sp->accum;
}
if (mask & GL_COLOR_BUFFER_BIT) {
dst->state.raster = sp->raster;
#ifdef NT
// A copy can occur from a double-buffered context to a single
// buffered context, leaving the drawBuffer in an invalid state
// Fix it up if necessary
if (dst->state.raster.drawBuffer == GL_BACK &&
!dst->modes.doubleBufferMode)
{
dst->state.raster.drawBuffer = GL_FRONT;
}
#endif
dst->state.enables.general &= ~__GL_COLOR_BUFFER_ENABLES;
dst->state.enables.general |=
sp->enables.general & __GL_COLOR_BUFFER_ENABLES;
dst->validateMask |= __GL_VALIDATE_ALPHA_FUNC; /*XXX*/
}
if (mask & GL_CURRENT_BIT) {
dst->state.current = sp->current;
}
if (mask & GL_DEPTH_BUFFER_BIT) {
dst->state.depth = sp->depth;
dst->state.enables.general &= ~__GL_DEPTH_TEST_ENABLE;
dst->state.enables.general |=
sp->enables.general & __GL_DEPTH_TEST_ENABLE;
__GL_DELAY_VALIDATE_MASK(dst, __GL_DIRTY_DEPTH);
}
if (mask & GL_ENABLE_BIT) {
dst->state.enables = sp->enables;
__GL_DELAY_VALIDATE_MASK(dst, __GL_DIRTY_LINE | __GL_DIRTY_POLYGON |
__GL_DIRTY_POINT | __GL_DIRTY_LIGHTING | __GL_DIRTY_DEPTH);
#ifdef NT
ComputeColorMaterialChange(dst);
#endif
(*dst->procs.pickColorMaterialProcs)(dst);
(*dst->procs.applyColor)(dst);
}
if (mask & GL_EVAL_BIT) {
dst->state.evaluator = sp->evaluator;
dst->state.enables.general &= ~__GL_AUTO_NORMAL_ENABLE;
dst->state.enables.general |=
sp->enables.general & __GL_AUTO_NORMAL_ENABLE;
dst->state.enables.eval1 = sp->enables.eval1;
dst->state.enables.eval2 = sp->enables.eval2;
}
if (mask & GL_FOG_BIT) {
dst->state.fog = sp->fog;
dst->state.enables.general &= ~__GL_FOG_ENABLE;
dst->state.enables.general |=
sp->enables.general & __GL_FOG_ENABLE;
#ifdef GL_WIN_specular_fog
dst->state.enables.general &= ~__GL_FOG_SPEC_TEX_ENABLE;
dst->state.enables.general |=
sp->enables.general & __GL_FOG_SPEC_TEX_ENABLE;
#endif //GL_WIN_specular_fog
}
if (mask & GL_HINT_BIT) {
dst->state.hints = sp->hints;
}
if (mask & GL_LIGHTING_BIT) {
dst->state.light.colorMaterialFace = sp->light.colorMaterialFace;
dst->state.light.colorMaterialParam = sp->light.colorMaterialParam;
dst->state.light.shadingModel = sp->light.shadingModel;
dst->state.light.model = sp->light.model;
dst->state.light.front = sp->light.front;
dst->state.light.back = sp->light.back;
dst->state.light.dirtyLights = (1 << dst->constants.numberOfLights)-1;
__GL_MEMCOPY(dst->state.light.source, sp->light.source,
dst->constants.numberOfLights
* sizeof(__GLlightSourceState));
dst->state.enables.general &= ~__GL_LIGHTING_ENABLES;
dst->state.enables.general |=
sp->enables.general & __GL_LIGHTING_ENABLES;
dst->state.enables.lights = sp->enables.lights;
__GL_DELAY_VALIDATE_MASK(dst, __GL_DIRTY_LIGHTING);
}
if (mask & GL_LINE_BIT) {
dst->state.line = sp->line;
dst->state.enables.general &= ~__GL_LINE_ENABLES;
dst->state.enables.general |=
sp->enables.general & __GL_LINE_ENABLES;
__GL_DELAY_VALIDATE_MASK(dst, __GL_DIRTY_LINE);
}
if (mask & GL_LIST_BIT) {
dst->state.list = sp->list;
}
if (mask & GL_PIXEL_MODE_BIT) {
dst->state.pixel.readBuffer = sp->pixel.readBuffer;
dst->state.pixel.readBufferReturn = sp->pixel.readBufferReturn;
dst->state.pixel.transferMode = sp->pixel.transferMode;
__GL_DELAY_VALIDATE_MASK(dst, __GL_DIRTY_PIXEL);
}
if (mask & GL_POINT_BIT) {
dst->state.point = sp->point;
dst->state.enables.general &= ~__GL_POINT_SMOOTH_ENABLE;
dst->state.enables.general |=
sp->enables.general & __GL_POINT_SMOOTH_ENABLE;
__GL_DELAY_VALIDATE_MASK(dst, __GL_DIRTY_POINT);
}
if (mask & GL_POLYGON_BIT) {
dst->state.polygon = sp->polygon;
dst->state.enables.general &= ~__GL_POLYGON_ENABLES;
dst->state.enables.general |=
sp->enables.general & __GL_POLYGON_ENABLES;
__GL_DELAY_VALIDATE_MASK(dst, __GL_DIRTY_POLYGON);
}
if (mask & GL_POLYGON_STIPPLE_BIT) {
dst->state.polygonStipple = sp->polygonStipple;
dst->state.enables.general &= ~__GL_POLYGON_STIPPLE_ENABLE;
dst->state.enables.general |=
sp->enables.general & __GL_POLYGON_STIPPLE_ENABLE;
__GL_DELAY_VALIDATE_MASK(dst, __GL_DIRTY_POLYGON |
__GL_DIRTY_POLYGON_STIPPLE);
}
if (mask & GL_SCISSOR_BIT) {
dst->state.scissor = sp->scissor;
dst->state.enables.general &= ~__GL_SCISSOR_TEST_ENABLE;
dst->state.enables.general |=
sp->enables.general & __GL_SCISSOR_TEST_ENABLE;
}
if (mask & GL_STENCIL_BUFFER_BIT) {
dst->state.stencil = sp->stencil;
dst->state.enables.general &= ~__GL_STENCIL_TEST_ENABLE;
dst->state.enables.general |=
sp->enables.general & __GL_STENCIL_TEST_ENABLE;
dst->validateMask |= __GL_VALIDATE_STENCIL_FUNC |
__GL_VALIDATE_STENCIL_OP; /*XXX*/
}
if (mask & GL_TEXTURE_BIT) {
dst->state.texture.s = sp->texture.s;
dst->state.texture.t = sp->texture.t;
dst->state.texture.r = sp->texture.r;
dst->state.texture.q = sp->texture.q;
__GL_MEMCOPY(dst->state.texture.texture, sp->texture.texture,
dst->constants.numberOfTextures
* sizeof(__GLperTextureState));
__GL_MEMCOPY(dst->state.texture.env, sp->texture.env,
dst->constants.numberOfTextureEnvs
* sizeof(__GLtextureEnvState));
dst->state.enables.general &= ~__GL_TEXTURE_ENABLES;
dst->state.enables.general |=
sp->enables.general & __GL_TEXTURE_ENABLES;
}
if (mask & GL_TRANSFORM_BIT) {
dst->state.transform.matrixMode = sp->transform.matrixMode;
#ifdef NT
if (sp->transform.eyeClipPlanes != NULL)
{
if (dst->state.transform.eyeClipPlanes != NULL)
{
__GL_MEMCOPY(dst->state.transform.eyeClipPlanes,
sp->transform.eyeClipPlanes,
dst->constants.numberOfClipPlanes *
sizeof(__GLcoord));
}
}
else
{
dst->state.transform.eyeClipPlanes = NULL;
}
#else
__GL_MEMCOPY(dst->state.transform.eyeClipPlanes,
sp->transform.eyeClipPlanes,
dst->constants.numberOfClipPlanes *
sizeof(__GLcoord));
#endif
dst->state.enables.general &= ~__GL_NORMALIZE_ENABLE;
dst->state.enables.general |=
sp->enables.general & __GL_NORMALIZE_ENABLE;
}
if (mask & GL_VIEWPORT_BIT) {
dst->state.viewport = sp->viewport;
__glUpdateViewportDependents(dst);
}
__glContextUnsetColorScales(dst);
__GL_DELAY_VALIDATE(dst);
#ifdef _MCD_
MCD_STATE_DIRTY(dst, ALL);
#endif
return rv;
}
/************************************************************************/
void APIPRIVATE __glim_PushAttrib(GLuint mask)
{
__GLattribute **spp;
__GLattribute *sp;
__GL_SETUP_NOT_IN_BEGIN();
spp = gc->attributes.stackPointer;
if (spp < &gc->attributes.stack[gc->constants.maxAttribStackDepth]) {
if (!(sp = *spp)) {
sp = (__GLattribute*)
GCALLOCZ(gc, sizeof(__GLattribute));
if (NULL == sp)
{
return;
}
*spp = sp;
}
sp->mask = mask;
sp->enables = gc->state.enables; /* Always save enables */
gc->attributes.stackPointer = spp + 1;
if (mask & GL_ACCUM_BUFFER_BIT) {
sp->accum = gc->state.accum;
}
if (mask & GL_COLOR_BUFFER_BIT) {
sp->raster = gc->state.raster;
}
if (mask & GL_CURRENT_BIT) {
sp->current = gc->state.current;
}
if (mask & GL_DEPTH_BUFFER_BIT) {
sp->depth = gc->state.depth;
}
if (mask & GL_EVAL_BIT) {
sp->evaluator = gc->state.evaluator;
}
if (mask & GL_FOG_BIT) {
sp->fog = gc->state.fog;
}
if (mask & GL_HINT_BIT) {
sp->hints = gc->state.hints;
}
if (mask & GL_LIGHTING_BIT) {
size_t bytes = (size_t)
(gc->constants.numberOfLights * sizeof(__GLlightSourceState));
sp->light.colorMaterialFace = gc->state.light.colorMaterialFace;
sp->light.colorMaterialParam = gc->state.light.colorMaterialParam;
sp->light.shadingModel = gc->state.light.shadingModel;
sp->light.model = gc->state.light.model;
sp->light.front = gc->state.light.front;
sp->light.back = gc->state.light.back;
sp->light.source = (__GLlightSourceState*)
GCALLOC(gc, bytes);
#ifdef NT
if (NULL == sp->light.source)
sp->mask &= ~GL_LIGHTING_BIT;
else
__GL_MEMCOPY(sp->light.source, gc->state.light.source, bytes);
#else
__GL_MEMCOPY(sp->light.source, gc->state.light.source, bytes);
#endif
}
if (mask & GL_LINE_BIT) {
sp->line = gc->state.line;
}
if (mask & GL_LIST_BIT) {
sp->list = gc->state.list;
}
if (mask & GL_PIXEL_MODE_BIT) {
sp->pixel.readBuffer = gc->state.pixel.readBuffer;
sp->pixel.readBufferReturn = gc->state.pixel.readBufferReturn;
sp->pixel.transferMode = gc->state.pixel.transferMode;
}
if (mask & GL_POINT_BIT) {
sp->point = gc->state.point;
}
if (mask & GL_POLYGON_BIT) {
sp->polygon = gc->state.polygon;
}
if (mask & GL_POLYGON_STIPPLE_BIT) {
sp->polygonStipple = gc->state.polygonStipple;
}
if (mask & GL_SCISSOR_BIT) {
sp->scissor = gc->state.scissor;
}
if (mask & GL_STENCIL_BUFFER_BIT) {
sp->stencil = gc->state.stencil;
}
if (mask & GL_TEXTURE_BIT) {
size_t texbytes = (size_t) (gc->constants.numberOfTextures
* sizeof(__GLperTextureState));
size_t envbytes = (size_t) (gc->constants.numberOfTextureEnvs
* sizeof(__GLtextureEnvState));
sp->texture.s = gc->state.texture.s;
sp->texture.t = gc->state.texture.t;
sp->texture.r = gc->state.texture.r;
sp->texture.q = gc->state.texture.q;
#ifdef NT
sp->texture.texture = (__GLperTextureState*)
GCALLOC(gc, texbytes);
sp->texture.env = (__GLtextureEnvState*)
GCALLOC(gc, envbytes);
if ((NULL == sp->texture.texture) || (NULL == sp->texture.env)) {
if (sp->texture.texture)
GCFREE(gc, sp->texture.texture);
sp->texture.texture = NULL;
if (sp->texture.env)
GCFREE(gc, sp->texture.env);
sp->texture.env = NULL;
sp->mask &= ~GL_TEXTURE_BIT;
} else {
__GL_MEMCOPY(sp->texture.texture, gc->state.texture.texture,
texbytes);
__GL_MEMCOPY(sp->texture.env, gc->state.texture.env, envbytes);
}
#else
sp->texture.texture = (__GLperTextureState*)
GCALLOC(gc, texbytes);
__GL_MEMCOPY(sp->texture.texture, gc->state.texture.texture,
texbytes);
sp->texture.env = (__GLtextureEnvState*)
GCALLOC(gc, envbytes);
__GL_MEMCOPY(sp->texture.env, gc->state.texture.env, envbytes);
#endif
}
if (mask & GL_TRANSFORM_BIT) {
size_t bytes = (size_t)
(gc->constants.numberOfClipPlanes * sizeof(__GLcoord));
sp->transform.matrixMode = gc->state.transform.matrixMode;
sp->transform.eyeClipPlanes = (__GLcoord*)
GCALLOC(gc, bytes);
#ifdef NT
if (NULL == sp->transform.eyeClipPlanes)
sp->mask &= ~GL_TRANSFORM_BIT;
else
__GL_MEMCOPY(sp->transform.eyeClipPlanes,
gc->state.transform.eyeClipPlanes, bytes);
#else
__GL_MEMCOPY(sp->transform.eyeClipPlanes,
gc->state.transform.eyeClipPlanes, bytes);
#endif
}
if (mask & GL_VIEWPORT_BIT) {
sp->viewport = gc->state.viewport;
}
} else {
__glSetError(GL_STACK_OVERFLOW);
return;
}
}
/************************************************************************/
GLuint FASTCALL __glInternalPopAttrib(__GLcontext *gc, GLboolean destroy)
{
__GLattribute **spp;
__GLattribute *sp;
GLuint mask;
GLuint dirtyMask = 0;
spp = gc->attributes.stackPointer;
if (spp > &gc->attributes.stack[0]) {
--spp;
sp = *spp;
ASSERTOPENGL(sp != NULL, "No attribute data to pop\n");
mask = sp->mask;
gc->attributes.stackPointer = spp;
if (mask & GL_ACCUM_BUFFER_BIT) {
gc->state.accum = sp->accum;
}
if (mask & GL_COLOR_BUFFER_BIT) {
gc->state.raster = sp->raster;
gc->state.enables.general &= ~__GL_COLOR_BUFFER_ENABLES;
gc->state.enables.general |=
sp->enables.general & __GL_COLOR_BUFFER_ENABLES;
gc->validateMask |= __GL_VALIDATE_ALPHA_FUNC; /*XXX*/
}
if (mask & GL_CURRENT_BIT) {
gc->state.current = sp->current;
}
if (mask & GL_DEPTH_BUFFER_BIT) {
gc->state.depth = sp->depth;
gc->state.enables.general &= ~__GL_DEPTH_TEST_ENABLE;
gc->state.enables.general |=
sp->enables.general & __GL_DEPTH_TEST_ENABLE;
dirtyMask |= __GL_DIRTY_DEPTH;
}
if (mask & GL_ENABLE_BIT) {
gc->state.enables = sp->enables;
dirtyMask |= (__GL_DIRTY_LINE | __GL_DIRTY_POLYGON |
__GL_DIRTY_POINT | __GL_DIRTY_LIGHTING | __GL_DIRTY_DEPTH);
#ifdef NT
ComputeColorMaterialChange(gc);
#endif
(*gc->procs.pickColorMaterialProcs)(gc);
(*gc->procs.applyColor)(gc);
#ifdef NT
if (!destroy)
{
// applyViewport does both
(*gc->procs.applyViewport)(gc);
}
#else
(*gc->procs.computeClipBox)(gc);
(*gc->procs.applyScissor)(gc);
#endif
}
if (mask & GL_EVAL_BIT) {
gc->state.evaluator = sp->evaluator;
gc->state.enables.general &= ~__GL_AUTO_NORMAL_ENABLE;
gc->state.enables.general |=
sp->enables.general & __GL_AUTO_NORMAL_ENABLE;
gc->state.enables.eval1 = sp->enables.eval1;
gc->state.enables.eval2 = sp->enables.eval2;
}
if (mask & GL_FOG_BIT) {
gc->state.fog = sp->fog;
gc->state.enables.general &= ~__GL_FOG_ENABLE;
gc->state.enables.general |=
sp->enables.general & __GL_FOG_ENABLE;
#ifdef GL_WIN_specular_fog
gc->state.enables.general &= ~__GL_FOG_SPEC_TEX_ENABLE;
gc->state.enables.general |=
sp->enables.general & __GL_FOG_SPEC_TEX_ENABLE;
#endif //GL_WIN_specular_fog
}
if (mask & GL_HINT_BIT) {
gc->state.hints = sp->hints;
}
if (mask & GL_LIGHTING_BIT) {
gc->state.light.colorMaterialFace = sp->light.colorMaterialFace;
gc->state.light.colorMaterialParam = sp->light.colorMaterialParam;
gc->state.light.shadingModel = sp->light.shadingModel;
gc->state.light.model = sp->light.model;
gc->state.light.front = sp->light.front;
gc->state.light.back = sp->light.back;
gc->state.light.dirtyLights =
(1 << gc->constants.numberOfLights)-1;
__GL_MEMCOPY(gc->state.light.source, sp->light.source,
gc->constants.numberOfLights
* sizeof(__GLlightSourceState));
GCFREE(gc, sp->light.source);
sp->light.source = 0;
gc->state.enables.general &= ~__GL_LIGHTING_ENABLES;
gc->state.enables.general |=
sp->enables.general & __GL_LIGHTING_ENABLES;
gc->state.enables.lights = sp->enables.lights;
dirtyMask |= __GL_DIRTY_LIGHTING;
}
if (mask & GL_LINE_BIT) {
gc->state.line = sp->line;
gc->state.enables.general &= ~__GL_LINE_ENABLES;
gc->state.enables.general |=
sp->enables.general & __GL_LINE_ENABLES;
dirtyMask |= __GL_DIRTY_LINE;
}
if (mask & GL_LIST_BIT) {
gc->state.list = sp->list;
}
if (mask & GL_PIXEL_MODE_BIT) {
gc->state.pixel.transferMode = sp->pixel.transferMode;
gc->state.pixel.readBufferReturn = sp->pixel.readBufferReturn;
gc->state.pixel.readBuffer = sp->pixel.readBuffer;
dirtyMask |= __GL_DIRTY_PIXEL;
}
if (mask & GL_POINT_BIT) {
gc->state.point = sp->point;
gc->state.enables.general &= ~__GL_POINT_SMOOTH_ENABLE;
gc->state.enables.general |=
sp->enables.general & __GL_POINT_SMOOTH_ENABLE;
dirtyMask |= __GL_DIRTY_POINT;
}
if (mask & GL_POLYGON_BIT) {
gc->state.polygon = sp->polygon;
gc->state.enables.general &= ~__GL_POLYGON_ENABLES;
gc->state.enables.general |=
sp->enables.general & __GL_POLYGON_ENABLES;
dirtyMask |= __GL_DIRTY_POLYGON;
}
if (mask & GL_POLYGON_STIPPLE_BIT) {
gc->state.polygonStipple = sp->polygonStipple;
gc->state.enables.general &= ~__GL_POLYGON_STIPPLE_ENABLE;
gc->state.enables.general |=
sp->enables.general & __GL_POLYGON_STIPPLE_ENABLE;
(*gc->procs.convertPolygonStipple)(gc);
dirtyMask |= __GL_DIRTY_POLYGON;
}
if (mask & GL_SCISSOR_BIT) {
gc->state.scissor = sp->scissor;
gc->state.enables.general &= ~__GL_SCISSOR_TEST_ENABLE;
gc->state.enables.general |=
sp->enables.general & __GL_SCISSOR_TEST_ENABLE;
#ifdef NT
if (!destroy)
{
// applyViewport does both
(*gc->procs.applyViewport)(gc);
}
#else
(*gc->procs.computeClipBox)(gc);
(*gc->procs.applyScissor)(gc);
#endif
}
if (mask & GL_STENCIL_BUFFER_BIT) {
gc->state.stencil = sp->stencil;
gc->state.enables.general &= ~__GL_STENCIL_TEST_ENABLE;
gc->state.enables.general |=
sp->enables.general & __GL_STENCIL_TEST_ENABLE;
gc->validateMask |= __GL_VALIDATE_STENCIL_FUNC |
__GL_VALIDATE_STENCIL_OP;/*XXX*/
}
if (mask & GL_TEXTURE_BIT) {
GLuint numTextures = gc->constants.numberOfTextures;
gc->state.texture.s = sp->texture.s;
gc->state.texture.t = sp->texture.t;
gc->state.texture.r = sp->texture.r;
gc->state.texture.q = sp->texture.q;
/*
** If the texture name is different, a new binding is
** called for. Deferring the binding is dangerous, because
** the state before the pop has to be saved with the
** texture that is being unbound. If we defer the binding,
** we need to watch out for cases like two pops in a row
** or a pop followed by a bind.
*/
{
GLuint targetIndex;
__GLperTextureState *pts, *spPts;
pts = gc->state.texture.texture;
spPts = sp->texture.texture;
for (targetIndex = 0; targetIndex < numTextures;
targetIndex++, pts++, spPts++) {
if (pts->texobjs.name != spPts->texobjs.name) {
__glBindTexture(gc, targetIndex,
spPts->texobjs.name, GL_TRUE);
}
}
}
__GL_MEMCOPY(gc->state.texture.texture, sp->texture.texture,
numTextures * sizeof(__GLperTextureState));
__GL_MEMCOPY(gc->state.texture.env, sp->texture.env,
gc->constants.numberOfTextureEnvs
* sizeof(__GLtextureEnvState));
GCFREE(gc, sp->texture.texture);
sp->texture.texture = 0;
GCFREE(gc, sp->texture.env);
sp->texture.env = 0;
gc->state.enables.general &= ~__GL_TEXTURE_ENABLES;
gc->state.enables.general |=
sp->enables.general & __GL_TEXTURE_ENABLES;
}
if (mask & GL_TRANSFORM_BIT) {
gc->state.transform.matrixMode = sp->transform.matrixMode;
__GL_MEMCOPY(gc->state.transform.eyeClipPlanes,
sp->transform.eyeClipPlanes,
gc->constants.numberOfClipPlanes * sizeof(__GLcoord));
GCFREE(gc, sp->transform.eyeClipPlanes);
sp->transform.eyeClipPlanes = 0;
gc->state.enables.general &= ~__GL_NORMALIZE_ENABLE;
gc->state.enables.general |=
sp->enables.general & __GL_NORMALIZE_ENABLE;
}
if (mask & GL_VIEWPORT_BIT) {
gc->state.viewport = sp->viewport;
__glUpdateViewportDependents(gc);
}
/*
** Clear out mask so that any memory frees done above won't get
** re-done when the context is destroyed
*/
sp->mask = 0;
dirtyMask |= __GL_DIRTY_GENERIC;
#ifdef _MCD_
MCD_STATE_DIRTY(gc, ALL);
#endif
} else {
__glSetError(GL_STACK_UNDERFLOW);
}
return dirtyMask;
}
void APIPRIVATE __glim_PopAttrib(void)
{
GLuint dirtyMask;
__GL_SETUP_NOT_IN_BEGIN();
dirtyMask = __glInternalPopAttrib(gc, GL_FALSE);
if (dirtyMask)
{
__GL_DELAY_VALIDATE_MASK(gc, dirtyMask);
}
}
/************************************************************************/
void APIPRIVATE __glim_Disable(GLenum cap)
{
GLuint frontChange, backChange;
__GL_SETUP_NOT_IN_BEGIN();
switch (cap) {
case GL_ALPHA_TEST:
if (!(gc->state.enables.general & __GL_ALPHA_TEST_ENABLE)) return;
gc->state.enables.general &= ~__GL_ALPHA_TEST_ENABLE;
break;
case GL_BLEND:
if (!(gc->state.enables.general & __GL_BLEND_ENABLE)) return;
gc->state.enables.general &= ~__GL_BLEND_ENABLE;
break;
case GL_COLOR_MATERIAL:
if (!(gc->state.enables.general & __GL_COLOR_MATERIAL_ENABLE)) return;
gc->state.enables.general &= ~__GL_COLOR_MATERIAL_ENABLE;
frontChange = gc->light.front.colorMaterialChange;
backChange = gc->light.back.colorMaterialChange;
ComputeColorMaterialChange(gc);
(*gc->procs.pickColorMaterialProcs)(gc);
__glValidateMaterial(gc, frontChange, backChange);
break;
case GL_CULL_FACE:
if (!(gc->state.enables.general & __GL_CULL_FACE_ENABLE)) return;
gc->state.enables.general &= ~__GL_CULL_FACE_ENABLE;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POLYGON);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, ENABLES);
#endif
return;
case GL_DEPTH_TEST:
if (!(gc->state.enables.general & __GL_DEPTH_TEST_ENABLE)) return;
gc->state.enables.general &= ~__GL_DEPTH_TEST_ENABLE;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_DEPTH);
break;
case GL_POLYGON_OFFSET_POINT:
if (!(gc->state.enables.general & __GL_POLYGON_OFFSET_POINT_ENABLE))
return;
gc->state.enables.general &= ~__GL_POLYGON_OFFSET_POINT_ENABLE;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POINT);
break;
case GL_POLYGON_OFFSET_LINE:
if (!(gc->state.enables.general & __GL_POLYGON_OFFSET_LINE_ENABLE))
return;
gc->state.enables.general &= ~__GL_POLYGON_OFFSET_LINE_ENABLE;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_LINE);
break;
case GL_POLYGON_OFFSET_FILL:
if (!(gc->state.enables.general & __GL_POLYGON_OFFSET_FILL_ENABLE))
return;
gc->state.enables.general &= ~__GL_POLYGON_OFFSET_FILL_ENABLE;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POLYGON);
break;
case GL_DITHER:
if (!(gc->state.enables.general & __GL_DITHER_ENABLE)) return;
gc->state.enables.general &= ~__GL_DITHER_ENABLE;
break;
#ifdef GL_WIN_specular_fog
case GL_FOG_SPECULAR_TEXTURE_WIN:
if (!(gc->state.enables.general & __GL_FOG_SPEC_TEX_ENABLE))
return;
gc->state.enables.general &= ~__GL_FOG_SPEC_TEX_ENABLE;
break;
#endif //GL_WIN_specular_fog
case GL_FOG:
if (!(gc->state.enables.general & __GL_FOG_ENABLE)) return;
gc->state.enables.general &= ~__GL_FOG_ENABLE;
break;
case GL_LIGHTING:
if (!(gc->state.enables.general & __GL_LIGHTING_ENABLE)) return;
gc->state.enables.general &= ~__GL_LIGHTING_ENABLE;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_LIGHTING);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, ENABLES);
#endif
#ifdef NT
ComputeColorMaterialChange(gc);
#endif
(*gc->procs.pickColorMaterialProcs)(gc);
(*gc->procs.applyColor)(gc);
return;
case GL_LINE_SMOOTH:
if (!(gc->state.enables.general & __GL_LINE_SMOOTH_ENABLE)) return;
gc->state.enables.general &= ~__GL_LINE_SMOOTH_ENABLE;
break;
case GL_LINE_STIPPLE:
if (!(gc->state.enables.general & __GL_LINE_STIPPLE_ENABLE)) return;
gc->state.enables.general &= ~__GL_LINE_STIPPLE_ENABLE;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_LINE);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, ENABLES);
#endif
return;
case GL_INDEX_LOGIC_OP:
if (!(gc->state.enables.general & __GL_INDEX_LOGIC_OP_ENABLE)) return;
gc->state.enables.general &= ~__GL_INDEX_LOGIC_OP_ENABLE;
break;
case GL_COLOR_LOGIC_OP:
if (!(gc->state.enables.general & __GL_COLOR_LOGIC_OP_ENABLE)) return;
gc->state.enables.general &= ~__GL_COLOR_LOGIC_OP_ENABLE;
break;
case GL_NORMALIZE:
if (!(gc->state.enables.general & __GL_NORMALIZE_ENABLE)) return;
gc->state.enables.general &= ~__GL_NORMALIZE_ENABLE;
break;
case GL_POINT_SMOOTH:
if (!(gc->state.enables.general & __GL_POINT_SMOOTH_ENABLE)) return;
gc->state.enables.general &= ~__GL_POINT_SMOOTH_ENABLE;
break;
case GL_POLYGON_SMOOTH:
if (!(gc->state.enables.general & __GL_POLYGON_SMOOTH_ENABLE)) return;
gc->state.enables.general &= ~__GL_POLYGON_SMOOTH_ENABLE;
break;
case GL_POLYGON_STIPPLE:
if (!(gc->state.enables.general & __GL_POLYGON_STIPPLE_ENABLE))
return;
gc->state.enables.general &= ~__GL_POLYGON_STIPPLE_ENABLE;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POLYGON);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, ENABLES);
#endif
return;
case GL_SCISSOR_TEST:
if (!(gc->state.enables.general & __GL_SCISSOR_TEST_ENABLE)) return;
gc->state.enables.general &= ~__GL_SCISSOR_TEST_ENABLE;
#ifdef NT
#ifdef _MCD_
MCD_STATE_DIRTY(gc, SCISSOR);
#endif
// applyViewport does both
(*gc->procs.applyViewport)(gc);
#else
(*gc->procs.computeClipBox)(gc);
(*gc->procs.applyScissor)(gc);
#endif
break;
case GL_STENCIL_TEST:
if (!(gc->state.enables.general & __GL_STENCIL_TEST_ENABLE)) return;
gc->state.enables.general &= ~__GL_STENCIL_TEST_ENABLE;
break;
case GL_TEXTURE_1D:
if (!(gc->state.enables.general & __GL_TEXTURE_1D_ENABLE)) return;
gc->state.enables.general &= ~__GL_TEXTURE_1D_ENABLE;
break;
case GL_TEXTURE_2D:
if (!(gc->state.enables.general & __GL_TEXTURE_2D_ENABLE)) return;
gc->state.enables.general &= ~__GL_TEXTURE_2D_ENABLE;
break;
case GL_AUTO_NORMAL:
if (!(gc->state.enables.general & __GL_AUTO_NORMAL_ENABLE)) return;
gc->state.enables.general &= ~__GL_AUTO_NORMAL_ENABLE;
break;
case GL_TEXTURE_GEN_S:
if (!(gc->state.enables.general & __GL_TEXTURE_GEN_S_ENABLE)) return;
gc->state.enables.general &= ~__GL_TEXTURE_GEN_S_ENABLE;
break;
case GL_TEXTURE_GEN_T:
if (!(gc->state.enables.general & __GL_TEXTURE_GEN_T_ENABLE)) return;
gc->state.enables.general &= ~__GL_TEXTURE_GEN_T_ENABLE;
break;
case GL_TEXTURE_GEN_R:
if (!(gc->state.enables.general & __GL_TEXTURE_GEN_R_ENABLE)) return;
gc->state.enables.general &= ~__GL_TEXTURE_GEN_R_ENABLE;
break;
case GL_TEXTURE_GEN_Q:
if (!(gc->state.enables.general & __GL_TEXTURE_GEN_Q_ENABLE)) return;
gc->state.enables.general &= ~__GL_TEXTURE_GEN_Q_ENABLE;
break;
#ifdef GL_WIN_multiple_textures
case GL_TEXCOMBINE_CLAMP_WIN:
if (!(gc->state.enables.general & __GL_TEXCOMBINE_CLAMP_ENABLE))
{
return;
}
gc->state.enables.general &= ~__GL_TEXCOMBINE_CLAMP_ENABLE;
break;
#endif // GL_WIN_multiple_textures
#ifdef GL_EXT_flat_paletted_lighting
case GL_PALETTED_LIGHTING_EXT:
gc->state.enables.general &= ~__GL_PALETTED_LIGHTING_ENABLE;
break;
#endif
case GL_CLIP_PLANE0: case GL_CLIP_PLANE1:
case GL_CLIP_PLANE2: case GL_CLIP_PLANE3:
case GL_CLIP_PLANE4: case GL_CLIP_PLANE5:
cap -= GL_CLIP_PLANE0;
if (!(gc->state.enables.clipPlanes & (1 << cap))) return;
gc->state.enables.clipPlanes &= ~(1 << cap);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, CLIPCTRL);
#endif
break;
case GL_LIGHT0: case GL_LIGHT1:
case GL_LIGHT2: case GL_LIGHT3:
case GL_LIGHT4: case GL_LIGHT5:
case GL_LIGHT6: case GL_LIGHT7:
cap -= GL_LIGHT0;
if (!(gc->state.enables.lights & (1 << cap))) return;
gc->state.enables.lights &= ~(1 << cap);
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_LIGHTING);
MCD_STATE_DIRTY(gc, LIGHTS);
return;
case GL_MAP1_COLOR_4:
case GL_MAP1_NORMAL:
case GL_MAP1_INDEX:
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:
cap = __GL_EVAL1D_INDEX(cap);
if (!(gc->state.enables.eval1 & (GLushort) ~(1 << cap))) return;
gc->state.enables.eval1 &= (GLushort) ~(1 << cap);
break;
case GL_MAP2_COLOR_4:
case GL_MAP2_NORMAL:
case GL_MAP2_INDEX:
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:
cap = __GL_EVAL2D_INDEX(cap);
if (!(gc->state.enables.eval2 & (GLushort) ~(1 << cap))) return;
gc->state.enables.eval2 &= (GLushort) ~(1 << cap);
break;
default:
__glSetError(GL_INVALID_ENUM);
return;
}
__GL_DELAY_VALIDATE(gc);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, ENABLES);
#endif
}
GLboolean APIPRIVATE __glim_IsEnabled(GLenum cap)
{
GLuint bit;
__GL_SETUP_NOT_IN_BEGIN2();
switch (cap) {
case GL_ALPHA_TEST:
bit = gc->state.enables.general & __GL_ALPHA_TEST_ENABLE;
break;
case GL_BLEND:
bit = gc->state.enables.general & __GL_BLEND_ENABLE;
break;
case GL_COLOR_MATERIAL:
bit = gc->state.enables.general & __GL_COLOR_MATERIAL_ENABLE;
break;
case GL_CULL_FACE:
bit = gc->state.enables.general & __GL_CULL_FACE_ENABLE;
break;
case GL_DEPTH_TEST:
bit = gc->state.enables.general & __GL_DEPTH_TEST_ENABLE;
break;
case GL_POLYGON_OFFSET_POINT:
bit = gc->state.enables.general & __GL_POLYGON_OFFSET_POINT_ENABLE;
break;
case GL_POLYGON_OFFSET_LINE:
bit = gc->state.enables.general & __GL_POLYGON_OFFSET_LINE_ENABLE;
break;
case GL_POLYGON_OFFSET_FILL:
bit = gc->state.enables.general & __GL_POLYGON_OFFSET_FILL_ENABLE;
break;
case GL_DITHER:
bit = gc->state.enables.general & __GL_DITHER_ENABLE;
break;
#ifdef GL_WIN_specular_fog
case GL_FOG_SPECULAR_TEXTURE_WIN:
bit = gc->state.enables.general & __GL_FOG_SPEC_TEX_ENABLE;
break;
#endif //GL_WIN_specular_fog
case GL_FOG:
bit = gc->state.enables.general & __GL_FOG_ENABLE;
break;
case GL_LIGHTING:
bit = gc->state.enables.general & __GL_LIGHTING_ENABLE;
break;
case GL_LINE_SMOOTH:
bit = gc->state.enables.general & __GL_LINE_SMOOTH_ENABLE;
break;
case GL_LINE_STIPPLE:
bit = gc->state.enables.general & __GL_LINE_STIPPLE_ENABLE;
break;
case GL_INDEX_LOGIC_OP:
bit = gc->state.enables.general & __GL_INDEX_LOGIC_OP_ENABLE;
break;
case GL_COLOR_LOGIC_OP:
bit = gc->state.enables.general & __GL_COLOR_LOGIC_OP_ENABLE;
break;
case GL_NORMALIZE:
bit = gc->state.enables.general & __GL_NORMALIZE_ENABLE;
break;
case GL_POINT_SMOOTH:
bit = gc->state.enables.general & __GL_POINT_SMOOTH_ENABLE;
break;
case GL_POLYGON_SMOOTH:
bit = gc->state.enables.general & __GL_POLYGON_SMOOTH_ENABLE;
break;
case GL_POLYGON_STIPPLE:
bit = gc->state.enables.general & __GL_POLYGON_STIPPLE_ENABLE;
break;
case GL_SCISSOR_TEST:
bit = gc->state.enables.general & __GL_SCISSOR_TEST_ENABLE;
break;
case GL_STENCIL_TEST:
bit = gc->state.enables.general & __GL_STENCIL_TEST_ENABLE;
break;
case GL_TEXTURE_1D:
bit = gc->state.enables.general & __GL_TEXTURE_1D_ENABLE;
break;
case GL_TEXTURE_2D:
bit = gc->state.enables.general & __GL_TEXTURE_2D_ENABLE;
break;
case GL_AUTO_NORMAL:
bit = gc->state.enables.general & __GL_AUTO_NORMAL_ENABLE;
break;
case GL_TEXTURE_GEN_S:
bit = gc->state.enables.general & __GL_TEXTURE_GEN_S_ENABLE;
break;
case GL_TEXTURE_GEN_T:
bit = gc->state.enables.general & __GL_TEXTURE_GEN_T_ENABLE;
break;
case GL_TEXTURE_GEN_R:
bit = gc->state.enables.general & __GL_TEXTURE_GEN_R_ENABLE;
break;
case GL_TEXTURE_GEN_Q:
bit = gc->state.enables.general & __GL_TEXTURE_GEN_Q_ENABLE;
break;
#ifdef GL_WIN_multiple_textures
case GL_TEXCOMBINE_CLAMP_WIN:
bit = gc->state.enables.general & __GL_TEXCOMBINE_CLAMP_ENABLE;
break;
#endif // GL_WIN_multiple_textures
#ifdef GL_EXT_flat_paletted_lighting
case GL_PALETTED_LIGHTING_EXT:
bit = gc->state.enables.general & __GL_PALETTED_LIGHTING_ENABLE;
break;
#endif // GL_EXT_flat_paletted_lighting
case GL_CLIP_PLANE0: case GL_CLIP_PLANE1:
case GL_CLIP_PLANE2: case GL_CLIP_PLANE3:
case GL_CLIP_PLANE4: case GL_CLIP_PLANE5:
cap -= GL_CLIP_PLANE0;
bit = gc->state.enables.clipPlanes & (1 << cap);
break;
case GL_LIGHT0: case GL_LIGHT1:
case GL_LIGHT2: case GL_LIGHT3:
case GL_LIGHT4: case GL_LIGHT5:
case GL_LIGHT6: case GL_LIGHT7:
cap -= GL_LIGHT0;
bit = gc->state.enables.lights & (1 << cap);
break;
case GL_MAP1_COLOR_4:
case GL_MAP1_NORMAL:
case GL_MAP1_INDEX:
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:
cap = __GL_EVAL1D_INDEX(cap);
bit = gc->state.enables.eval1 & (1 << cap);
break;
case GL_MAP2_COLOR_4:
case GL_MAP2_NORMAL:
case GL_MAP2_INDEX:
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:
cap = __GL_EVAL2D_INDEX(cap);
bit = gc->state.enables.eval2 & (1 << cap);
break;
case GL_VERTEX_ARRAY:
case GL_NORMAL_ARRAY:
case GL_COLOR_ARRAY:
case GL_INDEX_ARRAY:
case GL_TEXTURE_COORD_ARRAY:
case GL_EDGE_FLAG_ARRAY:
bit = gc->vertexArray.mask & vaEnable[cap - GL_VERTEX_ARRAY];
break;
default:
__glSetError(GL_INVALID_ENUM);
return GL_FALSE;
}
return bit != 0;
}
void APIPRIVATE __glim_PolygonOffset(GLfloat factor, GLfloat units)
{
__GL_SETUP_NOT_IN_BEGIN();
if (__GL_FLOAT_NE (gc->state.polygon.factor, factor) ||
__GL_FLOAT_NE (gc->state.polygon.units, units))
{
gc->state.polygon.factor = factor;
gc->state.polygon.units = units;
__GL_DELAY_VALIDATE_MASK(gc, __GL_DIRTY_POLYGON);
#ifdef _MCD_
MCD_STATE_DIRTY(gc, POLYDRAW);
#endif
}
}