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