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