/* ** 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 #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 } }