static void make_state_key(GLcontext *ctx, struct state_key *key) { static const GLfloat zero[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; static const GLfloat one[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; memset(key, 0, sizeof(*key)); if (ctx->Pixel.RedBias != 0.0 || ctx->Pixel.RedScale != 1.0 || ctx->Pixel.GreenBias != 0.0 || ctx->Pixel.GreenScale != 1.0 || ctx->Pixel.BlueBias != 0.0 || ctx->Pixel.BlueScale != 1.0 || ctx->Pixel.AlphaBias != 0.0 || ctx->Pixel.AlphaScale != 1.0) { key->scaleAndBias = 1; } if (!is_identity(ctx->ColorMatrixStack.Top->m)) { key->colorMatrix = 1; } if (!TEST_EQ_4V(ctx->Pixel.PostColorMatrixScale, one) || !TEST_EQ_4V(ctx->Pixel.PostColorMatrixBias, zero)) { key->colorMatrixPostScaleBias = 1; } key->pixelMaps = ctx->Pixel.MapColorFlag; }
void GLAPIENTRY _mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param ) { struct gl_texture_unit *texUnit; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (!ctx->Extensions.ATI_envmap_bumpmap) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBumpParameterfvATI"); return; } texUnit = _mesa_get_current_tex_unit(ctx); if (pname == GL_BUMP_ROT_MATRIX_ATI) { if (TEST_EQ_4V(param, texUnit->RotMatrix)) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); COPY_4FV(texUnit->RotMatrix, param); } else { _mesa_error( ctx, GL_INVALID_ENUM, "glTexBumpParameter(pname)" ); return; } /* Drivers might want to know about this, instead of dedicated function just shove it into TexEnv where it really belongs anyway */ if (ctx->Driver.TexEnv) { (*ctx->Driver.TexEnv)( ctx, 0, pname, param ); } }
/** * Try to accumulate this glBitmap call in the bitmap cache. * \return GL_TRUE for success, GL_FALSE if bitmap is too large, etc. */ static GLboolean accum_bitmap(struct st_context *st, GLint x, GLint y, GLsizei width, GLsizei height, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap ) { struct bitmap_cache *cache = st->bitmap.cache; int px = -999, py = -999; const GLfloat z = st->ctx->Current.RasterPos[2]; if (width > BITMAP_CACHE_WIDTH || height > BITMAP_CACHE_HEIGHT) return GL_FALSE; /* too big to cache */ if (!cache->empty) { px = x - cache->xpos; /* pos in buffer */ py = y - cache->ypos; if (px < 0 || px + width > BITMAP_CACHE_WIDTH || py < 0 || py + height > BITMAP_CACHE_HEIGHT || !TEST_EQ_4V(st->ctx->Current.RasterColor, cache->color) || ((fabs(z - cache->zpos) > Z_EPSILON))) { /* This bitmap would extend beyond cache bounds, or the bitmap * color is changing * so flush and continue. */ st_flush_bitmap_cache(st); } } if (cache->empty) { /* Initialize. Center bitmap vertically in the buffer. */ px = 0; py = (BITMAP_CACHE_HEIGHT - height) / 2; cache->xpos = x; cache->ypos = y - py; cache->zpos = z; cache->empty = GL_FALSE; COPY_4FV(cache->color, st->ctx->Current.RasterColor); } assert(px != -999); assert(py != -999); if (x < cache->xmin) cache->xmin = x; if (y < cache->ymin) cache->ymin = y; if (x + width > cache->xmax) cache->xmax = x + width; if (y + height > cache->ymax) cache->ymax = y + height; /* create the transfer if needed */ create_cache_trans(st); unpack_bitmap(st, px, py, width, height, unpack, bitmap, cache->buffer, BITMAP_CACHE_WIDTH); return GL_TRUE; /* accumulated */ }
/** * Set the blending color. * * \param red red color component. * \param green green color component. * \param blue blue color component. * \param alpha alpha color component. * * \sa glBlendColor(). * * Clamps the parameters and updates gl_colorbuffer_attrib::BlendColor. On a * change, flushes the vertices and notifies the driver via * dd_function_table::BlendColor callback. */ void GLAPIENTRY _mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) { GLfloat tmp[4]; GET_CURRENT_CONTEXT(ctx); tmp[0] = red; tmp[1] = green; tmp[2] = blue; tmp[3] = alpha; if (TEST_EQ_4V(tmp, ctx->Color.BlendColorUnclamped)) return; FLUSH_VERTICES(ctx, _NEW_COLOR); COPY_4FV( ctx->Color.BlendColorUnclamped, tmp ); ctx->Color.BlendColor[0] = CLAMP(tmp[0], 0.0F, 1.0F); ctx->Color.BlendColor[1] = CLAMP(tmp[1], 0.0F, 1.0F); ctx->Color.BlendColor[2] = CLAMP(tmp[2], 0.0F, 1.0F); ctx->Color.BlendColor[3] = CLAMP(tmp[3], 0.0F, 1.0F); if (ctx->Driver.BlendColor) ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor); }
/** * Enable or disable writing of frame buffer color components. * * \param red whether to mask writing of the red color component. * \param green whether to mask writing of the green color component. * \param blue whether to mask writing of the blue color component. * \param alpha whether to mask writing of the alpha color component. * * \sa glColorMask(). * * Sets the appropriate value of gl_colorbuffer_attrib::ColorMask. On a * change, flushes the vertices and notifies the driver via the * dd_function_table::ColorMask callback. */ void GLAPIENTRY _mesa_ColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ) { GET_CURRENT_CONTEXT(ctx); GLubyte tmp[4]; GLuint i; GLboolean flushed; if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glColorMask(%d, %d, %d, %d)\n", red, green, blue, alpha); /* Shouldn't have any information about channel depth in core mesa * -- should probably store these as the native booleans: */ tmp[RCOMP] = red ? 0xff : 0x0; tmp[GCOMP] = green ? 0xff : 0x0; tmp[BCOMP] = blue ? 0xff : 0x0; tmp[ACOMP] = alpha ? 0xff : 0x0; flushed = GL_FALSE; for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { if (!TEST_EQ_4V(tmp, ctx->Color.ColorMask[i])) { if (!flushed) { FLUSH_VERTICES(ctx, _NEW_COLOR); } flushed = GL_TRUE; COPY_4UBV(ctx->Color.ColorMask[i], tmp); } } if (ctx->Driver.ColorMask) ctx->Driver.ColorMask( ctx, red, green, blue, alpha ); }
/** * For GL_EXT_draw_buffers2 and GL3 */ void GLAPIENTRY _mesa_ColorMaski( GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ) { GLubyte tmp[4]; GET_CURRENT_CONTEXT(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glColorMaskIndexed %u %d %d %d %d\n", buf, red, green, blue, alpha); if (buf >= ctx->Const.MaxDrawBuffers) { _mesa_error(ctx, GL_INVALID_VALUE, "glColorMaskIndexed(buf=%u)", buf); return; } /* Shouldn't have any information about channel depth in core mesa * -- should probably store these as the native booleans: */ tmp[RCOMP] = red ? 0xff : 0x0; tmp[GCOMP] = green ? 0xff : 0x0; tmp[BCOMP] = blue ? 0xff : 0x0; tmp[ACOMP] = alpha ? 0xff : 0x0; if (TEST_EQ_4V(tmp, ctx->Color.ColorMask[buf])) return; FLUSH_VERTICES(ctx, _NEW_COLOR); COPY_4UBV(ctx->Color.ColorMask[buf], tmp); }
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 ); }
static void set_texgen_matrix( r200ContextPtr rmesa, GLuint unit, GLfloat *s_plane, GLfloat *t_plane ) { static const GLfloat scale_identity[4] = { 1,1,1,1 }; if (!TEST_EQ_4V( s_plane, scale_identity) || !(TEST_EQ_4V( t_plane, scale_identity))) { rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit; rmesa->TexGenMatrix[unit].m[0] = s_plane[0]; rmesa->TexGenMatrix[unit].m[4] = s_plane[1]; rmesa->TexGenMatrix[unit].m[8] = s_plane[2]; rmesa->TexGenMatrix[unit].m[12] = s_plane[3]; rmesa->TexGenMatrix[unit].m[1] = t_plane[0]; rmesa->TexGenMatrix[unit].m[5] = t_plane[1]; rmesa->TexGenMatrix[unit].m[9] = t_plane[2]; rmesa->TexGenMatrix[unit].m[13] = t_plane[3]; rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; } }
static void set_env_color(struct gl_context *ctx, struct gl_texture_unit *texUnit, const GLfloat *color) { if (TEST_EQ_4V(color, texUnit->EnvColorUnclamped)) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); COPY_4FV(texUnit->EnvColorUnclamped, color); texUnit->EnvColor[0] = CLAMP(color[0], 0.0F, 1.0F); texUnit->EnvColor[1] = CLAMP(color[1], 0.0F, 1.0F); texUnit->EnvColor[2] = CLAMP(color[2], 0.0F, 1.0F); texUnit->EnvColor[3] = CLAMP(color[3], 0.0F, 1.0F); }
static void set_env_color(GLcontext *ctx, struct gl_texture_unit *texUnit, const GLfloat *color) { GLfloat tmp[4]; tmp[0] = CLAMP(color[0], 0.0F, 1.0F); tmp[1] = CLAMP(color[1], 0.0F, 1.0F); tmp[2] = CLAMP(color[2], 0.0F, 1.0F); tmp[3] = CLAMP(color[3], 0.0F, 1.0F); if (TEST_EQ_4V(tmp, texUnit->EnvColor)) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); COPY_4FV(texUnit->EnvColor, tmp); }
void GLAPIENTRY _mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) { GLfloat tmp[4]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); tmp[0] = CLAMP( red, -1.0F, 1.0F ); tmp[1] = CLAMP( green, -1.0F, 1.0F ); tmp[2] = CLAMP( blue, -1.0F, 1.0F ); tmp[3] = CLAMP( alpha, -1.0F, 1.0F ); if (TEST_EQ_4V(tmp, ctx->Accum.ClearColor)) return; COPY_4FV( ctx->Accum.ClearColor, tmp ); }
/** * GL_EXT_texture_integer */ void GLAPIENTRY _mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a) { GLint tmp[4]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); tmp[0] = r; tmp[1] = g; tmp[2] = b; tmp[3] = a; if (TEST_EQ_4V(tmp, ctx->Color.ClearColor.i)) return; /* no change */ FLUSH_VERTICES(ctx, _NEW_COLOR); COPY_4V(ctx->Color.ClearColor.i, tmp); }
/** * Specify the clear values for the color buffers. * * \param red red color component. * \param green green color component. * \param blue blue color component. * \param alpha alpha component. * * \sa glClearColor(). * * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor. On a * change, flushes the vertices and notifies the driver via the * dd_function_table::ClearColor callback. */ void GLAPIENTRY _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) { GLfloat tmp[4]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); tmp[0] = red; tmp[1] = green; tmp[2] = blue; tmp[3] = alpha; if (TEST_EQ_4V(tmp, ctx->Color.ClearColor.f)) return; /* no change */ FLUSH_VERTICES(ctx, _NEW_COLOR); COPY_4V(ctx->Color.ClearColor.f, tmp); }
/** * Set the blending color. * * \param red red color component. * \param green green color component. * \param blue blue color component. * \param alpha alpha color component. * * \sa glBlendColor(). * * Clamps the parameters and updates gl_colorbuffer_attrib::BlendColor. On a * change, flushes the vertices and notifies the driver via * dd_function_table::BlendColor callback. */ void GLAPIENTRY _mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) { GLfloat tmp[4]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); tmp[0] = CLAMP( red, 0.0F, 1.0F ); tmp[1] = CLAMP( green, 0.0F, 1.0F ); tmp[2] = CLAMP( blue, 0.0F, 1.0F ); tmp[3] = CLAMP( alpha, 0.0F, 1.0F ); if (TEST_EQ_4V(tmp, ctx->Color.BlendColor)) return; FLUSH_VERTICES(ctx, _NEW_COLOR); COPY_4FV( ctx->Color.BlendColor, tmp ); if (ctx->Driver.BlendColor) (*ctx->Driver.BlendColor)(ctx, tmp); }
void _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) { GLfloat tmp[4]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); tmp[0] = CLAMP(red, 0.0F, 1.0F); tmp[1] = CLAMP(green, 0.0F, 1.0F); tmp[2] = CLAMP(blue, 0.0F, 1.0F); tmp[3] = CLAMP(alpha, 0.0F, 1.0F); if (TEST_EQ_4V(tmp, ctx->Color.ClearColor)) return; /* no change */ FLUSH_VERTICES(ctx, _NEW_COLOR); COPY_4V(ctx->Color.ClearColor, tmp); if (ctx->Visual.rgbMode && ctx->Driver.ClearColor) { /* it's OK to call glClearColor in CI mode but it should be a NOP */ (*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColor); } }
void GLAPIENTRY _mesa_Fogfv( GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); GLenum m; switch (pname) { case GL_FOG_MODE: m = (GLenum) (GLint) *params; switch (m) { case GL_LINEAR: ctx->Fog._PackedMode = FOG_LINEAR; break; case GL_EXP: ctx->Fog._PackedMode = FOG_EXP; break; case GL_EXP2: ctx->Fog._PackedMode = FOG_EXP2; break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glFog" ); return; } if (ctx->Fog.Mode == m) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.Mode = m; ctx->Fog._PackedEnabledMode = ctx->Fog.Enabled ? ctx->Fog._PackedMode : FOG_NONE; break; case GL_FOG_DENSITY: if (*params<0.0F) { _mesa_error( ctx, GL_INVALID_VALUE, "glFog" ); return; } if (ctx->Fog.Density == *params) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.Density = *params; break; case GL_FOG_START: if (ctx->Fog.Start == *params) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.Start = *params; break; case GL_FOG_END: if (ctx->Fog.End == *params) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.End = *params; break; case GL_FOG_INDEX: if (ctx->API != API_OPENGL_COMPAT) goto invalid_pname; if (ctx->Fog.Index == *params) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.Index = *params; break; case GL_FOG_COLOR: if (TEST_EQ_4V(ctx->Fog.Color, params)) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.ColorUnclamped[0] = params[0]; ctx->Fog.ColorUnclamped[1] = params[1]; ctx->Fog.ColorUnclamped[2] = params[2]; ctx->Fog.ColorUnclamped[3] = params[3]; ctx->Fog.Color[0] = CLAMP(params[0], 0.0F, 1.0F); ctx->Fog.Color[1] = CLAMP(params[1], 0.0F, 1.0F); ctx->Fog.Color[2] = CLAMP(params[2], 0.0F, 1.0F); ctx->Fog.Color[3] = CLAMP(params[3], 0.0F, 1.0F); break; case GL_FOG_COORDINATE_SOURCE_EXT: { GLenum p = (GLenum) (GLint) *params; if (ctx->API != API_OPENGL_COMPAT || (p != GL_FOG_COORDINATE_EXT && p != GL_FRAGMENT_DEPTH_EXT)) { _mesa_error(ctx, GL_INVALID_ENUM, "glFog"); return; } if (ctx->Fog.FogCoordinateSource == p) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.FogCoordinateSource = p; break; } case GL_FOG_DISTANCE_MODE_NV: { GLenum p = (GLenum) (GLint) *params; if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.NV_fog_distance || (p != GL_EYE_RADIAL_NV && p != GL_EYE_PLANE && p != GL_EYE_PLANE_ABSOLUTE_NV)) { _mesa_error(ctx, GL_INVALID_ENUM, "glFog"); return; } if (ctx->Fog.FogDistanceMode == p) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.FogDistanceMode = p; break; } default: goto invalid_pname; } if (ctx->Driver.Fogfv) { ctx->Driver.Fogfv( ctx, pname, params ); } return; invalid_pname: _mesa_error( ctx, GL_INVALID_ENUM, "glFog" ); return; }
void _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); GLint i = (GLint) (light - GL_LIGHT0); struct gl_light *l = &ctx->Light.Light[i]; if (i < 0 || i >= (GLint) ctx->Const.MaxLights) { _mesa_error( ctx, GL_INVALID_ENUM, "glLight" ); return; } switch (pname) { case GL_AMBIENT: if (TEST_EQ_4V(l->Ambient, params)) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); COPY_4V( l->Ambient, params ); break; case GL_DIFFUSE: if (TEST_EQ_4V(l->Diffuse, params)) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); COPY_4V( l->Diffuse, params ); break; case GL_SPECULAR: if (TEST_EQ_4V(l->Specular, params)) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); COPY_4V( l->Specular, params ); break; case GL_POSITION: { GLfloat tmp[4]; /* transform position by ModelView matrix */ TRANSFORM_POINT( tmp, ctx->ModelView.m, params ); if (TEST_EQ_4V(l->EyePosition, tmp)) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); COPY_4V(l->EyePosition, tmp); if (l->EyePosition[3] != 0.0F) l->_Flags |= LIGHT_POSITIONAL; else l->_Flags &= ~LIGHT_POSITIONAL; break; } case GL_SPOT_DIRECTION: { GLfloat tmp[4]; /* transform direction by inverse modelview */ if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { _math_matrix_analyse( &ctx->ModelView ); } TRANSFORM_NORMAL( tmp, params, ctx->ModelView.inv ); if (TEST_EQ_3V(l->EyeDirection, tmp)) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); COPY_3V(l->EyeDirection, tmp); break; } case GL_SPOT_EXPONENT: if (params[0]<0.0 || params[0]>128.0) { _mesa_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } if (l->SpotExponent == params[0]) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); l->SpotExponent = params[0]; _mesa_invalidate_spot_exp_table( l ); break; case GL_SPOT_CUTOFF: if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) { _mesa_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } if (l->SpotCutoff == params[0]) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); l->SpotCutoff = params[0]; l->_CosCutoff = (GLfloat) cos(params[0]*DEG2RAD); if (l->_CosCutoff < 0) l->_CosCutoff = 0; if (l->SpotCutoff != 180.0F) l->_Flags |= LIGHT_SPOT; else l->_Flags &= ~LIGHT_SPOT; break; case GL_CONSTANT_ATTENUATION: if (params[0]<0.0) { _mesa_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } if (l->ConstantAttenuation == params[0]) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); l->ConstantAttenuation = params[0]; break; case GL_LINEAR_ATTENUATION: if (params[0]<0.0) { _mesa_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } if (l->LinearAttenuation == params[0]) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); l->LinearAttenuation = params[0]; break; case GL_QUADRATIC_ATTENUATION: if (params[0]<0.0) { _mesa_error( ctx, GL_INVALID_VALUE, "glLight" ); return; } if (l->QuadraticAttenuation == params[0]) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); l->QuadraticAttenuation = params[0]; break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glLight" ); return; } if (ctx->Driver.Lightfv) ctx->Driver.Lightfv( ctx, light, pname, params ); }
void GLAPIENTRY _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) { GLuint maxUnit; GET_CURRENT_CONTEXT(ctx); struct gl_texture_unit *texUnit; ASSERT_OUTSIDE_BEGIN_END(ctx); maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV) ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits; if (ctx->Texture.CurrentUnit >= maxUnit) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)"); return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; #define TE_ERROR(errCode, msg, value) \ _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value)); if (target == GL_TEXTURE_ENV) { switch (pname) { case GL_TEXTURE_ENV_MODE: { GLenum mode = (GLenum) (GLint) *param; if (mode == GL_REPLACE_EXT) mode = GL_REPLACE; if (texUnit->EnvMode == mode) return; if (mode == GL_MODULATE || mode == GL_BLEND || mode == GL_DECAL || mode == GL_REPLACE || (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) || (mode == GL_COMBINE && (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine))) { /* legal */ FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->EnvMode = mode; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); return; } } break; case GL_TEXTURE_ENV_COLOR: { GLfloat tmp[4]; tmp[0] = CLAMP( param[0], 0.0F, 1.0F ); tmp[1] = CLAMP( param[1], 0.0F, 1.0F ); tmp[2] = CLAMP( param[2], 0.0F, 1.0F ); tmp[3] = CLAMP( param[3], 0.0F, 1.0F ); if (TEST_EQ_4V(tmp, texUnit->EnvColor)) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); COPY_4FV(texUnit->EnvColor, tmp); } break; case GL_COMBINE_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { const GLenum mode = (GLenum) (GLint) *param; if (texUnit->Combine.ModeRGB == mode) return; switch (mode) { case GL_REPLACE: case GL_MODULATE: case GL_ADD: case GL_ADD_SIGNED: case GL_INTERPOLATE: /* OK */ break; case GL_SUBTRACT: if (!ctx->Extensions.ARB_texture_env_combine) { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); return; } break; case GL_DOT3_RGB_EXT: case GL_DOT3_RGBA_EXT: if (!ctx->Extensions.EXT_texture_env_dot3) { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); return; } break; case GL_DOT3_RGB: case GL_DOT3_RGBA: if (!ctx->Extensions.ARB_texture_env_dot3) { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); return; } break; case GL_MODULATE_ADD_ATI: case GL_MODULATE_SIGNED_ADD_ATI: case GL_MODULATE_SUBTRACT_ATI: if (!ctx->Extensions.ATI_texture_env_combine3) { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); return; } break; default: TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); return; } FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Combine.ModeRGB = mode; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } break; case GL_COMBINE_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { const GLenum mode = (GLenum) (GLint) *param; if (texUnit->Combine.ModeA == mode) return; switch (mode) { case GL_REPLACE: case GL_MODULATE: case GL_ADD: case GL_ADD_SIGNED: case GL_INTERPOLATE: /* OK */ break; case GL_SUBTRACT: if (!ctx->Extensions.ARB_texture_env_combine) { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); return; } break; case GL_MODULATE_ADD_ATI: case GL_MODULATE_SIGNED_ADD_ATI: case GL_MODULATE_SUBTRACT_ATI: if (!ctx->Extensions.ATI_texture_env_combine3) { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); return; } break; default: TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); return; } FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Combine.ModeA = mode; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } break; case GL_SOURCE0_RGB: case GL_SOURCE1_RGB: case GL_SOURCE2_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { const GLenum source = (GLenum) (GLint) *param; const GLuint s = pname - GL_SOURCE0_RGB; if (texUnit->Combine.SourceRGB[s] == source) return; if (source == GL_TEXTURE || source == GL_CONSTANT || source == GL_PRIMARY_COLOR || source == GL_PREVIOUS || (ctx->Extensions.ARB_texture_env_crossbar && source >= GL_TEXTURE0 && source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) || (ctx->Extensions.ATI_texture_env_combine3 && (source == GL_ZERO || source == GL_ONE))) { /* legal */ FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Combine.SourceRGB[s] = source; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source); return; } } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } break; case GL_SOURCE0_ALPHA: case GL_SOURCE1_ALPHA: case GL_SOURCE2_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { const GLenum source = (GLenum) (GLint) *param; const GLuint s = pname - GL_SOURCE0_ALPHA; if (texUnit->Combine.SourceA[s] == source) return; if (source == GL_TEXTURE || source == GL_CONSTANT || source == GL_PRIMARY_COLOR || source == GL_PREVIOUS || (ctx->Extensions.ARB_texture_env_crossbar && source >= GL_TEXTURE0 && source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) || (ctx->Extensions.ATI_texture_env_combine3 && (source == GL_ZERO || source == GL_ONE))) { /* legal */ FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Combine.SourceA[s] = source; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source); return; } } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } break; case GL_OPERAND0_RGB: case GL_OPERAND1_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { const GLenum operand = (GLenum) (GLint) *param; const GLuint s = pname - GL_OPERAND0_RGB; if (texUnit->Combine.OperandRGB[s] == operand) return; switch (operand) { case GL_SRC_COLOR: case GL_ONE_MINUS_SRC_COLOR: case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Combine.OperandRGB[s] = operand; break; default: TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); return; } } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } break; case GL_OPERAND0_ALPHA: case GL_OPERAND1_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { const GLenum operand = (GLenum) (GLint) *param; if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] == operand) return; switch (operand) { case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand; break; default: TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); return; } } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } break; case GL_OPERAND2_RGB: if (ctx->Extensions.ARB_texture_env_combine) { const GLenum operand = (GLenum) (GLint) *param; if (texUnit->Combine.OperandRGB[2] == operand) return; switch (operand) { case GL_SRC_COLOR: /* ARB combine only */ case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */ case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */ FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Combine.OperandRGB[2] = operand; break; default: TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); return; } } else if (ctx->Extensions.EXT_texture_env_combine) { const GLenum operand = (GLenum) (GLint) *param; if (texUnit->Combine.OperandRGB[2] == operand) return; /* operand must be GL_SRC_ALPHA which is the initial value - thus don't need to actually compare the operand to the possible value */ else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); return; } } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } break; case GL_OPERAND2_ALPHA: if (ctx->Extensions.ARB_texture_env_combine) { const GLenum operand = (GLenum) (GLint) *param; if (texUnit->Combine.OperandA[2] == operand) return; switch (operand) { case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */ FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Combine.OperandA[2] = operand; break; default: TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); return; } } else if (ctx->Extensions.EXT_texture_env_combine) { const GLenum operand = (GLenum) (GLint) *param; if (texUnit->Combine.OperandA[2] == operand) return; /* operand must be GL_SRC_ALPHA which is the initial value - thus don't need to actually compare the operand to the possible value */ else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); return; } } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } break; case GL_RGB_SCALE: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { GLuint newshift; if (*param == 1.0) { newshift = 0; } else if (*param == 2.0) { newshift = 1; } else if (*param == 4.0) { newshift = 2; } else { _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" ); return; } if (texUnit->Combine.ScaleShiftRGB == newshift) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Combine.ScaleShiftRGB = newshift; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } break; case GL_ALPHA_SCALE: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { GLuint newshift; if (*param == 1.0) { newshift = 0; } else if (*param == 2.0) { newshift = 1; } else if (*param == 4.0) { newshift = 2; } else { _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" ); return; } if (texUnit->Combine.ScaleShiftA == newshift) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->Combine.ScaleShiftA = newshift; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" ); return; } } else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) { /* GL_EXT_texture_lod_bias */ if (!ctx->Extensions.EXT_texture_lod_bias) { _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target ); return; } if (pname == GL_TEXTURE_LOD_BIAS_EXT) { if (texUnit->LodBias == param[0]) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->LodBias = param[0]; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } } else if (target == GL_POINT_SPRITE_NV) { /* GL_ARB_point_sprite / GL_NV_point_sprite */ if (!ctx->Extensions.NV_point_sprite && !ctx->Extensions.ARB_point_sprite) { _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target ); return; } if (pname == GL_COORD_REPLACE_NV) { const GLenum value = (GLenum) param[0]; if (value == GL_TRUE || value == GL_FALSE) { /* It's kind of weird to set point state via glTexEnv, * but that's what the spec calls for. */ const GLboolean state = (GLboolean) value; if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state) return; FLUSH_VERTICES(ctx, _NEW_POINT); ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state; } else { _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value); return; } } else { _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname ); return; } } else { _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target ); return; } if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n", _mesa_lookup_enum_by_nr(target), _mesa_lookup_enum_by_nr(pname), *param, _mesa_lookup_enum_by_nr((GLenum) (GLint) *param)); /* Tell device driver about the new texture environment */ if (ctx->Driver.TexEnv) { (*ctx->Driver.TexEnv)( ctx, target, pname, param ); } }
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 ); }
void GLAPIENTRY _mesa_Fogfv( GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); GLenum m; ASSERT_OUTSIDE_BEGIN_END(ctx); switch (pname) { case GL_FOG_MODE: m = (GLenum) (GLint) *params; switch (m) { case GL_LINEAR: case GL_EXP: case GL_EXP2: break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glFog" ); return; } if (ctx->Fog.Mode == m) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.Mode = m; break; case GL_FOG_DENSITY: if (*params<0.0) { _mesa_error( ctx, GL_INVALID_VALUE, "glFog" ); return; } if (ctx->Fog.Density == *params) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.Density = *params; break; case GL_FOG_START: if (ctx->Fog.Start == *params) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.Start = *params; UPDATE_FOG_SCALE(ctx); break; case GL_FOG_END: if (ctx->Fog.End == *params) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.End = *params; UPDATE_FOG_SCALE(ctx); break; case GL_FOG_INDEX: if (ctx->Fog.Index == *params) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.Index = *params; break; case GL_FOG_COLOR: if (TEST_EQ_4V(ctx->Fog.Color, params)) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.Color[0] = CLAMP(params[0], 0.0F, 1.0F); ctx->Fog.Color[1] = CLAMP(params[1], 0.0F, 1.0F); ctx->Fog.Color[2] = CLAMP(params[2], 0.0F, 1.0F); ctx->Fog.Color[3] = CLAMP(params[3], 0.0F, 1.0F); break; case GL_FOG_COORDINATE_SOURCE_EXT: { GLenum p = (GLenum) (GLint) *params; if (!ctx->Extensions.EXT_fog_coord || (p != GL_FOG_COORDINATE_EXT && p != GL_FRAGMENT_DEPTH_EXT)) { _mesa_error(ctx, GL_INVALID_ENUM, "glFog"); return; } if (ctx->Fog.FogCoordinateSource == p) return; FLUSH_VERTICES(ctx, _NEW_FOG); ctx->Fog.FogCoordinateSource = p; break; } default: _mesa_error( ctx, GL_INVALID_ENUM, "glFog" ); return; } if (ctx->Driver.Fogfv) { (*ctx->Driver.Fogfv)( ctx, pname, params ); } }
/** * Leave meta state. This is like a light-weight version of glPopAttrib(). */ void _mesa_meta_end(struct gl_context *ctx) { struct save_state *save = &ctx->Meta->Save[--ctx->Meta->SaveStackDepth]; const GLbitfield state = save->SavedState; if (state & MESA_META_ALPHA_TEST) { if (ctx->Color.AlphaEnabled != save->AlphaEnabled) _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled); _mesa_AlphaFunc(save->AlphaFunc, save->AlphaRef); } if (state & MESA_META_BLEND) { if (ctx->Color.BlendEnabled != save->BlendEnabled) { _mesa_set_enable(ctx, GL_BLEND, (save->BlendEnabled & 1)); } if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled) _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled); } if (state & MESA_META_COLOR_MASK) { if (!TEST_EQ_4V(ctx->Color.ColorMask, save->ColorMask)) { _mesa_ColorMask(save->ColorMask[0], save->ColorMask[1], save->ColorMask[2], save->ColorMask[3]); } } if (state & MESA_META_DEPTH_TEST) { if (ctx->Depth.Test != save->Depth.Test) _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test); _mesa_DepthFunc(save->Depth.Func); _mesa_DepthMask(save->Depth.Mask); } if (state & MESA_META_FOG) { _mesa_set_enable(ctx, GL_FOG, save->Fog); } if (state & MESA_META_PIXEL_STORE) { ctx->Pack = save->Pack; ctx->Unpack = save->Unpack; } if (state & MESA_META_PIXEL_TRANSFER) { ctx->Pixel.RedScale = save->RedScale; ctx->Pixel.RedBias = save->RedBias; ctx->Pixel.GreenScale = save->GreenScale; ctx->Pixel.GreenBias = save->GreenBias; ctx->Pixel.BlueScale = save->BlueScale; ctx->Pixel.BlueBias = save->BlueBias; ctx->Pixel.AlphaScale = save->AlphaScale; ctx->Pixel.AlphaBias = save->AlphaBias; ctx->Pixel.MapColorFlag = save->MapColorFlag; /* XXX more state */ ctx->NewState |=_NEW_PIXEL; } if (state & MESA_META_RASTERIZATION) { _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode); _mesa_PolygonMode(GL_BACK, save->BackPolygonMode); _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple); _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset); _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth); _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull); } if (state & MESA_META_SCISSOR) { _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled); _mesa_Scissor(save->Scissor.X, save->Scissor.Y, save->Scissor.Width, save->Scissor.Height); } if (state & MESA_META_STENCIL_TEST) { const struct gl_stencil_attrib *stencil = &save->Stencil; _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); } if (state & MESA_META_TEXTURE) { GLuint tgt; /* restore texenv for unit[0] */ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode); /* restore texture objects for unit[0] only */ for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { if (ctx->Texture.Unit.CurrentTex[tgt] != save->CurrentTexture[tgt]) { FLUSH_VERTICES(ctx, _NEW_TEXTURE); _mesa_reference_texobj(&ctx->Texture.Unit.CurrentTex[tgt], save->CurrentTexture[tgt]); } _mesa_reference_texobj(&save->CurrentTexture[tgt], NULL); } /* Restore fixed function texture enables, texgen */ if (ctx->Texture.Unit.Enabled != save->TexEnabled) { FLUSH_VERTICES(ctx, _NEW_TEXTURE); ctx->Texture.Unit.Enabled = save->TexEnabled; } if (ctx->Texture.Unit.TexGenEnabled != save->TexGenEnabled) { FLUSH_VERTICES(ctx, _NEW_TEXTURE); ctx->Texture.Unit.TexGenEnabled = save->TexGenEnabled; } } if (state & MESA_META_TRANSFORM) { _mesa_MatrixMode(GL_TEXTURE); _mesa_LoadMatrixf(save->TextureMatrix); _mesa_MatrixMode(GL_MODELVIEW); _mesa_LoadMatrixf(save->ModelviewMatrix); _mesa_MatrixMode(GL_PROJECTION); _mesa_LoadMatrixf(save->ProjectionMatrix); _mesa_MatrixMode(save->MatrixMode); } if (state & MESA_META_CLIP) { if (save->ClipPlanesEnabled) { GLuint i; for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { if (save->ClipPlanesEnabled & (1 << i)) { _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE); } } } } if (state & MESA_META_VIEWPORT) { if (save->ViewportX != ctx->Viewport.X || save->ViewportY != ctx->Viewport.Y || save->ViewportW != ctx->Viewport.Width || save->ViewportH != ctx->Viewport.Height) { _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY, save->ViewportW, save->ViewportH); } _mesa_DepthRange(save->DepthNear, save->DepthFar); } /* misc */ if (save->Lighting) { _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE); } if (save->RasterDiscard) { _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_TRUE); } }
void _mesa_LightModelfv( GLenum pname, const GLfloat *params ) { GLenum newenum; GLboolean newbool; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); switch (pname) { case GL_LIGHT_MODEL_AMBIENT: if (TEST_EQ_4V( ctx->Light.Model.Ambient, params )) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); COPY_4V( ctx->Light.Model.Ambient, params ); break; case GL_LIGHT_MODEL_LOCAL_VIEWER: newbool = (params[0]!=0.0); if (ctx->Light.Model.LocalViewer == newbool) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.Model.LocalViewer = newbool; break; case GL_LIGHT_MODEL_TWO_SIDE: newbool = (params[0]!=0.0); if (ctx->Light.Model.TwoSide == newbool) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.Model.TwoSide = newbool; if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; else ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE; break; case GL_LIGHT_MODEL_COLOR_CONTROL: if (params[0] == (GLfloat) GL_SINGLE_COLOR) newenum = GL_SINGLE_COLOR; else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) newenum = GL_SEPARATE_SPECULAR_COLOR; else { _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" ); return; } if (ctx->Light.Model.ColorControl == newenum) return; FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.Model.ColorControl = newenum; if ((ctx->Light.Enabled && ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) || ctx->Fog.ColorSumEnabled) ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; else ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR; break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel" ); break; } if (ctx->Driver.LightModelfv) ctx->Driver.LightModelfv( ctx, pname, params ); }