VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texdiff.c@ 44289

最後變更 在這個檔案從44289是 44289,由 vboxsync 提交於 12 年 前

crOpenGL: saved state restoration fix

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 61.0 KB
 
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 "state.h"
8#include "state/cr_statetypes.h"
9#include "state/cr_texture.h"
10#include "cr_hash.h"
11#include "cr_string.h"
12#include "cr_mem.h"
13#include "cr_version.h"
14#include "state_internals.h"
15
16
17#define UNIMPLEMENTED() crStateError(__LINE__,__FILE__,GL_INVALID_OPERATION, "Unimplemented something or other" )
18
19
20#if 0 /* NOT USED??? */
21void crStateTextureObjSwitchCallback( unsigned long key, void *data1, void *data2 )
22{
23 CRTextureObj *tobj = (CRTextureObj *) data1;
24 CRContext *fromCtx = (CRContext *) data2;
25 unsigned int i = 0;
26 unsigned int j = 0;
27 CRbitvalue *bitID = fromCtx->bitid;
28 CRbitvalue nbitID[CR_MAX_BITARRAY];
29
30 for (j=0;j<CR_MAX_BITARRAY;j++)
31 nbitID[j] = ~bitID[j];
32
33 if (!tobj) return;
34
35 FILLDIRTY(tobj->dirty);
36 FILLDIRTY(tobj->imageBit);
37
38 for (i = 0; i < fromCtx->limits.maxTextureUnits; i++)
39 {
40 int j;
41
42 FILLDIRTY(tobj->paramsBit[i]);
43
44 switch (tobj->target)
45 {
46 case GL_TEXTURE_1D:
47 case GL_TEXTURE_2D:
48 for (j = 0; j <= fromCtx->texture.maxLevel; j++)
49 {
50 CRTextureLevel *tl = &(tobj->level[j]);
51 FILLDIRTY(tl->dirty);
52 }
53 break;
54#ifdef CR_OPENGL_VERSION_1_2
55 case GL_TEXTURE_3D:
56#endif
57 for (j = 0; j <= fromCtx->texture.max3DLevel; j++)
58 {
59 CRTextureLevel *tl = &(tobj->level[j]);
60 FILLDIRTY(tl->dirty);
61 }
62 break;
63#ifdef CR_ARB_texture_cube_map
64 case GL_TEXTURE_CUBE_MAP_ARB:
65 for (j = 0; j <= fromCtx->texture.maxCubeMapLevel; j++)
66 {
67 CRTextureLevel *tl;
68 /* Positive X */
69 tl = &(tobj->level[j]);
70 FILLDIRTY(tl->dirty);
71 /* Negative X */
72 tl = &(tobj->negativeXlevel[j]);
73 FILLDIRTY(tl->dirty);
74 /* Positive Y */
75 tl = &(tobj->positiveYlevel[j]);
76 FILLDIRTY(tl->dirty);
77 /* Negative Y */
78 tl = &(tobj->negativeYlevel[j]);
79 FILLDIRTY(tl->dirty);
80 /* Positive Z */
81 tl = &(tobj->positiveZlevel[j]);
82 FILLDIRTY(tl->dirty);
83 /* Negative Z */
84 tl = &(tobj->negativeZlevel[j]);
85 FILLDIRTY(tl->dirty);
86 }
87 break;
88#endif
89 default:
90 UNIMPLEMENTED();
91 }
92 }
93}
94#endif
95
96
97void crStateTextureSwitch( CRTextureBits *tb, CRbitvalue *bitID,
98 CRContext *fromCtx, CRContext *toCtx )
99{
100 CRTextureState *from = &(fromCtx->texture);
101 const CRTextureState *to = &(toCtx->texture);
102 unsigned int i,j;
103 glAble able[2];
104 CRbitvalue nbitID[CR_MAX_BITARRAY];
105 unsigned int activeUnit = (unsigned int) -1;
106
107 for (j=0;j<CR_MAX_BITARRAY;j++)
108 nbitID[j] = ~bitID[j];
109 able[0] = diff_api.Disable;
110 able[1] = diff_api.Enable;
111
112 for (i = 0; i < fromCtx->limits.maxTextureUnits; i++)
113 {
114 if (CHECKDIRTY(tb->enable[i], bitID))
115 {
116 if (activeUnit != i) {
117 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
118 activeUnit = i;
119 }
120 if (from->unit[i].enabled1D != to->unit[i].enabled1D)
121 {
122 able[to->unit[i].enabled1D](GL_TEXTURE_1D);
123 FILLDIRTY(tb->enable[i]);
124 FILLDIRTY(tb->dirty);
125 }
126 if (from->unit[i].enabled2D != to->unit[i].enabled2D)
127 {
128 able[to->unit[i].enabled2D](GL_TEXTURE_2D);
129 FILLDIRTY(tb->enable[i]);
130 FILLDIRTY(tb->dirty);
131 }
132#ifdef CR_OPENGL_VERSION_1_2
133 if (from->unit[i].enabled3D != to->unit[i].enabled3D)
134 {
135 able[to->unit[i].enabled3D](GL_TEXTURE_3D);
136 FILLDIRTY(tb->enable[i]);
137 FILLDIRTY(tb->dirty);
138 }
139#endif
140#ifdef CR_ARB_texture_cube_map
141 if (fromCtx->extensions.ARB_texture_cube_map &&
142 from->unit[i].enabledCubeMap != to->unit[i].enabledCubeMap)
143 {
144 able[to->unit[i].enabledCubeMap](GL_TEXTURE_CUBE_MAP_ARB);
145 FILLDIRTY(tb->enable[i]);
146 FILLDIRTY(tb->dirty);
147 }
148#endif
149#ifdef CR_NV_texture_rectangle
150 if (fromCtx->extensions.NV_texture_rectangle &&
151 from->unit[i].enabledRect != to->unit[i].enabledRect)
152 {
153 able[to->unit[i].enabledRect](GL_TEXTURE_RECTANGLE_NV);
154 FILLDIRTY(tb->enable[i]);
155 FILLDIRTY(tb->dirty);
156 }
157#endif
158 if (from->unit[i].textureGen.s != to->unit[i].textureGen.s ||
159 from->unit[i].textureGen.t != to->unit[i].textureGen.t ||
160 from->unit[i].textureGen.r != to->unit[i].textureGen.r ||
161 from->unit[i].textureGen.q != to->unit[i].textureGen.q)
162 {
163 able[to->unit[i].textureGen.s](GL_TEXTURE_GEN_S);
164 able[to->unit[i].textureGen.t](GL_TEXTURE_GEN_T);
165 able[to->unit[i].textureGen.r](GL_TEXTURE_GEN_R);
166 able[to->unit[i].textureGen.q](GL_TEXTURE_GEN_Q);
167 FILLDIRTY(tb->enable[i]);
168 FILLDIRTY(tb->dirty);
169 }
170 CLEARDIRTY(tb->enable[i], nbitID);
171 }
172
173 /*
174 ** A thought on switching with textures:
175 ** Since we are only performing a switch
176 ** and not a sync, we won't need to
177 ** update individual textures, just
178 ** the bindings....
179 */
180
181 if (CHECKDIRTY(tb->current[i], bitID))
182 {
183 if (activeUnit != i) {
184 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
185 activeUnit = i;
186 }
187 if (from->unit[i].currentTexture1D->hwid != to->unit[i].currentTexture1D->hwid)
188 {
189 diff_api.BindTexture(GL_TEXTURE_1D, crStateGetTextureObjHWID(to->unit[i].currentTexture1D));
190 FILLDIRTY(tb->current[i]);
191 FILLDIRTY(tb->dirty);
192 }
193 if (from->unit[i].currentTexture2D->hwid != to->unit[i].currentTexture2D->hwid)
194 {
195 diff_api.BindTexture(GL_TEXTURE_2D, crStateGetTextureObjHWID(to->unit[i].currentTexture2D));
196 FILLDIRTY(tb->current[i]);
197 FILLDIRTY(tb->dirty);
198 }
199#ifdef CR_OPENGL_VERSION_1_2
200 if (from->unit[i].currentTexture3D->hwid != to->unit[i].currentTexture3D->hwid)
201 {
202 diff_api.BindTexture(GL_TEXTURE_3D, crStateGetTextureObjHWID(to->unit[i].currentTexture3D));
203 FILLDIRTY(tb->current[i]);
204 FILLDIRTY(tb->dirty);
205 }
206#endif
207#ifdef CR_ARB_texture_cube_map
208 if (fromCtx->extensions.ARB_texture_cube_map &&
209 from->unit[i].currentTextureCubeMap->hwid != to->unit[i].currentTextureCubeMap->hwid)
210 {
211 diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, crStateGetTextureObjHWID(to->unit[i].currentTextureCubeMap));
212 FILLDIRTY(tb->current[i]);
213 FILLDIRTY(tb->dirty);
214 }
215#endif
216#ifdef CR_NV_texture_rectangle
217 if (fromCtx->extensions.NV_texture_rectangle &&
218 from->unit[i].currentTextureRect->hwid != to->unit[i].currentTextureRect->hwid)
219 {
220 diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, crStateGetTextureObjHWID(to->unit[i].currentTextureRect));
221 FILLDIRTY(tb->current[i]);
222 FILLDIRTY(tb->dirty);
223 }
224#endif
225 CLEARDIRTY(tb->current[i], nbitID);
226 }
227
228 if (CHECKDIRTY(tb->objGen[i], bitID))
229 {
230 if (activeUnit != i) {
231 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
232 activeUnit = i;
233 }
234 if (from->unit[i].objSCoeff.x != to->unit[i].objSCoeff.x ||
235 from->unit[i].objSCoeff.y != to->unit[i].objSCoeff.y ||
236 from->unit[i].objSCoeff.z != to->unit[i].objSCoeff.z ||
237 from->unit[i].objSCoeff.w != to->unit[i].objSCoeff.w)
238 {
239 GLfloat f[4];
240 f[0] = to->unit[i].objSCoeff.x;
241 f[1] = to->unit[i].objSCoeff.y;
242 f[2] = to->unit[i].objSCoeff.z;
243 f[3] = to->unit[i].objSCoeff.w;
244 diff_api.TexGenfv (GL_S, GL_OBJECT_PLANE, (const GLfloat *) f);
245 FILLDIRTY(tb->objGen[i]);
246 FILLDIRTY(tb->dirty);
247 }
248 if (from->unit[i].objTCoeff.x != to->unit[i].objTCoeff.x ||
249 from->unit[i].objTCoeff.y != to->unit[i].objTCoeff.y ||
250 from->unit[i].objTCoeff.z != to->unit[i].objTCoeff.z ||
251 from->unit[i].objTCoeff.w != to->unit[i].objTCoeff.w) {
252 GLfloat f[4];
253 f[0] = to->unit[i].objTCoeff.x;
254 f[1] = to->unit[i].objTCoeff.y;
255 f[2] = to->unit[i].objTCoeff.z;
256 f[3] = to->unit[i].objTCoeff.w;
257 diff_api.TexGenfv (GL_T, GL_OBJECT_PLANE, (const GLfloat *) f);
258 FILLDIRTY(tb->objGen[i]);
259 FILLDIRTY(tb->dirty);
260 }
261 if (from->unit[i].objRCoeff.x != to->unit[i].objRCoeff.x ||
262 from->unit[i].objRCoeff.y != to->unit[i].objRCoeff.y ||
263 from->unit[i].objRCoeff.z != to->unit[i].objRCoeff.z ||
264 from->unit[i].objRCoeff.w != to->unit[i].objRCoeff.w) {
265 GLfloat f[4];
266 f[0] = to->unit[i].objRCoeff.x;
267 f[1] = to->unit[i].objRCoeff.y;
268 f[2] = to->unit[i].objRCoeff.z;
269 f[3] = to->unit[i].objRCoeff.w;
270 diff_api.TexGenfv (GL_R, GL_OBJECT_PLANE, (const GLfloat *) f);
271 FILLDIRTY(tb->objGen[i]);
272 FILLDIRTY(tb->dirty);
273 }
274 if (from->unit[i].objQCoeff.x != to->unit[i].objQCoeff.x ||
275 from->unit[i].objQCoeff.y != to->unit[i].objQCoeff.y ||
276 from->unit[i].objQCoeff.z != to->unit[i].objQCoeff.z ||
277 from->unit[i].objQCoeff.w != to->unit[i].objQCoeff.w) {
278 GLfloat f[4];
279 f[0] = to->unit[i].objQCoeff.x;
280 f[1] = to->unit[i].objQCoeff.y;
281 f[2] = to->unit[i].objQCoeff.z;
282 f[3] = to->unit[i].objQCoeff.w;
283 diff_api.TexGenfv (GL_Q, GL_OBJECT_PLANE, (const GLfloat *) f);
284 FILLDIRTY(tb->objGen[i]);
285 FILLDIRTY(tb->dirty);
286 }
287 CLEARDIRTY(tb->objGen[i], nbitID);
288 }
289 if (CHECKDIRTY(tb->eyeGen[i], bitID))
290 {
291 if (activeUnit != i) {
292 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
293 activeUnit = i;
294 }
295 diff_api.MatrixMode(GL_MODELVIEW);
296 diff_api.PushMatrix();
297 diff_api.LoadIdentity();
298 if (from->unit[i].eyeSCoeff.x != to->unit[i].eyeSCoeff.x ||
299 from->unit[i].eyeSCoeff.y != to->unit[i].eyeSCoeff.y ||
300 from->unit[i].eyeSCoeff.z != to->unit[i].eyeSCoeff.z ||
301 from->unit[i].eyeSCoeff.w != to->unit[i].eyeSCoeff.w) {
302 GLfloat f[4];
303 f[0] = to->unit[i].eyeSCoeff.x;
304 f[1] = to->unit[i].eyeSCoeff.y;
305 f[2] = to->unit[i].eyeSCoeff.z;
306 f[3] = to->unit[i].eyeSCoeff.w;
307 diff_api.TexGenfv (GL_S, GL_EYE_PLANE, (const GLfloat *) f);
308 FILLDIRTY(tb->eyeGen[i]);
309 FILLDIRTY(tb->dirty);
310 }
311 if (from->unit[i].eyeTCoeff.x != to->unit[i].eyeTCoeff.x ||
312 from->unit[i].eyeTCoeff.y != to->unit[i].eyeTCoeff.y ||
313 from->unit[i].eyeTCoeff.z != to->unit[i].eyeTCoeff.z ||
314 from->unit[i].eyeTCoeff.w != to->unit[i].eyeTCoeff.w) {
315 GLfloat f[4];
316 f[0] = to->unit[i].eyeTCoeff.x;
317 f[1] = to->unit[i].eyeTCoeff.y;
318 f[2] = to->unit[i].eyeTCoeff.z;
319 f[3] = to->unit[i].eyeTCoeff.w;
320 diff_api.TexGenfv (GL_T, GL_EYE_PLANE, (const GLfloat *) f);
321 FILLDIRTY(tb->eyeGen[i]);
322 FILLDIRTY(tb->dirty);
323 }
324 if (from->unit[i].eyeRCoeff.x != to->unit[i].eyeRCoeff.x ||
325 from->unit[i].eyeRCoeff.y != to->unit[i].eyeRCoeff.y ||
326 from->unit[i].eyeRCoeff.z != to->unit[i].eyeRCoeff.z ||
327 from->unit[i].eyeRCoeff.w != to->unit[i].eyeRCoeff.w) {
328 GLfloat f[4];
329 f[0] = to->unit[i].eyeRCoeff.x;
330 f[1] = to->unit[i].eyeRCoeff.y;
331 f[2] = to->unit[i].eyeRCoeff.z;
332 f[3] = to->unit[i].eyeRCoeff.w;
333 diff_api.TexGenfv (GL_R, GL_EYE_PLANE, (const GLfloat *) f);
334 FILLDIRTY(tb->eyeGen[i]);
335 FILLDIRTY(tb->dirty);
336 }
337 if (from->unit[i].eyeQCoeff.x != to->unit[i].eyeQCoeff.x ||
338 from->unit[i].eyeQCoeff.y != to->unit[i].eyeQCoeff.y ||
339 from->unit[i].eyeQCoeff.z != to->unit[i].eyeQCoeff.z ||
340 from->unit[i].eyeQCoeff.w != to->unit[i].eyeQCoeff.w) {
341 GLfloat f[4];
342 f[0] = to->unit[i].eyeQCoeff.x;
343 f[1] = to->unit[i].eyeQCoeff.y;
344 f[2] = to->unit[i].eyeQCoeff.z;
345 f[3] = to->unit[i].eyeQCoeff.w;
346 diff_api.TexGenfv (GL_Q, GL_EYE_PLANE, (const GLfloat *) f);
347 FILLDIRTY(tb->eyeGen[i]);
348 FILLDIRTY(tb->dirty);
349 }
350 diff_api.PopMatrix();
351 CLEARDIRTY(tb->eyeGen[i], nbitID);
352 }
353 if (CHECKDIRTY(tb->genMode[i], bitID))
354 {
355 if (activeUnit != i) {
356 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
357 activeUnit = i;
358 }
359 if (from->unit[i].gen.s != to->unit[i].gen.s ||
360 from->unit[i].gen.t != to->unit[i].gen.t ||
361 from->unit[i].gen.r != to->unit[i].gen.r ||
362 from->unit[i].gen.q != to->unit[i].gen.q)
363 {
364 diff_api.TexGeni (GL_S, GL_TEXTURE_GEN_MODE, to->unit[i].gen.s);
365 diff_api.TexGeni (GL_T, GL_TEXTURE_GEN_MODE, to->unit[i].gen.t);
366 diff_api.TexGeni (GL_R, GL_TEXTURE_GEN_MODE, to->unit[i].gen.r);
367 diff_api.TexGeni (GL_Q, GL_TEXTURE_GEN_MODE, to->unit[i].gen.q);
368 FILLDIRTY(tb->genMode[i]);
369 FILLDIRTY(tb->dirty);
370 }
371 CLEARDIRTY(tb->genMode[i], nbitID);
372 }
373 CLEARDIRTY(tb->dirty, nbitID);
374
375 /* Texture enviroment */
376 if (CHECKDIRTY(tb->envBit[i], bitID))
377 {
378 if (activeUnit != i) {
379 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
380 activeUnit = i;
381 }
382 if (from->unit[i].envMode != to->unit[i].envMode)
383 {
384 diff_api.TexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, to->unit[i].envMode);
385 FILLDIRTY(tb->envBit[i]);
386 FILLDIRTY(tb->dirty);
387 }
388 if (from->unit[i].envColor.r != to->unit[i].envColor.r ||
389 from->unit[i].envColor.g != to->unit[i].envColor.g ||
390 from->unit[i].envColor.b != to->unit[i].envColor.b ||
391 from->unit[i].envColor.a != to->unit[i].envColor.a)
392 {
393 GLfloat f[4];
394 f[0] = to->unit[i].envColor.r;
395 f[1] = to->unit[i].envColor.g;
396 f[2] = to->unit[i].envColor.b;
397 f[3] = to->unit[i].envColor.a;
398 diff_api.TexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const GLfloat *) f);
399 FILLDIRTY(tb->envBit[i]);
400 FILLDIRTY(tb->dirty);
401 }
402 if (from->unit[i].combineModeRGB != to->unit[i].combineModeRGB)
403 {
404 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, to->unit[i].combineModeRGB);
405 FILLDIRTY(tb->envBit[i]);
406 FILLDIRTY(tb->dirty);
407 }
408 if (from->unit[i].combineModeA != to->unit[i].combineModeA)
409 {
410 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, to->unit[i].combineModeA);
411 FILLDIRTY(tb->envBit[i]);
412 FILLDIRTY(tb->dirty);
413 }
414 if (from->unit[i].combineSourceRGB[0] != to->unit[i].combineSourceRGB[0])
415 {
416 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, to->unit[i].combineSourceRGB[0]);
417 FILLDIRTY(tb->envBit[i]);
418 FILLDIRTY(tb->dirty);
419 }
420 if (from->unit[i].combineSourceRGB[1] != to->unit[i].combineSourceRGB[1])
421 {
422 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, to->unit[i].combineSourceRGB[1]);
423 FILLDIRTY(tb->envBit[i]);
424 FILLDIRTY(tb->dirty);
425 }
426 if (from->unit[i].combineSourceRGB[2] != to->unit[i].combineSourceRGB[2])
427 {
428 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, to->unit[i].combineSourceRGB[2]);
429 FILLDIRTY(tb->envBit[i]);
430 FILLDIRTY(tb->dirty);
431 }
432 if (from->unit[i].combineSourceA[0] != to->unit[i].combineSourceA[0])
433 {
434 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, to->unit[i].combineSourceA[0]);
435 FILLDIRTY(tb->envBit[i]);
436 FILLDIRTY(tb->dirty);
437 }
438 if (from->unit[i].combineSourceA[1] != to->unit[i].combineSourceA[1])
439 {
440 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, to->unit[i].combineSourceA[1]);
441 FILLDIRTY(tb->envBit[i]);
442 FILLDIRTY(tb->dirty);
443 }
444 if (from->unit[i].combineSourceA[2] != to->unit[i].combineSourceA[2])
445 {
446 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, to->unit[i].combineSourceA[2]);
447 FILLDIRTY(tb->envBit[i]);
448 FILLDIRTY(tb->dirty);
449 }
450 if (from->unit[i].combineOperandRGB[0] != to->unit[i].combineOperandRGB[0])
451 {
452 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, to->unit[i].combineOperandRGB[0]);
453 FILLDIRTY(tb->envBit[i]);
454 FILLDIRTY(tb->dirty);
455 }
456 if (from->unit[i].combineOperandRGB[1] != to->unit[i].combineOperandRGB[1])
457 {
458 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, to->unit[i].combineOperandRGB[1]);
459 FILLDIRTY(tb->envBit[i]);
460 FILLDIRTY(tb->dirty);
461 }
462 if (from->unit[i].combineOperandRGB[2] != to->unit[i].combineOperandRGB[2])
463 {
464 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, to->unit[i].combineOperandRGB[2]);
465 FILLDIRTY(tb->envBit[i]);
466 FILLDIRTY(tb->dirty);
467 }
468 if (from->unit[i].combineOperandA[0] != to->unit[i].combineOperandA[0])
469 {
470 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, to->unit[i].combineOperandA[0]);
471 FILLDIRTY(tb->envBit[i]);
472 FILLDIRTY(tb->dirty);
473 }
474 if (from->unit[i].combineOperandA[1] != to->unit[i].combineOperandA[1])
475 {
476 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, to->unit[i].combineOperandA[1]);
477 FILLDIRTY(tb->envBit[i]);
478 FILLDIRTY(tb->dirty);
479 }
480 if (from->unit[i].combineOperandA[2] != to->unit[i].combineOperandA[2])
481 {
482 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, to->unit[i].combineOperandA[2]);
483 FILLDIRTY(tb->envBit[i]);
484 FILLDIRTY(tb->dirty);
485 }
486 if (from->unit[i].combineScaleRGB != to->unit[i].combineScaleRGB)
487 {
488 diff_api.TexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, to->unit[i].combineScaleRGB);
489 FILLDIRTY(tb->envBit[i]);
490 FILLDIRTY(tb->dirty);
491 }
492 if (from->unit[i].combineScaleA != to->unit[i].combineScaleA)
493 {
494 diff_api.TexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, to->unit[i].combineScaleA);
495 FILLDIRTY(tb->envBit[i]);
496 FILLDIRTY(tb->dirty);
497 }
498 CLEARDIRTY(tb->envBit[i], nbitID);
499 }
500 }
501
502 /* Resend texture images */
503 if (toCtx->shared->bTexResyncNeeded)
504 {
505 toCtx->shared->bTexResyncNeeded = GL_FALSE;
506
507 crStateDiffAllTextureObjects(toCtx, bitID, GL_TRUE);
508 }
509
510 /* After possible fiddling put them back now */
511 if (activeUnit != toCtx->texture.curTextureUnit) {
512 diff_api.ActiveTextureARB( toCtx->texture.curTextureUnit + GL_TEXTURE0_ARB );
513 }
514 diff_api.MatrixMode(toCtx->transform.matrixMode);
515}
516
517
518/*
519 * Check the dirty bits for the specified texture on a given unit to
520 * determine if any of its images are dirty.
521 * Return: 1 -- dirty, 0 -- clean
522 */
523int crStateTextureCheckDirtyImages(CRContext *from, CRContext *to, GLenum target, int textureUnit)
524{
525 CRContext *g = GetCurrentContext();
526 CRTextureState *tsto;
527 CRbitvalue *bitID;
528 CRTextureObj *tobj = NULL;
529 int maxLevel = 0, i;
530 int face, numFaces;
531
532 CRASSERT(to);
533 CRASSERT(from);
534
535 tsto = &(to->texture);
536 bitID = from->bitid;
537
538 CRASSERT(tsto);
539
540 switch(target)
541 {
542 case GL_TEXTURE_1D:
543 tobj = tsto->unit[textureUnit].currentTexture1D;
544 maxLevel = tsto->maxLevel;
545 break;
546 case GL_TEXTURE_2D:
547 tobj = tsto->unit[textureUnit].currentTexture2D;
548 maxLevel = tsto->maxLevel;
549 break;
550#ifdef CR_OPENGL_VERSION_1_2
551 case GL_TEXTURE_3D:
552 tobj = tsto->unit[textureUnit].currentTexture3D;
553 maxLevel = tsto->max3DLevel;
554 break;
555#endif
556#ifdef CR_ARB_texture_cube_map
557 case GL_TEXTURE_CUBE_MAP:
558 if (g->extensions.ARB_texture_cube_map) {
559 tobj = tsto->unit[textureUnit].currentTextureCubeMap;
560 maxLevel = tsto->maxCubeMapLevel;
561 }
562 break;
563#endif
564#ifdef CR_NV_texture_rectangle
565 case GL_TEXTURE_RECTANGLE_NV:
566 if (g->extensions.NV_texture_rectangle) {
567 tobj = tsto->unit[textureUnit].currentTextureRect;
568 maxLevel = 1;
569 }
570 break;
571#endif
572 default:
573 crError("Bad texture target in crStateTextureCheckDirtyImages()");
574 return 0;
575 }
576
577 if (!tobj)
578 {
579 return 0;
580 }
581
582 numFaces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
583
584 for (face = 0; face < numFaces; face++) {
585 for (i = 0; i < maxLevel; i++) {
586 if (CHECKDIRTY(tobj->level[face][i].dirty, bitID))
587 return 1;
588 }
589 }
590
591 return 0;
592}
593
594
595/*
596 * Do texture state differencing for the given texture object.
597 */
598void
599crStateTextureObjectDiff(CRContext *fromCtx,
600 const CRbitvalue *bitID, const CRbitvalue *nbitID,
601 CRTextureObj *tobj, GLboolean alwaysDirty)
602{
603 CRTextureState *from = &(fromCtx->texture);
604 glAble able[2];
605 int u = 0; /* always use texture unit 0 for diff'ing */
606
607 able[0] = diff_api.Disable;
608 able[1] = diff_api.Enable;
609
610#if 0
611 /* XXX disabling this code fixed Wes Bethel's problem with missing/white
612 * textures. Setting the active texture unit here can screw up the
613 * current texture object bindings.
614 */
615 /* Set active texture unit, and bind this texture object */
616 if (from->curTextureUnit != u) {
617 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
618 from->curTextureUnit = u;
619 }
620#endif
621
622 diff_api.BindTexture(tobj->target, crStateGetTextureObjHWID(tobj));
623
624 if (alwaysDirty || CHECKDIRTY(tobj->paramsBit[u], bitID))
625 {
626 GLfloat f[4];
627 f[0] = tobj->borderColor.r;
628 f[1] = tobj->borderColor.g;
629 f[2] = tobj->borderColor.b;
630 f[3] = tobj->borderColor.a;
631 diff_api.TexParameteri(tobj->target, GL_TEXTURE_BASE_LEVEL, tobj->baseLevel);
632 diff_api.TexParameteri(tobj->target, GL_TEXTURE_MAX_LEVEL, tobj->maxLevel);
633 diff_api.TexParameteri(tobj->target, GL_TEXTURE_MIN_FILTER, tobj->minFilter);
634 diff_api.TexParameteri(tobj->target, GL_TEXTURE_MAG_FILTER, tobj->magFilter);
635 diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_S, tobj->wrapS);
636 diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_T, tobj->wrapT);
637#ifdef CR_OPENGL_VERSION_1_2
638 diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_R, tobj->wrapR);
639 diff_api.TexParameterf(tobj->target, GL_TEXTURE_PRIORITY, tobj->priority);
640#endif
641 diff_api.TexParameterfv(tobj->target, GL_TEXTURE_BORDER_COLOR, (const GLfloat *) f);
642#ifdef CR_EXT_texture_filter_anisotropic
643 if (fromCtx->extensions.EXT_texture_filter_anisotropic) {
644 diff_api.TexParameterf(tobj->target, GL_TEXTURE_MAX_ANISOTROPY_EXT, tobj->maxAnisotropy);
645 }
646#endif
647#ifdef CR_ARB_depth_texture
648 if (fromCtx->extensions.ARB_depth_texture)
649 diff_api.TexParameteri(tobj->target, GL_DEPTH_TEXTURE_MODE_ARB, tobj->depthMode);
650#endif
651#ifdef CR_ARB_shadow
652 if (fromCtx->extensions.ARB_shadow) {
653 diff_api.TexParameteri(tobj->target, GL_TEXTURE_COMPARE_MODE_ARB, tobj->compareMode);
654 diff_api.TexParameteri(tobj->target, GL_TEXTURE_COMPARE_FUNC_ARB, tobj->compareFunc);
655 }
656#endif
657#ifdef CR_ARB_shadow_ambient
658 if (fromCtx->extensions.ARB_shadow_ambient) {
659 diff_api.TexParameterf(tobj->target, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, tobj->compareFailValue);
660 }
661#endif
662#ifdef CR_SGIS_generate_mipmap
663 if (fromCtx->extensions.SGIS_generate_mipmap) {
664 diff_api.TexParameteri(tobj->target, GL_GENERATE_MIPMAP_SGIS, tobj->generateMipmap);
665 }
666#endif
667 if (!alwaysDirty)
668 CLEARDIRTY(tobj->paramsBit[u], nbitID);
669 }
670
671 /* now, if the texture images are dirty */
672 if (alwaysDirty || CHECKDIRTY(tobj->imageBit, bitID))
673 {
674 int lvl;
675 int face;
676
677 switch (tobj->target)
678 {
679 case GL_TEXTURE_1D:
680 for (lvl = 0; lvl <= from->maxLevel; lvl++)
681 {
682 CRTextureLevel *tl = &(tobj->level[0][lvl]);
683 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
684 {
685 if (tl->generateMipmap) {
686 diff_api.TexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
687 }
688 if (tl->width)
689 {
690 if (tl->compressed) {
691 diff_api.CompressedTexImage1DARB(GL_TEXTURE_1D, lvl,
692 tl->internalFormat, tl->width,
693 tl->border, tl->bytes, tl->img);
694 }
695 else {
696 /* alignment must be one */
697 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
698 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
699 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
700 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
701 if (tl->generateMipmap) {
702 diff_api.TexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, 1);
703 }
704 diff_api.TexImage1D(GL_TEXTURE_1D, lvl,
705 tl->internalFormat,
706 tl->width, tl->border,
707 tl->format, tl->type, tl->img);
708 }
709 }
710 if (!alwaysDirty)
711 {
712 CLEARDIRTY(tl->dirty, nbitID);
713 }
714#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
715 else
716 {
717 crFree(tl->img);
718 tl->img = NULL;
719 }
720#endif
721 }
722 }
723 break;
724 case GL_TEXTURE_2D:
725 for (lvl = 0; lvl <= from->maxLevel; lvl++)
726 {
727 CRTextureLevel *tl = &(tobj->level[0][lvl]);
728 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
729 {
730 if (tl->generateMipmap) {
731 diff_api.TexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
732 }
733
734 if (tl->width && tl->height)
735 {
736 if (tl->compressed) {
737 diff_api.CompressedTexImage2DARB(GL_TEXTURE_2D, lvl,
738 tl->internalFormat, tl->width,
739 tl->height, tl->border,
740 tl->bytes, tl->img);
741 }
742 else {
743 /* alignment must be one */
744 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
745 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
746 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
747 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
748 diff_api.TexImage2D(GL_TEXTURE_2D, lvl,
749 tl->internalFormat,
750 tl->width, tl->height, tl->border,
751 tl->format, tl->type, tl->img);
752 }
753 }
754
755 if (!alwaysDirty)
756 {
757 CLEARDIRTY(tl->dirty, nbitID);
758 }
759#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
760 else
761 {
762 crFree(tl->img);
763 tl->img = NULL;
764 }
765#endif
766 }
767 }
768 break;
769#ifdef CR_OPENGL_VERSION_1_2
770 case GL_TEXTURE_3D:
771 for (lvl = 0; lvl <= from->max3DLevel; lvl++)
772 {
773 CRTextureLevel *tl = &(tobj->level[0][lvl]);
774 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
775 {
776 if (tl->generateMipmap) {
777 diff_api.TexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP_SGIS, 1);
778 }
779
780 if (tl->width && tl->height)
781 {
782 if (tl->compressed) {
783 diff_api.CompressedTexImage3DARB(GL_TEXTURE_3D, lvl,
784 tl->internalFormat, tl->width,
785 tl->height, tl->depth,
786 tl->border, tl->bytes, tl->img);
787 }
788 else {
789 /* alignment must be one */
790 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
791 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
792 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
793 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
794 diff_api.TexImage3D(GL_TEXTURE_3D, lvl,
795 tl->internalFormat,
796 tl->width, tl->height, tl->depth,
797 tl->border, tl->format,
798 tl->type, tl->img);
799 }
800 }
801
802 if (!alwaysDirty)
803 {
804 CLEARDIRTY(tl->dirty, nbitID);
805 }
806#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
807 else
808 {
809 crFree(tl->img);
810 tl->img = NULL;
811 }
812#endif
813 }
814 }
815 break;
816#endif
817#ifdef CR_NV_texture_rectangle
818 case GL_TEXTURE_RECTANGLE_NV:
819 /* only one level */
820 for (lvl = 0; lvl <= from->maxRectLevel; lvl++)
821 {
822 CRTextureLevel *tl = &(tobj->level[0][lvl]);
823 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
824 {
825 if (tl->width && tl->height)
826 {
827 if (tl->compressed) {
828 diff_api.CompressedTexImage2DARB(GL_TEXTURE_RECTANGLE_NV, lvl,
829 tl->internalFormat, tl->width,
830 tl->height, tl->border,
831 tl->bytes, tl->img);
832 }
833 else {
834 /* alignment must be one */
835 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
836 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
837 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
838 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
839 diff_api.TexImage2D(GL_TEXTURE_RECTANGLE_NV, lvl,
840 tl->internalFormat,
841 tl->width, tl->height, tl->border,
842 tl->format, tl->type, tl->img);
843 }
844 }
845
846 if (!alwaysDirty)
847 {
848 CLEARDIRTY(tl->dirty, nbitID);
849 }
850#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
851 else
852 {
853 crFree(tl->img);
854 tl->img = NULL;
855 }
856#endif
857 }
858 }
859 break;
860#endif
861#ifdef CR_ARB_texture_cube_map
862 case GL_TEXTURE_CUBE_MAP_ARB:
863 for (face = 0; face < 6; face++)
864 {
865 const GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
866 for (lvl = 0; lvl <= from->maxCubeMapLevel; lvl++)
867 {
868 CRTextureLevel *tl = &(tobj->level[face][lvl]);
869 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
870 {
871 if (tl->generateMipmap) {
872 diff_api.TexParameteri(GL_TEXTURE_CUBE_MAP_ARB,
873 GL_GENERATE_MIPMAP_SGIS, 1);
874 }
875
876 if (tl->width && tl->height)
877 {
878 if (tl->compressed) {
879 diff_api.CompressedTexImage2DARB(target,
880 lvl, tl->internalFormat,
881 tl->width, tl->height,
882 tl->border, tl->bytes, tl->img);
883 }
884 else {
885 /* alignment must be one */
886 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
887 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
888 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
889 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
890 diff_api.TexImage2D(target, lvl,
891 tl->internalFormat,
892 tl->width, tl->height, tl->border,
893 tl->format, tl->type, tl->img);
894 }
895 }
896
897 if (!alwaysDirty)
898 {
899 CLEARDIRTY(tl->dirty, nbitID);
900 }
901#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
902 else
903 {
904 crFree(tl->img);
905 tl->img = NULL;
906 }
907#endif
908 }
909 } /* for lvl */
910 } /* for face */
911 break;
912#endif
913 default:
914 UNIMPLEMENTED();
915
916 } /* switch */
917 } /* if (CHECKDIRTY(tobj->imageBit, bitID)) */
918}
919
920
921
922void
923crStateTextureDiff( CRTextureBits *tb, CRbitvalue *bitID,
924 CRContext *fromCtx, CRContext *toCtx )
925{
926 CRTextureState *from = &(fromCtx->texture);
927 CRTextureState *to = &(toCtx->texture);
928 unsigned int u, t, j;
929 glAble able[2];
930 CRbitvalue nbitID[CR_MAX_BITARRAY];
931 const GLboolean haveFragProg = fromCtx->extensions.ARB_fragment_program || fromCtx->extensions.NV_fragment_program;
932
933 for (j=0;j<CR_MAX_BITARRAY;j++)
934 nbitID[j] = ~bitID[j];
935
936 able[0] = diff_api.Disable;
937 able[1] = diff_api.Enable;
938
939 /* loop over texture units */
940 for (u = 0; u < fromCtx->limits.maxTextureUnits; u++)
941 {
942 CRTextureObj **fromBinding = NULL;
943 CRTextureObj *tobj;
944
945 /* take care of enables/disables */
946 if (CHECKDIRTY(tb->enable[u], bitID))
947 {
948
949 /* Activate texture unit u if needed */
950 if (fromCtx->texture.curTextureUnit != u) {
951 diff_api.ActiveTextureARB( GL_TEXTURE0_ARB + u);
952 fromCtx->texture.curTextureUnit = u;
953 }
954
955 if (from->unit[u].enabled1D != to->unit[u].enabled1D)
956 {
957 able[to->unit[u].enabled1D](GL_TEXTURE_1D);
958 from->unit[u].enabled1D = to->unit[u].enabled1D;
959 }
960 if (from->unit[u].enabled2D != to->unit[u].enabled2D)
961 {
962 able[to->unit[u].enabled2D](GL_TEXTURE_2D);
963 from->unit[u].enabled2D = to->unit[u].enabled2D;
964 }
965#ifdef CR_OPENGL_VERSION_1_2
966 if (from->unit[u].enabled3D != to->unit[u].enabled3D)
967 {
968 able[to->unit[u].enabled3D](GL_TEXTURE_3D);
969 from->unit[u].enabled3D = to->unit[u].enabled3D;
970 }
971#endif
972#ifdef CR_ARB_texture_cube_map
973 if (fromCtx->extensions.ARB_texture_cube_map &&
974 from->unit[u].enabledCubeMap != to->unit[u].enabledCubeMap)
975 {
976 able[to->unit[u].enabledCubeMap](GL_TEXTURE_CUBE_MAP_ARB);
977 from->unit[u].enabledCubeMap = to->unit[u].enabledCubeMap;
978 }
979#endif
980#ifdef CR_NV_texture_rectangle
981 if (fromCtx->extensions.NV_texture_rectangle &&
982 from->unit[u].enabledRect != to->unit[u].enabledRect)
983 {
984 able[to->unit[u].enabledRect](GL_TEXTURE_RECTANGLE_NV);
985 from->unit[u].enabledRect = to->unit[u].enabledRect;
986 }
987#endif
988
989 /* texgen enables */
990 if (from->unit[u].textureGen.s != to->unit[u].textureGen.s ||
991 from->unit[u].textureGen.t != to->unit[u].textureGen.t ||
992 from->unit[u].textureGen.r != to->unit[u].textureGen.r ||
993 from->unit[u].textureGen.q != to->unit[u].textureGen.q)
994 {
995 able[to->unit[u].textureGen.s](GL_TEXTURE_GEN_S);
996 able[to->unit[u].textureGen.t](GL_TEXTURE_GEN_T);
997 able[to->unit[u].textureGen.r](GL_TEXTURE_GEN_R);
998 able[to->unit[u].textureGen.q](GL_TEXTURE_GEN_Q);
999 from->unit[u].textureGen = to->unit[u].textureGen;
1000 }
1001 CLEARDIRTY(tb->enable[u], nbitID);
1002 }
1003
1004
1005 /* Texgen coefficients */
1006 if (CHECKDIRTY(tb->objGen[u], bitID))
1007 {
1008 if (fromCtx->texture.curTextureUnit != u) {
1009 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
1010 fromCtx->texture.curTextureUnit = u;
1011 }
1012 if (from->unit[u].objSCoeff.x != to->unit[u].objSCoeff.x ||
1013 from->unit[u].objSCoeff.y != to->unit[u].objSCoeff.y ||
1014 from->unit[u].objSCoeff.z != to->unit[u].objSCoeff.z ||
1015 from->unit[u].objSCoeff.w != to->unit[u].objSCoeff.w)
1016 {
1017 GLfloat f[4];
1018 f[0] = to->unit[u].objSCoeff.x;
1019 f[1] = to->unit[u].objSCoeff.y;
1020 f[2] = to->unit[u].objSCoeff.z;
1021 f[3] = to->unit[u].objSCoeff.w;
1022 diff_api.TexGenfv (GL_S, GL_OBJECT_PLANE, (const GLfloat *) f);
1023 from->unit[u].objSCoeff = to->unit[u].objSCoeff;
1024 }
1025 if (from->unit[u].objTCoeff.x != to->unit[u].objTCoeff.x ||
1026 from->unit[u].objTCoeff.y != to->unit[u].objTCoeff.y ||
1027 from->unit[u].objTCoeff.z != to->unit[u].objTCoeff.z ||
1028 from->unit[u].objTCoeff.w != to->unit[u].objTCoeff.w)
1029 {
1030 GLfloat f[4];
1031 f[0] = to->unit[u].objTCoeff.x;
1032 f[1] = to->unit[u].objTCoeff.y;
1033 f[2] = to->unit[u].objTCoeff.z;
1034 f[3] = to->unit[u].objTCoeff.w;
1035 diff_api.TexGenfv (GL_T, GL_OBJECT_PLANE, (const GLfloat *) f);
1036 from->unit[u].objTCoeff = to->unit[u].objTCoeff;
1037 }
1038 if (from->unit[u].objRCoeff.x != to->unit[u].objRCoeff.x ||
1039 from->unit[u].objRCoeff.y != to->unit[u].objRCoeff.y ||
1040 from->unit[u].objRCoeff.z != to->unit[u].objRCoeff.z ||
1041 from->unit[u].objRCoeff.w != to->unit[u].objRCoeff.w)
1042 {
1043 GLfloat f[4];
1044 f[0] = to->unit[u].objRCoeff.x;
1045 f[1] = to->unit[u].objRCoeff.y;
1046 f[2] = to->unit[u].objRCoeff.z;
1047 f[3] = to->unit[u].objRCoeff.w;
1048 diff_api.TexGenfv (GL_R, GL_OBJECT_PLANE, (const GLfloat *) f);
1049 from->unit[u].objRCoeff = to->unit[u].objRCoeff;
1050 }
1051 if (from->unit[u].objQCoeff.x != to->unit[u].objQCoeff.x ||
1052 from->unit[u].objQCoeff.y != to->unit[u].objQCoeff.y ||
1053 from->unit[u].objQCoeff.z != to->unit[u].objQCoeff.z ||
1054 from->unit[u].objQCoeff.w != to->unit[u].objQCoeff.w)
1055 {
1056 GLfloat f[4];
1057 f[0] = to->unit[u].objQCoeff.x;
1058 f[1] = to->unit[u].objQCoeff.y;
1059 f[2] = to->unit[u].objQCoeff.z;
1060 f[3] = to->unit[u].objQCoeff.w;
1061 diff_api.TexGenfv (GL_Q, GL_OBJECT_PLANE, (const GLfloat *) f);
1062 from->unit[u].objQCoeff = to->unit[u].objQCoeff;
1063 }
1064 CLEARDIRTY(tb->objGen[u], nbitID);
1065 }
1066 if (CHECKDIRTY(tb->eyeGen[u], bitID))
1067 {
1068 if (fromCtx->texture.curTextureUnit != u) {
1069 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
1070 fromCtx->texture.curTextureUnit = u;
1071 }
1072 if (fromCtx->transform.matrixMode != GL_MODELVIEW) {
1073 diff_api.MatrixMode(GL_MODELVIEW);
1074 fromCtx->transform.matrixMode = GL_MODELVIEW;
1075 }
1076 diff_api.PushMatrix();
1077 diff_api.LoadIdentity();
1078 if (from->unit[u].eyeSCoeff.x != to->unit[u].eyeSCoeff.x ||
1079 from->unit[u].eyeSCoeff.y != to->unit[u].eyeSCoeff.y ||
1080 from->unit[u].eyeSCoeff.z != to->unit[u].eyeSCoeff.z ||
1081 from->unit[u].eyeSCoeff.w != to->unit[u].eyeSCoeff.w)
1082 {
1083 GLfloat f[4];
1084 f[0] = to->unit[u].eyeSCoeff.x;
1085 f[1] = to->unit[u].eyeSCoeff.y;
1086 f[2] = to->unit[u].eyeSCoeff.z;
1087 f[3] = to->unit[u].eyeSCoeff.w;
1088 diff_api.TexGenfv (GL_S, GL_EYE_PLANE, (const GLfloat *) f);
1089 from->unit[u].eyeSCoeff = to->unit[u].eyeSCoeff;
1090 }
1091 if (from->unit[u].eyeTCoeff.x != to->unit[u].eyeTCoeff.x ||
1092 from->unit[u].eyeTCoeff.y != to->unit[u].eyeTCoeff.y ||
1093 from->unit[u].eyeTCoeff.z != to->unit[u].eyeTCoeff.z ||
1094 from->unit[u].eyeTCoeff.w != to->unit[u].eyeTCoeff.w)
1095 {
1096 GLfloat f[4];
1097 f[0] = to->unit[u].eyeTCoeff.x;
1098 f[1] = to->unit[u].eyeTCoeff.y;
1099 f[2] = to->unit[u].eyeTCoeff.z;
1100 f[3] = to->unit[u].eyeTCoeff.w;
1101 diff_api.TexGenfv (GL_T, GL_EYE_PLANE, (const GLfloat *) f);
1102 from->unit[u].eyeTCoeff = to->unit[u].eyeTCoeff;
1103 }
1104 if (from->unit[u].eyeRCoeff.x != to->unit[u].eyeRCoeff.x ||
1105 from->unit[u].eyeRCoeff.y != to->unit[u].eyeRCoeff.y ||
1106 from->unit[u].eyeRCoeff.z != to->unit[u].eyeRCoeff.z ||
1107 from->unit[u].eyeRCoeff.w != to->unit[u].eyeRCoeff.w)
1108 {
1109 GLfloat f[4];
1110 f[0] = to->unit[u].eyeRCoeff.x;
1111 f[1] = to->unit[u].eyeRCoeff.y;
1112 f[2] = to->unit[u].eyeRCoeff.z;
1113 f[3] = to->unit[u].eyeRCoeff.w;
1114 diff_api.TexGenfv (GL_R, GL_EYE_PLANE, (const GLfloat *) f);
1115 from->unit[u].eyeRCoeff = to->unit[u].eyeRCoeff;
1116 }
1117 if (from->unit[u].eyeQCoeff.x != to->unit[u].eyeQCoeff.x ||
1118 from->unit[u].eyeQCoeff.y != to->unit[u].eyeQCoeff.y ||
1119 from->unit[u].eyeQCoeff.z != to->unit[u].eyeQCoeff.z ||
1120 from->unit[u].eyeQCoeff.w != to->unit[u].eyeQCoeff.w)
1121 {
1122 GLfloat f[4];
1123 f[0] = to->unit[u].eyeQCoeff.x;
1124 f[1] = to->unit[u].eyeQCoeff.y;
1125 f[2] = to->unit[u].eyeQCoeff.z;
1126 f[3] = to->unit[u].eyeQCoeff.w;
1127 diff_api.TexGenfv (GL_Q, GL_EYE_PLANE, (const GLfloat *) f);
1128 from->unit[u].eyeQCoeff = to->unit[u].eyeQCoeff;
1129 }
1130 diff_api.PopMatrix();
1131 CLEARDIRTY(tb->eyeGen[u], nbitID);
1132 }
1133 if (CHECKDIRTY(tb->genMode[u], bitID))
1134 {
1135 if (fromCtx->texture.curTextureUnit != u) {
1136 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
1137 fromCtx->texture.curTextureUnit = u;
1138 }
1139 if (from->unit[u].gen.s != to->unit[u].gen.s ||
1140 from->unit[u].gen.t != to->unit[u].gen.t ||
1141 from->unit[u].gen.r != to->unit[u].gen.r ||
1142 from->unit[u].gen.q != to->unit[u].gen.q)
1143 {
1144 diff_api.TexGeni (GL_S, GL_TEXTURE_GEN_MODE, to->unit[u].gen.s);
1145 diff_api.TexGeni (GL_T, GL_TEXTURE_GEN_MODE, to->unit[u].gen.t);
1146 diff_api.TexGeni (GL_R, GL_TEXTURE_GEN_MODE, to->unit[u].gen.r);
1147 diff_api.TexGeni (GL_Q, GL_TEXTURE_GEN_MODE, to->unit[u].gen.q);
1148 from->unit[u].gen = to->unit[u].gen;
1149 }
1150 CLEARDIRTY(tb->genMode[u], nbitID);
1151 }
1152
1153 /* Texture enviroment */
1154 if (CHECKDIRTY(tb->envBit[u], bitID))
1155 {
1156 if (from->unit[u].envMode != to->unit[u].envMode)
1157 {
1158 diff_api.TexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, to->unit[u].envMode);
1159 from->unit[u].envMode = to->unit[u].envMode;
1160 }
1161 if (from->unit[u].envColor.r != to->unit[u].envColor.r ||
1162 from->unit[u].envColor.g != to->unit[u].envColor.g ||
1163 from->unit[u].envColor.b != to->unit[u].envColor.b ||
1164 from->unit[u].envColor.a != to->unit[u].envColor.a)
1165 {
1166 GLfloat f[4];
1167 f[0] = to->unit[u].envColor.r;
1168 f[1] = to->unit[u].envColor.g;
1169 f[2] = to->unit[u].envColor.b;
1170 f[3] = to->unit[u].envColor.a;
1171 diff_api.TexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const GLfloat *) f);
1172 from->unit[u].envColor = to->unit[u].envColor;
1173 }
1174#ifdef CR_ARB_texture_env_combine
1175 if (from->unit[u].combineModeRGB != to->unit[u].combineModeRGB)
1176 {
1177 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, to->unit[u].combineModeRGB);
1178 from->unit[u].combineModeRGB = to->unit[u].combineModeRGB;
1179 }
1180 if (from->unit[u].combineModeA != to->unit[u].combineModeA)
1181 {
1182 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, to->unit[u].combineModeA);
1183 from->unit[u].combineModeA = to->unit[u].combineModeA;
1184 }
1185 if (from->unit[u].combineSourceRGB[0] != to->unit[u].combineSourceRGB[0])
1186 {
1187 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, to->unit[u].combineSourceRGB[0]);
1188 from->unit[u].combineSourceRGB[0] = to->unit[u].combineSourceRGB[0];
1189 }
1190 if (from->unit[u].combineSourceRGB[1] != to->unit[u].combineSourceRGB[1])
1191 {
1192 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, to->unit[u].combineSourceRGB[1]);
1193 from->unit[u].combineSourceRGB[1] = to->unit[u].combineSourceRGB[1];
1194 }
1195 if (from->unit[u].combineSourceRGB[2] != to->unit[u].combineSourceRGB[2])
1196 {
1197 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, to->unit[u].combineSourceRGB[2]);
1198 from->unit[u].combineSourceRGB[2] = to->unit[u].combineSourceRGB[2];
1199 }
1200 if (from->unit[u].combineSourceA[0] != to->unit[u].combineSourceA[0])
1201 {
1202 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, to->unit[u].combineSourceA[0]);
1203 from->unit[u].combineSourceA[0] = to->unit[u].combineSourceA[0];
1204 }
1205 if (from->unit[u].combineSourceA[1] != to->unit[u].combineSourceA[1])
1206 {
1207 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, to->unit[u].combineSourceA[1]);
1208 from->unit[u].combineSourceA[1] = to->unit[u].combineSourceA[1];
1209 }
1210 if (from->unit[u].combineSourceA[2] != to->unit[u].combineSourceA[2])
1211 {
1212 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, to->unit[u].combineSourceA[2]);
1213 from->unit[u].combineSourceA[2] = to->unit[u].combineSourceA[2];
1214 }
1215 if (from->unit[u].combineOperandRGB[0] != to->unit[u].combineOperandRGB[0])
1216 {
1217 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, to->unit[u].combineOperandRGB[0]);
1218 from->unit[u].combineOperandRGB[0] = to->unit[u].combineOperandRGB[0];
1219 }
1220 if (from->unit[u].combineOperandRGB[1] != to->unit[u].combineOperandRGB[1])
1221 {
1222 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, to->unit[u].combineOperandRGB[1]);
1223 from->unit[u].combineOperandRGB[1] = to->unit[u].combineOperandRGB[1];
1224 }
1225 if (from->unit[u].combineOperandRGB[2] != to->unit[u].combineOperandRGB[2])
1226 {
1227 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, to->unit[u].combineOperandRGB[2]);
1228 from->unit[u].combineOperandRGB[2] = to->unit[u].combineOperandRGB[2];
1229 }
1230 if (from->unit[u].combineOperandA[0] != to->unit[u].combineOperandA[0])
1231 {
1232 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, to->unit[u].combineOperandA[0]);
1233 from->unit[u].combineOperandA[0] = to->unit[u].combineOperandA[0];
1234 }
1235 if (from->unit[u].combineOperandA[1] != to->unit[u].combineOperandA[1])
1236 {
1237 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, to->unit[u].combineOperandA[1]);
1238 from->unit[u].combineOperandA[1] = to->unit[u].combineOperandA[1];
1239 }
1240 if (from->unit[u].combineOperandA[2] != to->unit[u].combineOperandA[2])
1241 {
1242 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, to->unit[u].combineOperandA[2]);
1243 from->unit[u].combineOperandA[2] = to->unit[u].combineOperandA[2];
1244 }
1245 if (from->unit[u].combineScaleRGB != to->unit[u].combineScaleRGB)
1246 {
1247 diff_api.TexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, to->unit[u].combineScaleRGB);
1248 from->unit[u].combineScaleRGB = to->unit[u].combineScaleRGB;
1249 }
1250 if (from->unit[u].combineScaleA != to->unit[u].combineScaleA)
1251 {
1252 diff_api.TexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, to->unit[u].combineScaleA);
1253 from->unit[u].combineScaleA = to->unit[u].combineScaleA;
1254 }
1255#endif
1256#if CR_EXT_texture_lod_bias
1257 if (from->unit[u].lodBias != to->unit[u].lodBias)
1258 {
1259 diff_api.TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, to->unit[u].lodBias);
1260 from->unit[u].lodBias = to->unit[u].lodBias;
1261 }
1262#endif
1263 CLEARDIRTY(tb->envBit[u], nbitID);
1264 }
1265
1266 /* loop over texture targets */
1267 for (t = 0; t < 5; t++)
1268 {
1269 tobj = NULL;
1270
1271 switch (t) {
1272 case 0:
1273 if (to->unit[u].enabled1D || haveFragProg) {
1274 tobj = to->unit[u].currentTexture1D;
1275 fromBinding = &(from->unit[u].currentTexture1D);
1276 }
1277 break;
1278 case 1:
1279 if (to->unit[u].enabled2D || haveFragProg) {
1280 tobj = to->unit[u].currentTexture2D;
1281 fromBinding = &(from->unit[u].currentTexture2D);
1282 }
1283 break;
1284#ifdef CR_OPENGL_VERSION_1_2
1285 case 2:
1286 if (to->unit[u].enabled3D || haveFragProg) {
1287 tobj = to->unit[u].currentTexture3D;
1288 fromBinding = &(from->unit[u].currentTexture3D);
1289 }
1290 break;
1291#endif
1292#ifdef CR_ARB_texture_cube_map
1293 case 3:
1294 if (fromCtx->extensions.ARB_texture_cube_map &&
1295 (to->unit[u].enabledCubeMap || haveFragProg)) {
1296 tobj = to->unit[u].currentTextureCubeMap;
1297 fromBinding = &(from->unit[u].currentTextureCubeMap);
1298 }
1299 break;
1300#endif
1301#ifdef CR_NV_texture_rectangle
1302 case 4:
1303 if (fromCtx->extensions.NV_texture_rectangle &&
1304 (to->unit[u].enabledRect || haveFragProg)) {
1305 tobj = to->unit[u].currentTextureRect;
1306 fromBinding = &(from->unit[u].currentTextureRect);
1307 }
1308 break;
1309#endif
1310 default:
1311 /* maybe don't support cube maps or rects */
1312 continue;
1313 }
1314
1315 if (!tobj) {
1316 continue; /* with next target */
1317 }
1318
1319 /* Activate texture unit u if needed */
1320 if (fromCtx->texture.curTextureUnit != u) {
1321 diff_api.ActiveTextureARB( GL_TEXTURE0_ARB + u);
1322 fromCtx->texture.curTextureUnit = u;
1323 }
1324
1325 /* bind this texture if needed */
1326 if (CHECKDIRTY(tb->current[u], bitID))
1327 {
1328 if (*fromBinding != tobj)
1329 {
1330 diff_api.BindTexture(tobj->target, crStateGetTextureObjHWID(tobj));
1331 *fromBinding = tobj;
1332 }
1333 }
1334
1335 /* now, if the texture object is dirty */
1336 if (CHECKDIRTY(tobj->dirty, bitID))
1337 {
1338 crStateTextureObjectDiff(fromCtx, bitID, nbitID, tobj, GL_FALSE);
1339 }
1340 CLEARDIRTY(tobj->dirty, nbitID);
1341
1342 } /* loop over targets */
1343
1344 CLEARDIRTY(tb->current[u], nbitID);
1345
1346 } /* loop over units */
1347
1348 /* After possible fiddling with the active unit, put it back now */
1349 if (fromCtx->texture.curTextureUnit != toCtx->texture.curTextureUnit) {
1350 diff_api.ActiveTextureARB( toCtx->texture.curTextureUnit + GL_TEXTURE0_ARB );
1351 fromCtx->texture.curTextureUnit = toCtx->texture.curTextureUnit;
1352 }
1353 if (fromCtx->transform.matrixMode != toCtx->transform.matrixMode) {
1354 diff_api.MatrixMode(toCtx->transform.matrixMode);
1355 fromCtx->transform.matrixMode = toCtx->transform.matrixMode;
1356 }
1357
1358 CLEARDIRTY(tb->dirty, nbitID);
1359}
1360
1361
1362
1363struct callback_info
1364{
1365 CRbitvalue *bitID, *nbitID;
1366 CRContext *g;
1367 GLboolean bForceUpdate;
1368};
1369
1370
1371/* Called by crHashtableWalk() below */
1372static void
1373DiffTextureObjectCallback( unsigned long key, void *texObj , void *cbData)
1374{
1375 struct callback_info *info = (struct callback_info *) cbData;
1376 CRTextureObj *tobj = (CRTextureObj *) texObj;
1377 /*
1378 printf(" Checking %d 0x%x bitid=0x%x\n",tobj->name, tobj->dirty[0], info->bitID[0]);
1379 */
1380 if (info->bForceUpdate || CHECKDIRTY(tobj->dirty, info->bitID)) {
1381 /*
1382 printf(" Found Dirty! %d\n", tobj->name);
1383 */
1384 crStateTextureObjectDiff(info->g, info->bitID, info->nbitID, tobj, info->bForceUpdate);
1385 CLEARDIRTY(tobj->dirty, info->nbitID);
1386 }
1387}
1388
1389
1390/*
1391 * This isn't used right now, but will be used in the future to fix some
1392 * potential display list problems. Specifically, if glBindTexture is
1393 * in a display list, we have to be sure that all outstanding texture object
1394 * updates are resolved before the list is called. If we don't, we may
1395 * wind up binding texture objects that are stale.
1396 */
1397void
1398crStateDiffAllTextureObjects( CRContext *g, CRbitvalue *bitID, GLboolean bForceUpdate )
1399{
1400 CRbitvalue nbitID[CR_MAX_BITARRAY];
1401 struct callback_info info;
1402 int j;
1403 int origUnit, orig1D, orig2D, orig3D, origCube, origRect;
1404
1405 for (j = 0; j < CR_MAX_BITARRAY; j++)
1406 nbitID[j] = ~bitID[j];
1407
1408 info.bitID = bitID;
1409 info.nbitID = nbitID;
1410 info.g = g;
1411 info.bForceUpdate = bForceUpdate;
1412
1413 /* save current texture bindings */
1414 origUnit = g->texture.curTextureUnit;
1415 orig1D = crStateGetTextureObjHWID(g->texture.unit[0].currentTexture1D);
1416 orig2D = crStateGetTextureObjHWID(g->texture.unit[0].currentTexture2D);
1417 orig3D = crStateGetTextureObjHWID(g->texture.unit[0].currentTexture3D);
1418#ifdef CR_ARB_texture_cube_map
1419 origCube = crStateGetTextureObjHWID(g->texture.unit[0].currentTextureCubeMap);
1420#endif
1421#ifdef CR_NV_texture_rectangle
1422 origRect = crStateGetTextureObjHWID(g->texture.unit[0].currentTextureRect);
1423#endif
1424
1425 /* use texture unit 0 for updates */
1426 diff_api.ActiveTextureARB(GL_TEXTURE0_ARB);
1427
1428 /* diff all the textures */
1429 crHashtableWalk(g->shared->textureTable, DiffTextureObjectCallback, (void *) &info);
1430
1431 /* default ones */
1432 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base1D, GL_TRUE);
1433 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base2D, GL_TRUE);
1434 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base3D, GL_TRUE);
1435 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy1D, GL_TRUE);
1436 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy2D, GL_TRUE);
1437 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy3D, GL_TRUE);
1438#ifdef CR_ARB_texture_cube_map
1439 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.baseCubeMap, GL_TRUE);
1440 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxyCubeMap, GL_TRUE);
1441#endif
1442#ifdef CR_NV_texture_rectangle
1443 if (g->extensions.NV_texture_rectangle)
1444 {
1445 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.baseRect, GL_TRUE);
1446 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxyRect, GL_TRUE);
1447 }
1448#endif
1449
1450 /* restore bindings */
1451 /* first restore unit 0 bindings the unit 0 is active currently */
1452 diff_api.BindTexture(GL_TEXTURE_1D, orig1D);
1453 diff_api.BindTexture(GL_TEXTURE_2D, orig2D);
1454 diff_api.BindTexture(GL_TEXTURE_3D, orig3D);
1455#ifdef CR_ARB_texture_cube_map
1456 diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, origCube);
1457#endif
1458#ifdef CR_NV_texture_rectangle
1459 diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, origRect);
1460#endif
1461 /* now restore the proper active unit */
1462 diff_api.ActiveTextureARB(GL_TEXTURE0_ARB + origUnit);
1463}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette