/* * Check if the global material has to be updated with info that was * associated with a vertex via glMaterial. * This function is used when any material values get changed between * glBegin/glEnd either by calling glMaterial() or by calling glColor() * when GL_COLOR_MATERIAL is enabled. * * src[0] is front material, src[1] is back material * * Additionally keeps the precomputed lighting state uptodate. */ void _mesa_update_material( GLcontext *ctx, const struct gl_material src[2], GLuint bitmask ) { struct gl_light *light, *list = &ctx->Light.EnabledList; if (ctx->Light.ColorMaterialEnabled) bitmask &= ~ctx->Light.ColorMaterialBitmask; if (MESA_VERBOSE&VERBOSE_IMMEDIATE) fprintf(stderr, "_mesa_update_material, mask 0x%x\n", bitmask); if (!bitmask) return; /* update material emission */ if (bitmask & FRONT_EMISSION_BIT) { struct gl_material *mat = &ctx->Light.Material[0]; COPY_4FV( mat->Emission, src[0].Emission ); } if (bitmask & BACK_EMISSION_BIT) { struct gl_material *mat = &ctx->Light.Material[1]; COPY_4FV( mat->Emission, src[1].Emission ); } /* update material ambience */ if (bitmask & FRONT_AMBIENT_BIT) { struct gl_material *mat = &ctx->Light.Material[0]; COPY_4FV( mat->Ambient, src[0].Ambient ); foreach (light, list) { SCALE_3V( light->_MatAmbient[0], light->Ambient, src[0].Ambient); } }
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" ); } }
/** * 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); }
/** * 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 */ }
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 ); } }
/** * All glWindowPosMESA and glWindowPosARB commands call this function to * update the current raster position. */ static void window_pos3f(GLfloat x, GLfloat y, GLfloat z) { GET_CURRENT_CONTEXT(ctx); GLfloat z2; FLUSH_VERTICES(ctx, 0); FLUSH_CURRENT(ctx, 0); z2 = CLAMP(z, 0.0F, 1.0F) * (ctx->ViewportArray[0].Far - ctx->ViewportArray[0].Near) + ctx->ViewportArray[0].Near; /* set raster position */ ctx->Current.RasterPos[0] = x; ctx->Current.RasterPos[1] = y; ctx->Current.RasterPos[2] = z2; ctx->Current.RasterPos[3] = 1.0F; ctx->Current.RasterPosValid = GL_TRUE; if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; else ctx->Current.RasterDistance = 0.0; /* raster color = current color or index */ ctx->Current.RasterColor[0] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0], 0.0F, 1.0F); ctx->Current.RasterColor[1] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1], 0.0F, 1.0F); ctx->Current.RasterColor[2] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2], 0.0F, 1.0F); ctx->Current.RasterColor[3] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[0] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[1] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[2] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[3] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3], 0.0F, 1.0F); /* raster texcoord = current texcoord */ { GLuint texSet; for (texSet = 0; texSet < ctx->Const.MaxTextureCoordUnits; texSet++) { assert(texSet < ARRAY_SIZE(ctx->Current.RasterTexCoords)); COPY_4FV( ctx->Current.RasterTexCoords[texSet], ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texSet] ); } } if (ctx->RenderMode==GL_SELECT) { _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); } }
INTERP_QUALIFIER void TAG(copy_pv_extras)( GLcontext *ctx, GLuint dst, GLuint src ) { LOCALVARS struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; if (VB->ColorPtr[1]) { COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), GET_COLOR(VB->ColorPtr[1], src) ); if (VB->SecondaryColorPtr[1]) { COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), GET_COLOR(VB->SecondaryColorPtr[1], src) ); } } COPY_PV_VERTEX(ctx, dst, src); }
/** * Copy back color(s) to front color(s). */ static INLINE struct vertex_header * copy_bfc( struct twoside_stage *twoside, const struct vertex_header *v, unsigned idx ) { struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx ); if (twoside->attrib_back0) { COPY_4FV(tmp->data[twoside->attrib_front0], tmp->data[twoside->attrib_back0]); } if (twoside->attrib_back1) { COPY_4FV(tmp->data[twoside->attrib_front1], tmp->data[twoside->attrib_back1]); } return tmp; }
void _mesa_EvalCoord2f( GLfloat u, GLfloat v ) { GET_CURRENT_CONTEXT( ctx ); GLfloat normal[3], texcoord[4], color[4]; GLuint index; COPY_3FV( normal, ctx->Current.Attrib[VERT_ATTRIB_NORMAL] ); COPY_4FV( texcoord, ctx->Current.Attrib[VERT_ATTRIB_TEX0] ); COPY_4FV( color, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] ); index = ctx->Current.Index; do_EvalCoord2f( ctx, u, v ); COPY_3FV( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], normal ); COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_TEX0], texcoord ); COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], color ); ctx->Current.Index = index; }
/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */ static INLINE void copy_colors2( struct draw_stage *stage, struct vertex_header *dst0, struct vertex_header *dst1, const struct vertex_header *src ) { const struct flat_stage *flat = flat_stage(stage); uint i; for (i = 0; i < flat->num_color_attribs; i++) { const uint attr = flat->color_attribs[i]; COPY_4FV(dst0->data[attr], src->data[attr]); COPY_4FV(dst1->data[attr], src->data[attr]); } for (i = 0; i < flat->num_spec_attribs; i++) { const uint attr = flat->spec_attribs[i]; COPY_3FV(dst0->data[attr], src->data[attr]); COPY_3FV(dst1->data[attr], src->data[attr]); } }
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 copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src ) { struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; if (VB->ColorPtr[1]) { COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), GET_COLOR(VB->ColorPtr[1], src) ); } setup_tab[TDFX_CONTEXT(ctx)->SetupIndex].copy_pv(ctx, dst, src); }
static void generic_copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src ) { struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; if (VB->ColorPtr[1]) { COPY_4FV( VB->ColorPtr[1]->data[dst], VB->ColorPtr[1]->data[src] ); if (VB->SecondaryColorPtr[1]) { COPY_4FV( VB->SecondaryColorPtr[1]->data[dst], VB->SecondaryColorPtr[1]->data[src] ); } } else if (VB->IndexPtr[1]) { VB->IndexPtr[1]->data[dst][0] = VB->IndexPtr[1]->data[src][0]; } generic_copy_pv(ctx, dst, src); }
/** * Copy front/back, primary/secondary colors from src vertex to dst vertex. * Used when flat shading. */ static void copy_colors( struct draw_stage *stage, struct vertex_header *dst, const struct vertex_header *src ) { const struct clip_stage *clipper = clip_stage(stage); uint i; for (i = 0; i < clipper->num_color_attribs; i++) { const uint attr = clipper->color_attribs[i]; COPY_4FV(dst->data[attr], src->data[attr]); } }
/** * Copy the last specified normal, color, texcoord, edge flag, etc * from the immediate struct into the ctx->Current attribute group. */ void _tnl_copy_to_current( GLcontext *ctx, struct immediate *IM, GLuint flag, GLuint count ) { if (MESA_VERBOSE&VERBOSE_IMMEDIATE) _tnl_print_vert_flags("copy to current", flag); /* XXX should be able to replace these conditions with a loop over * the 16 vertex attributes. */ if (flag & VERT_BIT_NORMAL) COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], IM->Attrib[VERT_ATTRIB_NORMAL][count]); if (flag & VERT_BIT_COLOR0) { COPY_4FV(ctx->Current.Attrib[VERT_ATTRIB_COLOR0], IM->Attrib[VERT_ATTRIB_COLOR0][count]); if (ctx->Light.ColorMaterialEnabled) { _mesa_update_color_material( ctx, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] ); TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx ); } } if (flag & VERT_BIT_COLOR1) COPY_4FV(ctx->Current.Attrib[VERT_ATTRIB_COLOR1], IM->Attrib[VERT_ATTRIB_COLOR1][count]); if (flag & VERT_BIT_FOG) ctx->Current.Attrib[VERT_ATTRIB_FOG][0] = IM->Attrib[VERT_ATTRIB_FOG][count][0]; if (flag & VERT_BIT_SIX) COPY_4FV(ctx->Current.Attrib[VERT_ATTRIB_SIX], IM->Attrib[VERT_ATTRIB_SIX][count]); if (flag & VERT_BIT_SEVEN) COPY_4FV(ctx->Current.Attrib[VERT_ATTRIB_SEVEN], IM->Attrib[VERT_ATTRIB_SEVEN][count]); if (flag & VERT_BITS_TEX_ANY) { GLuint i; for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { if (flag & VERT_BIT_TEX(i)) { COPY_4FV( ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i], IM->Attrib[VERT_ATTRIB_TEX0 + i][count]); } } } if (flag & VERT_BIT_INDEX) ctx->Current.Index = IM->Index[count]; if (flag & VERT_BIT_EDGEFLAG) ctx->Current.EdgeFlag = IM->EdgeFlag[count]; if (flag & VERT_BIT_MATERIAL) { _mesa_update_material( ctx, IM->Material[IM->LastMaterial], IM->MaterialOrMask ); TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx ); } }
/** * All glWindowPosMESA and glWindowPosARB commands call this function to * update the current raster position. */ static void window_pos3f(GLfloat x, GLfloat y, GLfloat z) { GET_CURRENT_CONTEXT(ctx); GLfloat z2; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); FLUSH_CURRENT(ctx, 0); z2 = CLAMP(z, 0.0F, 1.0F) * (ctx->Viewport.Far - ctx->Viewport.Near) + ctx->Viewport.Near; /* set raster position */ ctx->Current.RasterPos[0] = x; ctx->Current.RasterPos[1] = y; ctx->Current.RasterPos[2] = z2; ctx->Current.RasterPos[3] = 1.0F; ctx->Current.RasterPosValid = GL_TRUE; if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; else ctx->Current.RasterDistance = 0.0; /* raster color = current color or index */ ctx->Current.RasterColor[0] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0], 0.0F, 1.0F); ctx->Current.RasterColor[1] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1], 0.0F, 1.0F); ctx->Current.RasterColor[2] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2], 0.0F, 1.0F); ctx->Current.RasterColor[3] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[0] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[1] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[2] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[3] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3], 0.0F, 1.0F); /* raster texcoord = current texcoord */ COPY_4FV( ctx->Current.RasterTexCoords, ctx->Current.Attrib[VERT_ATTRIB_TEX] ); if (ctx->RenderMode==GL_SELECT) { _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); } }
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); }
void _tnl_generic_copy_pv_extras( struct gl_context *ctx, GLuint dst, GLuint src ) { struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; /* See above comment: */ if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) { COPY_4FV( VB->BackfaceColorPtr->data[dst], VB->BackfaceColorPtr->data[src] ); } if (VB->BackfaceSecondaryColorPtr) { COPY_4FV( VB->BackfaceSecondaryColorPtr->data[dst], VB->BackfaceSecondaryColorPtr->data[src] ); } if (VB->BackfaceIndexPtr) { VB->BackfaceIndexPtr->data[dst][0] = VB->BackfaceIndexPtr->data[src][0]; } _tnl_generic_copy_pv(ctx, dst, src); }
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); }
/* Perform a straight copy between pairs of materials. */ void _mesa_copy_material_pairs( struct gl_material dst[2], const struct gl_material src[2], GLuint bitmask ) { if (bitmask & FRONT_EMISSION_BIT) { COPY_4FV( dst[0].Emission, src[0].Emission ); } if (bitmask & BACK_EMISSION_BIT) { COPY_4FV( dst[1].Emission, src[1].Emission ); } if (bitmask & FRONT_AMBIENT_BIT) { COPY_4FV( dst[0].Ambient, src[0].Ambient ); } if (bitmask & BACK_AMBIENT_BIT) { COPY_4FV( dst[1].Ambient, src[1].Ambient ); } if (bitmask & FRONT_DIFFUSE_BIT) { COPY_4FV( dst[0].Diffuse, src[0].Diffuse ); } if (bitmask & BACK_DIFFUSE_BIT) { COPY_4FV( dst[1].Diffuse, src[1].Diffuse ); } if (bitmask & FRONT_SPECULAR_BIT) { COPY_4FV( dst[0].Specular, src[0].Specular ); } if (bitmask & BACK_SPECULAR_BIT) { COPY_4FV( dst[1].Specular, src[1].Specular ); } if (bitmask & FRONT_SHININESS_BIT) { dst[0].Shininess = src[0].Shininess; } if (bitmask & BACK_SHININESS_BIT) { dst[1].Shininess = src[1].Shininess; } if (bitmask & FRONT_INDEXES_BIT) { dst[0].AmbientIndex = src[0].AmbientIndex; dst[0].DiffuseIndex = src[0].DiffuseIndex; dst[0].SpecularIndex = src[0].SpecularIndex; } if (bitmask & BACK_INDEXES_BIT) { dst[1].AmbientIndex = src[1].AmbientIndex; dst[1].DiffuseIndex = src[1].DiffuseIndex; dst[1].SpecularIndex = src[1].SpecularIndex; } }
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 ); }
/** * 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); }
/** * Upload SAMPLER_BORDER_COLOR_STATE. */ void upload_default_color(struct brw_context *brw, struct gl_sampler_object *sampler, int unit, uint32_t *sdc_offset) { struct gl_context *ctx = &brw->ctx; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_object *texObj = texUnit->_Current; struct gl_texture_image *firstImage = texObj->Image[0][texObj->BaseLevel]; float color[4]; switch (firstImage->_BaseFormat) { case GL_DEPTH_COMPONENT: /* GL specs that border color for depth textures is taken from the * R channel, while the hardware uses A. Spam R into all the * channels for safety. */ color[0] = sampler->BorderColor.f[0]; color[1] = sampler->BorderColor.f[0]; color[2] = sampler->BorderColor.f[0]; color[3] = sampler->BorderColor.f[0]; break; case GL_ALPHA: color[0] = 0.0; color[1] = 0.0; color[2] = 0.0; color[3] = sampler->BorderColor.f[3]; break; case GL_INTENSITY: color[0] = sampler->BorderColor.f[0]; color[1] = sampler->BorderColor.f[0]; color[2] = sampler->BorderColor.f[0]; color[3] = sampler->BorderColor.f[0]; break; case GL_LUMINANCE: color[0] = sampler->BorderColor.f[0]; color[1] = sampler->BorderColor.f[0]; color[2] = sampler->BorderColor.f[0]; color[3] = 1.0; break; case GL_LUMINANCE_ALPHA: color[0] = sampler->BorderColor.f[0]; color[1] = sampler->BorderColor.f[0]; color[2] = sampler->BorderColor.f[0]; color[3] = sampler->BorderColor.f[3]; break; default: color[0] = sampler->BorderColor.f[0]; color[1] = sampler->BorderColor.f[1]; color[2] = sampler->BorderColor.f[2]; color[3] = sampler->BorderColor.f[3]; break; } /* In some cases we use an RGBA surface format for GL RGB textures, * where we've initialized the A channel to 1.0. We also have to set * the border color alpha to 1.0 in that case. */ if (firstImage->_BaseFormat == GL_RGB) color[3] = 1.0; if (brw->gen >= 8) { /* On Broadwell, the border color is represented as four 32-bit floats, * integers, or unsigned values, interpreted according to the surface * format. This matches the sampler->BorderColor union exactly. Since * we use floats both here and in the above reswizzling code, we preserve * the original bit pattern. So we actually handle all three formats. */ float *sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR, 4 * 4, 64, sdc_offset); COPY_4FV(sdc, color); } else if (brw->gen == 5 || brw->gen == 6) { struct gen5_sampler_default_color *sdc; sdc = brw_state_batch(brw, AUB_TRACE_SAMPLER_DEFAULT_COLOR, sizeof(*sdc), 32, sdc_offset); memset(sdc, 0, sizeof(*sdc)); UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[0], color[0]); UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[1], color[1]); UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[2], color[2]); UNCLAMPED_FLOAT_TO_UBYTE(sdc->ub[3], color[3]); UNCLAMPED_FLOAT_TO_USHORT(sdc->us[0], color[0]); UNCLAMPED_FLOAT_TO_USHORT(sdc->us[1], color[1]); UNCLAMPED_FLOAT_TO_USHORT(sdc->us[2], color[2]); UNCLAMPED_FLOAT_TO_USHORT(sdc->us[3], color[3]); UNCLAMPED_FLOAT_TO_SHORT(sdc->s[0], color[0]); UNCLAMPED_FLOAT_TO_SHORT(sdc->s[1], color[1]); UNCLAMPED_FLOAT_TO_SHORT(sdc->s[2], color[2]); UNCLAMPED_FLOAT_TO_SHORT(sdc->s[3], color[3]); sdc->hf[0] = _mesa_float_to_half(color[0]); sdc->hf[1] = _mesa_float_to_half(color[1]); sdc->hf[2] = _mesa_float_to_half(color[2]); sdc->hf[3] = _mesa_float_to_half(color[3]); sdc->b[0] = sdc->s[0] >> 8; sdc->b[1] = sdc->s[1] >> 8; sdc->b[2] = sdc->s[2] >> 8; sdc->b[3] = sdc->s[3] >> 8; sdc->f[0] = color[0]; sdc->f[1] = color[1]; sdc->f[2] = color[2]; sdc->f[3] = color[3]; } else {
void GLAPIENTRY _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) { GLuint maxUnit; const struct gl_texture_unit *texUnit; GET_CURRENT_CONTEXT(ctx); 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, "glGetTexEnvfv(current unit)"); return; } texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; if (target == GL_TEXTURE_ENV) { if (pname == GL_TEXTURE_ENV_COLOR) { COPY_4FV( params, texUnit->EnvColor ); } else { GLint val = get_texenvi(ctx, texUnit, pname); if (val >= 0) { *params = (GLfloat) val; } } } 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, "glGetTexEnvfv(target)" ); return; } if (pname == GL_TEXTURE_LOD_BIAS_EXT) { *params = texUnit->LodBias; } else { _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(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, "glGetTexEnvfv(target)" ); return; } if (pname == GL_COORD_REPLACE_NV) { *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit]; } else { _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" ); return; } } else { _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" ); return; } }
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 ); } }
/** * Perform glClear where mask contains only color, depth, and/or stencil. * * The implementation is based on calling into Mesa to set GL state and * performing normal triangle rendering. The intent of this path is to * have as generic a path as possible, so that any driver could make use of * it. */ void intel_clear_tris(GLcontext *ctx, GLbitfield mask) { struct intel_context *intel = intel_context(ctx); GLfloat dst_z; struct gl_framebuffer *fb = ctx->DrawBuffer; int i; GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE; GLuint saved_shader_program = 0; unsigned int saved_active_texture; struct gl_array_object *arraySave = NULL; if (!intel->clear.arrayObj) init_clear(ctx); assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) == 0); _mesa_PushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT | GL_TRANSFORM_BIT | GL_CURRENT_BIT); saved_active_texture = ctx->Texture.CurrentUnit; /* Disable existing GL state we don't want to apply to a clear. */ _mesa_Disable(GL_ALPHA_TEST); _mesa_Disable(GL_BLEND); _mesa_Disable(GL_CULL_FACE); _mesa_Disable(GL_FOG); _mesa_Disable(GL_POLYGON_SMOOTH); _mesa_Disable(GL_POLYGON_STIPPLE); _mesa_Disable(GL_POLYGON_OFFSET_FILL); _mesa_Disable(GL_LIGHTING); _mesa_Disable(GL_CLIP_PLANE0); _mesa_Disable(GL_CLIP_PLANE1); _mesa_Disable(GL_CLIP_PLANE2); _mesa_Disable(GL_CLIP_PLANE3); _mesa_Disable(GL_CLIP_PLANE4); _mesa_Disable(GL_CLIP_PLANE5); _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) { saved_fp_enable = GL_TRUE; _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); } if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) { saved_vp_enable = GL_TRUE; _mesa_Disable(GL_VERTEX_PROGRAM_ARB); } if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) { saved_shader_program = ctx->Shader.CurrentProgram->Name; _mesa_UseProgramObjectARB(0); } if (ctx->Texture._EnabledUnits != 0) { int i; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { _mesa_ActiveTextureARB(GL_TEXTURE0 + i); _mesa_Disable(GL_TEXTURE_1D); _mesa_Disable(GL_TEXTURE_2D); _mesa_Disable(GL_TEXTURE_3D); if (ctx->Extensions.ARB_texture_cube_map) _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB); if (ctx->Extensions.NV_texture_rectangle) _mesa_Disable(GL_TEXTURE_RECTANGLE_NV); if (ctx->Extensions.MESA_texture_array) { _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT); _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT); } } } /* save current array object, bind our private one */ _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj); _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, intel->clear.arrayObj); intel_meta_set_passthrough_transform(intel); for (i = 0; i < 4; i++) { COPY_4FV(intel->clear.color[i], ctx->Color.ClearColor); } /* convert clear Z from [0,1] to NDC coord in [-1,1] */ dst_z = -1.0 + 2.0 * ctx->Depth.Clear; /* Prepare the vertices, which are the same regardless of which buffer we're * drawing to. */ intel->clear.vertices[0][0] = fb->_Xmin; intel->clear.vertices[0][1] = fb->_Ymin; intel->clear.vertices[0][2] = dst_z; intel->clear.vertices[1][0] = fb->_Xmax; intel->clear.vertices[1][1] = fb->_Ymin; intel->clear.vertices[1][2] = dst_z; intel->clear.vertices[2][0] = fb->_Xmax; intel->clear.vertices[2][1] = fb->_Ymax; intel->clear.vertices[2][2] = dst_z; intel->clear.vertices[3][0] = fb->_Xmin; intel->clear.vertices[3][1] = fb->_Ymax; intel->clear.vertices[3][2] = dst_z; while (mask != 0) { GLuint this_mask = 0; GLuint color_bit; color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS); if (color_bit != 0) this_mask |= (1 << (color_bit - 1)); /* Clear depth/stencil in the same pass as color. */ this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)); /* Select the current color buffer and use the color write mask if * we have one, otherwise don't write any color channels. */ if (this_mask & BUFFER_BIT_FRONT_LEFT) _mesa_DrawBuffer(GL_FRONT_LEFT); else if (this_mask & BUFFER_BIT_BACK_LEFT) _mesa_DrawBuffer(GL_BACK_LEFT); else if (color_bit != 0) _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 + (color_bit - BUFFER_COLOR0 - 1)); else _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); /* Control writing of the depth clear value to depth. */ if (this_mask & BUFFER_BIT_DEPTH) { _mesa_DepthFunc(GL_ALWAYS); _mesa_Enable(GL_DEPTH_TEST); } else { _mesa_Disable(GL_DEPTH_TEST); _mesa_DepthMask(GL_FALSE); } /* Control writing of the stencil clear value to stencil. */ if (this_mask & BUFFER_BIT_STENCIL) { _mesa_Enable(GL_STENCIL_TEST); _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, GL_REPLACE, GL_REPLACE, GL_REPLACE); _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, ctx->Stencil.Clear, ctx->Stencil.WriteMask[0]); } else { _mesa_Disable(GL_STENCIL_TEST); } _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); mask &= ~this_mask; } intel_meta_restore_transform(intel); _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture); if (saved_fp_enable) _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); if (saved_vp_enable) _mesa_Enable(GL_VERTEX_PROGRAM_ARB); if (saved_shader_program) _mesa_UseProgramObjectARB(saved_shader_program); _mesa_PopAttrib(); /* restore current array object */ _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave); _mesa_reference_array_object(ctx, &arraySave, NULL); }
void glGetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) { GLuint maxUnit; const struct gl_texture_unit *texUnit; GET_CURRENT_CONTEXT(ctx); maxUnit = ctx->Const.MaxCombinedTextureImageUnits; // maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV) // ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits; if (ctx->Texture.CurrentUnit >= maxUnit) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnvfv(current unit)"); return; } texUnit = _mesa_get_current_tex_unit(ctx); if (target == GL_TEXTURE_ENV) { if (pname == GL_TEXTURE_ENV_COLOR) { if(ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP)) _mesa_update_state(ctx); if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) COPY_4FV( params, texUnit->EnvColor ); else COPY_4FV( params, texUnit->EnvColorUnclamped ); } else { GLint val = get_texenvi(ctx, texUnit, pname); if (val >= 0) { *params = (GLfloat) val; } } } else if (target == GL_TEXTURE_FILTER_CONTROL) { if (pname == GL_TEXTURE_LOD_BIAS) { *params = texUnit->LodBias; } else { _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(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, "glGetTexEnvfv(target)" ); // return; // } // if (pname == GL_COORD_REPLACE_NV) { // *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit]; // } // else { // _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" ); // return; // } // } else { _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" ); return; } }
static void _tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct immediate *IM = TNL_CURRENT_IM(ctx); GLuint count = IM->Count; struct gl_material *mat; GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, "Materialfv"); if (bitmask == 0) return; if (MESA_VERBOSE & VERBOSE_API) fprintf(stderr, "_tnl_Materialfv\n"); if (tnl->IsolateMaterials && !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */ { _tnl_flush_immediate( IM ); IM = TNL_CURRENT_IM(ctx); count = IM->Count; } if (!(IM->Flag[count] & VERT_MATERIAL)) { if (!IM->Material) { IM->Material = (GLmaterial (*)[2]) MALLOC( sizeof(GLmaterial) * IMM_SIZE * 2 ); IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE ); IM->MaterialMask[IM->LastMaterial] = 0; } else if (IM->MaterialOrMask & ~bitmask) { _mesa_copy_material_pairs( IM->Material[count], IM->Material[IM->LastMaterial], IM->MaterialOrMask & ~bitmask ); } IM->Flag[count] |= VERT_MATERIAL; IM->MaterialMask[count] = 0; IM->MaterialAndMask &= IM->MaterialMask[IM->LastMaterial]; IM->LastMaterial = count; } IM->MaterialOrMask |= bitmask; IM->MaterialMask[count] |= bitmask; mat = IM->Material[count]; if (bitmask & FRONT_AMBIENT_BIT) { COPY_4FV( mat[0].Ambient, params ); } if (bitmask & BACK_AMBIENT_BIT) { COPY_4FV( mat[1].Ambient, params ); } if (bitmask & FRONT_DIFFUSE_BIT) { COPY_4FV( mat[0].Diffuse, params ); } if (bitmask & BACK_DIFFUSE_BIT) { COPY_4FV( mat[1].Diffuse, params ); } if (bitmask & FRONT_SPECULAR_BIT) { COPY_4FV( mat[0].Specular, params ); } if (bitmask & BACK_SPECULAR_BIT) { COPY_4FV( mat[1].Specular, params ); } if (bitmask & FRONT_EMISSION_BIT) { COPY_4FV( mat[0].Emission, params ); } if (bitmask & BACK_EMISSION_BIT) { COPY_4FV( mat[1].Emission, params ); } if (bitmask & FRONT_SHININESS_BIT) { GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F ); mat[0].Shininess = shininess; } if (bitmask & BACK_SHININESS_BIT) { GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F ); mat[1].Shininess = shininess; } if (bitmask & FRONT_INDEXES_BIT) { mat[0].AmbientIndex = params[0]; mat[0].DiffuseIndex = params[1]; mat[0].SpecularIndex = params[2]; } if (bitmask & BACK_INDEXES_BIT) { mat[1].AmbientIndex = params[0]; mat[1].DiffuseIndex = params[1]; mat[1].SpecularIndex = params[2]; } if (tnl->IsolateMaterials && !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */ { _tnl_flush_immediate( IM ); } }
/** * glRasterPos transformation. Typically called via ctx->Driver.RasterPos(). * * \param vObj vertex position in object space */ void _mesa_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]) { if (_mesa_arb_vertex_program_enabled(ctx)) { /* XXX implement this */ _mesa_problem(ctx, "Vertex programs not implemented for glRasterPos"); return; } else { GLfloat eye[4], clip[4], ndc[3], d; GLfloat *norm, eyenorm[3]; GLfloat *objnorm = ctx->Current.Attrib[VERT_ATTRIB_NORMAL]; float scale[3], translate[3]; /* apply modelview matrix: eye = MV * obj */ TRANSFORM_POINT( eye, ctx->ModelviewMatrixStack.Top->m, vObj ); /* apply projection matrix: clip = Proj * eye */ TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye ); /* clip to view volume. */ if (!ctx->Transform.DepthClamp) { if (viewclip_point_z(clip) == 0) { ctx->Current.RasterPosValid = GL_FALSE; return; } } if (!ctx->Transform.RasterPositionUnclipped) { if (viewclip_point_xy(clip) == 0) { ctx->Current.RasterPosValid = GL_FALSE; return; } } /* clip to user clipping planes */ if (ctx->Transform.ClipPlanesEnabled && !userclip_point(ctx, clip)) { ctx->Current.RasterPosValid = GL_FALSE; return; } /* ndc = clip / W */ d = (clip[3] == 0.0F) ? 1.0F : 1.0F / clip[3]; ndc[0] = clip[0] * d; ndc[1] = clip[1] * d; ndc[2] = clip[2] * d; /* wincoord = viewport_mapping(ndc) */ _mesa_get_viewport_xform(ctx, 0, scale, translate); ctx->Current.RasterPos[0] = ndc[0] * scale[0] + translate[0]; ctx->Current.RasterPos[1] = ndc[1] * scale[1] + translate[1]; ctx->Current.RasterPos[2] = ndc[2] * scale[2] + translate[2]; ctx->Current.RasterPos[3] = clip[3]; if (ctx->Transform.DepthClamp) { ctx->Current.RasterPos[3] = CLAMP(ctx->Current.RasterPos[3], ctx->ViewportArray[0].Near, ctx->ViewportArray[0].Far); } /* compute raster distance */ if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; else ctx->Current.RasterDistance = sqrtf( eye[0]*eye[0] + eye[1]*eye[1] + eye[2]*eye[2] ); /* compute transformed normal vector (for lighting or texgen) */ if (ctx->_NeedEyeCoords) { const GLfloat *inv = ctx->ModelviewMatrixStack.Top->inv; TRANSFORM_NORMAL( eyenorm, objnorm, inv ); norm = eyenorm; } else { norm = objnorm; } /* update raster color */ if (ctx->Light.Enabled) { /* lighting */ shade_rastpos( ctx, vObj, norm, ctx->Current.RasterColor, ctx->Current.RasterSecondaryColor ); } else { /* use current color */ COPY_4FV(ctx->Current.RasterColor, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]); COPY_4FV(ctx->Current.RasterSecondaryColor, ctx->Current.Attrib[VERT_ATTRIB_COLOR1]); } /* texture coords */ { GLuint u; for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { GLfloat tc[4]; COPY_4V(tc, ctx->Current.Attrib[VERT_ATTRIB_TEX0 + u]); if (ctx->Texture.Unit[u].TexGenEnabled) { compute_texgen(ctx, vObj, eye, norm, u, tc); } TRANSFORM_POINT(ctx->Current.RasterTexCoords[u], ctx->TextureMatrixStack[u].Top->m, tc); } } ctx->Current.RasterPosValid = GL_TRUE; } if (ctx->RenderMode == GL_SELECT) { _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); } }
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 ); }