state_lists.c revision 022e56bff837db399121bc76e4f404a6cd959d6e
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include <stdio.h>
#include "cr_mem.h"
#include "state.h"
#include "state/cr_statetypes.h"
#include "state_internals.h"
void crStateListsDestroy(CRContext *ctx)
{
/* nothing - dlists are in shared state */
}
void crStateListsInit(CRContext *ctx)
{
CRListsState *l = &ctx->lists;
CRStateBits *sb = GetCurrentBits();
CRListsBits *lb = &(sb->lists);
l->newEnd = GL_FALSE;
l->mode = 0;
l->currentIndex = 0;
l->base = 0;
RESET(lb->base, ctx->bitid);
RESET(lb->dirty, ctx->bitid);
}
//#define CRSTATE_DEBUG_QUERY_HW_STATE
#ifndef CRSTATE_DEBUG_QUERY_HW_STATE
# define CRSTATE_SET_CAP(state, value, format) g->state=value
# define CR_STATE_SETTEX_MSG(state, st, hw)
# define CR_STATE_SETMAT_MSG(state, st, hw)
#else
# define CRSTATE_SET_CAP(state, value, format) \
if (g->state!=value) { \
crDebug("crStateQueryHWState fixed %s from "format" to "format, #state, g->state, value); \
g->state=value; \
}
# define CR_STATE_SETTEX_MSG(state, st, hw) crDebug("crStateQueryHWState fixed %s from %i to %i", state, st, hw)
# define CR_STATE_SETMAT_MSG(state, st, hw) \
{ \
crDebug("crStateQueryHWState fixed %s", state); \
crDebug("st: [%f, %f, %f, %f] [%f, %f, %f, %f] [%f, %f, %f, %f] [%f, %f, %f, %f]", \
st[0], st[1], st[2], st[3], st[4], st[5], st[6], st[7], \
st[8], st[9], st[10], st[11], st[12], st[13], st[14], st[15]); \
crDebug("hw: [%f, %f, %f, %f] [%f, %f, %f, %f] [%f, %f, %f, %f] [%f, %f, %f, %f]", \
hw[0], hw[1], hw[2], hw[3], hw[4], hw[5], hw[6], hw[7], \
hw[8], hw[9], hw[10], hw[11], hw[12], hw[13], hw[14], hw[15]); \
}
#endif
#define CRSTATE_SET_ENABLED(state, cap) CRSTATE_SET_CAP(state, diff_api.IsEnabled(cap), "%u")
#define CRSTATE_SET_ENUM(state, cap) {GLenum _e=g->state; diff_api.GetIntegerv(cap, &_e); CRSTATE_SET_CAP(state, _e, "%#x");}
#define CRSTATE_SET_FLOAT(state, cap) {GLfloat _f=g->state; diff_api.GetFloatv(cap, &_f); CRSTATE_SET_CAP(state, _f, "%f");}
#define CRSTATE_SET_INT(state, cap) {GLint _i=g->state; diff_api.GetIntegerv(cap, &_i); CRSTATE_SET_CAP(state, _i, "%i");}
#define CRSTATE_SET_BOOL(state, cap) {GLboolean _b=g->state; diff_api.GetBooleanv(cap, &_b); CRSTATE_SET_CAP(state, _b, "%u");}
#define CRSTATE_SET_COLORF(state, cap) \
{ \
GLfloat value[4]; \
value[0]=g->state.r; \
value[1]=g->state.g; \
value[2]=g->state.b; \
value[3]=g->state.a; \
diff_api.GetFloatv(cap, &value[0]); \
CRSTATE_SET_CAP(state.r, value[0], "%f"); \
CRSTATE_SET_CAP(state.g, value[1], "%f"); \
CRSTATE_SET_CAP(state.b, value[2], "%f"); \
CRSTATE_SET_CAP(state.a, value[3], "%f"); \
}
#define CRSTATE_SET_TEXTURE(state, cap, target) \
{ \
GLint _stex, _hwtex; \
_stex = _hwtex = crStateGetTextureObjHWID(g->state); \
diff_api.GetIntegerv(cap, &_hwtex); \
if (_stex!=_hwtex) \
{ \
CR_STATE_SETTEX_MSG(#state, _stex, _hwtex); \
crStateBindTexture(target, crStateTextureHWIDtoID(_hwtex)); \
} \
}
#define _CRSTATE_SET_4F_RGBA(state, p1, p2, func) \
{ \
GLfloat value[4]; \
value[0]=g->state.r; \
value[1]=g->state.g; \
value[2]=g->state.b; \
value[3]=g->state.a; \
diff_api.func(p1, p2, &value[0]); \
CRSTATE_SET_CAP(state.r, value[0], "%f"); \
CRSTATE_SET_CAP(state.g, value[1], "%f"); \
CRSTATE_SET_CAP(state.b, value[2], "%f"); \
CRSTATE_SET_CAP(state.a, value[3], "%f"); \
}
#define _CRSTATE_SET_4F_XYZW(state, p1, p2, func) \
{ \
GLfloat value[4]; \
value[0]=g->state.x; \
value[1]=g->state.y; \
value[2]=g->state.z; \
value[3]=g->state.w; \
diff_api.func(p1, p2, &value[0]); \
CRSTATE_SET_CAP(state.x, value[0], "%f"); \
CRSTATE_SET_CAP(state.y, value[1], "%f"); \
CRSTATE_SET_CAP(state.z, value[2], "%f"); \
CRSTATE_SET_CAP(state.w, value[3], "%f"); \
}
#define CRSTATE_SET_TEXGEN_4F(state, coord, pname) _CRSTATE_SET_4F_XYZW(state, coord, pname, GetTexGenfv)
#define CRSTATE_SET_TEXGEN_I(state, coord, pname) {GLint _i=g->state; diff_api.GetTexGeniv(coord, pname, &_i); CRSTATE_SET_CAP(state, _i, "%i");}
#define CRSTATE_SET_TEXENV_I(state, target, pname) {GLint _i=g->state; diff_api.GetTexEnviv(target, pname, &_i); CRSTATE_SET_CAP(state, _i, "%i");}
#define CRSTATE_SET_TEXENV_F(state, target, pname) {GLfloat _f=g->state; diff_api.GetTexEnvfv(target, pname, &_f); CRSTATE_SET_CAP(state, _f, "%f");}
#define CRSTATE_SET_TEXENV_COLOR(state, target, pname) _CRSTATE_SET_4F_RGBA(state, target, pname, GetTexEnvfv)
#define CRSTATE_SET_MATERIAL_COLOR(state, face, pname) _CRSTATE_SET_4F_RGBA(state, face, pname, GetMaterialfv)
#define CRSTATE_SET_MATERIAL_F(state, face, pname) {GLfloat _f=g->state; diff_api.GetMaterialfv(face, pname, &_f); CRSTATE_SET_CAP(state, _f, "%f");}
#define CRSTATE_SET_LIGHT_COLOR(state, light, pname) _CRSTATE_SET_4F_RGBA(state, light, pname, GetLightfv)
#define CRSTATE_SET_LIGHT_F(state, light, pname) {GLfloat _f=g->state; diff_api.GetLightfv(light, pname, &_f); CRSTATE_SET_CAP(state, _f, "%f");}
#define CRSTATE_SET_LIGHT_4F(state, light, pname) _CRSTATE_SET_4F_XYZW(state, light, pname, GetLightfv)
#define CRSTATE_SET_LIGHT_3F(state, light, pname) \
{ \
GLfloat value[3]; \
value[0]=g->state.x; \
value[1]=g->state.y; \
value[2]=g->state.z; \
diff_api.GetLightfv(light, pname, &value[0]); \
CRSTATE_SET_CAP(state.x, value[0], "%f"); \
CRSTATE_SET_CAP(state.y, value[1], "%f"); \
CRSTATE_SET_CAP(state.z, value[2], "%f"); \
}
#define CRSTATE_SET_CLIPPLANE_4D(state, plane) \
{ \
GLdouble value[4]; \
value[0]=g->state.x; \
value[1]=g->state.y; \
value[2]=g->state.z; \
value[3]=g->state.w; \
diff_api.GetClipPlane(plane, &value[0]); \
CRSTATE_SET_CAP(state.x, value[0], "%G"); \
CRSTATE_SET_CAP(state.y, value[1], "%G"); \
CRSTATE_SET_CAP(state.z, value[2], "%G"); \
CRSTATE_SET_CAP(state.w, value[3], "%G"); \
}
#define CRSTATE_SET_MATRIX(state, cap) \
{ \
GLfloat f[16], sm[16]; \
crMatrixGetFloats(&f[0], g->state); \
crMemcpy(&sm[0], &f[0], 16*sizeof(GLfloat)); \
diff_api.GetFloatv(cap, &f[0]); \
if (crMemcmp(&f[0], &sm[0], 16*sizeof(GLfloat))) \
{ \
CR_STATE_SETMAT_MSG(#state, sm, f); \
crMatrixInitFromFloats(g->state, &f[0]); \
} \
}
void STATE_APIENTRY crStateQueryHWState(GLuint fbFbo, GLuint bbFbo)
{
CRContext *g = GetCurrentContext();
CRStateBits *sb = GetCurrentBits();
CRbitvalue *bitID=g->bitid, *negbitID=g->neg_bitid;
CRASSERT(g_bVBoxEnableDiffOnMakeCurrent);
if (CHECKDIRTY(sb->buffer.dirty, negbitID))
{
if (CHECKDIRTY(sb->buffer.enable, negbitID))
{
CRSTATE_SET_ENABLED(buffer.depthTest, GL_DEPTH_TEST);
CRSTATE_SET_ENABLED(buffer.blend, GL_BLEND);
CRSTATE_SET_ENABLED(buffer.alphaTest, GL_ALPHA_TEST);
CRSTATE_SET_ENABLED(buffer.logicOp, GL_COLOR_LOGIC_OP);
CRSTATE_SET_ENABLED(buffer.indexLogicOp, GL_INDEX_LOGIC_OP);
CRSTATE_SET_ENABLED(buffer.dither, GL_DITHER);
}
if (CHECKDIRTY(sb->buffer.alphaFunc, negbitID))
{
CRSTATE_SET_ENUM(buffer.alphaTestFunc, GL_ALPHA_TEST_FUNC);
CRSTATE_SET_FLOAT(buffer.alphaTestRef, GL_ALPHA_TEST_REF);
}
if (CHECKDIRTY(sb->buffer.depthFunc, negbitID))
{
CRSTATE_SET_ENUM(buffer.depthFunc, GL_DEPTH_FUNC);
}
if (CHECKDIRTY(sb->buffer.blendFunc, negbitID))
{
CRSTATE_SET_ENUM(buffer.blendSrcRGB, GL_BLEND_SRC);
CRSTATE_SET_ENUM(buffer.blendDstRGB, GL_BLEND_DST);
}
if (CHECKDIRTY(sb->buffer.logicOp, negbitID))
{
CRSTATE_SET_ENUM(buffer.logicOpMode, GL_LOGIC_OP_MODE);
}
/* seems to always match previous .logicOp
if (CHECKDIRTY(sb->buffer.indexLogicOp, negbitID))
{
CRSTATE_SET_ENUM(buffer.logicOpMode, GL_LOGIC_OP_MODE);
}
*/
if (CHECKDIRTY(sb->buffer.drawBuffer, negbitID))
{
GLuint buf = 0;
diff_api.GetIntegerv(GL_DRAW_BUFFER, &buf);
if (buf == GL_COLOR_ATTACHMENT0_EXT && (bbFbo || fbFbo))
{
GLuint binding = 0;
diff_api.GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &binding);
if (!binding)
{
crWarning("HW state synch: GL_DRAW_FRAMEBUFFER_BINDING is NULL");
}
if (bbFbo && binding == bbFbo)
{
g->buffer.drawBuffer = GL_BACK;
}
else if (fbFbo && binding == fbFbo)
{
g->buffer.drawBuffer = GL_FRONT;
}
else
{
g->buffer.drawBuffer = buf;
}
}
else
{
g->buffer.drawBuffer = buf;
}
}
if (CHECKDIRTY(sb->buffer.readBuffer, negbitID))
{
GLuint buf = 0;
diff_api.GetIntegerv(GL_READ_BUFFER, &buf);
if (buf == GL_COLOR_ATTACHMENT0_EXT && (bbFbo || fbFbo))
{
GLuint binding = 0;
diff_api.GetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &binding);
if (!binding)
{
crWarning("HW state synch: GL_READ_FRAMEBUFFER_BINDING is NULL");
}
if (bbFbo && binding == bbFbo)
{
g->buffer.readBuffer = GL_BACK;
}
else if (fbFbo && binding == fbFbo)
{
g->buffer.readBuffer = GL_FRONT;
}
else
{
g->buffer.readBuffer = buf;
}
}
else
{
g->buffer.readBuffer = buf;
}
}
if (CHECKDIRTY(sb->buffer.indexMask, negbitID))
{
CRSTATE_SET_INT(buffer.indexWriteMask, GL_INDEX_WRITEMASK);
}
if (CHECKDIRTY(sb->buffer.colorWriteMask, negbitID))
{
GLboolean value[4];
value[0]=g->buffer.colorWriteMask.r;
value[1]=g->buffer.colorWriteMask.g;
value[2]=g->buffer.colorWriteMask.b;
value[3]=g->buffer.colorWriteMask.a;
diff_api.GetBooleanv(GL_COLOR_WRITEMASK, &value[0]);
CRSTATE_SET_CAP(buffer.colorWriteMask.r, value[0], "%u");
CRSTATE_SET_CAP(buffer.colorWriteMask.g, value[1], "%u");
CRSTATE_SET_CAP(buffer.colorWriteMask.b, value[2], "%u");
CRSTATE_SET_CAP(buffer.colorWriteMask.a, value[3], "%u");
}
if (CHECKDIRTY(sb->buffer.clearColor, negbitID))
{
CRSTATE_SET_COLORF(buffer.colorClearValue, GL_COLOR_CLEAR_VALUE);
}
if (CHECKDIRTY(sb->buffer.clearIndex, negbitID))
{
CRSTATE_SET_FLOAT(buffer.indexClearValue, GL_INDEX_CLEAR_VALUE);
}
if (CHECKDIRTY(sb->buffer.clearDepth, negbitID))
{
CRSTATE_SET_FLOAT(buffer.depthClearValue, GL_DEPTH_CLEAR_VALUE);
}
if (CHECKDIRTY(sb->buffer.clearAccum, negbitID))
{
CRSTATE_SET_COLORF(buffer.accumClearValue, GL_ACCUM_CLEAR_VALUE);
}
if (CHECKDIRTY(sb->buffer.depthMask, negbitID))
{
CRSTATE_SET_BOOL(buffer.depthMask, GL_DEPTH_WRITEMASK);
}
#ifdef CR_EXT_blend_color
if (CHECKDIRTY(sb->buffer.blendColor, negbitID))
{
CRSTATE_SET_COLORF(buffer.blendColor, GL_BLEND_COLOR);
}
#endif
#if defined(CR_EXT_blend_minmax) || defined(CR_EXT_blend_subtract) || defined(CR_EXT_blend_logic_op)
if (CHECKDIRTY(sb->buffer.blendEquation, negbitID))
{
CRSTATE_SET_ENUM(buffer.blendEquation, GL_BLEND_EQUATION_EXT);
}
#endif
#if defined(CR_EXT_blend_func_separate)
if (CHECKDIRTY(sb->buffer.blendFuncSeparate, negbitID))
{
CRSTATE_SET_ENUM(buffer.blendSrcRGB, GL_BLEND_SRC_RGB_EXT);
CRSTATE_SET_ENUM(buffer.blendDstRGB, GL_BLEND_DST_RGB_EXT);
CRSTATE_SET_ENUM(buffer.blendSrcA, GL_BLEND_SRC_ALPHA_EXT);
CRSTATE_SET_ENUM(buffer.blendDstA, GL_BLEND_DST_ALPHA_EXT);
}
#endif
}
if (CHECKDIRTY(sb->stencil.dirty, negbitID))
{
GLenum activeFace;
GLboolean backIsSet = GL_FALSE, frontIsSet = GL_FALSE;
if (CHECKDIRTY(sb->stencil.enable, negbitID))
{
CRSTATE_SET_ENABLED(stencil.stencilTest, GL_STENCIL_TEST);
}
if (CHECKDIRTY(sb->stencil.enableTwoSideEXT, negbitID))
{
CRSTATE_SET_ENABLED(stencil.stencilTwoSideEXT, GL_STENCIL_TEST_TWO_SIDE_EXT);
}
if (CHECKDIRTY(sb->stencil.activeStencilFace, negbitID))
{
CRSTATE_SET_ENUM(stencil.activeStencilFace, GL_ACTIVE_STENCIL_FACE_EXT);
}
activeFace = g->stencil.activeStencilFace;
#define CRSTATE_SET_STENCIL_FUNC(_idx, _suff) do { \
CRSTATE_SET_ENUM(stencil.buffers[(_idx)].func, GL_STENCIL##_suff##FUNC); \
CRSTATE_SET_INT(stencil.buffers[(_idx)].ref, GL_STENCIL##_suff##REF); \
CRSTATE_SET_INT(stencil.buffers[(_idx)].mask, GL_STENCIL##_suff##VALUE_MASK); \
} while (0)
#define CRSTATE_SET_STENCIL_OP(_idx, _suff) do { \
CRSTATE_SET_ENUM(stencil.buffers[(_idx)].fail, GL_STENCIL##_suff##FAIL); \
CRSTATE_SET_ENUM(stencil.buffers[(_idx)].passDepthFail, GL_STENCIL##_suff##PASS_DEPTH_FAIL); \
CRSTATE_SET_ENUM(stencil.buffers[(_idx)].passDepthPass, GL_STENCIL##_suff##PASS_DEPTH_PASS); \
} while (0)
/* func */
if (CHECKDIRTY(sb->stencil.bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].func, negbitID))
{
/* this if branch is not needed here actually, just in case ogl drivers misbehave */
if (activeFace == GL_BACK)
{
diff_api.ActiveStencilFaceEXT(GL_FRONT);
activeFace = GL_FRONT;
}
CRSTATE_SET_STENCIL_FUNC(CRSTATE_STENCIL_BUFFER_ID_BACK, _BACK_);
backIsSet = GL_TRUE;
}
if (CHECKDIRTY(sb->stencil.bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].func, negbitID))
{
if (activeFace == GL_BACK)
{
diff_api.ActiveStencilFaceEXT(GL_FRONT);
activeFace = GL_FRONT;
}
CRSTATE_SET_STENCIL_FUNC(CRSTATE_STENCIL_BUFFER_ID_FRONT, _);
frontIsSet = GL_TRUE;
}
if ((!frontIsSet || !backIsSet) && CHECKDIRTY(sb->stencil.bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].func, negbitID))
{
if (activeFace == GL_BACK)
{
diff_api.ActiveStencilFaceEXT(GL_FRONT);
activeFace = GL_FRONT;
}
CRSTATE_SET_STENCIL_FUNC(CRSTATE_STENCIL_BUFFER_ID_FRONT, _);
if (!backIsSet)
{
g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].func = g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].func;
g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].ref = g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].ref;
g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].mask = g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].mask;
}
}
/* op */
backIsSet = GL_FALSE, frontIsSet = GL_FALSE;
if (CHECKDIRTY(sb->stencil.bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_BACK].op, negbitID))
{
/* this if branch is not needed here actually, just in case ogl drivers misbehave */
if (activeFace == GL_BACK)
{
diff_api.ActiveStencilFaceEXT(GL_FRONT);
activeFace = GL_FRONT;
}
CRSTATE_SET_STENCIL_OP(CRSTATE_STENCIL_BUFFER_ID_BACK, _BACK_);
backIsSet = GL_TRUE;
}
if (CHECKDIRTY(sb->stencil.bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT].op, negbitID))
{
if (activeFace == GL_BACK)
{
diff_api.ActiveStencilFaceEXT(GL_FRONT);
activeFace = GL_FRONT;
}
CRSTATE_SET_STENCIL_OP(CRSTATE_STENCIL_BUFFER_ID_FRONT, _);
frontIsSet = GL_TRUE;
}
if ((!frontIsSet || !backIsSet) && CHECKDIRTY(sb->stencil.bufferRefs[CRSTATE_STENCIL_BUFFER_REF_ID_FRONT_AND_BACK].op, negbitID))
{
if (activeFace == GL_BACK)
{
diff_api.ActiveStencilFaceEXT(GL_FRONT);
activeFace = GL_FRONT;
}
CRSTATE_SET_STENCIL_OP(CRSTATE_STENCIL_BUFFER_ID_FRONT, _);
if (!backIsSet)
{
g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].fail = g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].fail;
g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthFail = g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthFail;
g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_BACK].passDepthPass = g->stencil.buffers[CRSTATE_STENCIL_BUFFER_ID_FRONT].passDepthPass;
}
}
if (CHECKDIRTY(sb->stencil.clearValue, negbitID))
{
CRSTATE_SET_INT(stencil.clearValue, GL_STENCIL_CLEAR_VALUE);
}
if (CHECKDIRTY(sb->stencil.writeMask, negbitID))
{
CRSTATE_SET_INT(stencil.writeMask, GL_STENCIL_WRITEMASK);
}
}
if (CHECKDIRTY(sb->texture.dirty, negbitID))
{
unsigned int i, activeUnit = g->texture.curTextureUnit;
for (i=0; i<g->limits.maxTextureUnits; ++i)
{
if (CHECKDIRTY(sb->texture.enable[i], negbitID))
{
if (i!=activeUnit)
{
diff_api.ActiveTextureARB(i + GL_TEXTURE0_ARB);
activeUnit=i;
}
CRSTATE_SET_ENABLED(texture.unit[i].enabled1D, GL_TEXTURE_1D);
CRSTATE_SET_ENABLED(texture.unit[i].enabled2D, GL_TEXTURE_2D);
#ifdef CR_OPENGL_VERSION_1_2
CRSTATE_SET_ENABLED(texture.unit[i].enabled3D, GL_TEXTURE_3D);
#endif
#ifdef CR_ARB_texture_cube_map
if (g->extensions.ARB_texture_cube_map)
{
CRSTATE_SET_ENABLED(texture.unit[i].enabledCubeMap, GL_TEXTURE_CUBE_MAP_ARB);
}
#endif
#ifdef CR_NV_texture_rectangle
if (g->extensions.NV_texture_rectangle)
{
CRSTATE_SET_ENABLED(texture.unit[i].enabledRect, GL_TEXTURE_RECTANGLE_NV);
}
#endif
CRSTATE_SET_ENABLED(texture.unit[i].textureGen.s, GL_TEXTURE_GEN_S);
CRSTATE_SET_ENABLED(texture.unit[i].textureGen.t, GL_TEXTURE_GEN_T);
CRSTATE_SET_ENABLED(texture.unit[i].textureGen.r, GL_TEXTURE_GEN_R);
CRSTATE_SET_ENABLED(texture.unit[i].textureGen.q, GL_TEXTURE_GEN_Q);
}
if (CHECKDIRTY(sb->texture.current[i], negbitID))
{
if (i!=activeUnit)
{
diff_api.ActiveTextureARB(i + GL_TEXTURE0_ARB);
activeUnit=i;
}
CRSTATE_SET_TEXTURE(texture.unit[i].currentTexture1D, GL_TEXTURE_BINDING_1D, GL_TEXTURE_1D);
CRSTATE_SET_TEXTURE(texture.unit[i].currentTexture2D, GL_TEXTURE_BINDING_2D, GL_TEXTURE_2D);
#ifdef CR_OPENGL_VERSION_1_2
CRSTATE_SET_TEXTURE(texture.unit[i].currentTexture3D, GL_TEXTURE_BINDING_3D, GL_TEXTURE_3D);
#endif
#ifdef CR_ARB_texture_cube_map
if (g->extensions.ARB_texture_cube_map)
{
CRSTATE_SET_TEXTURE(texture.unit[i].currentTextureCubeMap, GL_TEXTURE_BINDING_CUBE_MAP_ARB, GL_TEXTURE_CUBE_MAP_ARB);
}
#endif
#ifdef CR_NV_texture_rectangle
if (g->extensions.NV_texture_rectangle)
{
CRSTATE_SET_TEXTURE(texture.unit[i].currentTextureRect, GL_TEXTURE_BINDING_RECTANGLE_NV, GL_TEXTURE_RECTANGLE_NV);
}
#endif
}
if (CHECKDIRTY(sb->texture.objGen[i], negbitID))
{
if (i!=activeUnit)
{
diff_api.ActiveTextureARB(i + GL_TEXTURE0_ARB);
activeUnit=i;
}
CRSTATE_SET_TEXGEN_4F(texture.unit[i].objSCoeff, GL_S, GL_OBJECT_PLANE);
CRSTATE_SET_TEXGEN_4F(texture.unit[i].objTCoeff, GL_T, GL_OBJECT_PLANE);
CRSTATE_SET_TEXGEN_4F(texture.unit[i].objRCoeff, GL_R, GL_OBJECT_PLANE);
CRSTATE_SET_TEXGEN_4F(texture.unit[i].objQCoeff, GL_Q, GL_OBJECT_PLANE);
}
if (CHECKDIRTY(sb->texture.eyeGen[i], negbitID))
{
if (i!=activeUnit)
{
diff_api.ActiveTextureARB(i + GL_TEXTURE0_ARB);
activeUnit=i;
}
CRSTATE_SET_TEXGEN_4F(texture.unit[i].eyeSCoeff, GL_S, GL_EYE_PLANE);
CRSTATE_SET_TEXGEN_4F(texture.unit[i].eyeTCoeff, GL_T, GL_EYE_PLANE);
CRSTATE_SET_TEXGEN_4F(texture.unit[i].eyeRCoeff, GL_R, GL_EYE_PLANE);
CRSTATE_SET_TEXGEN_4F(texture.unit[i].eyeQCoeff, GL_Q, GL_EYE_PLANE);
}
if (CHECKDIRTY(sb->texture.genMode[i], negbitID))
{
if (i!=activeUnit)
{
diff_api.ActiveTextureARB(i + GL_TEXTURE0_ARB);
activeUnit=i;
}
CRSTATE_SET_TEXGEN_I(texture.unit[i].gen.s, GL_S, GL_TEXTURE_GEN_MODE);
CRSTATE_SET_TEXGEN_I(texture.unit[i].gen.t, GL_T, GL_TEXTURE_GEN_MODE);
CRSTATE_SET_TEXGEN_I(texture.unit[i].gen.r, GL_R, GL_TEXTURE_GEN_MODE);
CRSTATE_SET_TEXGEN_I(texture.unit[i].gen.q, GL_Q, GL_TEXTURE_GEN_MODE);
}
if (CHECKDIRTY(sb->texture.envBit[i], negbitID))
{
if (i!=activeUnit)
{
diff_api.ActiveTextureARB(i + GL_TEXTURE0_ARB);
activeUnit=i;
}
CRSTATE_SET_TEXENV_I(texture.unit[i].envMode, GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE);
CRSTATE_SET_TEXENV_COLOR(texture.unit[i].envColor, GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineModeRGB, GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineModeA, GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineSourceRGB[0], GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineSourceRGB[1], GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineSourceRGB[2], GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineSourceA[0], GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineSourceA[1], GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineSourceA[2], GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineOperandRGB[0], GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineOperandRGB[1], GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineOperandRGB[2], GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineOperandA[0], GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineOperandA[1], GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB);
CRSTATE_SET_TEXENV_I(texture.unit[i].combineOperandA[2], GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB);
CRSTATE_SET_TEXENV_F(texture.unit[i].combineScaleRGB, GL_TEXTURE_ENV, GL_RGB_SCALE_ARB);
CRSTATE_SET_TEXENV_F(texture.unit[i].combineScaleA, GL_TEXTURE_ENV, GL_ALPHA_SCALE);
}
}
if (activeUnit!=g->texture.curTextureUnit)
{
diff_api.ActiveTextureARB(g->texture.curTextureUnit + GL_TEXTURE0_ARB);
}
}
if (CHECKDIRTY(sb->lighting.dirty, negbitID))
{
int i;
if (CHECKDIRTY(sb->lighting.enable, negbitID))
{
CRSTATE_SET_ENABLED(lighting.lighting, GL_LIGHTING);
CRSTATE_SET_ENABLED(lighting.colorMaterial, GL_COLOR_MATERIAL);
CRSTATE_SET_ENABLED(lighting.colorSumEXT, GL_COLOR_SUM_EXT);
}
if (CHECKDIRTY(sb->lighting.shadeModel, negbitID))
{
CRSTATE_SET_ENUM(lighting.shadeModel, GL_SHADE_MODEL);
}
if (CHECKDIRTY(sb->lighting.colorMaterial, negbitID))
{
CRSTATE_SET_ENUM(lighting.colorMaterialFace, GL_COLOR_MATERIAL_FACE);
CRSTATE_SET_ENUM(lighting.colorMaterialMode, GL_COLOR_MATERIAL_PARAMETER);
}
if (CHECKDIRTY(sb->lighting.lightModel, negbitID))
{
CRSTATE_SET_COLORF(lighting.lightModelAmbient, GL_LIGHT_MODEL_AMBIENT);
CRSTATE_SET_BOOL(lighting.lightModelLocalViewer, GL_LIGHT_MODEL_LOCAL_VIEWER);
CRSTATE_SET_BOOL(lighting.lightModelTwoSide, GL_LIGHT_MODEL_TWO_SIDE);
CRSTATE_SET_ENUM(lighting.lightModelColorControlEXT, GL_LIGHT_MODEL_COLOR_CONTROL);
}
if (CHECKDIRTY(sb->lighting.material, negbitID))
{
CRSTATE_SET_MATERIAL_COLOR(lighting.ambient[0], GL_FRONT, GL_AMBIENT);
CRSTATE_SET_MATERIAL_COLOR(lighting.ambient[1], GL_BACK, GL_AMBIENT);
CRSTATE_SET_MATERIAL_COLOR(lighting.diffuse[0], GL_FRONT, GL_DIFFUSE);
CRSTATE_SET_MATERIAL_COLOR(lighting.diffuse[1], GL_BACK, GL_DIFFUSE);
CRSTATE_SET_MATERIAL_COLOR(lighting.specular[0], GL_FRONT, GL_SPECULAR);
CRSTATE_SET_MATERIAL_COLOR(lighting.specular[1], GL_BACK, GL_SPECULAR);
CRSTATE_SET_MATERIAL_COLOR(lighting.emission[0], GL_FRONT, GL_EMISSION);
CRSTATE_SET_MATERIAL_COLOR(lighting.emission[1], GL_BACK, GL_EMISSION);
CRSTATE_SET_MATERIAL_F(lighting.shininess[0], GL_FRONT, GL_SHININESS);
CRSTATE_SET_MATERIAL_F(lighting.shininess[1], GL_BACK, GL_SHININESS);
}
for (i=0; i<CR_MAX_LIGHTS; ++i)
{
if (CHECKDIRTY(sb->lighting.light[i].dirty, negbitID))
{
if (CHECKDIRTY(sb->lighting.light[i].enable, negbitID))
{
CRSTATE_SET_ENABLED(lighting.light[i].enable, GL_LIGHT0+i);
}
if (CHECKDIRTY(sb->lighting.light[i].ambient, negbitID))
{
CRSTATE_SET_LIGHT_COLOR(lighting.light[i].ambient, GL_LIGHT0+i, GL_AMBIENT);
}
if (CHECKDIRTY(sb->lighting.light[i].diffuse, negbitID))
{
CRSTATE_SET_LIGHT_COLOR(lighting.light[i].diffuse, GL_LIGHT0+i, GL_DIFFUSE);
}
if (CHECKDIRTY(sb->lighting.light[i].specular, negbitID))
{
CRSTATE_SET_LIGHT_COLOR(lighting.light[i].specular, GL_LIGHT0+i, GL_SPECULAR);
}
if (CHECKDIRTY(sb->lighting.light[i].position, negbitID))
{
CRSTATE_SET_LIGHT_4F(lighting.light[i].position, GL_LIGHT0+i, GL_POSITION);
}
if (CHECKDIRTY(sb->lighting.light[i].attenuation, negbitID))
{
CRSTATE_SET_LIGHT_F(lighting.light[i].constantAttenuation, GL_LIGHT0+i, GL_CONSTANT_ATTENUATION);
CRSTATE_SET_LIGHT_F(lighting.light[i].linearAttenuation, GL_LIGHT0+i, GL_LINEAR_ATTENUATION);
CRSTATE_SET_LIGHT_F(lighting.light[i].quadraticAttenuation, GL_LIGHT0+i, GL_QUADRATIC_ATTENUATION);
}
if (CHECKDIRTY(sb->lighting.light[i].spot, negbitID))
{
CRSTATE_SET_LIGHT_3F(lighting.light[i].spotDirection, GL_LIGHT0+i, GL_SPOT_DIRECTION);
CRSTATE_SET_LIGHT_F(lighting.light[i].spotExponent, GL_LIGHT0+i, GL_SPOT_EXPONENT);
CRSTATE_SET_LIGHT_F(lighting.light[i].spotCutoff, GL_LIGHT0+i, GL_SPOT_CUTOFF);
}
}
}
}
if (CHECKDIRTY(sb->transform.dirty, negbitID))
{
if (CHECKDIRTY(sb->transform.enable, negbitID))
{
CRSTATE_SET_ENABLED(transform.normalize, GL_NORMALIZE);
#ifdef CR_OPENGL_VERSION_1_2
CRSTATE_SET_ENABLED(transform.rescaleNormals, GL_RESCALE_NORMAL);
#endif
#ifdef CR_IBM_rasterpos_clip
CRSTATE_SET_ENABLED(transform.rasterPositionUnclipped, GL_RASTER_POSITION_UNCLIPPED_IBM);
#endif
}
if (CHECKDIRTY(sb->transform.clipPlane, negbitID))
{
int i;
for (i=0; i<CR_MAX_CLIP_PLANES; i++)
{
CRSTATE_SET_CLIPPLANE_4D(transform.clipPlane[i], GL_CLIP_PLANE0+i);
}
}
if (CHECKDIRTY(sb->transform.modelviewMatrix, negbitID))
{
CRSTATE_SET_MATRIX(transform.modelViewStack.top, GL_MODELVIEW_MATRIX);
}
if (CHECKDIRTY(sb->transform.projectionMatrix, negbitID))
{
CRSTATE_SET_MATRIX(transform.projectionStack.top, GL_PROJECTION_MATRIX);
}
if (CHECKDIRTY(sb->transform.textureMatrix, negbitID))
{
unsigned int i;
for (i=0; i<g->limits.maxTextureUnits; i++)
{
diff_api.ActiveTextureARB(GL_TEXTURE0_ARB+i);
CRSTATE_SET_MATRIX(transform.textureStack[i].top, GL_TEXTURE_MATRIX);
}
diff_api.ActiveTextureARB(g->texture.curTextureUnit + GL_TEXTURE0_ARB);
}
if (CHECKDIRTY(sb->transform.colorMatrix, negbitID))
{
CRSTATE_SET_MATRIX(transform.colorStack.top, GL_COLOR_MATRIX);
}
if (CHECKDIRTY(sb->transform.matrixMode, negbitID))
{
CRSTATE_SET_ENUM(transform.matrixMode, GL_MATRIX_MODE);
}
}
if (CHECKDIRTY(sb->viewport.dirty, negbitID))
{
if (CHECKDIRTY(sb->viewport.enable, negbitID))
{
CRSTATE_SET_ENABLED(viewport.scissorTest, GL_SCISSOR_TEST);
}
if (CHECKDIRTY(sb->viewport.s_dims, negbitID))
{
GLint value[4];
value[0] = g->viewport.scissorX;
value[1] = g->viewport.scissorY;
value[2] = g->viewport.scissorW;
value[3] = g->viewport.scissorH;
diff_api.GetIntegerv(GL_SCISSOR_BOX, &value[0]);
CRSTATE_SET_CAP(viewport.scissorX, value[0], "%i");
CRSTATE_SET_CAP(viewport.scissorY, value[1], "%i");
CRSTATE_SET_CAP(viewport.scissorW, value[2], "%i");
CRSTATE_SET_CAP(viewport.scissorH, value[3], "%i");
}
if (CHECKDIRTY(sb->viewport.v_dims, negbitID))
{
GLint value[4];
value[0] = g->viewport.viewportX;
value[1] = g->viewport.viewportY;
value[2] = g->viewport.viewportW;
value[3] = g->viewport.viewportH;
diff_api.GetIntegerv(GL_VIEWPORT, &value[0]);
CRSTATE_SET_CAP(viewport.viewportX, value[0], "%i");
CRSTATE_SET_CAP(viewport.viewportY, value[1], "%i");
CRSTATE_SET_CAP(viewport.viewportW, value[2], "%i");
CRSTATE_SET_CAP(viewport.viewportH, value[3], "%i");
}
if (CHECKDIRTY(sb->viewport.depth, negbitID))
{
GLfloat value[2];
value[0] = g->viewport.nearClip;
value[1] = g->viewport.farClip;
diff_api.GetFloatv(GL_DEPTH_RANGE, &value[0]);
CRSTATE_SET_CAP(viewport.nearClip, value[0], "%f");
CRSTATE_SET_CAP(viewport.farClip, value[1], "%f");
}
}
if (CHECKDIRTY(sb->eval.dirty, negbitID))
{
int i;
const int gleval_sizes[] = {4, 1, 3, 1, 2, 3, 4, 3, 4};
if (CHECKDIRTY(sb->eval.enable, negbitID))
{
CRSTATE_SET_ENABLED(eval.autoNormal, GL_AUTO_NORMAL);
}
for (i=0; i<GLEVAL_TOT; i++)
{
if (CHECKDIRTY(sb->eval.enable1D[i], negbitID))
{
CRSTATE_SET_ENABLED(eval.enable1D[i], i + GL_MAP1_COLOR_4);
}
if (CHECKDIRTY(sb->eval.enable2D[i], negbitID))
{
CRSTATE_SET_ENABLED(eval.enable2D[i], i + GL_MAP2_COLOR_4);
}
if (CHECKDIRTY(sb->eval.eval1D[i], negbitID) && g->eval.enable1D[i])
{
GLfloat *coeffs=NULL;
GLint order;
GLfloat uval[2];
order = g->eval.eval1D[i].order;
uval[0] = g->eval.eval1D[i].u1;
uval[1] = g->eval.eval1D[i].u2;
diff_api.GetMapiv(i + GL_MAP1_COLOR_4, GL_ORDER, &order);
diff_api.GetMapfv(i + GL_MAP1_COLOR_4, GL_DOMAIN, &uval[0]);
if (order>0)
{
coeffs = crAlloc(order * gleval_sizes[i] * sizeof(GLfloat));
if (!coeffs)
{
crWarning("crStateQueryHWState: out of memory, at eval1D[%i]", i);
continue;
}
diff_api.GetMapfv(i + GL_MAP1_COLOR_4, GL_COEFF, coeffs);
}
CRSTATE_SET_CAP(eval.eval1D[i].order, order, "%i");
CRSTATE_SET_CAP(eval.eval1D[i].u1, uval[0], "%f");
CRSTATE_SET_CAP(eval.eval1D[i].u2, uval[1], "%f");
if (g->eval.eval1D[i].coeff)
{
crFree(g->eval.eval1D[i].coeff);
}
g->eval.eval1D[i].coeff = coeffs;
if (uval[0]!=uval[1])
{
g->eval.eval1D[i].du = 1.0f / (uval[0] - uval[1]);
}
}
if (CHECKDIRTY(sb->eval.eval2D[i], negbitID) && g->eval.enable2D[i])
{
GLfloat *coeffs=NULL;
GLint order[2];
GLfloat uval[4];
order[0] = g->eval.eval2D[i].uorder;
order[1] = g->eval.eval2D[i].vorder;
uval[0] = g->eval.eval2D[i].u1;
uval[1] = g->eval.eval2D[i].u2;
uval[2] = g->eval.eval2D[i].v1;
uval[3] = g->eval.eval2D[i].v2;
diff_api.GetMapiv(i + GL_MAP2_COLOR_4, GL_ORDER, &order[0]);
diff_api.GetMapfv(i + GL_MAP2_COLOR_4, GL_DOMAIN, &uval[0]);
if (order[0]>0 && order[1]>0)
{
coeffs = crAlloc(order[0] * order[1] * gleval_sizes[i] * sizeof(GLfloat));
if (!coeffs)
{
crWarning("crStateQueryHWState: out of memory, at eval2D[%i]", i);
continue;
}
diff_api.GetMapfv(i + GL_MAP1_COLOR_4, GL_COEFF, coeffs);
}
CRSTATE_SET_CAP(eval.eval2D[i].uorder, order[0], "%i");
CRSTATE_SET_CAP(eval.eval2D[i].vorder, order[1], "%i");
CRSTATE_SET_CAP(eval.eval2D[i].u1, uval[0], "%f");
CRSTATE_SET_CAP(eval.eval2D[i].u2, uval[1], "%f");
CRSTATE_SET_CAP(eval.eval2D[i].v1, uval[2], "%f");
CRSTATE_SET_CAP(eval.eval2D[i].v2, uval[3], "%f");
if (g->eval.eval2D[i].coeff)
{
crFree(g->eval.eval2D[i].coeff);
}
g->eval.eval2D[i].coeff = coeffs;
if (uval[0]!=uval[1])
{
g->eval.eval2D[i].du = 1.0f / (uval[0] - uval[1]);
}
if (uval[2]!=uval[3])
{
g->eval.eval2D[i].dv = 1.0f / (uval[2] - uval[3]);
}
}
}
if (CHECKDIRTY(sb->eval.grid1D, negbitID))
{
GLfloat value[2];
CRSTATE_SET_INT(eval.un1D, GL_MAP1_GRID_SEGMENTS);
value[0] = g->eval.u11D;
value[1] = g->eval.u21D;
diff_api.GetFloatv(GL_MAP1_GRID_DOMAIN, &value[0]);
CRSTATE_SET_CAP(eval.u11D, value[0], "%f");
CRSTATE_SET_CAP(eval.u21D, value[1], "%f");
}
if (CHECKDIRTY(sb->eval.grid2D, negbitID))
{
GLint iv[2];
GLfloat value[4];
iv[0] = g->eval.un2D;
iv[1] = g->eval.vn2D;
diff_api.GetIntegerv(GL_MAP1_GRID_SEGMENTS, &iv[0]);
CRSTATE_SET_CAP(eval.un2D, iv[0], "%i");
CRSTATE_SET_CAP(eval.vn2D, iv[1], "%i");
value[0] = g->eval.u12D;
value[1] = g->eval.u22D;
value[2] = g->eval.v12D;
value[3] = g->eval.v22D;
diff_api.GetFloatv(GL_MAP2_GRID_DOMAIN, &value[0]);
CRSTATE_SET_CAP(eval.u12D, value[0], "%f");
CRSTATE_SET_CAP(eval.u22D, value[1], "%f");
CRSTATE_SET_CAP(eval.v12D, value[2], "%f");
CRSTATE_SET_CAP(eval.v22D, value[3], "%f");
}
}
if (CHECKDIRTY(sb->fog.dirty, negbitID))
{
if (CHECKDIRTY(sb->fog.enable, negbitID))
{
CRSTATE_SET_ENABLED(fog.enable, GL_FOG);
}
if (CHECKDIRTY(sb->fog.color, negbitID))
{
CRSTATE_SET_COLORF(fog.color, GL_FOG_COLOR);
}
if (CHECKDIRTY(sb->fog.index, negbitID))
{
CRSTATE_SET_INT(fog.index, GL_FOG_INDEX);
}
if (CHECKDIRTY(sb->fog.density, negbitID))
{
CRSTATE_SET_FLOAT(fog.density, GL_FOG_DENSITY);
}
if (CHECKDIRTY(sb->fog.start, negbitID))
{
CRSTATE_SET_FLOAT(fog.start, GL_FOG_START);
}
if (CHECKDIRTY(sb->fog.end, negbitID))
{
CRSTATE_SET_FLOAT(fog.end, GL_FOG_END);
}
if (CHECKDIRTY(sb->fog.mode, negbitID))
{
CRSTATE_SET_INT(fog.mode, GL_FOG_MODE);
}
#ifdef CR_NV_fog_distance
if (CHECKDIRTY(sb->fog.fogDistanceMode, negbitID))
{
CRSTATE_SET_ENUM(fog.fogDistanceMode, GL_FOG_DISTANCE_MODE_NV);
}
#endif
#ifdef CR_EXT_fog_coord
if (CHECKDIRTY(sb->fog.fogCoordinateSource, negbitID))
{
CRSTATE_SET_ENUM(fog.fogCoordinateSource, GL_FOG_COORDINATE_SOURCE_EXT);
}
#endif
}
if (CHECKDIRTY(sb->hint.dirty, negbitID))
{
if (CHECKDIRTY(sb->hint.perspectiveCorrection, negbitID))
{
CRSTATE_SET_ENUM(hint.perspectiveCorrection, GL_PERSPECTIVE_CORRECTION_HINT);
}
if (CHECKDIRTY(sb->hint.pointSmooth, negbitID))
{
CRSTATE_SET_ENUM(hint.pointSmooth, GL_POINT_SMOOTH_HINT);
}
if (CHECKDIRTY(sb->hint.lineSmooth, negbitID))
{
CRSTATE_SET_ENUM(hint.lineSmooth, GL_LINE_SMOOTH_HINT);
}
if (CHECKDIRTY(sb->hint.polygonSmooth, negbitID))
{
CRSTATE_SET_ENUM(hint.polygonSmooth, GL_POINT_SMOOTH_HINT);
}
if (CHECKDIRTY(sb->hint.fog, negbitID))
{
CRSTATE_SET_ENUM(hint.fog, GL_FOG_HINT);
}
#ifdef CR_EXT_clip_volume_hint
if (CHECKDIRTY(sb->hint.clipVolumeClipping, negbitID))
{
CRSTATE_SET_ENUM(hint.clipVolumeClipping, GL_CLIP_VOLUME_CLIPPING_HINT_EXT);
}
#endif
#ifdef CR_ARB_texture_compression
if (CHECKDIRTY(sb->hint.textureCompression, negbitID))
{
CRSTATE_SET_ENUM(hint.textureCompression, GL_TEXTURE_COMPRESSION_HINT_ARB);
}
#endif
#ifdef CR_SGIS_generate_mipmap
if (CHECKDIRTY(sb->hint.generateMipmap, negbitID))
{
CRSTATE_SET_ENUM(hint.generateMipmap, GL_GENERATE_MIPMAP_HINT_SGIS);
}
#endif
}
if (CHECKDIRTY(sb->line.dirty, negbitID))
{
if (CHECKDIRTY(sb->line.enable, negbitID))
{
CRSTATE_SET_ENABLED(line.lineSmooth, GL_LINE_SMOOTH);
CRSTATE_SET_ENABLED(line.lineStipple, GL_LINE_STIPPLE);
}
if (CHECKDIRTY(sb->line.width, negbitID))
{
CRSTATE_SET_FLOAT(line.width, GL_LINE_WIDTH);
}
if (CHECKDIRTY(sb->line.stipple, negbitID))
{
CRSTATE_SET_INT(line.repeat, GL_LINE_STIPPLE_REPEAT);
CRSTATE_SET_INT(line.pattern, GL_LINE_STIPPLE_PATTERN);
}
}
if (CHECKDIRTY(sb->multisample.dirty, negbitID))
{
if (CHECKDIRTY(sb->multisample.enable, negbitID))
{
CRSTATE_SET_ENABLED(multisample.enabled, GL_MULTISAMPLE_ARB);
CRSTATE_SET_ENABLED(multisample.sampleAlphaToCoverage, GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
CRSTATE_SET_ENABLED(multisample.sampleAlphaToOne, GL_SAMPLE_ALPHA_TO_ONE_ARB);
CRSTATE_SET_ENABLED(multisample.sampleCoverage, GL_SAMPLE_COVERAGE_ARB);
}
if (CHECKDIRTY(sb->multisample.sampleCoverageValue, negbitID))
{
CRSTATE_SET_FLOAT(multisample.sampleCoverageValue, GL_SAMPLE_COVERAGE_VALUE_ARB)
CRSTATE_SET_BOOL(multisample.sampleCoverageInvert, GL_SAMPLE_COVERAGE_INVERT_ARB)
}
}
if (CHECKDIRTY(sb->point.dirty, negbitID))
{
if (CHECKDIRTY(sb->point.enableSmooth, negbitID))
{
CRSTATE_SET_ENABLED(point.pointSmooth, GL_POINT_SMOOTH);
}
if (CHECKDIRTY(sb->point.size, negbitID))
{
CRSTATE_SET_FLOAT(point.pointSize, GL_POINT_SIZE);
}
#ifdef CR_ARB_point_parameters
if (CHECKDIRTY(sb->point.minSize, negbitID))
{
CRSTATE_SET_FLOAT(point.minSize, GL_POINT_SIZE_MIN_ARB);
}
if (CHECKDIRTY(sb->point.maxSize, negbitID))
{
CRSTATE_SET_FLOAT(point.maxSize, GL_POINT_SIZE_MAX_ARB);
}
if (CHECKDIRTY(sb->point.fadeThresholdSize, negbitID))
{
CRSTATE_SET_FLOAT(point.fadeThresholdSize, GL_POINT_FADE_THRESHOLD_SIZE_ARB);
}
if (CHECKDIRTY(sb->point.distanceAttenuation, negbitID))
{
GLfloat value[3];
value[0] = g->point.distanceAttenuation[0];
value[1] = g->point.distanceAttenuation[1];
value[2] = g->point.distanceAttenuation[2];
diff_api.GetFloatv(GL_POINT_DISTANCE_ATTENUATION, &value[0]);
CRSTATE_SET_CAP(point.distanceAttenuation[0], value[0], "%f");
CRSTATE_SET_CAP(point.distanceAttenuation[1], value[1], "%f");
CRSTATE_SET_CAP(point.distanceAttenuation[2], value[2], "%f");
}
#endif
#ifdef CR_ARB_point_sprite
if (CHECKDIRTY(sb->point.enableSprite, negbitID))
{
CRSTATE_SET_ENABLED(point.pointSprite, GL_POINT_SPRITE_ARB);
}
{
unsigned int i, activeUnit = g->texture.curTextureUnit;
for (i=0; i<g->limits.maxTextureUnits; ++i)
{
if (CHECKDIRTY(sb->point.coordReplacement[i], negbitID))
{
GLint val=g->point.coordReplacement[i];
if (activeUnit!=i)
{
diff_api.ActiveTextureARB(i + GL_TEXTURE0_ARB);
activeUnit=i;
}
diff_api.GetTexEnviv(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, &val);
CRSTATE_SET_CAP(point.coordReplacement[i], val, "%i");
}
}
if (activeUnit!=g->texture.curTextureUnit)
{
diff_api.ActiveTextureARB(g->texture.curTextureUnit + GL_TEXTURE0_ARB);
}
}
#endif
}
if (CHECKDIRTY(sb->polygon.dirty, negbitID))
{
if (CHECKDIRTY(sb->polygon.enable, negbitID))
{
CRSTATE_SET_ENABLED(polygon.polygonSmooth, GL_POLYGON_SMOOTH);
CRSTATE_SET_ENABLED(polygon.polygonOffsetFill, GL_POLYGON_OFFSET_FILL);
CRSTATE_SET_ENABLED(polygon.polygonOffsetLine, GL_POLYGON_OFFSET_LINE);
CRSTATE_SET_ENABLED(polygon.polygonOffsetPoint, GL_POLYGON_OFFSET_POINT);
CRSTATE_SET_ENABLED(polygon.polygonStipple, GL_POLYGON_STIPPLE);
CRSTATE_SET_ENABLED(polygon.cullFace, GL_CULL_FACE);
}
if (CHECKDIRTY(sb->polygon.offset, negbitID))
{
CRSTATE_SET_FLOAT(polygon.offsetFactor, GL_POLYGON_OFFSET_FACTOR);
CRSTATE_SET_FLOAT(polygon.offsetUnits, GL_POLYGON_OFFSET_UNITS);
}
if (CHECKDIRTY(sb->polygon.mode, negbitID))
{
GLint val[2];
CRSTATE_SET_ENUM(polygon.frontFace, GL_FRONT_FACE);
CRSTATE_SET_ENUM(polygon.cullFaceMode, GL_CULL_FACE_MODE);
val[0] = g->polygon.frontMode;
val[1] = g->polygon.backMode;
diff_api.GetIntegerv(GL_POLYGON_MODE, &val[0]);
CRSTATE_SET_CAP(polygon.frontMode, val[0], "%#x");
CRSTATE_SET_CAP(polygon.backMode, val[1], "%#x");
}
if (CHECKDIRTY(sb->polygon.stipple, negbitID))
{
GLint stipple[32];
crMemcpy(&stipple[0], &g->polygon.stipple[0], sizeof(stipple));
diff_api.GetPolygonStipple((GLubyte*) &stipple[0]);
if (crMemcmp(&stipple[0], &g->polygon.stipple[0], sizeof(stipple)))
{
#ifdef CRSTATE_DEBUG_QUERY_HW_STATE
{
crDebug("crStateQueryHWState fixed polygon.stipple");
}
#endif
crMemcpy(&g->polygon.stipple[0], &stipple[0], sizeof(stipple));
}
}
}
}
void STATE_APIENTRY crStateNewList (GLuint list, GLenum mode)
{
CRContext *g = GetCurrentContext();
CRListsState *l = &(g->lists);
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glNewList called in Begin/End");
return;
}
if (list == 0)
{
crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glNewList(list=0)");
return;
}
if (l->currentIndex)
{
/* already building a list */
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glNewList called inside display list");
return;
}
if (mode != GL_COMPILE && mode != GL_COMPILE_AND_EXECUTE)
{
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glNewList invalid mode");
return;
}
FLUSH();
/* Must log that this key is used */
if (!crHashtableIsKeyUsed(g->shared->dlistTable, list)) {
crHashtableAdd(g->shared->dlistTable, list, NULL);
}
/* Need this???
crStateCurrentRecover();
*/
l->currentIndex = list;
l->mode = mode;
}
void STATE_APIENTRY crStateEndList (void)
{
CRContext *g = GetCurrentContext();
CRListsState *l = &(g->lists);
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glEndList called in Begin/End");
return;
}
if (!l->currentIndex)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glEndList called outside display list");
return;
}
l->currentIndex = 0;
l->mode = 0;
}
GLuint STATE_APIENTRY crStateGenLists(GLsizei range)
{
CRContext *g = GetCurrentContext();
GLuint start;
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glGenLists called in Begin/End");
return 0;
}
if (range < 0)
{
crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative range passed to glGenLists: %d", range);
return 0;
}
start = crHashtableAllocKeys(g->shared->dlistTable, range);
CRASSERT(start > 0);
return start;
}
void STATE_APIENTRY crStateDeleteLists (GLuint list, GLsizei range)
{
CRContext *g = GetCurrentContext();
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glDeleteLists called in Begin/End");
return;
}
if (range < 0)
{
crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative range passed to glDeleteLists: %d", range);
return;
}
crHashtableDeleteBlock(g->shared->dlistTable, list, range, crFree); /* call crFree to delete list data */
}
GLboolean STATE_APIENTRY crStateIsList(GLuint list)
{
CRContext *g = GetCurrentContext();
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
"GenLists called in Begin/End");
return GL_FALSE;
}
if (list == 0)
return GL_FALSE;
return crHashtableIsKeyUsed(g->shared->dlistTable, list);
}
void STATE_APIENTRY crStateListBase (GLuint base)
{
CRContext *g = GetCurrentContext();
CRListsState *l = &(g->lists);
CRStateBits *sb = GetCurrentBits();
CRListsBits *lb = &(sb->lists);
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
"ListBase called in Begin/End");
return;
}
l->base = base;
DIRTY(lb->base, g->neg_bitid);
DIRTY(lb->dirty, g->neg_bitid);
}
void
crStateListsDiff( CRListsBits *b, CRbitvalue *bitID,
CRContext *fromCtx, CRContext *toCtx )
{
CRListsState *from = &(fromCtx->lists);
CRListsState *to = &(toCtx->lists);
unsigned int j;
CRbitvalue nbitID[CR_MAX_BITARRAY];
for (j=0;j<CR_MAX_BITARRAY;j++)
nbitID[j] = ~bitID[j];
if (CHECKDIRTY(b->base, bitID))
{
if (from->base != to->base) {
diff_api.ListBase(to->base);
from->base = to->base;
}
CLEARDIRTY(b->base, nbitID);
}
CLEARDIRTY(b->dirty, nbitID);
}
void
crStateListsSwitch( CRListsBits *b, CRbitvalue *bitID,
CRContext *fromCtx, CRContext *toCtx )
{
CRListsState *from = &(fromCtx->lists);
CRListsState *to = &(toCtx->lists);
unsigned int j;
CRbitvalue nbitID[CR_MAX_BITARRAY];
for (j=0;j<CR_MAX_BITARRAY;j++)
nbitID[j] = ~bitID[j];
if (CHECKDIRTY(b->base, bitID))
{
if (from->base != to->base) {
diff_api.ListBase(to->base);
FILLDIRTY(b->base);
FILLDIRTY(b->dirty);
}
CLEARDIRTY(b->base, nbitID);
}
CLEARDIRTY(b->dirty, nbitID);
}