source: trunk/src/opengl/mesa/attrib.c@ 3721

Last change on this file since 3721 was 3598, checked in by jeroen, 25 years ago

* empty log message *

File size: 36.4 KB
Line 
1/* $Id: attrib.c,v 1.2 2000-05-23 20:40:22 jeroen Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.1
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28#ifdef PC_HEADER
29#include "all.h"
30#else
31#include "glheader.h"
32#include "attrib.h"
33#include "context.h"
34#include "enable.h"
35#include "enums.h"
36#include "mem.h"
37#include "buffers.h"
38#include "macros.h"
39#include "simple_list.h"
40#include "texstate.h"
41#include "types.h"
42#endif
43
44
45
46
47/*
48 * Allocate a new attribute state node. These nodes have a
49 * "kind" value and a pointer to a struct of state data.
50 */
51static struct gl_attrib_node *
52new_attrib_node( GLbitfield kind )
53{
54 struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node);
55 if (an) {
56 an->kind = kind;
57 }
58 return an;
59}
60
61
62
63/*
64 * Copy texture object state from one texture object to another.
65 */
66static void
67copy_texobj_state( struct gl_texture_object *dest,
68 const struct gl_texture_object *src )
69{
70 /*
71 dest->Name = src->Name;
72 dest->Dimensions = src->Dimensions;
73 */
74 dest->Priority = src->Priority;
75 dest->BorderColor[0] = src->BorderColor[0];
76 dest->BorderColor[1] = src->BorderColor[1];
77 dest->BorderColor[2] = src->BorderColor[2];
78 dest->BorderColor[3] = src->BorderColor[3];
79 dest->WrapS = src->WrapS;
80 dest->WrapT = src->WrapT;
81 dest->WrapR = src->WrapR;
82 dest->MinFilter = src->MinFilter;
83 dest->MagFilter = src->MagFilter;
84 dest->MinLod = src->MinLod;
85 dest->MaxLod = src->MaxLod;
86 dest->BaseLevel = src->BaseLevel;
87 dest->MaxLevel = src->MaxLevel;
88 dest->P = src->P;
89 dest->M = src->M;
90 dest->MinMagThresh = src->MinMagThresh;
91 dest->Palette = src->Palette;
92 dest->Complete = src->Complete;
93 dest->SampleFunc = src->SampleFunc;
94}
95
96
97
98void
99_mesa_PushAttrib(GLbitfield mask)
100{
101 struct gl_attrib_node *newnode;
102 struct gl_attrib_node *head;
103
104 GET_CURRENT_CONTEXT(ctx);
105 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPushAttrib");
106
107 if (MESA_VERBOSE&VERBOSE_API)
108 fprintf(stderr, "glPushAttrib %x\n", (int)mask);
109
110 if (ctx->AttribStackDepth>=MAX_ATTRIB_STACK_DEPTH) {
111 gl_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" );
112 return;
113 }
114
115 /* Build linked list of attribute nodes which save all attribute */
116 /* groups specified by the mask. */
117 head = NULL;
118
119 if (mask & GL_ACCUM_BUFFER_BIT) {
120 struct gl_accum_attrib *attr;
121 attr = MALLOC_STRUCT( gl_accum_attrib );
122 MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) );
123 newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT );
124 newnode->data = attr;
125 newnode->next = head;
126 head = newnode;
127 }
128
129 if (mask & GL_COLOR_BUFFER_BIT) {
130 struct gl_colorbuffer_attrib *attr;
131 attr = MALLOC_STRUCT( gl_colorbuffer_attrib );
132 MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) );
133 newnode = new_attrib_node( GL_COLOR_BUFFER_BIT );
134 newnode->data = attr;
135 newnode->next = head;
136 head = newnode;
137 }
138
139 if (mask & GL_CURRENT_BIT) {
140 struct gl_current_attrib *attr;
141 attr = MALLOC_STRUCT( gl_current_attrib );
142 MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
143 newnode = new_attrib_node( GL_CURRENT_BIT );
144 newnode->data = attr;
145 newnode->next = head;
146 head = newnode;
147 }
148
149 if (mask & GL_DEPTH_BUFFER_BIT) {
150 struct gl_depthbuffer_attrib *attr;
151 attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
152 MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) );
153 newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT );
154 newnode->data = attr;
155 newnode->next = head;
156 head = newnode;
157 }
158
159 if (mask & GL_ENABLE_BIT) {
160 struct gl_enable_attrib *attr;
161 GLuint i;
162 attr = MALLOC_STRUCT( gl_enable_attrib );
163 /* Copy enable flags from all other attributes into the enable struct. */
164 attr->AlphaTest = ctx->Color.AlphaEnabled;
165 attr->AutoNormal = ctx->Eval.AutoNormal;
166 attr->Blend = ctx->Color.BlendEnabled;
167 for (i=0;i<MAX_CLIP_PLANES;i++) {
168 attr->ClipPlane[i] = ctx->Transform.ClipEnabled[i];
169 }
170 attr->ColorMaterial = ctx->Light.ColorMaterialEnabled;
171 attr->CullFace = ctx->Polygon.CullFlag;
172 attr->DepthTest = ctx->Depth.Test;
173 attr->Dither = ctx->Color.DitherFlag;
174 attr->Fog = ctx->Fog.Enabled;
175 for (i=0;i<MAX_LIGHTS;i++) {
176 attr->Light[i] = ctx->Light.Light[i].Enabled;
177 }
178 attr->Lighting = ctx->Light.Enabled;
179 attr->LineSmooth = ctx->Line.SmoothFlag;
180 attr->LineStipple = ctx->Line.StippleFlag;
181 attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled;
182 attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled;
183 attr->Map1Color4 = ctx->Eval.Map1Color4;
184 attr->Map1Index = ctx->Eval.Map1Index;
185 attr->Map1Normal = ctx->Eval.Map1Normal;
186 attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1;
187 attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2;
188 attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3;
189 attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4;
190 attr->Map1Vertex3 = ctx->Eval.Map1Vertex3;
191 attr->Map1Vertex4 = ctx->Eval.Map1Vertex4;
192 attr->Map2Color4 = ctx->Eval.Map2Color4;
193 attr->Map2Index = ctx->Eval.Map2Index;
194 attr->Map2Normal = ctx->Eval.Map2Normal;
195 attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1;
196 attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2;
197 attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3;
198 attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4;
199 attr->Map2Vertex3 = ctx->Eval.Map2Vertex3;
200 attr->Map2Vertex4 = ctx->Eval.Map2Vertex4;
201 attr->Normalize = ctx->Transform.Normalize;
202 attr->PointSmooth = ctx->Point.SmoothFlag;
203 attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint;
204 attr->PolygonOffsetLine = ctx->Polygon.OffsetLine;
205 attr->PolygonOffsetFill = ctx->Polygon.OffsetFill;
206 attr->PolygonSmooth = ctx->Polygon.SmoothFlag;
207 attr->PolygonStipple = ctx->Polygon.StippleFlag;
208 attr->RescaleNormals = ctx->Transform.RescaleNormals;
209 attr->Scissor = ctx->Scissor.Enabled;
210 attr->Stencil = ctx->Stencil.Enabled;
211 attr->Texture = ctx->Texture.Enabled;
212 for (i=0; i<MAX_TEXTURE_UNITS; i++) {
213 attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled;
214 }
215 newnode = new_attrib_node( GL_ENABLE_BIT );
216 newnode->data = attr;
217 newnode->next = head;
218 head = newnode;
219 }
220
221 if (mask & GL_EVAL_BIT) {
222 struct gl_eval_attrib *attr;
223 attr = MALLOC_STRUCT( gl_eval_attrib );
224 MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) );
225 newnode = new_attrib_node( GL_EVAL_BIT );
226 newnode->data = attr;
227 newnode->next = head;
228 head = newnode;
229 }
230
231 if (mask & GL_FOG_BIT) {
232 struct gl_fog_attrib *attr;
233 attr = MALLOC_STRUCT( gl_fog_attrib );
234 MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) );
235 newnode = new_attrib_node( GL_FOG_BIT );
236 newnode->data = attr;
237 newnode->next = head;
238 head = newnode;
239 }
240
241 if (mask & GL_HINT_BIT) {
242 struct gl_hint_attrib *attr;
243 attr = MALLOC_STRUCT( gl_hint_attrib );
244 MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) );
245 newnode = new_attrib_node( GL_HINT_BIT );
246 newnode->data = attr;
247 newnode->next = head;
248 head = newnode;
249 }
250
251 if (mask & GL_LIGHTING_BIT) {
252 struct gl_light_attrib *attr;
253 attr = MALLOC_STRUCT( gl_light_attrib );
254 MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) );
255 newnode = new_attrib_node( GL_LIGHTING_BIT );
256 newnode->data = attr;
257 newnode->next = head;
258 head = newnode;
259 }
260
261 if (mask & GL_LINE_BIT) {
262 struct gl_line_attrib *attr;
263 attr = MALLOC_STRUCT( gl_line_attrib );
264 MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) );
265 newnode = new_attrib_node( GL_LINE_BIT );
266 newnode->data = attr;
267 newnode->next = head;
268 head = newnode;
269 }
270
271 if (mask & GL_LIST_BIT) {
272 struct gl_list_attrib *attr;
273 attr = MALLOC_STRUCT( gl_list_attrib );
274 MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) );
275 newnode = new_attrib_node( GL_LIST_BIT );
276 newnode->data = attr;
277 newnode->next = head;
278 head = newnode;
279 }
280
281 if (mask & GL_PIXEL_MODE_BIT) {
282 struct gl_pixel_attrib *attr;
283 attr = MALLOC_STRUCT( gl_pixel_attrib );
284 MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) );
285 newnode = new_attrib_node( GL_PIXEL_MODE_BIT );
286 newnode->data = attr;
287 newnode->next = head;
288 head = newnode;
289 }
290
291 if (mask & GL_POINT_BIT) {
292 struct gl_point_attrib *attr;
293 attr = MALLOC_STRUCT( gl_point_attrib );
294 MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) );
295 newnode = new_attrib_node( GL_POINT_BIT );
296 newnode->data = attr;
297 newnode->next = head;
298 head = newnode;
299 }
300
301 if (mask & GL_POLYGON_BIT) {
302 struct gl_polygon_attrib *attr;
303 attr = MALLOC_STRUCT( gl_polygon_attrib );
304 MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) );
305 newnode = new_attrib_node( GL_POLYGON_BIT );
306 newnode->data = attr;
307 newnode->next = head;
308 head = newnode;
309 }
310
311 if (mask & GL_POLYGON_STIPPLE_BIT) {
312 GLuint *stipple;
313 stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) );
314 MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) );
315 newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT );
316 newnode->data = stipple;
317 newnode->next = head;
318 head = newnode;
319 }
320
321 if (mask & GL_SCISSOR_BIT) {
322 struct gl_scissor_attrib *attr;
323 attr = MALLOC_STRUCT( gl_scissor_attrib );
324 MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) );
325 newnode = new_attrib_node( GL_SCISSOR_BIT );
326 newnode->data = attr;
327 newnode->next = head;
328 head = newnode;
329 }
330
331 if (mask & GL_STENCIL_BUFFER_BIT) {
332 struct gl_stencil_attrib *attr;
333 attr = MALLOC_STRUCT( gl_stencil_attrib );
334 MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) );
335 newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT );
336 newnode->data = attr;
337 newnode->next = head;
338 head = newnode;
339 }
340
341 if (mask & GL_TEXTURE_BIT) {
342 struct gl_texture_attrib *attr;
343 GLuint u;
344 /* Take care of texture object reference counters */
345 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
346 ctx->Texture.Unit[u].CurrentD[1]->RefCount++;
347 ctx->Texture.Unit[u].CurrentD[2]->RefCount++;
348 ctx->Texture.Unit[u].CurrentD[3]->RefCount++;
349 }
350 attr = MALLOC_STRUCT( gl_texture_attrib );
351 MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) );
352 /* copy state of the currently bound texture objects */
353 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
354 copy_texobj_state(&attr->Unit[u].Saved1D, attr->Unit[u].CurrentD[1]);
355 copy_texobj_state(&attr->Unit[u].Saved2D, attr->Unit[u].CurrentD[2]);
356 copy_texobj_state(&attr->Unit[u].Saved3D, attr->Unit[u].CurrentD[3]);
357 }
358 newnode = new_attrib_node( GL_TEXTURE_BIT );
359 newnode->data = attr;
360 newnode->next = head;
361 head = newnode;
362 }
363
364 if (mask & GL_TRANSFORM_BIT) {
365 struct gl_transform_attrib *attr;
366 attr = MALLOC_STRUCT( gl_transform_attrib );
367 MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) );
368 newnode = new_attrib_node( GL_TRANSFORM_BIT );
369 newnode->data = attr;
370 newnode->next = head;
371 head = newnode;
372 }
373
374 if (mask & GL_VIEWPORT_BIT) {
375 struct gl_viewport_attrib *attr;
376 attr = MALLOC_STRUCT( gl_viewport_attrib );
377 MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) );
378 newnode = new_attrib_node( GL_VIEWPORT_BIT );
379 newnode->data = attr;
380 newnode->next = head;
381 head = newnode;
382 }
383
384 ctx->AttribStack[ctx->AttribStackDepth] = head;
385 ctx->AttribStackDepth++;
386}
387
388
389
390/*
391 * This function is kind of long just because we have to call a lot
392 * of device driver functions to update device driver state.
393 */
394void
395_mesa_PopAttrib(void)
396{
397 struct gl_attrib_node *attr, *next;
398 GET_CURRENT_CONTEXT(ctx);
399
400 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPopAttrib");
401
402
403 if (ctx->AttribStackDepth==0) {
404 gl_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" );
405 return;
406 }
407
408 ctx->AttribStackDepth--;
409 attr = ctx->AttribStack[ctx->AttribStackDepth];
410
411 while (attr) {
412
413 if (MESA_VERBOSE&VERBOSE_API)
414 fprintf(stderr, "glPopAttrib %s\n", gl_lookup_enum_by_nr(attr->kind));
415
416 switch (attr->kind) {
417 case GL_ACCUM_BUFFER_BIT:
418 MEMCPY( &ctx->Accum, attr->data, sizeof(struct gl_accum_attrib) );
419 break;
420 case GL_COLOR_BUFFER_BIT:
421 {
422 GLenum oldDrawBuffer = ctx->Color.DrawBuffer;
423 GLenum oldAlphaFunc = ctx->Color.AlphaFunc;
424 GLubyte oldAlphaRef = ctx->Color.AlphaRef;
425 GLenum oldBlendSrc = ctx->Color.BlendSrcRGB;
426 GLenum oldBlendDst = ctx->Color.BlendDstRGB;
427 GLenum oldLogicOp = ctx->Color.LogicOp;
428 MEMCPY( &ctx->Color, attr->data,
429 sizeof(struct gl_colorbuffer_attrib) );
430 if (ctx->Color.DrawBuffer != oldDrawBuffer) {
431 _mesa_DrawBuffer( ctx->Color.DrawBuffer);
432 }
433 if ((ctx->Color.BlendSrcRGB != oldBlendSrc ||
434 ctx->Color.BlendDstRGB != oldBlendDst) &&
435 ctx->Driver.BlendFunc)
436 (*ctx->Driver.BlendFunc)( ctx, ctx->Color.BlendSrcRGB,
437 ctx->Color.BlendDstRGB);
438 if (ctx->Color.LogicOp != oldLogicOp &&
439 ctx->Driver.LogicOpcode) {
440 ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp );
441 }
442 if (ctx->Visual->RGBAflag) {
443 GLubyte r = (GLint) (ctx->Color.ClearColor[0] * 255.0F);
444 GLubyte g = (GLint) (ctx->Color.ClearColor[1] * 255.0F);
445 GLubyte b = (GLint) (ctx->Color.ClearColor[2] * 255.0F);
446 GLubyte a = (GLint) (ctx->Color.ClearColor[3] * 255.0F);
447 (*ctx->Driver.ClearColor)( ctx, r, g, b, a );
448 if ((ctx->Color.AlphaFunc != oldAlphaFunc ||
449 ctx->Color.AlphaRef != oldAlphaRef) &&
450 ctx->Driver.AlphaFunc)
451 (*ctx->Driver.AlphaFunc)( ctx, ctx->Color.AlphaFunc,
452 ctx->Color.AlphaRef / 255.0F);
453 if (ctx->Driver.ColorMask) {
454 (*ctx->Driver.ColorMask)(ctx,
455 ctx->Color.ColorMask[0],
456 ctx->Color.ColorMask[1],
457 ctx->Color.ColorMask[2],
458 ctx->Color.ColorMask[3]);
459 }
460 }
461 else {
462 (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex);
463 }
464 }
465 break;
466 case GL_CURRENT_BIT:
467 MEMCPY( &ctx->Current, attr->data,
468 sizeof(struct gl_current_attrib) );
469 break;
470 case GL_DEPTH_BUFFER_BIT:
471 {
472 GLenum oldDepthFunc = ctx->Depth.Func;
473 GLboolean oldDepthMask = ctx->Depth.Mask;
474 GLfloat oldDepthClear = ctx->Depth.Clear;
475 MEMCPY( &ctx->Depth, attr->data,
476 sizeof(struct gl_depthbuffer_attrib) );
477 if (ctx->Depth.Func != oldDepthFunc && ctx->Driver.DepthFunc)
478 (*ctx->Driver.DepthFunc)( ctx, ctx->Depth.Func );
479 if (ctx->Depth.Mask != oldDepthMask && ctx->Driver.DepthMask)
480 (*ctx->Driver.DepthMask)( ctx, ctx->Depth.Mask );
481 if (ctx->Depth.Clear != oldDepthClear && ctx->Driver.ClearDepth)
482 (*ctx->Driver.ClearDepth)( ctx, ctx->Depth.Clear );
483 }
484 break;
485 case GL_ENABLE_BIT:
486 {
487 const struct gl_enable_attrib *enable;
488 enable = (const struct gl_enable_attrib *) attr->data;
489
490#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \
491 if ((VALUE) != (NEWVALUE)) { \
492 _mesa_set_enable( ctx, ENUM, (NEWVALUE) ); \
493 }
494
495 TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST);
496 TEST_AND_UPDATE(ctx->Transform.Normalize, enable->AutoNormal, GL_NORMALIZE);
497 TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND);
498 {
499 GLuint i;
500 for (i=0;i<MAX_CLIP_PLANES;i++) {
501 if (ctx->Transform.ClipEnabled[i] != enable->ClipPlane[i])
502 _mesa_set_enable( ctx, (GLenum) (GL_CLIP_PLANE0 + i), enable->ClipPlane[i] );
503 }
504 }
505 TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial, GL_COLOR_MATERIAL);
506 TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
507 TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST);
508 TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
509 TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG);
510 TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING);
511 TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH);
512 TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple, GL_LINE_STIPPLE);
513 TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp, GL_INDEX_LOGIC_OP);
514 TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp, GL_COLOR_LOGIC_OP);
515 TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4);
516 TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX);
517 TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL);
518 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1, GL_MAP1_TEXTURE_COORD_1);
519 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2, GL_MAP1_TEXTURE_COORD_2);
520 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3, GL_MAP1_TEXTURE_COORD_3);
521 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4, GL_MAP1_TEXTURE_COORD_4);
522 TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3, GL_MAP1_VERTEX_3);
523 TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4, GL_MAP1_VERTEX_4);
524 TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4);
525 TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX);
526 TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL);
527 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1, GL_MAP2_TEXTURE_COORD_1);
528 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2, GL_MAP2_TEXTURE_COORD_2);
529 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3, GL_MAP2_TEXTURE_COORD_3);
530 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4, GL_MAP2_TEXTURE_COORD_4);
531 TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3, GL_MAP2_VERTEX_3);
532 TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4, GL_MAP2_VERTEX_4);
533 TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE);
534 TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals, GL_RESCALE_NORMAL_EXT);
535 TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth, GL_POINT_SMOOTH);
536 TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint, GL_POLYGON_OFFSET_POINT);
537 TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine, GL_POLYGON_OFFSET_LINE);
538 TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill, GL_POLYGON_OFFSET_FILL);
539 TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth, GL_POLYGON_SMOOTH);
540 TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple, GL_POLYGON_STIPPLE);
541 TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST);
542 TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST);
543 if (ctx->Texture.Enabled != enable->Texture) {
544 ctx->Texture.Enabled = enable->Texture;
545 if (ctx->Driver.Enable) {
546 if (ctx->Driver.ActiveTexture)
547 (*ctx->Driver.ActiveTexture)( ctx, 0 );
548 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D, (GLboolean) (enable->Texture & TEXTURE0_1D) );
549 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D, (GLboolean) (enable->Texture & TEXTURE0_2D) );
550 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D, (GLboolean) (enable->Texture & TEXTURE0_3D) );
551 if (ctx->Driver.ActiveTexture)
552 (*ctx->Driver.ActiveTexture)( ctx, 1 );
553 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D, (GLboolean) (enable->Texture & TEXTURE1_1D) );
554 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D, (GLboolean) (enable->Texture & TEXTURE1_2D) );
555 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D, (GLboolean) (enable->Texture & TEXTURE1_3D) );
556 if (ctx->Driver.ActiveTexture)
557 (*ctx->Driver.ActiveTexture)( ctx, ctx->Texture.CurrentUnit );
558 }
559 }
560#undef TEST_AND_UPDATE
561 {
562 GLuint i;
563 for (i=0; i<MAX_TEXTURE_UNITS; i++) {
564 if (ctx->Texture.Unit[i].TexGenEnabled != enable->TexGen[i]) {
565 ctx->Texture.Unit[i].TexGenEnabled = enable->TexGen[i];
566
567 /* ctx->Enabled recalculated in state change
568 processing */
569
570 if (ctx->Driver.Enable) {
571 if (ctx->Driver.ActiveTexture)
572 (*ctx->Driver.ActiveTexture)( ctx, i );
573 if (enable->TexGen[i] & S_BIT)
574 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_TRUE);
575 else
576 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_FALSE);
577 if (enable->TexGen[i] & T_BIT)
578 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_TRUE);
579 else
580 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_FALSE);
581 if (enable->TexGen[i] & R_BIT)
582 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_TRUE);
583 else
584 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_FALSE);
585 if (enable->TexGen[i] & Q_BIT)
586 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
587 else
588 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
589 }
590 }
591 }
592 if (ctx->Driver.ActiveTexture)
593 (*ctx->Driver.ActiveTexture)( ctx, ctx->Texture.CurrentUnit );
594 }
595 }
596 break;
597 case GL_EVAL_BIT:
598 MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) );
599 break;
600 case GL_FOG_BIT:
601 {
602 GLboolean anyChange = (GLboolean) (memcmp( &ctx->Fog, attr->data, sizeof(struct gl_fog_attrib) ) != 0);
603 MEMCPY( &ctx->Fog, attr->data, sizeof(struct gl_fog_attrib) );
604 if (anyChange && ctx->Driver.Fogfv) {
605 const GLfloat mode = (GLfloat) ctx->Fog.Mode;
606 const GLfloat density = ctx->Fog.Density;
607 const GLfloat start = ctx->Fog.Start;
608 const GLfloat end = ctx->Fog.End;
609 const GLfloat index = ctx->Fog.Index;
610 (*ctx->Driver.Fogfv)( ctx, GL_FOG_MODE, &mode);
611 (*ctx->Driver.Fogfv)( ctx, GL_FOG_DENSITY, &density );
612 (*ctx->Driver.Fogfv)( ctx, GL_FOG_START, &start );
613 (*ctx->Driver.Fogfv)( ctx, GL_FOG_END, &end );
614 (*ctx->Driver.Fogfv)( ctx, GL_FOG_INDEX, &index );
615 (*ctx->Driver.Fogfv)( ctx, GL_FOG_COLOR, ctx->Fog.Color );
616 }
617 ctx->Enabled &= ~ENABLE_FOG;
618 if (ctx->Fog.Enabled) ctx->Enabled |= ENABLE_FOG;
619 }
620 break;
621 case GL_HINT_BIT:
622 MEMCPY( &ctx->Hint, attr->data, sizeof(struct gl_hint_attrib) );
623 if (ctx->Driver.Hint) {
624 (*ctx->Driver.Hint)( ctx, GL_PERSPECTIVE_CORRECTION_HINT,
625 ctx->Hint.PerspectiveCorrection );
626 (*ctx->Driver.Hint)( ctx, GL_POINT_SMOOTH_HINT,
627 ctx->Hint.PointSmooth);
628 (*ctx->Driver.Hint)( ctx, GL_LINE_SMOOTH_HINT,
629 ctx->Hint.LineSmooth );
630 (*ctx->Driver.Hint)( ctx, GL_POLYGON_SMOOTH_HINT,
631 ctx->Hint.PolygonSmooth );
632 (*ctx->Driver.Hint)( ctx, GL_FOG_HINT, ctx->Hint.Fog );
633 }
634 break;
635 case GL_LIGHTING_BIT:
636 MEMCPY( &ctx->Light, attr->data, sizeof(struct gl_light_attrib) );
637 if (ctx->Driver.Enable) {
638 GLuint i;
639 for (i = 0; i < MAX_LIGHTS; i++) {
640 GLenum light = (GLenum) (GL_LIGHT0 + i);
641 (*ctx->Driver.Enable)( ctx, light, ctx->Light.Light[i].Enabled );
642 }
643 (*ctx->Driver.Enable)( ctx, GL_LIGHTING, ctx->Light.Enabled );
644 }
645 if (ctx->Light.ShadeModel == GL_FLAT)
646 ctx->TriangleCaps |= DD_FLATSHADE;
647 else
648 ctx->TriangleCaps &= ~DD_FLATSHADE;
649 if (ctx->Driver.ShadeModel)
650 (*ctx->Driver.ShadeModel)(ctx, ctx->Light.ShadeModel);
651 ctx->Enabled &= ~ENABLE_LIGHT;
652 if (ctx->Light.Enabled && !is_empty_list(&ctx->Light.EnabledList))
653 ctx->Enabled |= ENABLE_LIGHT;
654 break;
655 case GL_LINE_BIT:
656 MEMCPY( &ctx->Line, attr->data, sizeof(struct gl_line_attrib) );
657 if (ctx->Driver.Enable) {
658 (*ctx->Driver.Enable)( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
659 (*ctx->Driver.Enable)( ctx, GL_LINE_STIPPLE, ctx->Line.StippleFlag );
660 }
661 if (ctx->Driver.LineStipple)
662 (*ctx->Driver.LineStipple)(ctx, ctx->Line.StippleFactor,
663 ctx->Line.StipplePattern);
664 if (ctx->Driver.LineWidth)
665 (*ctx->Driver.LineWidth)(ctx, ctx->Line.Width);
666 break;
667 case GL_LIST_BIT:
668 MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) );
669 break;
670 case GL_PIXEL_MODE_BIT:
671 MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) );
672 break;
673 case GL_POINT_BIT:
674 MEMCPY( &ctx->Point, attr->data, sizeof(struct gl_point_attrib) );
675 if (ctx->Driver.Enable)
676 (*ctx->Driver.Enable)( ctx, GL_POINT_SMOOTH, ctx->Point.SmoothFlag );
677 break;
678 case GL_POLYGON_BIT:
679 {
680 GLenum oldFrontMode = ctx->Polygon.FrontMode;
681 GLenum oldBackMode = ctx->Polygon.BackMode;
682 MEMCPY( &ctx->Polygon, attr->data,
683 sizeof(struct gl_polygon_attrib) );
684 if ((ctx->Polygon.FrontMode != oldFrontMode ||
685 ctx->Polygon.BackMode != oldBackMode) &&
686 ctx->Driver.PolygonMode) {
687 (*ctx->Driver.PolygonMode)( ctx, GL_FRONT, ctx->Polygon.FrontMode);
688 (*ctx->Driver.PolygonMode)( ctx, GL_BACK, ctx->Polygon.BackMode);
689 }
690 if (ctx->Driver.CullFace)
691 ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode );
692
693 if (ctx->Driver.FrontFace)
694 ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace );
695
696 if (ctx->Driver.Enable)
697 (*ctx->Driver.Enable)( ctx, GL_POLYGON_SMOOTH, ctx->Polygon.SmoothFlag );
698 }
699 break;
700 case GL_POLYGON_STIPPLE_BIT:
701 MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) );
702 if (ctx->Driver.PolygonStipple)
703 ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data );
704 break;
705 case GL_SCISSOR_BIT:
706 MEMCPY( &ctx->Scissor, attr->data,
707 sizeof(struct gl_scissor_attrib) );
708 if (ctx->Driver.Enable)
709 (*ctx->Driver.Enable)( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
710 if (ctx->Driver.Scissor)
711 ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
712 ctx->Scissor.Width, ctx->Scissor.Height );
713 break;
714 case GL_STENCIL_BUFFER_BIT:
715 MEMCPY( &ctx->Stencil, attr->data,
716 sizeof(struct gl_stencil_attrib) );
717 if (ctx->Driver.StencilFunc)
718 (*ctx->Driver.StencilFunc)( ctx, ctx->Stencil.Function,
719 ctx->Stencil.Ref, ctx->Stencil.ValueMask);
720 if (ctx->Driver.StencilMask)
721 (*ctx->Driver.StencilMask)( ctx, ctx->Stencil.WriteMask );
722 if (ctx->Driver.StencilOp)
723 (*ctx->Driver.StencilOp)( ctx, ctx->Stencil.FailFunc,
724 ctx->Stencil.ZFailFunc, ctx->Stencil.ZPassFunc);
725 if (ctx->Driver.ClearStencil)
726 (*ctx->Driver.ClearStencil)( ctx, ctx->Stencil.Clear );
727 if (ctx->Driver.Enable)
728 (*ctx->Driver.Enable)( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
729 ctx->TriangleCaps &= ~DD_STENCIL;
730 if (ctx->Stencil.Enabled)
731 ctx->TriangleCaps |= DD_STENCIL;
732
733 break;
734 case GL_TRANSFORM_BIT:
735 MEMCPY( &ctx->Transform, attr->data,
736 sizeof(struct gl_transform_attrib) );
737 if (ctx->Driver.Enable) {
738 (*ctx->Driver.Enable)( ctx, GL_NORMALIZE, ctx->Transform.Normalize );
739 (*ctx->Driver.Enable)( ctx, GL_RESCALE_NORMAL_EXT, ctx->Transform.RescaleNormals );
740 }
741 ctx->Enabled &= ~(ENABLE_NORMALIZE|ENABLE_RESCALE);
742 if (ctx->Transform.Normalize) ctx->Enabled |= ENABLE_NORMALIZE;
743 if (ctx->Transform.RescaleNormals) ctx->Enabled |= ENABLE_RESCALE;
744 break;
745 case GL_TEXTURE_BIT:
746 /* Take care of texture object reference counters */
747 {
748 GLuint u;
749 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
750 ctx->Texture.Unit[u].CurrentD[1]->RefCount--;
751 ctx->Texture.Unit[u].CurrentD[2]->RefCount--;
752 ctx->Texture.Unit[u].CurrentD[3]->RefCount--;
753 }
754 MEMCPY( &ctx->Texture, attr->data,
755 sizeof(struct gl_texture_attrib) );
756 /* restore state of the currently bound texture objects */
757 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
758 copy_texobj_state( ctx->Texture.Unit[u].CurrentD[1],
759 &(ctx->Texture.Unit[u].Saved1D) );
760 copy_texobj_state( ctx->Texture.Unit[u].CurrentD[2],
761 &(ctx->Texture.Unit[u].Saved2D) );
762 copy_texobj_state( ctx->Texture.Unit[u].CurrentD[3],
763 &(ctx->Texture.Unit[u].Saved3D) );
764 gl_put_texobj_on_dirty_list( ctx, ctx->Texture.Unit[u].CurrentD[1] );
765 gl_put_texobj_on_dirty_list( ctx, ctx->Texture.Unit[u].CurrentD[2] );
766 gl_put_texobj_on_dirty_list( ctx, ctx->Texture.Unit[u].CurrentD[3] );
767
768 }
769 }
770 break;
771 case GL_VIEWPORT_BIT:
772 {
773 struct gl_viewport_attrib *v =
774 (struct gl_viewport_attrib *)attr->data;
775
776 _mesa_Viewport( v->X, v->Y, v->Width, v->Height );
777 _mesa_DepthRange( v->Near, v->Far );
778 break;
779 }
780 default:
781 gl_problem( ctx, "Bad attrib flag in PopAttrib");
782 break;
783 }
784
785 next = attr->next;
786 FREE( attr->data );
787 FREE( attr );
788 attr = next;
789 }
790
791 ctx->NewState = NEW_ALL;
792}
793
794
795#define GL_CLIENT_PACK_BIT (1<<20)
796#define GL_CLIENT_UNPACK_BIT (1<<21)
797
798
799void
800_mesa_PushClientAttrib(GLbitfield mask)
801{
802 struct gl_attrib_node *newnode;
803 struct gl_attrib_node *head;
804
805 GET_CURRENT_CONTEXT(ctx);
806 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPushClientAttrib");
807
808 if (ctx->ClientAttribStackDepth>=MAX_CLIENT_ATTRIB_STACK_DEPTH) {
809 gl_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" );
810 return;
811 }
812
813 /* Build linked list of attribute nodes which save all attribute */
814 /* groups specified by the mask. */
815 head = NULL;
816
817 if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
818 struct gl_pixelstore_attrib *attr;
819 /* packing attribs */
820 attr = MALLOC_STRUCT( gl_pixelstore_attrib );
821 MEMCPY( attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib) );
822 newnode = new_attrib_node( GL_CLIENT_PACK_BIT );
823 newnode->data = attr;
824 newnode->next = head;
825 head = newnode;
826 /* unpacking attribs */
827 attr = MALLOC_STRUCT( gl_pixelstore_attrib );
828 MEMCPY( attr, &ctx->Unpack, sizeof(struct gl_pixelstore_attrib) );
829 newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT );
830 newnode->data = attr;
831 newnode->next = head;
832 head = newnode;
833 }
834 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
835 struct gl_array_attrib *attr;
836 attr = MALLOC_STRUCT( gl_array_attrib );
837 MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) );
838 newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT );
839 newnode->data = attr;
840 newnode->next = head;
841 head = newnode;
842 }
843
844 ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
845 ctx->ClientAttribStackDepth++;
846}
847
848
849
850
851void
852_mesa_PopClientAttrib(void)
853{
854 struct gl_attrib_node *attr, *next;
855
856 GET_CURRENT_CONTEXT(ctx);
857 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPopClientAttrib");
858
859 if (ctx->ClientAttribStackDepth==0) {
860 gl_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" );
861 return;
862 }
863
864 ctx->ClientAttribStackDepth--;
865 attr = ctx->ClientAttribStack[ctx->ClientAttribStackDepth];
866
867 while (attr) {
868 switch (attr->kind) {
869 case GL_CLIENT_PACK_BIT:
870 MEMCPY( &ctx->Pack, attr->data,
871 sizeof(struct gl_pixelstore_attrib) );
872 break;
873 case GL_CLIENT_UNPACK_BIT:
874 MEMCPY( &ctx->Unpack, attr->data,
875 sizeof(struct gl_pixelstore_attrib) );
876 break;
877 case GL_CLIENT_VERTEX_ARRAY_BIT:
878 MEMCPY( &ctx->Array, attr->data,
879 sizeof(struct gl_array_attrib) );
880 break;
881 default:
882 gl_problem( ctx, "Bad attrib flag in PopClientAttrib");
883 break;
884 }
885
886 next = attr->next;
887 FREE( attr->data );
888 FREE( attr );
889 attr = next;
890 }
891
892 ctx->NewState = NEW_ALL;
893}
894
895
896
Note: See TracBrowser for help on using the repository browser.