2151 lines
61 KiB
C
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
|
|
}
|
|
}
|