1 | /* Copyright (c) 2001, Stanford University
|
---|
2 | * All rights reserved
|
---|
3 | *
|
---|
4 | * See the file LICENSE.txt for information on redistributing this software.
|
---|
5 | */
|
---|
6 |
|
---|
7 | #include <stdio.h>
|
---|
8 | #include "state.h"
|
---|
9 | #include "state/cr_statetypes.h"
|
---|
10 | #include "state_internals.h"
|
---|
11 | #include "cr_error.h"
|
---|
12 | #include "cr_mem.h"
|
---|
13 |
|
---|
14 | /**
|
---|
15 | * \mainpage state_tracker
|
---|
16 | *
|
---|
17 | * \section StateTrackerIntroduction Introduction
|
---|
18 | *
|
---|
19 | * Chromium consists of all the top-level files in the cr
|
---|
20 | * directory. The state_tracker module basically takes care of API dispatch,
|
---|
21 | * and OpenGL state management.
|
---|
22 | *
|
---|
23 | *
|
---|
24 | */
|
---|
25 | void crStateAttribInit (CRAttribState *a)
|
---|
26 | {
|
---|
27 | int i;
|
---|
28 | a->attribStackDepth = 0;
|
---|
29 | a->accumBufferStackDepth = 0;
|
---|
30 | a->colorBufferStackDepth = 0;
|
---|
31 | a->currentStackDepth = 0;
|
---|
32 | a->depthBufferStackDepth = 0;
|
---|
33 | a->enableStackDepth = 0;
|
---|
34 | for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
|
---|
35 | {
|
---|
36 | a->enableStack[i].clip = NULL;
|
---|
37 | a->enableStack[i].light = NULL;
|
---|
38 | a->lightingStack[i].light = NULL;
|
---|
39 | a->transformStack[i].clip = NULL;
|
---|
40 | a->transformStack[i].clipPlane = NULL;
|
---|
41 | }
|
---|
42 | a->evalStackDepth = 0;
|
---|
43 | a->fogStackDepth = 0;
|
---|
44 | a->lightingStackDepth = 0;
|
---|
45 | a->lineStackDepth = 0;
|
---|
46 | a->listStackDepth = 0;
|
---|
47 | a->pixelModeStackDepth = 0;
|
---|
48 | a->pointStackDepth = 0;
|
---|
49 | a->polygonStackDepth = 0;
|
---|
50 | a->polygonStippleStackDepth = 0;
|
---|
51 | a->scissorStackDepth = 0;
|
---|
52 | a->stencilBufferStackDepth = 0;
|
---|
53 | a->textureStackDepth = 0;
|
---|
54 | a->transformStackDepth = 0;
|
---|
55 | a->viewportStackDepth = 0;
|
---|
56 | }
|
---|
57 |
|
---|
58 | /*@todo check if NV rect needed too*/
|
---|
59 | static void
|
---|
60 | copy_texunit(CRTextureUnit *dest, const CRTextureUnit *src)
|
---|
61 | {
|
---|
62 | dest->enabled1D = src->enabled1D;
|
---|
63 | dest->enabled2D = src->enabled2D;
|
---|
64 | dest->enabled3D = src->enabled3D;
|
---|
65 | dest->enabledCubeMap = src->enabledCubeMap;
|
---|
66 | dest->envMode = src->envMode;
|
---|
67 | dest->envColor = src->envColor;
|
---|
68 | dest->textureGen = src->textureGen;
|
---|
69 | dest->objSCoeff = src->objSCoeff;
|
---|
70 | dest->objTCoeff = src->objTCoeff;
|
---|
71 | dest->objRCoeff = src->objRCoeff;
|
---|
72 | dest->objQCoeff = src->objQCoeff;
|
---|
73 | dest->eyeSCoeff = src->eyeSCoeff;
|
---|
74 | dest->eyeTCoeff = src->eyeTCoeff;
|
---|
75 | dest->eyeRCoeff = src->eyeRCoeff;
|
---|
76 | dest->eyeQCoeff = src->eyeQCoeff;
|
---|
77 | dest->gen = src->gen;
|
---|
78 | dest->currentTexture1D = src->currentTexture1D;
|
---|
79 | dest->currentTexture2D = src->currentTexture2D;
|
---|
80 | dest->currentTexture3D = src->currentTexture3D;
|
---|
81 | dest->currentTextureCubeMap = src->currentTextureCubeMap;
|
---|
82 | }
|
---|
83 |
|
---|
84 | static void
|
---|
85 | copy_texobj(CRTextureObj *dest, const CRTextureObj *src, GLboolean copyName)
|
---|
86 | {
|
---|
87 | if (copyName)
|
---|
88 | dest->name = src->name;
|
---|
89 | dest->borderColor = src->borderColor;
|
---|
90 | dest->wrapS = src->wrapS;
|
---|
91 | dest->wrapT = src->wrapT;
|
---|
92 | dest->minFilter = src->minFilter;
|
---|
93 | dest->magFilter = src->magFilter;
|
---|
94 | #ifdef CR_OPENGL_VERSION_1_2
|
---|
95 | dest->priority = src->priority;
|
---|
96 | dest->wrapR = src->wrapR;
|
---|
97 | dest->minLod = src->minLod;
|
---|
98 | dest->maxLod = src->maxLod;
|
---|
99 | dest->baseLevel = src->baseLevel;
|
---|
100 | dest->maxLevel = src->maxLevel;
|
---|
101 | #endif
|
---|
102 | #ifdef CR_EXT_texture_filter_anisotropic
|
---|
103 | dest->maxAnisotropy = src->maxAnisotropy;
|
---|
104 | #endif
|
---|
105 | }
|
---|
106 |
|
---|
107 | void STATE_APIENTRY crStatePushAttrib(GLbitfield mask)
|
---|
108 | {
|
---|
109 | CRContext *g = GetCurrentContext();
|
---|
110 | CRAttribState *a = &(g->attrib);
|
---|
111 | CRStateBits *sb = GetCurrentBits();
|
---|
112 | CRAttribBits *ab = &(sb->attrib);
|
---|
113 | unsigned int i;
|
---|
114 |
|
---|
115 | if (g->current.inBeginEnd)
|
---|
116 | {
|
---|
117 | crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glPushAttrib called in Begin/End");
|
---|
118 | return;
|
---|
119 | }
|
---|
120 |
|
---|
121 | if (a->attribStackDepth == CR_MAX_ATTRIB_STACK_DEPTH - 1)
|
---|
122 | {
|
---|
123 | crStateError(__LINE__, __FILE__, GL_STACK_OVERFLOW, "glPushAttrib called with a full stack!" );
|
---|
124 | return;
|
---|
125 | }
|
---|
126 |
|
---|
127 | FLUSH();
|
---|
128 |
|
---|
129 | a->pushMaskStack[a->attribStackDepth++] = mask;
|
---|
130 |
|
---|
131 | if (mask & GL_ACCUM_BUFFER_BIT)
|
---|
132 | {
|
---|
133 | a->accumBufferStack[a->accumBufferStackDepth].accumClearValue = g->buffer.accumClearValue;
|
---|
134 | a->accumBufferStackDepth++;
|
---|
135 | }
|
---|
136 | if (mask & GL_COLOR_BUFFER_BIT)
|
---|
137 | {
|
---|
138 | a->colorBufferStack[a->colorBufferStackDepth].alphaTest = g->buffer.alphaTest;
|
---|
139 | a->colorBufferStack[a->colorBufferStackDepth].alphaTestFunc = g->buffer.alphaTestFunc;
|
---|
140 | a->colorBufferStack[a->colorBufferStackDepth].alphaTestRef = g->buffer.alphaTestRef;
|
---|
141 | a->colorBufferStack[a->colorBufferStackDepth].blend = g->buffer.blend;
|
---|
142 | a->colorBufferStack[a->colorBufferStackDepth].blendSrcRGB = g->buffer.blendSrcRGB;
|
---|
143 | a->colorBufferStack[a->colorBufferStackDepth].blendDstRGB = g->buffer.blendDstRGB;
|
---|
144 | #if defined(CR_EXT_blend_func_separate)
|
---|
145 | a->colorBufferStack[a->colorBufferStackDepth].blendSrcA = g->buffer.blendSrcA;
|
---|
146 | a->colorBufferStack[a->colorBufferStackDepth].blendDstA = g->buffer.blendDstA;
|
---|
147 | #endif
|
---|
148 | #ifdef CR_EXT_blend_color
|
---|
149 | a->colorBufferStack[a->colorBufferStackDepth].blendColor = g->buffer.blendColor;
|
---|
150 | #endif
|
---|
151 | #if defined(CR_EXT_blend_minmax) || defined(CR_EXT_blend_subtract) || defined(CR_EXT_blend_logic_op)
|
---|
152 | a->colorBufferStack[a->colorBufferStackDepth].blendEquation = g->buffer.blendEquation;
|
---|
153 | #endif
|
---|
154 | a->colorBufferStack[a->colorBufferStackDepth].dither = g->buffer.dither;
|
---|
155 | a->colorBufferStack[a->colorBufferStackDepth].drawBuffer = g->buffer.drawBuffer;
|
---|
156 | a->colorBufferStack[a->colorBufferStackDepth].logicOp = g->buffer.logicOp;
|
---|
157 | a->colorBufferStack[a->colorBufferStackDepth].indexLogicOp = g->buffer.indexLogicOp;
|
---|
158 | a->colorBufferStack[a->colorBufferStackDepth].logicOpMode = g->buffer.logicOpMode;
|
---|
159 | a->colorBufferStack[a->colorBufferStackDepth].colorClearValue = g->buffer.colorClearValue;
|
---|
160 | a->colorBufferStack[a->colorBufferStackDepth].indexClearValue = g->buffer.indexClearValue;
|
---|
161 | a->colorBufferStack[a->colorBufferStackDepth].colorWriteMask = g->buffer.colorWriteMask;
|
---|
162 | a->colorBufferStack[a->colorBufferStackDepth].indexWriteMask = g->buffer.indexWriteMask;
|
---|
163 | a->colorBufferStackDepth++;
|
---|
164 | }
|
---|
165 | if (mask & GL_CURRENT_BIT)
|
---|
166 | {
|
---|
167 | for (i = 0 ; i < CR_MAX_VERTEX_ATTRIBS ; i++)
|
---|
168 | {
|
---|
169 | COPY_4V(a->currentStack[a->currentStackDepth].attrib[i] , g->current.vertexAttrib[i]);
|
---|
170 | COPY_4V(a->currentStack[a->currentStackDepth].rasterAttrib[i] , g->current.rasterAttrib[i]);
|
---|
171 | }
|
---|
172 | a->currentStack[a->currentStackDepth].rasterValid = g->current.rasterValid;
|
---|
173 | a->currentStack[a->currentStackDepth].edgeFlag = g->current.edgeFlag;
|
---|
174 | a->currentStack[a->currentStackDepth].colorIndex = g->current.colorIndex;
|
---|
175 | a->currentStackDepth++;
|
---|
176 | }
|
---|
177 | if (mask & GL_DEPTH_BUFFER_BIT)
|
---|
178 | {
|
---|
179 | a->depthBufferStack[a->depthBufferStackDepth].depthTest = g->buffer.depthTest;
|
---|
180 | a->depthBufferStack[a->depthBufferStackDepth].depthFunc = g->buffer.depthFunc;
|
---|
181 | a->depthBufferStack[a->depthBufferStackDepth].depthClearValue = g->buffer.depthClearValue;
|
---|
182 | a->depthBufferStack[a->depthBufferStackDepth].depthMask = g->buffer.depthMask;
|
---|
183 | a->depthBufferStackDepth++;
|
---|
184 | }
|
---|
185 | if (mask & GL_ENABLE_BIT)
|
---|
186 | {
|
---|
187 | if (a->enableStack[a->enableStackDepth].clip == NULL)
|
---|
188 | {
|
---|
189 | a->enableStack[a->enableStackDepth].clip = (GLboolean *) crCalloc( g->limits.maxClipPlanes * sizeof( GLboolean ));
|
---|
190 | }
|
---|
191 | if (a->enableStack[a->enableStackDepth].light == NULL)
|
---|
192 | {
|
---|
193 | a->enableStack[a->enableStackDepth].light = (GLboolean *) crCalloc( g->limits.maxLights * sizeof( GLboolean ));
|
---|
194 | }
|
---|
195 | a->enableStack[a->enableStackDepth].alphaTest = g->buffer.alphaTest;
|
---|
196 | a->enableStack[a->enableStackDepth].autoNormal = g->eval.autoNormal;
|
---|
197 | a->enableStack[a->enableStackDepth].blend = g->buffer.blend;
|
---|
198 | for (i = 0 ; i < g->limits.maxClipPlanes ; i++)
|
---|
199 | {
|
---|
200 | a->enableStack[a->enableStackDepth].clip[i] = g->transform.clip[i];
|
---|
201 | }
|
---|
202 | a->enableStack[a->enableStackDepth].colorMaterial = g->lighting.colorMaterial;
|
---|
203 | a->enableStack[a->enableStackDepth].cullFace = g->polygon.cullFace;
|
---|
204 | a->enableStack[a->enableStackDepth].depthTest = g->buffer.depthTest;
|
---|
205 | a->enableStack[a->enableStackDepth].dither = g->buffer.dither;
|
---|
206 | a->enableStack[a->enableStackDepth].fog = g->fog.enable;
|
---|
207 | for (i = 0 ; i < g->limits.maxLights ; i++)
|
---|
208 | {
|
---|
209 | a->enableStack[a->enableStackDepth].light[i] = g->lighting.light[i].enable;
|
---|
210 | }
|
---|
211 | a->enableStack[a->enableStackDepth].lighting = g->lighting.lighting;
|
---|
212 | a->enableStack[a->enableStackDepth].lineSmooth = g->line.lineSmooth;
|
---|
213 | a->enableStack[a->enableStackDepth].lineStipple = g->line.lineStipple;
|
---|
214 | a->enableStack[a->enableStackDepth].logicOp = g->buffer.logicOp;
|
---|
215 | a->enableStack[a->enableStackDepth].indexLogicOp = g->buffer.indexLogicOp;
|
---|
216 | for (i = 0 ; i < GLEVAL_TOT ; i++)
|
---|
217 | {
|
---|
218 | a->enableStack[a->enableStackDepth].map1[i] = g->eval.enable1D[i];
|
---|
219 | a->enableStack[a->enableStackDepth].map2[i] = g->eval.enable2D[i];
|
---|
220 | }
|
---|
221 | a->enableStack[a->enableStackDepth].normalize = g->transform.normalize;
|
---|
222 | a->enableStack[a->enableStackDepth].pointSmooth = g->point.pointSmooth;
|
---|
223 | #if CR_ARB_point_sprite
|
---|
224 | a->enableStack[a->enableStackDepth].pointSprite = g->point.pointSprite;
|
---|
225 | for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
|
---|
226 | a->enableStack[a->enableStackDepth].coordReplacement[i] = g->point.coordReplacement[i];
|
---|
227 | #endif
|
---|
228 | a->enableStack[a->enableStackDepth].polygonOffsetLine = g->polygon.polygonOffsetLine;
|
---|
229 | a->enableStack[a->enableStackDepth].polygonOffsetFill = g->polygon.polygonOffsetFill;
|
---|
230 | a->enableStack[a->enableStackDepth].polygonOffsetPoint = g->polygon.polygonOffsetPoint;
|
---|
231 | a->enableStack[a->enableStackDepth].polygonSmooth = g->polygon.polygonSmooth;
|
---|
232 | a->enableStack[a->enableStackDepth].polygonStipple = g->polygon.polygonStipple;
|
---|
233 | #ifdef CR_OPENGL_VERSION_1_2
|
---|
234 | a->enableStack[a->enableStackDepth].rescaleNormals = g->transform.rescaleNormals;
|
---|
235 | #endif
|
---|
236 | a->enableStack[a->enableStackDepth].scissorTest = g->viewport.scissorTest;
|
---|
237 | a->enableStack[a->enableStackDepth].stencilTest = g->stencil.stencilTest;
|
---|
238 | for (i = 0 ; i < g->limits.maxTextureUnits; i++)
|
---|
239 | {
|
---|
240 | a->enableStack[a->enableStackDepth].texture1D[i] = g->texture.unit[i].enabled1D;
|
---|
241 | a->enableStack[a->enableStackDepth].texture2D[i] = g->texture.unit[i].enabled2D;
|
---|
242 | #ifdef CR_OPENGL_VERSION_1_2
|
---|
243 | a->enableStack[a->enableStackDepth].texture3D[i] = g->texture.unit[i].enabled3D;
|
---|
244 | #endif
|
---|
245 | #ifdef CR_ARB_texture_cube_map
|
---|
246 | a->enableStack[a->enableStackDepth].textureCubeMap[i] = g->texture.unit[i].enabledCubeMap;
|
---|
247 | #endif
|
---|
248 | #ifdef CR_NV_texture_rectangle
|
---|
249 | a->enableStack[a->enableStackDepth].textureRect[i] = g->texture.unit[i].enabledRect;
|
---|
250 | #endif
|
---|
251 | a->enableStack[a->enableStackDepth].textureGenS[i] = g->texture.unit[i].textureGen.s;
|
---|
252 | a->enableStack[a->enableStackDepth].textureGenT[i] = g->texture.unit[i].textureGen.t;
|
---|
253 | a->enableStack[a->enableStackDepth].textureGenR[i] = g->texture.unit[i].textureGen.r;
|
---|
254 | a->enableStack[a->enableStackDepth].textureGenQ[i] = g->texture.unit[i].textureGen.q;
|
---|
255 | }
|
---|
256 | a->enableStackDepth++;
|
---|
257 | }
|
---|
258 | if (mask & GL_EVAL_BIT)
|
---|
259 | {
|
---|
260 | for (i = 0 ; i < GLEVAL_TOT ; i++)
|
---|
261 | {
|
---|
262 | int size1 = g->eval.eval1D[i].order * gleval_sizes[i] *
|
---|
263 | sizeof (GLfloat);
|
---|
264 | int size2 = g->eval.eval2D[i].uorder * g->eval.eval2D[i].vorder *
|
---|
265 | gleval_sizes[i] * sizeof (GLfloat);
|
---|
266 | a->evalStack[a->evalStackDepth].enable1D[i] = g->eval.enable1D[i];
|
---|
267 | a->evalStack[a->evalStackDepth].enable2D[i] = g->eval.enable2D[i];
|
---|
268 | a->evalStack[a->evalStackDepth].eval1D[i].u1 = g->eval.eval1D[i].u1;
|
---|
269 | a->evalStack[a->evalStackDepth].eval1D[i].u2 = g->eval.eval1D[i].u2;
|
---|
270 | a->evalStack[a->evalStackDepth].eval1D[i].order = g->eval.eval1D[i].order;
|
---|
271 | a->evalStack[a->evalStackDepth].eval1D[i].coeff = (GLfloat*)crCalloc(size1);
|
---|
272 | crMemcpy(a->evalStack[a->evalStackDepth].eval1D[i].coeff, g->eval.eval1D[i].coeff, size1);
|
---|
273 | a->evalStack[a->evalStackDepth].eval2D[i].u1 = g->eval.eval2D[i].u1;
|
---|
274 | a->evalStack[a->evalStackDepth].eval2D[i].u2 = g->eval.eval2D[i].u2;
|
---|
275 | a->evalStack[a->evalStackDepth].eval2D[i].v1 = g->eval.eval2D[i].v1;
|
---|
276 | a->evalStack[a->evalStackDepth].eval2D[i].v2 = g->eval.eval2D[i].v2;
|
---|
277 | a->evalStack[a->evalStackDepth].eval2D[i].uorder = g->eval.eval2D[i].uorder;
|
---|
278 | a->evalStack[a->evalStackDepth].eval2D[i].vorder = g->eval.eval2D[i].vorder;
|
---|
279 | a->evalStack[a->evalStackDepth].eval2D[i].coeff = (GLfloat*)crCalloc(size2);
|
---|
280 | crMemcpy(a->evalStack[a->evalStackDepth].eval2D[i].coeff, g->eval.eval2D[i].coeff, size2);
|
---|
281 | }
|
---|
282 | a->evalStack[a->evalStackDepth].autoNormal = g->eval.autoNormal;
|
---|
283 | a->evalStack[a->evalStackDepth].un1D = g->eval.un1D;
|
---|
284 | a->evalStack[a->evalStackDepth].u11D = g->eval.u11D;
|
---|
285 | a->evalStack[a->evalStackDepth].u21D = g->eval.u21D;
|
---|
286 | a->evalStack[a->evalStackDepth].un2D = g->eval.un2D;
|
---|
287 | a->evalStack[a->evalStackDepth].u12D = g->eval.u12D;
|
---|
288 | a->evalStack[a->evalStackDepth].u22D = g->eval.u22D;
|
---|
289 | a->evalStack[a->evalStackDepth].vn2D = g->eval.vn2D;
|
---|
290 | a->evalStack[a->evalStackDepth].v12D = g->eval.v12D;
|
---|
291 | a->evalStack[a->evalStackDepth].v22D = g->eval.v22D;
|
---|
292 | a->evalStackDepth++;
|
---|
293 | }
|
---|
294 | if (mask & GL_FOG_BIT)
|
---|
295 | {
|
---|
296 | a->fogStack[a->fogStackDepth].enable = g->fog.enable;
|
---|
297 | a->fogStack[a->fogStackDepth].color = g->fog.color;
|
---|
298 | a->fogStack[a->fogStackDepth].density = g->fog.density;
|
---|
299 | a->fogStack[a->fogStackDepth].start = g->fog.start;
|
---|
300 | a->fogStack[a->fogStackDepth].end = g->fog.end;
|
---|
301 | a->fogStack[a->fogStackDepth].index = g->fog.index;
|
---|
302 | a->fogStack[a->fogStackDepth].mode = g->fog.mode;
|
---|
303 | a->fogStackDepth++;
|
---|
304 | }
|
---|
305 | if (mask & GL_HINT_BIT)
|
---|
306 | {
|
---|
307 | a->hintStack[a->hintStackDepth].perspectiveCorrection = g->hint.perspectiveCorrection;
|
---|
308 | a->hintStack[a->hintStackDepth].pointSmooth = g->hint.pointSmooth;
|
---|
309 | a->hintStack[a->hintStackDepth].lineSmooth = g->hint.lineSmooth;
|
---|
310 | a->hintStack[a->hintStackDepth].polygonSmooth = g->hint.polygonSmooth;
|
---|
311 | a->hintStack[a->hintStackDepth].fog = g->hint.fog;
|
---|
312 | #ifdef CR_EXT_clip_volume_hint
|
---|
313 | a->hintStack[a->hintStackDepth].clipVolumeClipping = g->hint.clipVolumeClipping;
|
---|
314 | #endif
|
---|
315 | #ifdef CR_ARB_texture_compression
|
---|
316 | a->hintStack[a->hintStackDepth].textureCompression = g->hint.textureCompression;
|
---|
317 | #endif
|
---|
318 | #ifdef CR_SGIS_generate_mipmap
|
---|
319 | a->hintStack[a->hintStackDepth].generateMipmap = g->hint.generateMipmap;
|
---|
320 | #endif
|
---|
321 | a->hintStackDepth++;
|
---|
322 | }
|
---|
323 | if (mask & GL_LIGHTING_BIT)
|
---|
324 | {
|
---|
325 | if (a->lightingStack[a->lightingStackDepth].light == NULL)
|
---|
326 | {
|
---|
327 | a->lightingStack[a->lightingStackDepth].light = (CRLight *) crCalloc( g->limits.maxLights * sizeof( CRLight ));
|
---|
328 | }
|
---|
329 | a->lightingStack[a->lightingStackDepth].lightModelAmbient = g->lighting.lightModelAmbient;
|
---|
330 | a->lightingStack[a->lightingStackDepth].lightModelLocalViewer = g->lighting.lightModelLocalViewer;
|
---|
331 | a->lightingStack[a->lightingStackDepth].lightModelTwoSide = g->lighting.lightModelTwoSide;
|
---|
332 | #if defined(CR_EXT_separate_specular_color) || defined(CR_OPENGL_VERSION_1_2)
|
---|
333 | a->lightingStack[a->lightingStackDepth].lightModelColorControlEXT = g->lighting.lightModelColorControlEXT;
|
---|
334 | #endif
|
---|
335 | a->lightingStack[a->lightingStackDepth].lighting = g->lighting.lighting;
|
---|
336 | a->lightingStack[a->lightingStackDepth].colorMaterial = g->lighting.colorMaterial;
|
---|
337 | a->lightingStack[a->lightingStackDepth].colorMaterialMode = g->lighting.colorMaterialMode;
|
---|
338 | a->lightingStack[a->lightingStackDepth].colorMaterialFace = g->lighting.colorMaterialFace;
|
---|
339 | for (i = 0 ; i < g->limits.maxLights; i++)
|
---|
340 | {
|
---|
341 | a->lightingStack[a->lightingStackDepth].light[i].enable = g->lighting.light[i].enable;
|
---|
342 | a->lightingStack[a->lightingStackDepth].light[i].ambient = g->lighting.light[i].ambient;
|
---|
343 | a->lightingStack[a->lightingStackDepth].light[i].diffuse = g->lighting.light[i].diffuse;
|
---|
344 | a->lightingStack[a->lightingStackDepth].light[i].specular = g->lighting.light[i].specular;
|
---|
345 | a->lightingStack[a->lightingStackDepth].light[i].spotDirection = g->lighting.light[i].spotDirection;
|
---|
346 | a->lightingStack[a->lightingStackDepth].light[i].position = g->lighting.light[i].position;
|
---|
347 | a->lightingStack[a->lightingStackDepth].light[i].spotExponent = g->lighting.light[i].spotExponent;
|
---|
348 | a->lightingStack[a->lightingStackDepth].light[i].spotCutoff = g->lighting.light[i].spotCutoff;
|
---|
349 | a->lightingStack[a->lightingStackDepth].light[i].constantAttenuation = g->lighting.light[i].constantAttenuation;
|
---|
350 | a->lightingStack[a->lightingStackDepth].light[i].linearAttenuation = g->lighting.light[i].linearAttenuation;
|
---|
351 | a->lightingStack[a->lightingStackDepth].light[i].quadraticAttenuation = g->lighting.light[i].quadraticAttenuation;
|
---|
352 | }
|
---|
353 | for (i = 0 ; i < 2 ; i++)
|
---|
354 | {
|
---|
355 | a->lightingStack[a->lightingStackDepth].ambient[i] = g->lighting.ambient[i];
|
---|
356 | a->lightingStack[a->lightingStackDepth].diffuse[i] = g->lighting.diffuse[i];
|
---|
357 | a->lightingStack[a->lightingStackDepth].specular[i] = g->lighting.specular[i];
|
---|
358 | a->lightingStack[a->lightingStackDepth].emission[i] = g->lighting.emission[i];
|
---|
359 | a->lightingStack[a->lightingStackDepth].shininess[i] = g->lighting.shininess[i];
|
---|
360 | a->lightingStack[a->lightingStackDepth].indexes[i][0] = g->lighting.indexes[i][0];
|
---|
361 | a->lightingStack[a->lightingStackDepth].indexes[i][1] = g->lighting.indexes[i][1];
|
---|
362 | a->lightingStack[a->lightingStackDepth].indexes[i][2] = g->lighting.indexes[i][2];
|
---|
363 | }
|
---|
364 | a->lightingStack[a->lightingStackDepth].shadeModel = g->lighting.shadeModel;
|
---|
365 | a->lightingStackDepth++;
|
---|
366 | }
|
---|
367 | if (mask & GL_LINE_BIT)
|
---|
368 | {
|
---|
369 | a->lineStack[a->lineStackDepth].lineSmooth = g->line.lineSmooth;
|
---|
370 | a->lineStack[a->lineStackDepth].lineStipple = g->line.lineStipple;
|
---|
371 | a->lineStack[a->lineStackDepth].pattern = g->line.pattern;
|
---|
372 | a->lineStack[a->lineStackDepth].repeat = g->line.repeat;
|
---|
373 | a->lineStack[a->lineStackDepth].width = g->line.width;
|
---|
374 | a->lineStackDepth++;
|
---|
375 | }
|
---|
376 | if (mask & GL_LIST_BIT)
|
---|
377 | {
|
---|
378 | a->listStack[a->listStackDepth].base = g->lists.base;
|
---|
379 | a->listStackDepth++;
|
---|
380 | }
|
---|
381 | if (mask & GL_PIXEL_MODE_BIT)
|
---|
382 | {
|
---|
383 | a->pixelModeStack[a->pixelModeStackDepth].bias = g->pixel.bias;
|
---|
384 | a->pixelModeStack[a->pixelModeStackDepth].scale = g->pixel.scale;
|
---|
385 | a->pixelModeStack[a->pixelModeStackDepth].indexOffset = g->pixel.indexOffset;
|
---|
386 | a->pixelModeStack[a->pixelModeStackDepth].indexShift = g->pixel.indexShift;
|
---|
387 | a->pixelModeStack[a->pixelModeStackDepth].mapColor = g->pixel.mapColor;
|
---|
388 | a->pixelModeStack[a->pixelModeStackDepth].mapStencil = g->pixel.mapStencil;
|
---|
389 | a->pixelModeStack[a->pixelModeStackDepth].xZoom = g->pixel.xZoom;
|
---|
390 | a->pixelModeStack[a->pixelModeStackDepth].yZoom = g->pixel.yZoom;
|
---|
391 | a->pixelModeStack[a->pixelModeStackDepth].readBuffer = g->buffer.readBuffer;
|
---|
392 | a->pixelModeStackDepth++;
|
---|
393 | }
|
---|
394 | if (mask & GL_POINT_BIT)
|
---|
395 | {
|
---|
396 | a->pointStack[a->pointStackDepth].pointSmooth = g->point.pointSmooth;
|
---|
397 | #if CR_ARB_point_sprite
|
---|
398 | a->pointStack[a->pointStackDepth].pointSprite = g->point.pointSprite;
|
---|
399 | for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
|
---|
400 | a->pointStack[a->enableStackDepth].coordReplacement[i] = g->point.coordReplacement[i];
|
---|
401 | #endif
|
---|
402 | a->pointStack[a->pointStackDepth].pointSize = g->point.pointSize;
|
---|
403 | a->pointStackDepth++;
|
---|
404 | }
|
---|
405 | if (mask & GL_POLYGON_BIT)
|
---|
406 | {
|
---|
407 | a->polygonStack[a->polygonStackDepth].cullFace = g->polygon.cullFace;
|
---|
408 | a->polygonStack[a->polygonStackDepth].cullFaceMode = g->polygon.cullFaceMode;
|
---|
409 | a->polygonStack[a->polygonStackDepth].frontFace = g->polygon.frontFace;
|
---|
410 | a->polygonStack[a->polygonStackDepth].frontMode = g->polygon.frontMode;
|
---|
411 | a->polygonStack[a->polygonStackDepth].backMode = g->polygon.backMode;
|
---|
412 | a->polygonStack[a->polygonStackDepth].polygonSmooth = g->polygon.polygonSmooth;
|
---|
413 | a->polygonStack[a->polygonStackDepth].polygonStipple = g->polygon.polygonStipple;
|
---|
414 | a->polygonStack[a->polygonStackDepth].polygonOffsetFill = g->polygon.polygonOffsetFill;
|
---|
415 | a->polygonStack[a->polygonStackDepth].polygonOffsetLine = g->polygon.polygonOffsetLine;
|
---|
416 | a->polygonStack[a->polygonStackDepth].polygonOffsetPoint = g->polygon.polygonOffsetPoint;
|
---|
417 | a->polygonStack[a->polygonStackDepth].offsetFactor = g->polygon.offsetFactor;
|
---|
418 | a->polygonStack[a->polygonStackDepth].offsetUnits = g->polygon.offsetUnits;
|
---|
419 | a->polygonStackDepth++;
|
---|
420 | }
|
---|
421 | if (mask & GL_POLYGON_STIPPLE_BIT)
|
---|
422 | {
|
---|
423 | crMemcpy( a->polygonStippleStack[a->polygonStippleStackDepth].pattern, g->polygon.stipple, 32*sizeof(GLint) );
|
---|
424 | a->polygonStippleStackDepth++;
|
---|
425 | }
|
---|
426 | if (mask & GL_SCISSOR_BIT)
|
---|
427 | {
|
---|
428 | a->scissorStack[a->scissorStackDepth].scissorTest = g->viewport.scissorTest;
|
---|
429 | a->scissorStack[a->scissorStackDepth].scissorX = g->viewport.scissorX;
|
---|
430 | a->scissorStack[a->scissorStackDepth].scissorY = g->viewport.scissorY;
|
---|
431 | a->scissorStack[a->scissorStackDepth].scissorW = g->viewport.scissorW;
|
---|
432 | a->scissorStack[a->scissorStackDepth].scissorH = g->viewport.scissorH;
|
---|
433 | a->scissorStackDepth++;
|
---|
434 | }
|
---|
435 | if (mask & GL_STENCIL_BUFFER_BIT)
|
---|
436 | {
|
---|
437 | a->stencilBufferStack[a->stencilBufferStackDepth].stencilTest = g->stencil.stencilTest;
|
---|
438 | a->stencilBufferStack[a->stencilBufferStackDepth].func = g->stencil.func;
|
---|
439 | a->stencilBufferStack[a->stencilBufferStackDepth].mask = g->stencil.mask;
|
---|
440 | a->stencilBufferStack[a->stencilBufferStackDepth].ref = g->stencil.ref;
|
---|
441 | a->stencilBufferStack[a->stencilBufferStackDepth].fail = g->stencil.fail;
|
---|
442 | a->stencilBufferStack[a->stencilBufferStackDepth].passDepthFail = g->stencil.passDepthFail;
|
---|
443 | a->stencilBufferStack[a->stencilBufferStackDepth].passDepthPass = g->stencil.passDepthPass;
|
---|
444 | a->stencilBufferStack[a->stencilBufferStackDepth].clearValue = g->stencil.clearValue;
|
---|
445 | a->stencilBufferStack[a->stencilBufferStackDepth].writeMask = g->stencil.writeMask;
|
---|
446 | a->stencilBufferStackDepth++;
|
---|
447 | }
|
---|
448 | if (mask & GL_TEXTURE_BIT)
|
---|
449 | {
|
---|
450 | CRTextureStack *tState = a->textureStack + a->textureStackDepth;
|
---|
451 | tState->curTextureUnit = g->texture.curTextureUnit;
|
---|
452 | for (i = 0 ; i < g->limits.maxTextureUnits ; i++)
|
---|
453 | {
|
---|
454 | /* per-unit state */
|
---|
455 | copy_texunit(&tState->unit[i], &g->texture.unit[i]);
|
---|
456 | /* texture object state */
|
---|
457 | copy_texobj(&tState->unit[i].Saved1D, g->texture.unit[i].currentTexture1D, GL_TRUE);
|
---|
458 | copy_texobj(&tState->unit[i].Saved2D, g->texture.unit[i].currentTexture2D, GL_TRUE);
|
---|
459 | #ifdef CR_OPENGL_VERSION_1_2
|
---|
460 | copy_texobj(&tState->unit[i].Saved3D, g->texture.unit[i].currentTexture3D, GL_TRUE);
|
---|
461 | #endif
|
---|
462 | #ifdef CR_ARB_texture_cube_map
|
---|
463 | copy_texobj(&tState->unit[i].SavedCubeMap, g->texture.unit[i].currentTextureCubeMap, GL_TRUE);
|
---|
464 | #endif
|
---|
465 | #ifdef CR_NV_texture_rectangle
|
---|
466 | copy_texobj(&tState->unit[i].SavedRect, g->texture.unit[i].currentTextureRect, GL_TRUE);
|
---|
467 | #endif
|
---|
468 | }
|
---|
469 | a->textureStackDepth++;
|
---|
470 | }
|
---|
471 | if (mask & GL_TRANSFORM_BIT)
|
---|
472 | {
|
---|
473 | if (a->transformStack[a->transformStackDepth].clip == NULL)
|
---|
474 | {
|
---|
475 | a->transformStack[a->transformStackDepth].clip = (GLboolean *) crCalloc( g->limits.maxClipPlanes * sizeof( GLboolean ));
|
---|
476 | }
|
---|
477 | if (a->transformStack[a->transformStackDepth].clipPlane == NULL)
|
---|
478 | {
|
---|
479 | a->transformStack[a->transformStackDepth].clipPlane = (GLvectord *) crCalloc( g->limits.maxClipPlanes * sizeof( GLvectord ));
|
---|
480 | }
|
---|
481 | a->transformStack[a->transformStackDepth].matrixMode = g->transform.matrixMode;
|
---|
482 | for (i = 0 ; i < g->limits.maxClipPlanes ; i++)
|
---|
483 | {
|
---|
484 | a->transformStack[a->transformStackDepth].clip[i] = g->transform.clip[i];
|
---|
485 | a->transformStack[a->transformStackDepth].clipPlane[i] = g->transform.clipPlane[i];
|
---|
486 | }
|
---|
487 | a->transformStack[a->transformStackDepth].normalize = g->transform.normalize;
|
---|
488 | #ifdef CR_OPENGL_VERSION_1_2
|
---|
489 | a->transformStack[a->transformStackDepth].rescaleNormals = g->transform.rescaleNormals;
|
---|
490 | #endif
|
---|
491 | a->transformStackDepth++;
|
---|
492 | }
|
---|
493 | if (mask & GL_VIEWPORT_BIT)
|
---|
494 | {
|
---|
495 | a->viewportStack[a->viewportStackDepth].viewportX = g->viewport.viewportX;
|
---|
496 | a->viewportStack[a->viewportStackDepth].viewportY = g->viewport.viewportY;
|
---|
497 | a->viewportStack[a->viewportStackDepth].viewportW = g->viewport.viewportW;
|
---|
498 | a->viewportStack[a->viewportStackDepth].viewportH = g->viewport.viewportH;
|
---|
499 | a->viewportStack[a->viewportStackDepth].nearClip = g->viewport.nearClip;
|
---|
500 | a->viewportStack[a->viewportStackDepth].farClip = g->viewport.farClip;
|
---|
501 | a->viewportStackDepth++;
|
---|
502 | }
|
---|
503 |
|
---|
504 | DIRTY(ab->dirty, g->neg_bitid);
|
---|
505 | }
|
---|
506 |
|
---|
507 | void STATE_APIENTRY crStatePopAttrib(void)
|
---|
508 | {
|
---|
509 | CRContext *g = GetCurrentContext();
|
---|
510 | CRAttribState *a = &(g->attrib);
|
---|
511 | CRStateBits *sb = GetCurrentBits();
|
---|
512 | CRAttribBits *ab = &(sb->attrib);
|
---|
513 | CRbitvalue mask;
|
---|
514 | unsigned int i;
|
---|
515 |
|
---|
516 | if (g->current.inBeginEnd)
|
---|
517 | {
|
---|
518 | crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glPopAttrib called in Begin/End");
|
---|
519 | return;
|
---|
520 | }
|
---|
521 |
|
---|
522 | if (a->attribStackDepth == 0)
|
---|
523 | {
|
---|
524 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty stack!" );
|
---|
525 | return;
|
---|
526 | }
|
---|
527 |
|
---|
528 | FLUSH();
|
---|
529 |
|
---|
530 | mask = a->pushMaskStack[--a->attribStackDepth];
|
---|
531 |
|
---|
532 | if (mask & GL_ACCUM_BUFFER_BIT)
|
---|
533 | {
|
---|
534 | if (a->accumBufferStackDepth == 0)
|
---|
535 | {
|
---|
536 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty accum buffer stack!" );
|
---|
537 | return;
|
---|
538 | }
|
---|
539 | a->accumBufferStackDepth--;
|
---|
540 | g->buffer.accumClearValue = a->accumBufferStack[a->accumBufferStackDepth].accumClearValue;
|
---|
541 | DIRTY(sb->buffer.dirty, g->neg_bitid);
|
---|
542 | DIRTY(sb->buffer.clearAccum, g->neg_bitid);
|
---|
543 | }
|
---|
544 | if (mask & GL_COLOR_BUFFER_BIT)
|
---|
545 | {
|
---|
546 | if (a->colorBufferStackDepth == 0)
|
---|
547 | {
|
---|
548 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty color buffer stack!" );
|
---|
549 | return;
|
---|
550 | }
|
---|
551 | a->colorBufferStackDepth--;
|
---|
552 | g->buffer.alphaTest = a->colorBufferStack[a->colorBufferStackDepth].alphaTest;
|
---|
553 | g->buffer.alphaTestFunc = a->colorBufferStack[a->colorBufferStackDepth].alphaTestFunc;
|
---|
554 | g->buffer.alphaTestRef = a->colorBufferStack[a->colorBufferStackDepth].alphaTestRef;
|
---|
555 | g->buffer.blend = a->colorBufferStack[a->colorBufferStackDepth].blend;
|
---|
556 | g->buffer.blendSrcRGB = a->colorBufferStack[a->colorBufferStackDepth].blendSrcRGB;
|
---|
557 | g->buffer.blendDstRGB = a->colorBufferStack[a->colorBufferStackDepth].blendDstRGB;
|
---|
558 | #if defined(CR_EXT_blend_func_separate)
|
---|
559 | g->buffer.blendSrcA = a->colorBufferStack[a->colorBufferStackDepth].blendSrcA;
|
---|
560 | g->buffer.blendDstA = a->colorBufferStack[a->colorBufferStackDepth].blendDstA;
|
---|
561 | #endif
|
---|
562 | #ifdef CR_EXT_blend_color
|
---|
563 | g->buffer.blendColor = a->colorBufferStack[a->colorBufferStackDepth].blendColor;
|
---|
564 | #endif
|
---|
565 | #if defined(CR_EXT_blend_minmax) || defined(CR_EXT_blend_subtract) || defined(CR_EXT_blend_logic_op)
|
---|
566 | g->buffer.blendEquation = a->colorBufferStack[a->colorBufferStackDepth].blendEquation;
|
---|
567 | #endif
|
---|
568 | g->buffer.dither = a->colorBufferStack[a->colorBufferStackDepth].dither;
|
---|
569 | g->buffer.drawBuffer = a->colorBufferStack[a->colorBufferStackDepth].drawBuffer;
|
---|
570 | g->buffer.logicOp = a->colorBufferStack[a->colorBufferStackDepth].logicOp;
|
---|
571 | g->buffer.indexLogicOp = a->colorBufferStack[a->colorBufferStackDepth].indexLogicOp;
|
---|
572 | g->buffer.logicOpMode = a->colorBufferStack[a->colorBufferStackDepth].logicOpMode;
|
---|
573 | g->buffer.colorClearValue = a->colorBufferStack[a->colorBufferStackDepth].colorClearValue;
|
---|
574 | g->buffer.indexClearValue = a->colorBufferStack[a->colorBufferStackDepth].indexClearValue;
|
---|
575 | g->buffer.colorWriteMask = a->colorBufferStack[a->colorBufferStackDepth].colorWriteMask;
|
---|
576 | g->buffer.indexWriteMask = a->colorBufferStack[a->colorBufferStackDepth].indexWriteMask;
|
---|
577 | DIRTY(sb->buffer.dirty, g->neg_bitid);
|
---|
578 | DIRTY(sb->buffer.enable, g->neg_bitid);
|
---|
579 | DIRTY(sb->buffer.alphaFunc, g->neg_bitid);
|
---|
580 | DIRTY(sb->buffer.blendFunc, g->neg_bitid);
|
---|
581 | #ifdef CR_EXT_blend_color
|
---|
582 | DIRTY(sb->buffer.blendColor, g->neg_bitid);
|
---|
583 | #endif
|
---|
584 | #if defined(CR_EXT_blend_minmax) || defined(CR_EXT_blend_subtract) || defined(CR_EXT_blend_logic_op)
|
---|
585 | DIRTY(sb->buffer.blendEquation, g->neg_bitid);
|
---|
586 | #endif
|
---|
587 | DIRTY(sb->buffer.drawBuffer, g->neg_bitid);
|
---|
588 | DIRTY(sb->buffer.logicOp, g->neg_bitid);
|
---|
589 | DIRTY(sb->buffer.indexLogicOp, g->neg_bitid);
|
---|
590 | DIRTY(sb->buffer.clearColor, g->neg_bitid);
|
---|
591 | DIRTY(sb->buffer.clearIndex, g->neg_bitid);
|
---|
592 | DIRTY(sb->buffer.colorWriteMask, g->neg_bitid);
|
---|
593 | DIRTY(sb->buffer.indexMask, g->neg_bitid);
|
---|
594 | }
|
---|
595 | if (mask & GL_CURRENT_BIT)
|
---|
596 | {
|
---|
597 | if (a->currentStackDepth == 0)
|
---|
598 | {
|
---|
599 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty current stack!" );
|
---|
600 | return;
|
---|
601 | }
|
---|
602 | a->currentStackDepth--;
|
---|
603 | for (i = 0 ; i < CR_MAX_VERTEX_ATTRIBS ; i++)
|
---|
604 | {
|
---|
605 | COPY_4V(g->current.vertexAttrib[i], a->currentStack[a->currentStackDepth].attrib[i]);
|
---|
606 | COPY_4V(g->current.rasterAttrib[i], a->currentStack[a->currentStackDepth].rasterAttrib[i]);
|
---|
607 | DIRTY(sb->current.vertexAttrib[i], g->neg_bitid);
|
---|
608 | }
|
---|
609 | g->current.rasterValid = a->currentStack[a->currentStackDepth].rasterValid;
|
---|
610 | g->current.edgeFlag = a->currentStack[a->currentStackDepth].edgeFlag;
|
---|
611 | g->current.colorIndex = a->currentStack[a->currentStackDepth].colorIndex;
|
---|
612 | DIRTY(sb->current.dirty, g->neg_bitid);
|
---|
613 | DIRTY(sb->current.edgeFlag, g->neg_bitid);
|
---|
614 | DIRTY(sb->current.colorIndex, g->neg_bitid);
|
---|
615 | DIRTY(sb->current.rasterPos, g->neg_bitid);
|
---|
616 | }
|
---|
617 | if (mask & GL_DEPTH_BUFFER_BIT)
|
---|
618 | {
|
---|
619 | if (a->depthBufferStackDepth == 0)
|
---|
620 | {
|
---|
621 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty depth buffer stack!" );
|
---|
622 | return;
|
---|
623 | }
|
---|
624 | a->depthBufferStackDepth--;
|
---|
625 | g->buffer.depthTest = a->depthBufferStack[a->depthBufferStackDepth].depthTest;
|
---|
626 | g->buffer.depthFunc = a->depthBufferStack[a->depthBufferStackDepth].depthFunc;
|
---|
627 | g->buffer.depthClearValue = a->depthBufferStack[a->depthBufferStackDepth].depthClearValue;
|
---|
628 | g->buffer.depthMask = a->depthBufferStack[a->depthBufferStackDepth].depthMask;
|
---|
629 | DIRTY(sb->buffer.dirty, g->neg_bitid);
|
---|
630 | DIRTY(sb->buffer.enable, g->neg_bitid);
|
---|
631 | DIRTY(sb->buffer.depthFunc, g->neg_bitid);
|
---|
632 | DIRTY(sb->buffer.clearDepth, g->neg_bitid);
|
---|
633 | DIRTY(sb->buffer.depthMask, g->neg_bitid);
|
---|
634 | }
|
---|
635 | if (mask & GL_ENABLE_BIT)
|
---|
636 | {
|
---|
637 | if (a->enableStackDepth == 0)
|
---|
638 | {
|
---|
639 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty enable stack!" );
|
---|
640 | return;
|
---|
641 | }
|
---|
642 | a->enableStackDepth--;
|
---|
643 | g->buffer.alphaTest = a->enableStack[a->enableStackDepth].alphaTest;
|
---|
644 | g->eval.autoNormal = a->enableStack[a->enableStackDepth].autoNormal;
|
---|
645 | g->buffer.blend = a->enableStack[a->enableStackDepth].blend;
|
---|
646 | for (i = 0 ; i < g->limits.maxClipPlanes ; i++)
|
---|
647 | {
|
---|
648 | g->transform.clip[i] = a->enableStack[a->enableStackDepth].clip[i];
|
---|
649 | }
|
---|
650 | g->lighting.colorMaterial = a->enableStack[a->enableStackDepth].colorMaterial;
|
---|
651 | g->polygon.cullFace = a->enableStack[a->enableStackDepth].cullFace;
|
---|
652 | g->buffer.depthTest = a->enableStack[a->enableStackDepth].depthTest;
|
---|
653 | g->buffer.dither = a->enableStack[a->enableStackDepth].dither;
|
---|
654 | g->fog.enable = a->enableStack[a->enableStackDepth].fog;
|
---|
655 | for (i = 0 ; i < g->limits.maxLights ; i++)
|
---|
656 | {
|
---|
657 | g->lighting.light[i].enable = a->enableStack[a->enableStackDepth].light[i];
|
---|
658 | }
|
---|
659 | g->lighting.lighting = a->enableStack[a->enableStackDepth].lighting;
|
---|
660 | g->line.lineSmooth = a->enableStack[a->enableStackDepth].lineSmooth;
|
---|
661 | g->line.lineStipple = a->enableStack[a->enableStackDepth].lineStipple;
|
---|
662 | g->buffer.logicOp = a->enableStack[a->enableStackDepth].logicOp;
|
---|
663 | g->buffer.indexLogicOp = a->enableStack[a->enableStackDepth].indexLogicOp;
|
---|
664 | for (i = 0 ; i < GLEVAL_TOT ; i++)
|
---|
665 | {
|
---|
666 | g->eval.enable1D[i] = a->enableStack[a->enableStackDepth].map1[i];
|
---|
667 | g->eval.enable2D[i] = a->enableStack[a->enableStackDepth].map2[i];
|
---|
668 | }
|
---|
669 | g->transform.normalize = a->enableStack[a->enableStackDepth].normalize;
|
---|
670 | g->point.pointSmooth = a->enableStack[a->enableStackDepth].pointSmooth;
|
---|
671 | #ifdef CR_ARB_point_sprite
|
---|
672 | g->point.pointSprite = a->enableStack[a->enableStackDepth].pointSprite;
|
---|
673 | for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
|
---|
674 | g->point.coordReplacement[i] = a->enableStack[a->enableStackDepth].coordReplacement[i];
|
---|
675 | #endif
|
---|
676 | g->polygon.polygonOffsetLine = a->enableStack[a->enableStackDepth].polygonOffsetLine;
|
---|
677 | g->polygon.polygonOffsetFill = a->enableStack[a->enableStackDepth].polygonOffsetFill;
|
---|
678 | g->polygon.polygonOffsetPoint = a->enableStack[a->enableStackDepth].polygonOffsetPoint;
|
---|
679 | g->polygon.polygonSmooth = a->enableStack[a->enableStackDepth].polygonSmooth;
|
---|
680 | g->polygon.polygonStipple = a->enableStack[a->enableStackDepth].polygonStipple;
|
---|
681 | #ifdef CR_OPENGL_VERSION_1_2
|
---|
682 | g->transform.rescaleNormals = a->enableStack[a->enableStackDepth].rescaleNormals;
|
---|
683 | #endif
|
---|
684 | g->viewport.scissorTest = a->enableStack[a->enableStackDepth].scissorTest;
|
---|
685 | g->stencil.stencilTest = a->enableStack[a->enableStackDepth].stencilTest;
|
---|
686 | for (i = 0 ; i < g->limits.maxTextureUnits; i++)
|
---|
687 | {
|
---|
688 | g->texture.unit[i].enabled1D = a->enableStack[a->enableStackDepth].texture1D[i];
|
---|
689 | g->texture.unit[i].enabled2D = a->enableStack[a->enableStackDepth].texture2D[i];
|
---|
690 | #ifdef CR_OPENGL_VERSION_1_2
|
---|
691 | g->texture.unit[i].enabled3D = a->enableStack[a->enableStackDepth].texture3D[i];
|
---|
692 | #endif
|
---|
693 | #ifdef CR_ARB_texture_cube_map
|
---|
694 | g->texture.unit[i].enabledCubeMap = a->enableStack[a->enableStackDepth].textureCubeMap[i];
|
---|
695 | #endif
|
---|
696 | #ifdef CR_NV_texture_rectangle
|
---|
697 | g->texture.unit[i].enabledRect = a->enableStack[a->enableStackDepth].textureRect[i];
|
---|
698 | #endif
|
---|
699 | g->texture.unit[i].textureGen.s = a->enableStack[a->enableStackDepth].textureGenS[i];
|
---|
700 | g->texture.unit[i].textureGen.t = a->enableStack[a->enableStackDepth].textureGenT[i];
|
---|
701 | g->texture.unit[i].textureGen.r = a->enableStack[a->enableStackDepth].textureGenR[i];
|
---|
702 | g->texture.unit[i].textureGen.q = a->enableStack[a->enableStackDepth].textureGenQ[i];
|
---|
703 | }
|
---|
704 | DIRTY(sb->buffer.dirty, g->neg_bitid);
|
---|
705 | DIRTY(sb->eval.dirty, g->neg_bitid);
|
---|
706 | DIRTY(sb->transform.dirty, g->neg_bitid);
|
---|
707 | DIRTY(sb->lighting.dirty, g->neg_bitid);
|
---|
708 | DIRTY(sb->fog.dirty, g->neg_bitid);
|
---|
709 | DIRTY(sb->line.dirty, g->neg_bitid);
|
---|
710 | DIRTY(sb->polygon.dirty, g->neg_bitid);
|
---|
711 | DIRTY(sb->viewport.dirty, g->neg_bitid);
|
---|
712 | DIRTY(sb->stencil.dirty, g->neg_bitid);
|
---|
713 | DIRTY(sb->texture.dirty, g->neg_bitid);
|
---|
714 |
|
---|
715 | DIRTY(sb->buffer.enable, g->neg_bitid);
|
---|
716 | DIRTY(sb->eval.enable, g->neg_bitid);
|
---|
717 | DIRTY(sb->transform.enable, g->neg_bitid);
|
---|
718 | DIRTY(sb->lighting.enable, g->neg_bitid);
|
---|
719 | DIRTY(sb->fog.enable, g->neg_bitid);
|
---|
720 | DIRTY(sb->line.enable, g->neg_bitid);
|
---|
721 | DIRTY(sb->polygon.enable, g->neg_bitid);
|
---|
722 | DIRTY(sb->viewport.enable, g->neg_bitid);
|
---|
723 | DIRTY(sb->stencil.enable, g->neg_bitid);
|
---|
724 | for (i = 0 ; i < g->limits.maxTextureUnits ; i++)
|
---|
725 | {
|
---|
726 | DIRTY(sb->texture.enable[i], g->neg_bitid);
|
---|
727 | }
|
---|
728 | }
|
---|
729 | if (mask & GL_EVAL_BIT)
|
---|
730 | {
|
---|
731 | if (a->evalStackDepth == 0)
|
---|
732 | {
|
---|
733 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty eval stack!" );
|
---|
734 | return;
|
---|
735 | }
|
---|
736 | a->evalStackDepth--;
|
---|
737 | for (i = 0 ; i < GLEVAL_TOT ; i++)
|
---|
738 | {
|
---|
739 | int size1 = a->evalStack[a->evalStackDepth].eval1D[i].order * gleval_sizes[i] * sizeof(GLfloat);
|
---|
740 | int size2 = a->evalStack[a->evalStackDepth].eval2D[i].uorder * a->evalStack[a->evalStackDepth].eval2D[i].vorder * gleval_sizes[i] * sizeof (GLfloat);
|
---|
741 | g->eval.enable1D[i] = a->evalStack[a->evalStackDepth].enable1D[i];
|
---|
742 | g->eval.enable2D[i] = a->evalStack[a->evalStackDepth].enable2D[i];
|
---|
743 | g->eval.eval1D[i].u1 = a->evalStack[a->evalStackDepth].eval1D[i].u1;
|
---|
744 | g->eval.eval1D[i].u2 = a->evalStack[a->evalStackDepth].eval1D[i].u2;
|
---|
745 | g->eval.eval1D[i].order = a->evalStack[a->evalStackDepth].eval1D[i].order;
|
---|
746 | crMemcpy((char*)g->eval.eval1D[i].coeff, a->evalStack[a->evalStackDepth].eval1D[i].coeff, size1);
|
---|
747 | crFree(a->evalStack[a->evalStackDepth].eval1D[i].coeff);
|
---|
748 | a->evalStack[a->evalStackDepth].eval1D[i].coeff = NULL;
|
---|
749 | g->eval.eval2D[i].u1 = a->evalStack[a->evalStackDepth].eval2D[i].u1;
|
---|
750 | g->eval.eval2D[i].u2 = a->evalStack[a->evalStackDepth].eval2D[i].u2;
|
---|
751 | g->eval.eval2D[i].v1 = a->evalStack[a->evalStackDepth].eval2D[i].v1;
|
---|
752 | g->eval.eval2D[i].v2 = a->evalStack[a->evalStackDepth].eval2D[i].v2;
|
---|
753 | g->eval.eval2D[i].uorder = a->evalStack[a->evalStackDepth].eval2D[i].uorder;
|
---|
754 | g->eval.eval2D[i].vorder = a->evalStack[a->evalStackDepth].eval2D[i].vorder;
|
---|
755 | crMemcpy((char*)g->eval.eval2D[i].coeff, a->evalStack[a->evalStackDepth].eval2D[i].coeff, size2);
|
---|
756 | crFree(a->evalStack[a->evalStackDepth].eval2D[i].coeff);
|
---|
757 | a->evalStack[a->evalStackDepth].eval2D[i].coeff = NULL;
|
---|
758 | }
|
---|
759 | g->eval.autoNormal = a->evalStack[a->evalStackDepth].autoNormal;
|
---|
760 | g->eval.un1D = a->evalStack[a->evalStackDepth].un1D;
|
---|
761 | g->eval.u11D = a->evalStack[a->evalStackDepth].u11D;
|
---|
762 | g->eval.u21D = a->evalStack[a->evalStackDepth].u21D;
|
---|
763 | g->eval.un2D = a->evalStack[a->evalStackDepth].un2D;
|
---|
764 | g->eval.u12D = a->evalStack[a->evalStackDepth].u12D;
|
---|
765 | g->eval.u22D = a->evalStack[a->evalStackDepth].u22D;
|
---|
766 | g->eval.vn2D = a->evalStack[a->evalStackDepth].vn2D;
|
---|
767 | g->eval.v12D = a->evalStack[a->evalStackDepth].v12D;
|
---|
768 | g->eval.v22D = a->evalStack[a->evalStackDepth].v22D;
|
---|
769 | for (i = 0; i < GLEVAL_TOT; i++) {
|
---|
770 | DIRTY(sb->eval.eval1D[i], g->neg_bitid);
|
---|
771 | DIRTY(sb->eval.eval2D[i], g->neg_bitid);
|
---|
772 | }
|
---|
773 | DIRTY(sb->eval.dirty, g->neg_bitid);
|
---|
774 | DIRTY(sb->eval.grid1D, g->neg_bitid);
|
---|
775 | DIRTY(sb->eval.grid2D, g->neg_bitid);
|
---|
776 | DIRTY(sb->eval.enable, g->neg_bitid);
|
---|
777 | }
|
---|
778 | if (mask & GL_FOG_BIT)
|
---|
779 | {
|
---|
780 | if (a->fogStackDepth == 0)
|
---|
781 | {
|
---|
782 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty fog stack!" );
|
---|
783 | return;
|
---|
784 | }
|
---|
785 | a->fogStackDepth--;
|
---|
786 | g->fog.enable = a->fogStack[a->fogStackDepth].enable;
|
---|
787 | g->fog.color = a->fogStack[a->fogStackDepth].color;
|
---|
788 | g->fog.density = a->fogStack[a->fogStackDepth].density;
|
---|
789 | g->fog.start = a->fogStack[a->fogStackDepth].start;
|
---|
790 | g->fog.end = a->fogStack[a->fogStackDepth].end;
|
---|
791 | g->fog.index = a->fogStack[a->fogStackDepth].index;
|
---|
792 | g->fog.mode = a->fogStack[a->fogStackDepth].mode;
|
---|
793 | DIRTY(sb->fog.dirty, g->neg_bitid);
|
---|
794 | DIRTY(sb->fog.color, g->neg_bitid);
|
---|
795 | DIRTY(sb->fog.index, g->neg_bitid);
|
---|
796 | DIRTY(sb->fog.density, g->neg_bitid);
|
---|
797 | DIRTY(sb->fog.start, g->neg_bitid);
|
---|
798 | DIRTY(sb->fog.end, g->neg_bitid);
|
---|
799 | DIRTY(sb->fog.mode, g->neg_bitid);
|
---|
800 | DIRTY(sb->fog.enable, g->neg_bitid);
|
---|
801 | }
|
---|
802 | if (mask & GL_HINT_BIT)
|
---|
803 | {
|
---|
804 | if (a->hintStackDepth == 0)
|
---|
805 | {
|
---|
806 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty hint stack!" );
|
---|
807 | return;
|
---|
808 | }
|
---|
809 | a->hintStackDepth--;
|
---|
810 | g->hint.perspectiveCorrection = a->hintStack[a->hintStackDepth].perspectiveCorrection;
|
---|
811 | g->hint.pointSmooth = a->hintStack[a->hintStackDepth].pointSmooth;
|
---|
812 | g->hint.lineSmooth = a->hintStack[a->hintStackDepth].lineSmooth;
|
---|
813 | g->hint.polygonSmooth = a->hintStack[a->hintStackDepth].polygonSmooth;
|
---|
814 | g->hint.fog = a->hintStack[a->hintStackDepth].fog;
|
---|
815 | DIRTY(sb->hint.dirty, g->neg_bitid);
|
---|
816 | DIRTY(sb->hint.perspectiveCorrection, g->neg_bitid);
|
---|
817 | DIRTY(sb->hint.pointSmooth, g->neg_bitid);
|
---|
818 | DIRTY(sb->hint.lineSmooth, g->neg_bitid);
|
---|
819 | DIRTY(sb->hint.polygonSmooth, g->neg_bitid);
|
---|
820 | #ifdef CR_EXT_clip_volume_hint
|
---|
821 | g->hint.clipVolumeClipping = a->hintStack[a->hintStackDepth].clipVolumeClipping;
|
---|
822 | DIRTY(sb->hint.clipVolumeClipping, g->neg_bitid);
|
---|
823 | #endif
|
---|
824 | #ifdef CR_ARB_texture_compression
|
---|
825 | g->hint.textureCompression = a->hintStack[a->hintStackDepth].textureCompression;
|
---|
826 | DIRTY(sb->hint.textureCompression, g->neg_bitid);
|
---|
827 | #endif
|
---|
828 | #ifdef CR_SGIS_generate_mipmap
|
---|
829 | g->hint.generateMipmap = a->hintStack[a->hintStackDepth].generateMipmap;
|
---|
830 | DIRTY(sb->hint.generateMipmap, g->neg_bitid);
|
---|
831 | #endif
|
---|
832 | }
|
---|
833 | if (mask & GL_LIGHTING_BIT)
|
---|
834 | {
|
---|
835 | if (a->lightingStackDepth == 0)
|
---|
836 | {
|
---|
837 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty lighting stack!" );
|
---|
838 | return;
|
---|
839 | }
|
---|
840 | a->lightingStackDepth--;
|
---|
841 | g->lighting.lightModelAmbient = a->lightingStack[a->lightingStackDepth].lightModelAmbient;
|
---|
842 | g->lighting.lightModelLocalViewer = a->lightingStack[a->lightingStackDepth].lightModelLocalViewer;
|
---|
843 | g->lighting.lightModelTwoSide = a->lightingStack[a->lightingStackDepth].lightModelTwoSide;
|
---|
844 | #if defined(CR_EXT_separate_specular_color) || defined(CR_OPENGL_VERSION_1_2)
|
---|
845 | g->lighting.lightModelColorControlEXT = a->lightingStack[a->lightingStackDepth].lightModelColorControlEXT;
|
---|
846 | #endif
|
---|
847 | g->lighting.lighting = a->lightingStack[a->lightingStackDepth].lighting;
|
---|
848 | g->lighting.colorMaterial = a->lightingStack[a->lightingStackDepth].colorMaterial;
|
---|
849 | g->lighting.colorMaterialMode = a->lightingStack[a->lightingStackDepth].colorMaterialMode;
|
---|
850 | g->lighting.colorMaterialFace = a->lightingStack[a->lightingStackDepth].colorMaterialFace;
|
---|
851 | for (i = 0 ; i < g->limits.maxLights; i++)
|
---|
852 | {
|
---|
853 | g->lighting.light[i].enable = a->lightingStack[a->lightingStackDepth].light[i].enable;
|
---|
854 | g->lighting.light[i].ambient = a->lightingStack[a->lightingStackDepth].light[i].ambient;
|
---|
855 | g->lighting.light[i].diffuse = a->lightingStack[a->lightingStackDepth].light[i].diffuse;
|
---|
856 | g->lighting.light[i].specular = a->lightingStack[a->lightingStackDepth].light[i].specular;
|
---|
857 | g->lighting.light[i].spotDirection = a->lightingStack[a->lightingStackDepth].light[i].spotDirection;
|
---|
858 | g->lighting.light[i].position = a->lightingStack[a->lightingStackDepth].light[i].position;
|
---|
859 | g->lighting.light[i].spotExponent = a->lightingStack[a->lightingStackDepth].light[i].spotExponent;
|
---|
860 | g->lighting.light[i].spotCutoff = a->lightingStack[a->lightingStackDepth].light[i].spotCutoff;
|
---|
861 | g->lighting.light[i].constantAttenuation = a->lightingStack[a->lightingStackDepth].light[i].constantAttenuation;
|
---|
862 | g->lighting.light[i].linearAttenuation = a->lightingStack[a->lightingStackDepth].light[i].linearAttenuation;
|
---|
863 | g->lighting.light[i].quadraticAttenuation = a->lightingStack[a->lightingStackDepth].light[i].quadraticAttenuation;
|
---|
864 | }
|
---|
865 | for (i = 0 ; i < 2 ; i++)
|
---|
866 | {
|
---|
867 | g->lighting.ambient[i] = a->lightingStack[a->lightingStackDepth].ambient[i];
|
---|
868 | g->lighting.diffuse[i] = a->lightingStack[a->lightingStackDepth].diffuse[i];
|
---|
869 | g->lighting.specular[i] = a->lightingStack[a->lightingStackDepth].specular[i];
|
---|
870 | g->lighting.emission[i] = a->lightingStack[a->lightingStackDepth].emission[i];
|
---|
871 | g->lighting.shininess[i] = a->lightingStack[a->lightingStackDepth].shininess[i];
|
---|
872 | g->lighting.indexes[i][0] = a->lightingStack[a->lightingStackDepth].indexes[i][0];
|
---|
873 | g->lighting.indexes[i][1] = a->lightingStack[a->lightingStackDepth].indexes[i][1];
|
---|
874 | g->lighting.indexes[i][2] = a->lightingStack[a->lightingStackDepth].indexes[i][2];
|
---|
875 | }
|
---|
876 | g->lighting.shadeModel = a->lightingStack[a->lightingStackDepth].shadeModel;
|
---|
877 | DIRTY(sb->lighting.dirty, g->neg_bitid);
|
---|
878 | DIRTY(sb->lighting.shadeModel, g->neg_bitid);
|
---|
879 | DIRTY(sb->lighting.lightModel, g->neg_bitid);
|
---|
880 | DIRTY(sb->lighting.material, g->neg_bitid);
|
---|
881 | DIRTY(sb->lighting.enable, g->neg_bitid);
|
---|
882 | for (i = 0 ; i < g->limits.maxLights; i++)
|
---|
883 | {
|
---|
884 | DIRTY(sb->lighting.light[i].dirty, g->neg_bitid);
|
---|
885 | DIRTY(sb->lighting.light[i].enable, g->neg_bitid);
|
---|
886 | DIRTY(sb->lighting.light[i].ambient, g->neg_bitid);
|
---|
887 | DIRTY(sb->lighting.light[i].diffuse, g->neg_bitid);
|
---|
888 | DIRTY(sb->lighting.light[i].specular, g->neg_bitid);
|
---|
889 | DIRTY(sb->lighting.light[i].position, g->neg_bitid);
|
---|
890 | DIRTY(sb->lighting.light[i].attenuation, g->neg_bitid);
|
---|
891 | DIRTY(sb->lighting.light[i].spot, g->neg_bitid);
|
---|
892 | }
|
---|
893 | }
|
---|
894 | if (mask & GL_LINE_BIT)
|
---|
895 | {
|
---|
896 | if (a->lineStackDepth == 0)
|
---|
897 | {
|
---|
898 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty line stack!" );
|
---|
899 | return;
|
---|
900 | }
|
---|
901 | a->lineStackDepth--;
|
---|
902 | g->line.lineSmooth = a->lineStack[a->lineStackDepth].lineSmooth;
|
---|
903 | g->line.lineStipple = a->lineStack[a->lineStackDepth].lineStipple;
|
---|
904 | g->line.pattern = a->lineStack[a->lineStackDepth].pattern;
|
---|
905 | g->line.repeat = a->lineStack[a->lineStackDepth].repeat;
|
---|
906 | g->line.width = a->lineStack[a->lineStackDepth].width;
|
---|
907 | DIRTY(sb->line.dirty, g->neg_bitid);
|
---|
908 | DIRTY(sb->line.enable, g->neg_bitid);
|
---|
909 | DIRTY(sb->line.width, g->neg_bitid);
|
---|
910 | DIRTY(sb->line.stipple, g->neg_bitid);
|
---|
911 | }
|
---|
912 | if (mask & GL_LIST_BIT)
|
---|
913 | {
|
---|
914 | if (a->listStackDepth == 0)
|
---|
915 | {
|
---|
916 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty list stack!" );
|
---|
917 | return;
|
---|
918 | }
|
---|
919 | a->listStackDepth--;
|
---|
920 | g->lists.base = a->listStack[a->listStackDepth].base;
|
---|
921 | DIRTY(sb->lists.dirty, g->neg_bitid);
|
---|
922 | }
|
---|
923 | if (mask & GL_PIXEL_MODE_BIT)
|
---|
924 | {
|
---|
925 | if (a->pixelModeStackDepth == 0)
|
---|
926 | {
|
---|
927 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty pixel mode stack!" );
|
---|
928 | return;
|
---|
929 | }
|
---|
930 | a->pixelModeStackDepth--;
|
---|
931 | g->pixel.bias = a->pixelModeStack[a->pixelModeStackDepth].bias;
|
---|
932 | g->pixel.scale = a->pixelModeStack[a->pixelModeStackDepth].scale;
|
---|
933 | g->pixel.indexOffset = a->pixelModeStack[a->pixelModeStackDepth].indexOffset;
|
---|
934 | g->pixel.indexShift = a->pixelModeStack[a->pixelModeStackDepth].indexShift;
|
---|
935 | g->pixel.mapColor = a->pixelModeStack[a->pixelModeStackDepth].mapColor;
|
---|
936 | g->pixel.mapStencil = a->pixelModeStack[a->pixelModeStackDepth].mapStencil;
|
---|
937 | g->pixel.xZoom = a->pixelModeStack[a->pixelModeStackDepth].xZoom;
|
---|
938 | g->pixel.yZoom = a->pixelModeStack[a->pixelModeStackDepth].yZoom;
|
---|
939 | g->buffer.readBuffer = a->pixelModeStack[a->pixelModeStackDepth].readBuffer;
|
---|
940 | DIRTY(sb->pixel.dirty, g->neg_bitid);
|
---|
941 | DIRTY(sb->pixel.transfer, g->neg_bitid);
|
---|
942 | DIRTY(sb->pixel.zoom, g->neg_bitid);
|
---|
943 | DIRTY(sb->buffer.dirty, g->neg_bitid);
|
---|
944 | DIRTY(sb->buffer.readBuffer, g->neg_bitid);
|
---|
945 | }
|
---|
946 | if (mask & GL_POINT_BIT)
|
---|
947 | {
|
---|
948 | if (a->pointStackDepth == 0)
|
---|
949 | {
|
---|
950 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty point stack!" );
|
---|
951 | return;
|
---|
952 | }
|
---|
953 | a->pointStackDepth--;
|
---|
954 | g->point.pointSmooth = a->pointStack[a->pointStackDepth].pointSmooth;
|
---|
955 | g->point.pointSize = a->pointStack[a->pointStackDepth].pointSize;
|
---|
956 | #if GL_ARB_point_sprite
|
---|
957 | g->point.pointSprite = a->pointStack[a->pointStackDepth].pointSprite;
|
---|
958 | DIRTY(sb->point.enableSprite, g->neg_bitid);
|
---|
959 | for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++) {
|
---|
960 | g->point.coordReplacement[i] = a->enableStack[a->enableStackDepth].coordReplacement[i];
|
---|
961 | DIRTY(sb->point.coordReplacement[i], g->neg_bitid);
|
---|
962 | }
|
---|
963 | #endif
|
---|
964 | DIRTY(sb->point.dirty, g->neg_bitid);
|
---|
965 | DIRTY(sb->point.size, g->neg_bitid);
|
---|
966 | DIRTY(sb->point.enableSmooth, g->neg_bitid);
|
---|
967 | }
|
---|
968 | if (mask & GL_POLYGON_BIT)
|
---|
969 | {
|
---|
970 | if (a->polygonStackDepth == 0)
|
---|
971 | {
|
---|
972 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty polygon stack!" );
|
---|
973 | return;
|
---|
974 | }
|
---|
975 | a->polygonStackDepth--;
|
---|
976 | g->polygon.cullFace = a->polygonStack[a->polygonStackDepth].cullFace;
|
---|
977 | g->polygon.cullFaceMode = a->polygonStack[a->polygonStackDepth].cullFaceMode;
|
---|
978 | g->polygon.frontFace = a->polygonStack[a->polygonStackDepth].frontFace;
|
---|
979 | g->polygon.frontMode = a->polygonStack[a->polygonStackDepth].frontMode;
|
---|
980 | g->polygon.backMode = a->polygonStack[a->polygonStackDepth].backMode;
|
---|
981 | g->polygon.polygonSmooth = a->polygonStack[a->polygonStackDepth].polygonSmooth;
|
---|
982 | g->polygon.polygonStipple = a->polygonStack[a->polygonStackDepth].polygonStipple;
|
---|
983 | g->polygon.polygonOffsetFill = a->polygonStack[a->polygonStackDepth].polygonOffsetFill;
|
---|
984 | g->polygon.polygonOffsetLine = a->polygonStack[a->polygonStackDepth].polygonOffsetLine;
|
---|
985 | g->polygon.polygonOffsetPoint = a->polygonStack[a->polygonStackDepth].polygonOffsetPoint;
|
---|
986 | g->polygon.offsetFactor = a->polygonStack[a->polygonStackDepth].offsetFactor;
|
---|
987 | g->polygon.offsetUnits = a->polygonStack[a->polygonStackDepth].offsetUnits;
|
---|
988 | DIRTY(sb->polygon.dirty, g->neg_bitid);
|
---|
989 | DIRTY(sb->polygon.enable, g->neg_bitid);
|
---|
990 | DIRTY(sb->polygon.offset, g->neg_bitid);
|
---|
991 | DIRTY(sb->polygon.mode, g->neg_bitid);
|
---|
992 | DIRTY(sb->polygon.stipple, g->neg_bitid);
|
---|
993 | }
|
---|
994 | if (mask & GL_POLYGON_STIPPLE_BIT)
|
---|
995 | {
|
---|
996 | if (a->polygonStippleStackDepth == 0)
|
---|
997 | {
|
---|
998 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty polygon stipple stack!" );
|
---|
999 | return;
|
---|
1000 | }
|
---|
1001 | a->polygonStippleStackDepth--;
|
---|
1002 | crMemcpy( g->polygon.stipple, a->polygonStippleStack[a->polygonStippleStackDepth].pattern, 32*sizeof(GLint) );
|
---|
1003 | DIRTY(sb->polygon.dirty, g->neg_bitid);
|
---|
1004 | DIRTY(sb->polygon.stipple, g->neg_bitid);
|
---|
1005 | }
|
---|
1006 | if (mask & GL_SCISSOR_BIT)
|
---|
1007 | {
|
---|
1008 | if (a->scissorStackDepth == 0)
|
---|
1009 | {
|
---|
1010 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty scissor stack!" );
|
---|
1011 | return;
|
---|
1012 | }
|
---|
1013 | a->scissorStackDepth--;
|
---|
1014 | g->viewport.scissorTest = a->scissorStack[a->scissorStackDepth].scissorTest;
|
---|
1015 | g->viewport.scissorX = a->scissorStack[a->scissorStackDepth].scissorX;
|
---|
1016 | g->viewport.scissorY = a->scissorStack[a->scissorStackDepth].scissorY;
|
---|
1017 | g->viewport.scissorW = a->scissorStack[a->scissorStackDepth].scissorW;
|
---|
1018 | g->viewport.scissorH = a->scissorStack[a->scissorStackDepth].scissorH;
|
---|
1019 | DIRTY(sb->viewport.dirty, g->neg_bitid);
|
---|
1020 | DIRTY(sb->viewport.enable, g->neg_bitid);
|
---|
1021 | DIRTY(sb->viewport.s_dims, g->neg_bitid);
|
---|
1022 | }
|
---|
1023 | if (mask & GL_STENCIL_BUFFER_BIT)
|
---|
1024 | {
|
---|
1025 | if (a->stencilBufferStackDepth == 0)
|
---|
1026 | {
|
---|
1027 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty stencil stack!" );
|
---|
1028 | return;
|
---|
1029 | }
|
---|
1030 | a->stencilBufferStackDepth--;
|
---|
1031 | g->stencil.stencilTest = a->stencilBufferStack[a->stencilBufferStackDepth].stencilTest;
|
---|
1032 | g->stencil.func = a->stencilBufferStack[a->stencilBufferStackDepth].func;
|
---|
1033 | g->stencil.mask = a->stencilBufferStack[a->stencilBufferStackDepth].mask;
|
---|
1034 | g->stencil.ref = a->stencilBufferStack[a->stencilBufferStackDepth].ref;
|
---|
1035 | g->stencil.fail = a->stencilBufferStack[a->stencilBufferStackDepth].fail;
|
---|
1036 | g->stencil.passDepthFail = a->stencilBufferStack[a->stencilBufferStackDepth].passDepthFail;
|
---|
1037 | g->stencil.passDepthPass = a->stencilBufferStack[a->stencilBufferStackDepth].passDepthPass;
|
---|
1038 | g->stencil.clearValue = a->stencilBufferStack[a->stencilBufferStackDepth].clearValue;
|
---|
1039 | g->stencil.writeMask = a->stencilBufferStack[a->stencilBufferStackDepth].writeMask;
|
---|
1040 | DIRTY(sb->stencil.dirty, g->neg_bitid);
|
---|
1041 | DIRTY(sb->stencil.enable, g->neg_bitid);
|
---|
1042 | DIRTY(sb->stencil.func, g->neg_bitid);
|
---|
1043 | DIRTY(sb->stencil.op, g->neg_bitid);
|
---|
1044 | DIRTY(sb->stencil.clearValue, g->neg_bitid);
|
---|
1045 | DIRTY(sb->stencil.writeMask, g->neg_bitid);
|
---|
1046 | }
|
---|
1047 | if (mask & GL_TEXTURE_BIT)
|
---|
1048 | {
|
---|
1049 | CRTextureStack *tState;
|
---|
1050 | if (a->textureStackDepth == 0)
|
---|
1051 | {
|
---|
1052 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty texture stack!" );
|
---|
1053 | return;
|
---|
1054 | }
|
---|
1055 | a->textureStackDepth--;
|
---|
1056 | tState = a->textureStack + a->textureStackDepth;
|
---|
1057 |
|
---|
1058 | g->texture.curTextureUnit = tState->curTextureUnit;
|
---|
1059 | for (i = 0 ; i < g->limits.maxTextureUnits ; i++)
|
---|
1060 | {
|
---|
1061 | copy_texunit(&g->texture.unit[i], &tState->unit[i]);
|
---|
1062 | /* first, restore the bindings! */
|
---|
1063 | g->texture.unit[i].currentTexture1D = crStateTextureGet(GL_TEXTURE_1D, tState->unit[i].Saved1D.name);
|
---|
1064 | copy_texobj(g->texture.unit[i].currentTexture1D, &tState->unit[i].Saved1D, GL_FALSE);
|
---|
1065 | g->texture.unit[i].currentTexture2D = crStateTextureGet(GL_TEXTURE_2D, tState->unit[i].Saved2D.name);
|
---|
1066 | copy_texobj(g->texture.unit[i].currentTexture2D, &tState->unit[i].Saved2D, GL_FALSE);
|
---|
1067 | #ifdef CR_OPENGL_VERSION_1_2
|
---|
1068 | g->texture.unit[i].currentTexture3D = crStateTextureGet(GL_TEXTURE_3D, tState->unit[i].Saved3D.name);
|
---|
1069 | copy_texobj(g->texture.unit[i].currentTexture3D, &tState->unit[i].Saved3D, GL_FALSE);
|
---|
1070 | #endif
|
---|
1071 | #ifdef CR_ARB_texture_cube_map
|
---|
1072 | g->texture.unit[i].currentTextureCubeMap = crStateTextureGet(GL_TEXTURE_CUBE_MAP_ARB, tState->unit[i].SavedCubeMap.name);
|
---|
1073 | copy_texobj(g->texture.unit[i].currentTextureCubeMap, &tState->unit[i].SavedCubeMap, GL_FALSE);
|
---|
1074 | #endif
|
---|
1075 | #ifdef CR_NV_texture_rectangle
|
---|
1076 | g->texture.unit[i].currentTextureRect = crStateTextureGet(GL_TEXTURE_CUBE_MAP_ARB, tState->unit[i].SavedRect.name);
|
---|
1077 | copy_texobj(g->texture.unit[i].currentTextureRect, &tState->unit[i].SavedRect, GL_FALSE);
|
---|
1078 | #endif
|
---|
1079 | }
|
---|
1080 | DIRTY(sb->texture.dirty, g->neg_bitid);
|
---|
1081 | for (i = 0 ; i < g->limits.maxTextureUnits ; i++)
|
---|
1082 | {
|
---|
1083 | DIRTY(sb->texture.enable[i], g->neg_bitid);
|
---|
1084 | DIRTY(sb->texture.current[i], g->neg_bitid);
|
---|
1085 | DIRTY(sb->texture.objGen[i], g->neg_bitid);
|
---|
1086 | DIRTY(sb->texture.eyeGen[i], g->neg_bitid);
|
---|
1087 | DIRTY(sb->texture.envBit[i], g->neg_bitid);
|
---|
1088 | DIRTY(sb->texture.genMode[i], g->neg_bitid);
|
---|
1089 | }
|
---|
1090 |
|
---|
1091 | for (i = 0 ; i < g->limits.maxTextureUnits ; i++)
|
---|
1092 | {
|
---|
1093 | DIRTY(g->texture.unit[i].currentTexture1D->dirty, g->neg_bitid);
|
---|
1094 | DIRTY(g->texture.unit[i].currentTexture2D->dirty, g->neg_bitid);
|
---|
1095 | DIRTY(g->texture.unit[i].currentTexture3D->dirty, g->neg_bitid);
|
---|
1096 | #ifdef CR_ARB_texture_cube_map
|
---|
1097 | DIRTY(g->texture.unit[i].currentTextureCubeMap->dirty, g->neg_bitid);
|
---|
1098 | #endif
|
---|
1099 | #ifdef CR_NV_texture_rectangle
|
---|
1100 | DIRTY(g->texture.unit[i].currentTextureRect->dirty, g->neg_bitid);
|
---|
1101 | #endif
|
---|
1102 | DIRTY(g->texture.unit[i].currentTexture1D->paramsBit[i], g->neg_bitid);
|
---|
1103 | DIRTY(g->texture.unit[i].currentTexture2D->paramsBit[i], g->neg_bitid);
|
---|
1104 | DIRTY(g->texture.unit[i].currentTexture3D->paramsBit[i], g->neg_bitid);
|
---|
1105 | #ifdef CR_ARB_texture_cube_map
|
---|
1106 | DIRTY(g->texture.unit[i].currentTextureCubeMap->paramsBit[i], g->neg_bitid);
|
---|
1107 | #endif
|
---|
1108 | #ifdef CR_NV_texture_rectangle
|
---|
1109 | DIRTY(g->texture.unit[i].currentTextureRect->paramsBit[i], g->neg_bitid);
|
---|
1110 | #endif
|
---|
1111 | }
|
---|
1112 | }
|
---|
1113 | if (mask & GL_TRANSFORM_BIT)
|
---|
1114 | {
|
---|
1115 | if (a->transformStackDepth == 0)
|
---|
1116 | {
|
---|
1117 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty transform stack!" );
|
---|
1118 | return;
|
---|
1119 | }
|
---|
1120 | a->transformStackDepth--;
|
---|
1121 | g->transform.matrixMode = a->transformStack[a->transformStackDepth].matrixMode;
|
---|
1122 | crStateMatrixMode(g->transform.matrixMode);
|
---|
1123 | for (i = 0 ; i < g->limits.maxClipPlanes ; i++)
|
---|
1124 | {
|
---|
1125 | g->transform.clip[i] = a->transformStack[a->transformStackDepth].clip[i];
|
---|
1126 | g->transform.clipPlane[i] = a->transformStack[a->transformStackDepth].clipPlane[i];
|
---|
1127 | }
|
---|
1128 | g->transform.normalize = a->transformStack[a->transformStackDepth].normalize;
|
---|
1129 | #ifdef CR_OPENGL_VERSION_1_2
|
---|
1130 | g->transform.rescaleNormals = a->transformStack[a->transformStackDepth].rescaleNormals;
|
---|
1131 | #endif
|
---|
1132 | DIRTY(sb->transform.dirty, g->neg_bitid);
|
---|
1133 | DIRTY(sb->transform.matrixMode, g->neg_bitid);
|
---|
1134 | DIRTY(sb->transform.clipPlane, g->neg_bitid);
|
---|
1135 | DIRTY(sb->transform.enable, g->neg_bitid);
|
---|
1136 | }
|
---|
1137 | if (mask & GL_VIEWPORT_BIT)
|
---|
1138 | {
|
---|
1139 | if (a->viewportStackDepth == 0)
|
---|
1140 | {
|
---|
1141 | crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW, "glPopAttrib called with an empty viewport stack!" );
|
---|
1142 | return;
|
---|
1143 | }
|
---|
1144 | a->viewportStackDepth--;
|
---|
1145 | g->viewport.viewportX = a->viewportStack[a->viewportStackDepth].viewportX;
|
---|
1146 | g->viewport.viewportY = a->viewportStack[a->viewportStackDepth].viewportY;
|
---|
1147 | g->viewport.viewportW = a->viewportStack[a->viewportStackDepth].viewportW;
|
---|
1148 | g->viewport.viewportH = a->viewportStack[a->viewportStackDepth].viewportH;
|
---|
1149 | g->viewport.nearClip = a->viewportStack[a->viewportStackDepth].nearClip;
|
---|
1150 | g->viewport.farClip = a->viewportStack[a->viewportStackDepth].farClip;
|
---|
1151 | DIRTY(sb->viewport.dirty, g->neg_bitid);
|
---|
1152 | DIRTY(sb->viewport.v_dims, g->neg_bitid);
|
---|
1153 | DIRTY(sb->viewport.depth, g->neg_bitid);
|
---|
1154 | }
|
---|
1155 | DIRTY(ab->dirty, g->neg_bitid);
|
---|
1156 | }
|
---|
1157 |
|
---|
1158 | void crStateAttribSwitch( CRAttribBits *bb, CRbitvalue *bitID,
|
---|
1159 | CRContext *fromCtx, CRContext *toCtx )
|
---|
1160 | {
|
---|
1161 | CRAttribState *to = &(toCtx->attrib);
|
---|
1162 | CRAttribState *from = &(fromCtx->attrib);
|
---|
1163 | if (to->attribStackDepth != 0 || from->attribStackDepth != 0)
|
---|
1164 | {
|
---|
1165 | crWarning( "Trying to switch contexts when the attribute stacks "
|
---|
1166 | "weren't empty. Currently, this is not supported." );
|
---|
1167 | }
|
---|
1168 | (void) bb;
|
---|
1169 | (void) bitID;
|
---|
1170 | }
|
---|