void GLAPIENTRY _mesa_CullParameterfvEXT (GLenum cap, GLfloat *v) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); switch (cap) { case GL_CULL_VERTEX_EYE_POSITION_EXT: FLUSH_VERTICES(ctx, _NEW_TRANSFORM); COPY_4FV(ctx->Transform.CullEyePos, v); _mesa_transform_vector( ctx->Transform.CullObjPos, ctx->Transform.CullEyePos, ctx->ModelviewMatrixStack.Top->inv ); break; case GL_CULL_VERTEX_OBJECT_POSITION_EXT: FLUSH_VERTICES(ctx, _NEW_TRANSFORM); COPY_4FV(ctx->Transform.CullObjPos, v); _mesa_transform_vector( ctx->Transform.CullEyePos, ctx->Transform.CullObjPos, ctx->ModelviewMatrixStack.Top->m ); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glCullParameterfvEXT" ); } }
void GLAPIENTRY _mesa_ClipPlane( GLenum plane, const GLdouble *eq ) { GET_CURRENT_CONTEXT(ctx); GLint p; GLfloat equation[4]; ASSERT_OUTSIDE_BEGIN_END(ctx); p = (GLint) plane - (GLint) GL_CLIP_PLANE0; if (p < 0 || p >= (GLint) ctx->Const.MaxClipPlanes) { _mesa_error( ctx, GL_INVALID_ENUM, "glClipPlane" ); return; } equation[0] = (GLfloat) eq[0]; equation[1] = (GLfloat) eq[1]; equation[2] = (GLfloat) eq[2]; equation[3] = (GLfloat) eq[3]; /* * The equation is transformed by the transpose of the inverse of the * current modelview matrix and stored in the resulting eye coordinates. * * KW: Eqn is then transformed to the current clip space, where user * clipping now takes place. The clip-space equations are recalculated * whenever the projection matrix changes. */ if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); _mesa_transform_vector( equation, equation, ctx->ModelviewMatrixStack.Top->inv ); if (TEST_EQ_4V(ctx->Transform.EyeUserPlane[p], equation)) return; FLUSH_VERTICES(ctx, _NEW_TRANSFORM); COPY_4FV(ctx->Transform.EyeUserPlane[p], equation); /* Update derived state. This state also depends on the projection * matrix, and is recalculated on changes to the projection matrix by * code in _mesa_update_state(). */ if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top)) _math_matrix_analyse( ctx->ProjectionMatrixStack.Top ); _mesa_transform_vector( ctx->Transform._ClipUserPlane[p], ctx->Transform.EyeUserPlane[p], ctx->ProjectionMatrixStack.Top->inv ); } if (ctx->Driver.ClipPlane) ctx->Driver.ClipPlane( ctx, plane, equation ); }
/** * Update derived clip plane state. */ void _mesa_update_clip_plane(struct gl_context *ctx, GLuint plane) { if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top)) _math_matrix_analyse( ctx->ProjectionMatrixStack.Top ); /* Clip-Space Plane = Eye-Space Plane * Projection Matrix */ _mesa_transform_vector(ctx->Transform._ClipUserPlane[plane], ctx->Transform.EyeUserPlane[plane], ctx->ProjectionMatrixStack.Top->inv); }
/** * Update the projection matrix stack. * * \param ctx GL context. * * Calls _math_matrix_analyse() with the top-matrix of the projection matrix * stack, and recomputes user clip positions if necessary. * * \note This routine references __struct gl_contextRec::Tranform attribute * values to compute userclip positions in clip space, but is only called on * _NEW_PROJECTION. The _mesa_ClipPlane() function keeps these values up to * date across changes to the __struct gl_contextRec::Transform attributes. */ static void update_projection( struct gl_context *ctx ) { _math_matrix_analyse( ctx->ProjectionMatrixStack.Top ); /* Recompute clip plane positions in clipspace. This is also done * in _mesa_ClipPlane(). */ if (ctx->Transform.ClipPlanesEnabled) { GLuint p; for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { _mesa_transform_vector( ctx->Transform._ClipUserPlane[p], ctx->Transform.EyeUserPlane[p], ctx->ProjectionMatrixStack.Top->inv ); } } } }
/* NOTE: This routine references Tranform attribute values to compute * userclip positions in clip space, but is only called on * _NEW_PROJECTION. The _mesa_ClipPlane() function keeps these values * uptodate across changes to the Transform attributes. */ static void update_projection( GLcontext *ctx ) { _math_matrix_analyse( &ctx->ProjectionMatrix ); /* Recompute clip plane positions in clipspace. This is also done * in _mesa_ClipPlane(). */ if (ctx->Transform._AnyClip) { GLuint p; for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { if (ctx->Transform.ClipEnabled[p]) { _mesa_transform_vector( ctx->Transform._ClipUserPlane[p], ctx->Transform.EyeUserPlane[p], ctx->ProjectionMatrix.inv ); } } } }
/** * Helper function to enable or disable state. * * \param ctx GL context. * \param cap the state to enable/disable * \param state whether to enable or disable the specified capability. * * Updates the current context and flushes the vertices as needed. For * capabilities associated with extensions it verifies that those extensions * are effectivly present before updating. Notifies the driver via * dd_function_table::Enable. */ void _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state) { if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "%s %s (newstate is %x)\n", state ? "glEnable" : "glDisable", _mesa_lookup_enum_by_nr(cap), ctx->NewState); switch (cap) { case GL_ALPHA_TEST: if (ctx->Color.AlphaEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_COLOR); ctx->Color.AlphaEnabled = state; break; case GL_AUTO_NORMAL: if (ctx->Eval.AutoNormal == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.AutoNormal = state; break; case GL_BLEND: if (ctx->Color.BlendEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_COLOR); ctx->Color.BlendEnabled = state; break; #if FEATURE_userclip case GL_CLIP_PLANE0: case GL_CLIP_PLANE1: case GL_CLIP_PLANE2: case GL_CLIP_PLANE3: case GL_CLIP_PLANE4: case GL_CLIP_PLANE5: { const GLuint p = cap - GL_CLIP_PLANE0; if ((ctx->Transform.ClipPlanesEnabled & (1 << p)) == ((GLuint) state << p)) return; FLUSH_VERTICES(ctx, _NEW_TRANSFORM); if (state) { ctx->Transform.ClipPlanesEnabled |= (1 << p); if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top)) _math_matrix_analyse( ctx->ProjectionMatrixStack.Top ); /* This derived state also calculated in clip.c and * from _mesa_update_state() on changes to EyeUserPlane * and ctx->ProjectionMatrix respectively. */ _mesa_transform_vector( ctx->Transform._ClipUserPlane[p], ctx->Transform.EyeUserPlane[p], ctx->ProjectionMatrixStack.Top->inv ); } else { ctx->Transform.ClipPlanesEnabled &= ~(1 << p); } } break; #endif case GL_COLOR_MATERIAL: if (ctx->Light.ColorMaterialEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); FLUSH_CURRENT(ctx, 0); ctx->Light.ColorMaterialEnabled = state; if (state) { _mesa_update_color_material( ctx, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] ); } break; case GL_CULL_FACE: if (ctx->Polygon.CullFlag == state) return; FLUSH_VERTICES(ctx, _NEW_POLYGON); ctx->Polygon.CullFlag = state; break; case GL_CULL_VERTEX_EXT: CHECK_EXTENSION(EXT_cull_vertex, cap); if (ctx->Transform.CullVertexFlag == state) return; FLUSH_VERTICES(ctx, _NEW_TRANSFORM); ctx->Transform.CullVertexFlag = state; break; case GL_DEPTH_TEST: if (ctx->Depth.Test == state) return; FLUSH_VERTICES(ctx, _NEW_DEPTH); ctx->Depth.Test = state; break; case GL_DITHER: if (ctx->NoDither) { state = GL_FALSE; /* MESA_NO_DITHER env var */ } if (ctx->Color.DitherFlag == state) return; FLUSH_VERTICES(ctx, _NEW_COLOR); ctx->Color.DitherFlag = state; break; case GL_FOG: if (ctx->Fog.Enabled == state) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.Enabled = state; break; case GL_HISTOGRAM: CHECK_EXTENSION(EXT_histogram, cap); if (ctx->Pixel.HistogramEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_PIXEL); ctx->Pixel.HistogramEnabled = state; 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: if (ctx->Light.Light[cap-GL_LIGHT0].Enabled == state) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.Light[cap-GL_LIGHT0].Enabled = state; if (state) { insert_at_tail(&ctx->Light.EnabledList, &ctx->Light.Light[cap-GL_LIGHT0]); } else { remove_from_list(&ctx->Light.Light[cap-GL_LIGHT0]); } break; case GL_LIGHTING: if (ctx->Light.Enabled == state) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.Enabled = state; if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; else ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE; break; case GL_LINE_SMOOTH: if (ctx->Line.SmoothFlag == state) return; FLUSH_VERTICES(ctx, _NEW_LINE); ctx->Line.SmoothFlag = state; ctx->_TriangleCaps ^= DD_LINE_SMOOTH; break; case GL_LINE_STIPPLE: if (ctx->Line.StippleFlag == state) return; FLUSH_VERTICES(ctx, _NEW_LINE); ctx->Line.StippleFlag = state; ctx->_TriangleCaps ^= DD_LINE_STIPPLE; break; case GL_INDEX_LOGIC_OP: if (ctx->Color.IndexLogicOpEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_COLOR); ctx->Color.IndexLogicOpEnabled = state; break; case GL_COLOR_LOGIC_OP: if (ctx->Color.ColorLogicOpEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_COLOR); ctx->Color.ColorLogicOpEnabled = state; break; case GL_MAP1_COLOR_4: if (ctx->Eval.Map1Color4 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map1Color4 = state; break; case GL_MAP1_INDEX: if (ctx->Eval.Map1Index == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map1Index = state; break; case GL_MAP1_NORMAL: if (ctx->Eval.Map1Normal == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map1Normal = state; break; case GL_MAP1_TEXTURE_COORD_1: if (ctx->Eval.Map1TextureCoord1 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map1TextureCoord1 = state; break; case GL_MAP1_TEXTURE_COORD_2: if (ctx->Eval.Map1TextureCoord2 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map1TextureCoord2 = state; break; case GL_MAP1_TEXTURE_COORD_3: if (ctx->Eval.Map1TextureCoord3 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map1TextureCoord3 = state; break; case GL_MAP1_TEXTURE_COORD_4: if (ctx->Eval.Map1TextureCoord4 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map1TextureCoord4 = state; break; case GL_MAP1_VERTEX_3: if (ctx->Eval.Map1Vertex3 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map1Vertex3 = state; break; case GL_MAP1_VERTEX_4: if (ctx->Eval.Map1Vertex4 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map1Vertex4 = state; break; case GL_MAP2_COLOR_4: if (ctx->Eval.Map2Color4 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map2Color4 = state; break; case GL_MAP2_INDEX: if (ctx->Eval.Map2Index == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map2Index = state; break; case GL_MAP2_NORMAL: if (ctx->Eval.Map2Normal == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map2Normal = state; break; case GL_MAP2_TEXTURE_COORD_1: if (ctx->Eval.Map2TextureCoord1 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map2TextureCoord1 = state; break; case GL_MAP2_TEXTURE_COORD_2: if (ctx->Eval.Map2TextureCoord2 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map2TextureCoord2 = state; break; case GL_MAP2_TEXTURE_COORD_3: if (ctx->Eval.Map2TextureCoord3 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map2TextureCoord3 = state; break; case GL_MAP2_TEXTURE_COORD_4: if (ctx->Eval.Map2TextureCoord4 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map2TextureCoord4 = state; break; case GL_MAP2_VERTEX_3: if (ctx->Eval.Map2Vertex3 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map2Vertex3 = state; break; case GL_MAP2_VERTEX_4: if (ctx->Eval.Map2Vertex4 == state) return; FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map2Vertex4 = state; break; case GL_MINMAX: if (ctx->Pixel.MinMaxEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_PIXEL); ctx->Pixel.MinMaxEnabled = state; break; case GL_NORMALIZE: if (ctx->Transform.Normalize == state) return; FLUSH_VERTICES(ctx, _NEW_TRANSFORM); ctx->Transform.Normalize = state; break; case GL_POINT_SMOOTH: if (ctx->Point.SmoothFlag == state) return; FLUSH_VERTICES(ctx, _NEW_POINT); ctx->Point.SmoothFlag = state; ctx->_TriangleCaps ^= DD_POINT_SMOOTH; break; case GL_POLYGON_SMOOTH: if (ctx->Polygon.SmoothFlag == state) return; FLUSH_VERTICES(ctx, _NEW_POLYGON); ctx->Polygon.SmoothFlag = state; ctx->_TriangleCaps ^= DD_TRI_SMOOTH; break; case GL_POLYGON_STIPPLE: if (ctx->Polygon.StippleFlag == state) return; FLUSH_VERTICES(ctx, _NEW_POLYGON); ctx->Polygon.StippleFlag = state; ctx->_TriangleCaps ^= DD_TRI_STIPPLE; break; case GL_POLYGON_OFFSET_POINT: if (ctx->Polygon.OffsetPoint == state) return; FLUSH_VERTICES(ctx, _NEW_POLYGON); ctx->Polygon.OffsetPoint = state; break; case GL_POLYGON_OFFSET_LINE: if (ctx->Polygon.OffsetLine == state) return; FLUSH_VERTICES(ctx, _NEW_POLYGON); ctx->Polygon.OffsetLine = state; break; case GL_POLYGON_OFFSET_FILL: /*case GL_POLYGON_OFFSET_EXT:*/ if (ctx->Polygon.OffsetFill == state) return; FLUSH_VERTICES(ctx, _NEW_POLYGON); ctx->Polygon.OffsetFill = state; break; case GL_RESCALE_NORMAL_EXT: if (ctx->Transform.RescaleNormals == state) return; FLUSH_VERTICES(ctx, _NEW_TRANSFORM); ctx->Transform.RescaleNormals = state; break; case GL_SCISSOR_TEST: if (ctx->Scissor.Enabled == state) return; FLUSH_VERTICES(ctx, _NEW_SCISSOR); ctx->Scissor.Enabled = state; break; case GL_SHARED_TEXTURE_PALETTE_EXT: if (ctx->Texture.SharedPalette == state) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); ctx->Texture.SharedPalette = state; break; case GL_STENCIL_TEST: if (ctx->Stencil.Enabled == state) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); ctx->Stencil.Enabled = state; break; case GL_TEXTURE_1D: if (!enable_texture(ctx, state, TEXTURE_1D_BIT)) { return; } break; case GL_TEXTURE_2D: if (!enable_texture(ctx, state, TEXTURE_2D_BIT)) { return; } break; case GL_TEXTURE_3D: if (!enable_texture(ctx, state, TEXTURE_3D_BIT)) { return; } break; case GL_TEXTURE_GEN_Q: { struct gl_texture_unit *texUnit = get_texcoord_unit(ctx); if (texUnit) { GLuint newenabled = texUnit->TexGenEnabled & ~Q_BIT; if (state) newenabled |= Q_BIT; if (texUnit->TexGenEnabled == newenabled) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->TexGenEnabled = newenabled; } } break; case GL_TEXTURE_GEN_R: { struct gl_texture_unit *texUnit = get_texcoord_unit(ctx); if (texUnit) { GLuint newenabled = texUnit->TexGenEnabled & ~R_BIT; if (state) newenabled |= R_BIT; if (texUnit->TexGenEnabled == newenabled) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->TexGenEnabled = newenabled; } } break; case GL_TEXTURE_GEN_S: { struct gl_texture_unit *texUnit = get_texcoord_unit(ctx); if (texUnit) { GLuint newenabled = texUnit->TexGenEnabled & ~S_BIT; if (state) newenabled |= S_BIT; if (texUnit->TexGenEnabled == newenabled) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->TexGenEnabled = newenabled; } } break; case GL_TEXTURE_GEN_T: { struct gl_texture_unit *texUnit = get_texcoord_unit(ctx); if (texUnit) { GLuint newenabled = texUnit->TexGenEnabled & ~T_BIT; if (state) newenabled |= T_BIT; if (texUnit->TexGenEnabled == newenabled) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->TexGenEnabled = newenabled; } } break; /* * CLIENT STATE!!! */ 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: case GL_FOG_COORDINATE_ARRAY_EXT: case GL_SECONDARY_COLOR_ARRAY_EXT: case GL_POINT_SIZE_ARRAY_OES: client_state( ctx, cap, state ); return; /* GL_SGI_color_table */ case GL_COLOR_TABLE_SGI: CHECK_EXTENSION(SGI_color_table, cap); if (ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION] == state) return; FLUSH_VERTICES(ctx, _NEW_PIXEL); ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION] = state; break; case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: CHECK_EXTENSION(SGI_color_table, cap); if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION] == state) return; FLUSH_VERTICES(ctx, _NEW_PIXEL); ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION] = state; break; case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: CHECK_EXTENSION(SGI_color_table, cap); if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX] == state) return; FLUSH_VERTICES(ctx, _NEW_PIXEL); ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX] = state; break; case GL_TEXTURE_COLOR_TABLE_SGI: CHECK_EXTENSION(SGI_texture_color_table, cap); if (ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled = state; break; /* GL_EXT_convolution */ case GL_CONVOLUTION_1D: CHECK_EXTENSION(EXT_convolution, cap); if (ctx->Pixel.Convolution1DEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_PIXEL); ctx->Pixel.Convolution1DEnabled = state; break; case GL_CONVOLUTION_2D: CHECK_EXTENSION(EXT_convolution, cap); if (ctx->Pixel.Convolution2DEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_PIXEL); ctx->Pixel.Convolution2DEnabled = state; break; case GL_SEPARABLE_2D: CHECK_EXTENSION(EXT_convolution, cap); if (ctx->Pixel.Separable2DEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_PIXEL); ctx->Pixel.Separable2DEnabled = state; break; /* GL_ARB_texture_cube_map */ case GL_TEXTURE_CUBE_MAP_ARB: CHECK_EXTENSION(ARB_texture_cube_map, cap); if (!enable_texture(ctx, state, TEXTURE_CUBE_BIT)) { return; } break; /* GL_EXT_secondary_color */ case GL_COLOR_SUM_EXT: CHECK_EXTENSION2(EXT_secondary_color, ARB_vertex_program, cap); if (ctx->Fog.ColorSumEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.ColorSumEnabled = state; break; /* GL_ARB_multisample */ case GL_MULTISAMPLE_ARB: if (ctx->Multisample.Enabled == state) return; FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); ctx->Multisample.Enabled = state; break; case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: if (ctx->Multisample.SampleAlphaToCoverage == state) return; FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); ctx->Multisample.SampleAlphaToCoverage = state; break; case GL_SAMPLE_ALPHA_TO_ONE_ARB: if (ctx->Multisample.SampleAlphaToOne == state) return; FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); ctx->Multisample.SampleAlphaToOne = state; break; case GL_SAMPLE_COVERAGE_ARB: if (ctx->Multisample.SampleCoverage == state) return; FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); ctx->Multisample.SampleCoverage = state; break; case GL_SAMPLE_COVERAGE_INVERT_ARB: if (ctx->Multisample.SampleCoverageInvert == state) return; FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); ctx->Multisample.SampleCoverageInvert = state; break; /* GL_IBM_rasterpos_clip */ case GL_RASTER_POSITION_UNCLIPPED_IBM: CHECK_EXTENSION(IBM_rasterpos_clip, cap); if (ctx->Transform.RasterPositionUnclipped == state) return; FLUSH_VERTICES(ctx, _NEW_TRANSFORM); ctx->Transform.RasterPositionUnclipped = state; break; /* GL_NV_point_sprite */ case GL_POINT_SPRITE_NV: CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite, cap); if (ctx->Point.PointSprite == state) return; FLUSH_VERTICES(ctx, _NEW_POINT); ctx->Point.PointSprite = state; break; #if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program case GL_VERTEX_PROGRAM_ARB: CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap); if (ctx->VertexProgram.Enabled == state) return; FLUSH_VERTICES(ctx, _NEW_PROGRAM); ctx->VertexProgram.Enabled = state; break; case GL_VERTEX_PROGRAM_POINT_SIZE_ARB: CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap); if (ctx->VertexProgram.PointSizeEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_PROGRAM); ctx->VertexProgram.PointSizeEnabled = state; break; case GL_VERTEX_PROGRAM_TWO_SIDE_ARB: CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap); if (ctx->VertexProgram.TwoSideEnabled == state) return; FLUSH_VERTICES(ctx, _NEW_PROGRAM); ctx->VertexProgram.TwoSideEnabled = state; break; #endif #if FEATURE_NV_vertex_program 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: CHECK_EXTENSION(NV_vertex_program, cap); { const GLuint map = (GLuint) (cap - GL_MAP1_VERTEX_ATTRIB0_4_NV); FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map1Attrib[map] = state; } 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: CHECK_EXTENSION(NV_vertex_program, cap); { const GLuint map = (GLuint) (cap - GL_MAP2_VERTEX_ATTRIB0_4_NV); FLUSH_VERTICES(ctx, _NEW_EVAL); ctx->Eval.Map2Attrib[map] = state; } break; #endif /* FEATURE_NV_vertex_program */ #if FEATURE_NV_fragment_program case GL_FRAGMENT_PROGRAM_NV: CHECK_EXTENSION(NV_fragment_program, cap); if (ctx->FragmentProgram.Enabled == state) return; FLUSH_VERTICES(ctx, _NEW_PROGRAM); ctx->FragmentProgram.Enabled = state; break; #endif /* FEATURE_NV_fragment_program */ /* GL_NV_texture_rectangle */ case GL_TEXTURE_RECTANGLE_NV: CHECK_EXTENSION(NV_texture_rectangle, cap); if (!enable_texture(ctx, state, TEXTURE_RECT_BIT)) { return; } break; /* GL_EXT_stencil_two_side */ case GL_STENCIL_TEST_TWO_SIDE_EXT: CHECK_EXTENSION(EXT_stencil_two_side, cap); if (ctx->Stencil.TestTwoSide == state) return; FLUSH_VERTICES(ctx, _NEW_STENCIL); ctx->Stencil.TestTwoSide = state; if (state) { ctx->Stencil._BackFace = 2; ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL; } else { ctx->Stencil._BackFace = 1; ctx->_TriangleCaps &= ~DD_TRI_TWOSTENCIL; } break; #if FEATURE_ARB_fragment_program case GL_FRAGMENT_PROGRAM_ARB: CHECK_EXTENSION(ARB_fragment_program, cap); if (ctx->FragmentProgram.Enabled == state) return; FLUSH_VERTICES(ctx, _NEW_PROGRAM); ctx->FragmentProgram.Enabled = state; break; #endif /* FEATURE_ARB_fragment_program */ /* GL_EXT_depth_bounds_test */ case GL_DEPTH_BOUNDS_TEST_EXT: CHECK_EXTENSION(EXT_depth_bounds_test, cap); if (state && ctx->DrawBuffer->Visual.depthBits == 0) { _mesa_warning(ctx, "glEnable(GL_DEPTH_BOUNDS_TEST_EXT) but no depth buffer"); return; } if (ctx->Depth.BoundsTest == state) return; FLUSH_VERTICES(ctx, _NEW_DEPTH); ctx->Depth.BoundsTest = state; break; #if FEATURE_ATI_fragment_shader case GL_FRAGMENT_SHADER_ATI: CHECK_EXTENSION(ATI_fragment_shader, cap); if (ctx->ATIFragmentShader.Enabled == state) return; FLUSH_VERTICES(ctx, _NEW_PROGRAM); ctx->ATIFragmentShader.Enabled = state; break; #endif /* GL_MESA_texture_array */ case GL_TEXTURE_1D_ARRAY_EXT: CHECK_EXTENSION(MESA_texture_array, cap); if (!enable_texture(ctx, state, TEXTURE_1D_ARRAY_BIT)) { return; } break; case GL_TEXTURE_2D_ARRAY_EXT: CHECK_EXTENSION(MESA_texture_array, cap); if (!enable_texture(ctx, state, TEXTURE_2D_ARRAY_BIT)) { return; } break; default: _mesa_error(ctx, GL_INVALID_ENUM, "%s(0x%x)", state ? "glEnable" : "glDisable", cap); return; } if (ctx->Driver.Enable) { ctx->Driver.Enable( ctx, cap, state ); } }
void GLAPIENTRY _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) { struct gl_texture_unit *texUnit; struct gl_texgen *texgen; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n", _mesa_lookup_enum_by_nr(coord), _mesa_lookup_enum_by_nr(pname), *params, _mesa_lookup_enum_by_nr((GLenum) (GLint) *params)); if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)"); return; } texUnit = _mesa_get_current_tex_unit(ctx); texgen = get_texgen(texUnit, coord); if (!texgen) { _mesa_error(ctx, GL_INVALID_ENUM, "glTexGen(coord)"); return; } switch (pname) { case GL_TEXTURE_GEN_MODE: { GLenum mode = (GLenum) (GLint) params[0]; GLbitfield bit = 0x0; if (texgen->Mode == mode) return; switch (mode) { case GL_OBJECT_LINEAR: bit = TEXGEN_OBJ_LINEAR; break; case GL_EYE_LINEAR: bit = TEXGEN_EYE_LINEAR; break; case GL_SPHERE_MAP: if (coord == GL_S || coord == GL_T) bit = TEXGEN_SPHERE_MAP; break; case GL_REFLECTION_MAP_NV: if (coord != GL_Q) bit = TEXGEN_REFLECTION_MAP_NV; break; case GL_NORMAL_MAP_NV: if (coord != GL_Q) bit = TEXGEN_NORMAL_MAP_NV; break; default: ; /* nop */ } if (!bit) { _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); return; } FLUSH_VERTICES(ctx, _NEW_TEXTURE); texgen->Mode = mode; texgen->_ModeBit = bit; } break; case GL_OBJECT_PLANE: { if (TEST_EQ_4V(texgen->ObjectPlane, params)) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); COPY_4FV(texgen->ObjectPlane, params); } break; case GL_EYE_PLANE: { GLfloat tmp[4]; /* Transform plane equation by the inverse modelview matrix */ if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { _math_matrix_analyse(ctx->ModelviewMatrixStack.Top); } _mesa_transform_vector(tmp, params, ctx->ModelviewMatrixStack.Top->inv); if (TEST_EQ_4V(texgen->EyePlane, tmp)) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); COPY_4FV(texgen->EyePlane, tmp); } break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); return; } if (ctx->Driver.TexGen) ctx->Driver.TexGen( ctx, coord, pname, params ); }
/* * This function is kind of long just because we have to call a lot * of device driver functions to update device driver state. * * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions * in order to restore GL state. This isn't terribly efficient but it * ensures that dirty flags and any derived state gets updated correctly. * We could at least check if the value to restore equals the current value * and then skip the Mesa call. */ void _mesa_PopAttrib(void) { struct gl_attrib_node *attr, *next; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (ctx->AttribStackDepth == 0) { _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" ); return; } ctx->AttribStackDepth--; attr = ctx->AttribStack[ctx->AttribStackDepth]; while (attr) { if (MESA_VERBOSE&VERBOSE_API) { fprintf(stderr, "glPopAttrib %s\n", _mesa_lookup_enum_by_nr(attr->kind)); } switch (attr->kind) { case GL_ACCUM_BUFFER_BIT: { const struct gl_accum_attrib *accum; accum = (const struct gl_accum_attrib *) attr->data; _mesa_ClearAccum(accum->ClearColor[0], accum->ClearColor[1], accum->ClearColor[2], accum->ClearColor[3]); } break; case GL_COLOR_BUFFER_BIT: { const struct gl_colorbuffer_attrib *color; color = (const struct gl_colorbuffer_attrib *) attr->data; _mesa_ClearIndex((GLfloat) color->ClearIndex); _mesa_ClearColor(CHAN_TO_FLOAT(color->ClearColor[0]), CHAN_TO_FLOAT(color->ClearColor[1]), CHAN_TO_FLOAT(color->ClearColor[2]), CHAN_TO_FLOAT(color->ClearColor[3])); _mesa_IndexMask(color->IndexMask); _mesa_ColorMask((GLboolean) (color->ColorMask[0] != 0), (GLboolean) (color->ColorMask[1] != 0), (GLboolean) (color->ColorMask[2] != 0), (GLboolean) (color->ColorMask[3] != 0)); _mesa_DrawBuffer(color->DrawBuffer); _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled); _mesa_AlphaFunc(color->AlphaFunc, CHAN_TO_FLOAT(color->AlphaRef)); _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled); _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB, color->BlendDstRGB, color->BlendSrcA, color->BlendDstA); _mesa_BlendEquation(color->BlendEquation); _mesa_BlendColor(color->BlendColor[0], color->BlendColor[1], color->BlendColor[2], color->BlendColor[3]); _mesa_LogicOp(color->LogicOp); _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, color->ColorLogicOpEnabled); _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP, color->IndexLogicOpEnabled); _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag); } break; case GL_CURRENT_BIT: FLUSH_CURRENT( ctx, 0 ); MEMCPY( &ctx->Current, attr->data, sizeof(struct gl_current_attrib) ); break; case GL_DEPTH_BUFFER_BIT: { const struct gl_depthbuffer_attrib *depth; depth = (const struct gl_depthbuffer_attrib *) attr->data; _mesa_DepthFunc(depth->Func); _mesa_ClearDepth(depth->Clear); _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test); _mesa_DepthMask(depth->Mask); if (ctx->Extensions.HP_occlusion_test) _mesa_set_enable(ctx, GL_OCCLUSION_TEST_HP, depth->OcclusionTest); } break; case GL_ENABLE_BIT: { const struct gl_enable_attrib *enable; enable = (const struct gl_enable_attrib *) attr->data; pop_enable_group(ctx, enable); ctx->NewState |= _NEW_ALL; } break; case GL_EVAL_BIT: MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) ); ctx->NewState |= _NEW_EVAL; break; case GL_FOG_BIT: { const struct gl_fog_attrib *fog; fog = (const struct gl_fog_attrib *) attr->data; _mesa_set_enable(ctx, GL_FOG, fog->Enabled); _mesa_Fogfv(GL_FOG_COLOR, fog->Color); _mesa_Fogf(GL_FOG_DENSITY, fog->Density); _mesa_Fogf(GL_FOG_START, fog->Start); _mesa_Fogf(GL_FOG_END, fog->End); _mesa_Fogf(GL_FOG_INDEX, fog->Index); _mesa_Fogi(GL_FOG_MODE, fog->Mode); } break; case GL_HINT_BIT: { const struct gl_hint_attrib *hint; hint = (const struct gl_hint_attrib *) attr->data; _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT, hint->PerspectiveCorrection ); _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth); _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth); _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth); _mesa_Hint(GL_FOG_HINT, hint->Fog); _mesa_Hint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, hint->ClipVolumeClipping); if (ctx->Extensions.ARB_texture_compression) _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB, hint->TextureCompression); } break; case GL_LIGHTING_BIT: { GLuint i; const struct gl_light_attrib *light; light = (const struct gl_light_attrib *) attr->data; /* lighting enable */ _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled); /* per-light state */ if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) _math_matrix_analyse( &ctx->ModelView ); for (i = 0; i < MAX_LIGHTS; i++) { GLenum lgt = (GLenum) (GL_LIGHT0 + i); const struct gl_light *l = &light->Light[i]; GLfloat tmp[4]; _mesa_set_enable(ctx, lgt, l->Enabled); _mesa_Lightfv( lgt, GL_AMBIENT, l->Ambient ); _mesa_Lightfv( lgt, GL_DIFFUSE, l->Diffuse ); _mesa_Lightfv( lgt, GL_SPECULAR, l->Specular ); TRANSFORM_POINT( tmp, ctx->ModelView.inv, l->EyePosition ); _mesa_Lightfv( lgt, GL_POSITION, tmp ); TRANSFORM_POINT( tmp, ctx->ModelView.m, l->EyeDirection ); _mesa_Lightfv( lgt, GL_SPOT_DIRECTION, tmp ); _mesa_Lightfv( lgt, GL_SPOT_EXPONENT, &l->SpotExponent ); _mesa_Lightfv( lgt, GL_SPOT_CUTOFF, &l->SpotCutoff ); _mesa_Lightfv( lgt, GL_CONSTANT_ATTENUATION, &l->ConstantAttenuation ); _mesa_Lightfv( lgt, GL_LINEAR_ATTENUATION, &l->LinearAttenuation ); _mesa_Lightfv( lgt, GL_QUADRATIC_ATTENUATION, &l->QuadraticAttenuation ); } /* light model */ _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT, light->Model.Ambient); _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, (GLfloat) light->Model.LocalViewer); _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE, (GLfloat) light->Model.TwoSide); _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, (GLfloat) light->Model.ColorControl); /* materials */ MEMCPY(ctx->Light.Material, light->Material, 2 * sizeof(struct gl_material)); /* shade model */ _mesa_ShadeModel(light->ShadeModel); /* color material */ _mesa_ColorMaterial(light->ColorMaterialFace, light->ColorMaterialMode); _mesa_set_enable(ctx, GL_COLOR_MATERIAL, light->ColorMaterialEnabled); } break; case GL_LINE_BIT: { const struct gl_line_attrib *line; line = (const struct gl_line_attrib *) attr->data; _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag); _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag); _mesa_LineStipple(line->StippleFactor, line->StipplePattern); _mesa_LineWidth(line->Width); } break; case GL_LIST_BIT: MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) ); break; case GL_PIXEL_MODE_BIT: MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) ); ctx->NewState |= _NEW_PIXEL; break; case GL_POINT_BIT: { const struct gl_point_attrib *point; point = (const struct gl_point_attrib *) attr->data; _mesa_PointSize(point->Size); _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag); if (ctx->Extensions.EXT_point_parameters) { _mesa_PointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, point->Params); _mesa_PointParameterfEXT(GL_POINT_SIZE_MIN_EXT, point->MinSize); _mesa_PointParameterfEXT(GL_POINT_SIZE_MAX_EXT, point->MaxSize); _mesa_PointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, point->Threshold); } } break; case GL_POLYGON_BIT: { const struct gl_polygon_attrib *polygon; polygon = (const struct gl_polygon_attrib *) attr->data; _mesa_CullFace(polygon->CullFaceMode); _mesa_FrontFace(polygon->FrontFace); _mesa_PolygonMode(GL_FRONT, polygon->FrontMode); _mesa_PolygonMode(GL_BACK, polygon->BackMode); _mesa_PolygonOffset(polygon->OffsetFactor, polygon->OffsetUnits); _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag); _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag); _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag); _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT, polygon->OffsetPoint); _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE, polygon->OffsetLine); _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, polygon->OffsetFill); } break; case GL_POLYGON_STIPPLE_BIT: MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) ); ctx->NewState |= _NEW_POLYGONSTIPPLE; if (ctx->Driver.PolygonStipple) ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data ); break; case GL_SCISSOR_BIT: { const struct gl_scissor_attrib *scissor; scissor = (const struct gl_scissor_attrib *) attr->data; _mesa_Scissor(scissor->X, scissor->Y, scissor->Width, scissor->Height); _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->Enabled); } break; case GL_STENCIL_BUFFER_BIT: { const struct gl_stencil_attrib *stencil; stencil = (const struct gl_stencil_attrib *) attr->data; _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); _mesa_ClearStencil(stencil->Clear); _mesa_StencilFunc(stencil->Function, stencil->Ref, stencil->ValueMask); _mesa_StencilMask(stencil->WriteMask); _mesa_StencilOp(stencil->FailFunc, stencil->ZFailFunc, stencil->ZPassFunc); } break; case GL_TRANSFORM_BIT: { GLuint i; const struct gl_transform_attrib *xform; xform = (const struct gl_transform_attrib *) attr->data; _mesa_MatrixMode(xform->MatrixMode); if (ctx->ProjectionMatrix.flags & MAT_DIRTY) _math_matrix_analyse( &ctx->ProjectionMatrix ); /* restore clip planes */ for (i = 0; i < MAX_CLIP_PLANES; i++) { const GLfloat *eyePlane = xform->EyeUserPlane[i]; COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane); if (xform->ClipEnabled[i]) { _mesa_transform_vector( ctx->Transform._ClipUserPlane[i], eyePlane, ctx->ProjectionMatrix.inv ); _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE ); } else { _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE ); } if (ctx->Driver.ClipPlane) ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, eyePlane ); } /* normalize/rescale */ _mesa_set_enable(ctx, GL_NORMALIZE, ctx->Transform.Normalize); _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT, ctx->Transform.RescaleNormals); } break; case GL_TEXTURE_BIT: /* Take care of texture object reference counters */ { const struct gl_texture_attrib *texture; texture = (const struct gl_texture_attrib *) attr->data; pop_texture_group(ctx, texture); ctx->NewState |= _NEW_TEXTURE; } break; case GL_VIEWPORT_BIT: { const struct gl_viewport_attrib *vp; vp = (const struct gl_viewport_attrib *) attr->data; _mesa_Viewport(vp->X, vp->Y, vp->Width, vp->Height); _mesa_DepthRange(vp->Near, vp->Far); } break; case GL_MULTISAMPLE_BIT_ARB: { const struct gl_multisample_attrib *ms; ms = (const struct gl_multisample_attrib *) attr->data; _mesa_SampleCoverageARB(ms->SampleCoverageValue, ms->SampleCoverageInvert); } break; default: _mesa_problem( ctx, "Bad attrib flag in PopAttrib"); break; } next = attr->next; FREE( attr->data ); FREE( attr ); attr = next; } }