state_enable.c revision 79664e45c3d7123821dcd5de01991c6de96b8794
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include <stdio.h>
#include "state.h"
#include "state/cr_statetypes.h"
#include "state_internals.h"
static void __enableSet (CRContext *g, CRStateBits *sb, CRbitvalue *neg_bitid,
GLenum cap, GLboolean val)
{
unsigned int i;
i = cap - GL_CLIP_PLANE0;
if (i < g->limits.maxClipPlanes) {
g->transform.clip[i] = val;
DIRTY(sb->transform.enable, neg_bitid);
DIRTY(sb->transform.dirty, neg_bitid);
return;
}
i = cap - GL_LIGHT0;
if (i < g->limits.maxLights) {
g->lighting.light[i].enable = val;
DIRTY(sb->lighting.light[i].dirty, neg_bitid);
DIRTY(sb->lighting.light[i].enable, neg_bitid);
DIRTY(sb->lighting.dirty, neg_bitid);
return;
}
switch (cap) {
case GL_AUTO_NORMAL:
g->eval.autoNormal = val;
DIRTY(sb->eval.enable, neg_bitid);
DIRTY(sb->eval.dirty, neg_bitid);
break;
case GL_ALPHA_TEST:
g->buffer.alphaTest = val;
DIRTY(sb->buffer.enable, neg_bitid);
DIRTY(sb->buffer.dirty, neg_bitid);
break;
case GL_BLEND:
g->buffer.blend = val;
DIRTY(sb->buffer.enable, neg_bitid);
DIRTY(sb->buffer.dirty, neg_bitid);
break;
case GL_COLOR_MATERIAL :
if (!val)
{
/* We're TURNING OFF color material. In this case,
* we should make sure that the very very latest
* color that was specified gets copied into the
* material parameters, since this might be our
* last chance (see frame 1 of progs/kirchner
* for an example of why). */
crStateCurrentRecover( );
crStateColorMaterialRecover( );
}
g->lighting.colorMaterial = val;
DIRTY(sb->lighting.enable, neg_bitid);
DIRTY(sb->lighting.dirty, neg_bitid);
break;
#ifdef CR_EXT_secondary_color
case GL_COLOR_SUM_EXT :
if (g->extensions.EXT_secondary_color) { /* XXX does EXT_separate_specular color support this enable, too? */
g->lighting.colorSumEXT = val;
DIRTY(sb->lighting.enable, neg_bitid);
DIRTY(sb->lighting.dirty, neg_bitid);
}
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEnable/glDisable(GL_COLOR_SUM_EXT) - No support for secondary color!");
return;
}
break;
#endif
case GL_CULL_FACE :
g->polygon.cullFace = val;
DIRTY(sb->polygon.enable, neg_bitid);
DIRTY(sb->polygon.dirty, neg_bitid);
break;
case GL_DEPTH_TEST :
g->buffer.depthTest = val;
DIRTY(sb->buffer.enable, neg_bitid);
DIRTY(sb->buffer.dirty, neg_bitid);
break;
case GL_DITHER :
g->buffer.dither = val;
DIRTY(sb->buffer.enable, neg_bitid);
DIRTY(sb->buffer.dirty, neg_bitid);
break;
case GL_FOG :
g->fog.enable = val;
DIRTY(sb->fog.enable, neg_bitid);
DIRTY(sb->fog.dirty, neg_bitid);
break;
case GL_LIGHTING :
g->lighting.lighting = val;
DIRTY(sb->lighting.enable, neg_bitid);
DIRTY(sb->lighting.dirty, neg_bitid);
break;
case GL_LINE_SMOOTH :
g->line.lineSmooth = val;
DIRTY(sb->line.enable, neg_bitid);
DIRTY(sb->line.dirty, neg_bitid);
break;
case GL_LINE_STIPPLE :
g->line.lineStipple = val;
DIRTY(sb->line.enable, neg_bitid);
DIRTY(sb->line.dirty, neg_bitid);
break;
case GL_COLOR_LOGIC_OP :
g->buffer.logicOp = val;
DIRTY(sb->buffer.enable, neg_bitid);
DIRTY(sb->buffer.dirty, neg_bitid);
break;
case GL_INDEX_LOGIC_OP :
g->buffer.indexLogicOp = val;
DIRTY(sb->buffer.enable, neg_bitid);
DIRTY(sb->buffer.dirty, neg_bitid);
break;
case GL_NORMALIZE :
g->transform.normalize = val;
DIRTY(sb->transform.enable, neg_bitid);
DIRTY(sb->transform.dirty, neg_bitid);
break;
case GL_POINT_SMOOTH :
g->point.pointSmooth = val;
DIRTY(sb->point.enableSmooth, neg_bitid);
DIRTY(sb->point.dirty, neg_bitid);
break;
case GL_POLYGON_OFFSET_FILL:
g->polygon.polygonOffsetFill = val;
DIRTY(sb->polygon.enable, neg_bitid);
DIRTY(sb->polygon.dirty, neg_bitid);
break;
case GL_POLYGON_OFFSET_LINE:
g->polygon.polygonOffsetLine = val;
DIRTY(sb->polygon.enable, neg_bitid);
DIRTY(sb->polygon.dirty, neg_bitid);
break;
case GL_POLYGON_OFFSET_POINT:
g->polygon.polygonOffsetPoint = val;
DIRTY(sb->polygon.enable, neg_bitid);
DIRTY(sb->polygon.dirty, neg_bitid);
break;
case GL_POLYGON_SMOOTH :
g->polygon.polygonSmooth = val;
DIRTY(sb->polygon.enable, neg_bitid);
DIRTY(sb->polygon.dirty, neg_bitid);
break;
case GL_POLYGON_STIPPLE :
g->polygon.polygonStipple = val;
DIRTY(sb->polygon.enable, neg_bitid);
DIRTY(sb->polygon.dirty, neg_bitid);
break;
#ifdef CR_NV_register_combiners
case GL_REGISTER_COMBINERS_NV :
if (g->extensions.NV_register_combiners) {
g->regcombiner.enabledRegCombiners = val;
DIRTY(sb->regcombiner.enable, neg_bitid);
DIRTY(sb->regcombiner.dirty, neg_bitid);
}
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEnable/glDisable(GL_REGISTER_COMBINERS_NV) - No support for NV_register_combiners");
return;
}
break;
#endif
#ifdef CR_NV_register_combiners2
case GL_PER_STAGE_CONSTANTS_NV :
if (g->extensions.NV_register_combiners2) {
g->regcombiner.enabledPerStageConstants = val;
DIRTY(sb->regcombiner.enable, neg_bitid);
DIRTY(sb->regcombiner.dirty, neg_bitid);
}
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEnable/glDisable(GL_PER_STAGE_CONSTANTS_NV) - No support for NV_register_combiners2");
return;
}
break;
#endif
#ifdef CR_NV_texture_rectangle
case GL_TEXTURE_RECTANGLE_NV:
if (g->extensions.NV_texture_rectangle) {
g->texture.unit[g->texture.curTextureUnit].enabledRect = val;
DIRTY(sb->texture.enable[g->texture.curTextureUnit], neg_bitid);
DIRTY(sb->texture.dirty, neg_bitid);
}
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEnable/glDisable(0x%x)", cap);
return;
}
break;
#endif /* CR_NV_texture_rectangle */
#ifdef CR_OPENGL_VERSION_1_2
case GL_RESCALE_NORMAL :
g->transform.rescaleNormals = val;
DIRTY(sb->transform.enable, neg_bitid);
DIRTY(sb->transform.dirty, neg_bitid);
break;
#endif
case GL_SCISSOR_TEST :
g->viewport.scissorTest = val;
DIRTY(sb->viewport.enable, neg_bitid);
DIRTY(sb->viewport.dirty, neg_bitid);
break;
case GL_STENCIL_TEST :
g->stencil.stencilTest= val;
DIRTY(sb->stencil.enable, neg_bitid);
DIRTY(sb->stencil.dirty, neg_bitid);
break;
case GL_TEXTURE_1D :
g->texture.unit[g->texture.curTextureUnit].enabled1D = val;
DIRTY(sb->texture.enable[g->texture.curTextureUnit], neg_bitid);
DIRTY(sb->texture.dirty, neg_bitid);
break;
case GL_TEXTURE_2D :
g->texture.unit[g->texture.curTextureUnit].enabled2D = val;
DIRTY(sb->texture.enable[g->texture.curTextureUnit], neg_bitid);
DIRTY(sb->texture.dirty, neg_bitid);
break;
#ifdef CR_OPENGL_VERSION_1_2
case GL_TEXTURE_3D :
g->texture.unit[g->texture.curTextureUnit].enabled3D = val;
DIRTY(sb->texture.enable[g->texture.curTextureUnit], neg_bitid);
DIRTY(sb->texture.dirty, neg_bitid);
break;
#endif
#ifdef CR_ARB_texture_cube_map
case GL_TEXTURE_CUBE_MAP_ARB:
if (g->extensions.ARB_texture_cube_map) {
g->texture.unit[g->texture.curTextureUnit].enabledCubeMap = val;
DIRTY(sb->texture.enable[g->texture.curTextureUnit], neg_bitid);
DIRTY(sb->texture.dirty, neg_bitid);
}
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEnable/glDisable(0x%x)", cap);
return;
}
break;
#endif /* CR_ARB_texture_cube_map */
case GL_TEXTURE_GEN_Q :
g->texture.unit[g->texture.curTextureUnit].textureGen.q = val;
DIRTY(sb->texture.enable[g->texture.curTextureUnit], neg_bitid);
DIRTY(sb->texture.dirty, neg_bitid);
break;
case GL_TEXTURE_GEN_R :
g->texture.unit[g->texture.curTextureUnit].textureGen.r = val;
DIRTY(sb->texture.enable[g->texture.curTextureUnit], neg_bitid);
DIRTY(sb->texture.dirty, neg_bitid);
break;
case GL_TEXTURE_GEN_S :
g->texture.unit[g->texture.curTextureUnit].textureGen.s = val;
DIRTY(sb->texture.enable[g->texture.curTextureUnit], neg_bitid);
DIRTY(sb->texture.dirty, neg_bitid);
break;
case GL_TEXTURE_GEN_T :
g->texture.unit[g->texture.curTextureUnit].textureGen.t = val;
DIRTY(sb->texture.enable[g->texture.curTextureUnit], neg_bitid);
DIRTY(sb->texture.dirty, neg_bitid);
break;
case GL_MAP1_COLOR_4 :
case GL_MAP1_INDEX :
case GL_MAP1_NORMAL :
case GL_MAP1_TEXTURE_COORD_1 :
case GL_MAP1_TEXTURE_COORD_2 :
case GL_MAP1_TEXTURE_COORD_3 :
case GL_MAP1_TEXTURE_COORD_4 :
case GL_MAP1_VERTEX_3 :
case GL_MAP1_VERTEX_4 :
if (g->texture.curTextureUnit != 0)
{
crStateError( __LINE__, __FILE__, GL_INVALID_OPERATION, "Map stuff was enabled while the current texture unit was not GL_TEXTURE0_ARB!" );
return;
}
g->eval.enable1D[cap - GL_MAP1_COLOR_4] = val;
DIRTY(sb->eval.enable1D[cap - GL_MAP1_COLOR_4], neg_bitid);
DIRTY(sb->eval.dirty, neg_bitid);
break;
case GL_MAP2_COLOR_4 :
case GL_MAP2_INDEX :
case GL_MAP2_NORMAL :
case GL_MAP2_TEXTURE_COORD_1 :
case GL_MAP2_TEXTURE_COORD_2 :
case GL_MAP2_TEXTURE_COORD_3 :
case GL_MAP2_TEXTURE_COORD_4 :
case GL_MAP2_VERTEX_3 :
case GL_MAP2_VERTEX_4 :
#if 0
if (g->texture.curTextureUnit != 0)
{
crStateError( __LINE__, __FILE__, GL_INVALID_OPERATION, "Map stuff was enabled while the current texture unit was not GL_TEXTURE0_ARB!" );
return;
}
#endif
g->eval.enable2D[cap - GL_MAP2_COLOR_4] = val;
DIRTY(sb->eval.enable2D[cap - GL_MAP2_COLOR_4], neg_bitid);
DIRTY(sb->eval.dirty, neg_bitid);
break;
#ifdef CR_ARB_multisample
case GL_MULTISAMPLE_ARB:
g->multisample.enabled = val;
DIRTY(sb->multisample.enable, neg_bitid);
DIRTY(sb->multisample.dirty, neg_bitid);
break;
case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
g->multisample.sampleAlphaToCoverage = val;
DIRTY(sb->multisample.sampleAlphaToCoverage, neg_bitid);
DIRTY(sb->multisample.dirty, neg_bitid);
break;
case GL_SAMPLE_ALPHA_TO_ONE_ARB:
g->multisample.sampleAlphaToOne = val;
DIRTY(sb->multisample.sampleAlphaToOne, neg_bitid);
DIRTY(sb->multisample.dirty, neg_bitid);
break;
case GL_SAMPLE_COVERAGE_ARB:
g->multisample.sampleCoverage = val;
DIRTY(sb->multisample.sampleCoverage, neg_bitid);
DIRTY(sb->multisample.dirty, neg_bitid);
break;
#endif
#ifdef CR_NV_vertex_program
case GL_VERTEX_PROGRAM_NV:
if (g->extensions.NV_vertex_program) {
g->program.vpEnabled = val;
DIRTY(sb->program.vpEnable, neg_bitid);
DIRTY(sb->program.dirty, neg_bitid);
}
else if (g->extensions.ARB_vertex_program) {
g->program.vpEnabled = val;
DIRTY(sb->program.vpEnable, neg_bitid);
DIRTY(sb->program.dirty, neg_bitid);
}
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEnable/glDisable(0x%x)", cap);
return;
}
break;
case GL_VERTEX_PROGRAM_POINT_SIZE_NV:
if (g->extensions.NV_vertex_program) {
g->program.vpPointSize = val;
DIRTY(sb->program.vpEnable, neg_bitid);
DIRTY(sb->program.dirty, neg_bitid);
}
else if (g->extensions.ARB_vertex_program) {
g->program.vpPointSize = val;
DIRTY(sb->program.vpEnable, neg_bitid);
DIRTY(sb->program.dirty, neg_bitid);
}
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEnable/glDisable(0x%x)", cap);
return;
}
break;
case GL_VERTEX_PROGRAM_TWO_SIDE_NV:
if (g->extensions.NV_vertex_program) {
g->program.vpTwoSide = val;
DIRTY(sb->program.vpEnable, neg_bitid);
DIRTY(sb->program.dirty, neg_bitid);
}
else if (g->extensions.ARB_vertex_program) {
g->program.vpTwoSide = val;
DIRTY(sb->program.vpEnable, neg_bitid);
DIRTY(sb->program.dirty, neg_bitid);
}
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEnable/glDisable(0x%x)", cap);
return;
}
break;
case GL_MAP1_VERTEX_ATTRIB0_4_NV:
case GL_MAP1_VERTEX_ATTRIB1_4_NV:
case GL_MAP1_VERTEX_ATTRIB2_4_NV:
case GL_MAP1_VERTEX_ATTRIB3_4_NV:
case GL_MAP1_VERTEX_ATTRIB4_4_NV:
case GL_MAP1_VERTEX_ATTRIB5_4_NV:
case GL_MAP1_VERTEX_ATTRIB6_4_NV:
case GL_MAP1_VERTEX_ATTRIB7_4_NV:
case GL_MAP1_VERTEX_ATTRIB8_4_NV:
case GL_MAP1_VERTEX_ATTRIB9_4_NV:
case GL_MAP1_VERTEX_ATTRIB10_4_NV:
case GL_MAP1_VERTEX_ATTRIB11_4_NV:
case GL_MAP1_VERTEX_ATTRIB12_4_NV:
case GL_MAP1_VERTEX_ATTRIB13_4_NV:
case GL_MAP1_VERTEX_ATTRIB14_4_NV:
case GL_MAP1_VERTEX_ATTRIB15_4_NV:
{
const GLint i = cap - GL_MAP1_VERTEX_ATTRIB0_4_NV;
g->eval.enableAttrib1D[i] = val;
DIRTY(sb->program.map1AttribArrayEnable[i], neg_bitid);
DIRTY(sb->program.dirty, neg_bitid);
}
break;
case GL_MAP2_VERTEX_ATTRIB0_4_NV:
case GL_MAP2_VERTEX_ATTRIB1_4_NV:
case GL_MAP2_VERTEX_ATTRIB2_4_NV:
case GL_MAP2_VERTEX_ATTRIB3_4_NV:
case GL_MAP2_VERTEX_ATTRIB4_4_NV:
case GL_MAP2_VERTEX_ATTRIB5_4_NV:
case GL_MAP2_VERTEX_ATTRIB6_4_NV:
case GL_MAP2_VERTEX_ATTRIB7_4_NV:
case GL_MAP2_VERTEX_ATTRIB8_4_NV:
case GL_MAP2_VERTEX_ATTRIB9_4_NV:
case GL_MAP2_VERTEX_ATTRIB10_4_NV:
case GL_MAP2_VERTEX_ATTRIB11_4_NV:
case GL_MAP2_VERTEX_ATTRIB12_4_NV:
case GL_MAP2_VERTEX_ATTRIB13_4_NV:
case GL_MAP2_VERTEX_ATTRIB14_4_NV:
case GL_MAP2_VERTEX_ATTRIB15_4_NV:
{
const GLint i = cap - GL_MAP2_VERTEX_ATTRIB0_4_NV;
g->eval.enableAttrib2D[i] = val;
DIRTY(sb->program.map2AttribArrayEnable[i], neg_bitid);
DIRTY(sb->program.dirty, neg_bitid);
}
break;
#endif
#ifdef CR_NV_fragment_program
case GL_FRAGMENT_PROGRAM_NV:
if (g->extensions.NV_fragment_program) {
g->program.fpEnabled = val;
DIRTY(sb->program.fpEnable, neg_bitid);
DIRTY(sb->program.dirty, neg_bitid);
}
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEnable/glDisable(0x%x)", cap);
return;
}
break;
#endif
#ifdef CR_ARB_fragment_program
case GL_FRAGMENT_PROGRAM_ARB:
if (g->extensions.ARB_fragment_program) {
g->program.fpEnabledARB = val;
DIRTY(sb->program.fpEnable, neg_bitid);
DIRTY(sb->program.dirty, neg_bitid);
}
else {
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEnable/glDisable(0x%x)", cap);
return;
}
break;
#endif
#ifdef CR_IBM_rasterpos_clip
case GL_RASTER_POSITION_UNCLIPPED_IBM:
g->transform.rasterPositionUnclipped = val;
DIRTY(sb->transform.enable, neg_bitid);
DIRTY(sb->transform.dirty, neg_bitid);
break;
#endif
#ifdef CR_ARB_point_sprite
case GL_POINT_SPRITE_ARB:
g->point.pointSprite = val;
DIRTY(sb->point.enableSprite, neg_bitid);
DIRTY(sb->point.dirty, neg_bitid);
break;
#endif
/* Client-side enables */
case GL_VERTEX_ARRAY:
case GL_COLOR_ARRAY:
case GL_NORMAL_ARRAY:
case GL_INDEX_ARRAY:
case GL_TEXTURE_COORD_ARRAY:
case GL_EDGE_FLAG_ARRAY:
#ifdef CR_EXT_fog_coord
case GL_FOG_COORDINATE_ARRAY_POINTER_EXT:
#endif
#ifdef CR_EXT_secondary_color
case GL_SECONDARY_COLOR_ARRAY_EXT:
#endif
#ifdef CR_NV_vertex_program
case GL_VERTEX_ATTRIB_ARRAY0_NV:
case GL_VERTEX_ATTRIB_ARRAY1_NV:
case GL_VERTEX_ATTRIB_ARRAY2_NV:
case GL_VERTEX_ATTRIB_ARRAY3_NV:
case GL_VERTEX_ATTRIB_ARRAY4_NV:
case GL_VERTEX_ATTRIB_ARRAY5_NV:
case GL_VERTEX_ATTRIB_ARRAY6_NV:
case GL_VERTEX_ATTRIB_ARRAY7_NV:
case GL_VERTEX_ATTRIB_ARRAY8_NV:
case GL_VERTEX_ATTRIB_ARRAY9_NV:
case GL_VERTEX_ATTRIB_ARRAY10_NV:
case GL_VERTEX_ATTRIB_ARRAY11_NV:
case GL_VERTEX_ATTRIB_ARRAY12_NV:
case GL_VERTEX_ATTRIB_ARRAY13_NV:
case GL_VERTEX_ATTRIB_ARRAY14_NV:
case GL_VERTEX_ATTRIB_ARRAY15_NV:
#endif
if (val)
crStateEnableClientState(cap);
else
crStateDisableClientState(cap);
break;
#ifdef CR_EXT_stencil_two_side
case GL_STENCIL_TEST_TWO_SIDE_EXT:
g->stencil.stencilTwoSideEXT= val;
DIRTY(sb->stencil.enableTwoSideEXT, neg_bitid);
DIRTY(sb->stencil.dirty, neg_bitid);
break;
#endif
default:
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glEnable/glDisable called with bogus cap: 0x%x", cap);
return;
}
}
void STATE_APIENTRY crStateEnable (GLenum cap)
{
CRContext *g = GetCurrentContext();
CRStateBits *sb = GetCurrentBits();
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glEnable called in begin/end");
return;
}
FLUSH();
__enableSet(g, sb, g->neg_bitid, cap, GL_TRUE);
}
void STATE_APIENTRY crStateDisable (GLenum cap)
{
CRContext *g = GetCurrentContext();
CRStateBits *sb = GetCurrentBits();
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glDisable called in begin/end");
return;
}
FLUSH();
__enableSet(g, sb, g->neg_bitid, cap, GL_FALSE);
}