VirtualBox

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

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

crOpenGL: Ubuntu 12.10 saved state working

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 61.1 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 GLuint hwid = crStateGetTextureObjHWID(tobj);
607
608 if (!hwid)
609 return;
610
611 able[0] = diff_api.Disable;
612 able[1] = diff_api.Enable;
613
614#if 0
615 /* XXX disabling this code fixed Wes Bethel's problem with missing/white
616 * textures. Setting the active texture unit here can screw up the
617 * current texture object bindings.
618 */
619 /* Set active texture unit, and bind this texture object */
620 if (from->curTextureUnit != u) {
621 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
622 from->curTextureUnit = u;
623 }
624#endif
625
626 diff_api.BindTexture(tobj->target, hwid);
627
628 if (alwaysDirty || CHECKDIRTY(tobj->paramsBit[u], bitID))
629 {
630 GLfloat f[4];
631 f[0] = tobj->borderColor.r;
632 f[1] = tobj->borderColor.g;
633 f[2] = tobj->borderColor.b;
634 f[3] = tobj->borderColor.a;
635 diff_api.TexParameteri(tobj->target, GL_TEXTURE_BASE_LEVEL, tobj->baseLevel);
636 diff_api.TexParameteri(tobj->target, GL_TEXTURE_MAX_LEVEL, tobj->maxLevel);
637 diff_api.TexParameteri(tobj->target, GL_TEXTURE_MIN_FILTER, tobj->minFilter);
638 diff_api.TexParameteri(tobj->target, GL_TEXTURE_MAG_FILTER, tobj->magFilter);
639 diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_S, tobj->wrapS);
640 diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_T, tobj->wrapT);
641#ifdef CR_OPENGL_VERSION_1_2
642 diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_R, tobj->wrapR);
643 diff_api.TexParameterf(tobj->target, GL_TEXTURE_PRIORITY, tobj->priority);
644#endif
645 diff_api.TexParameterfv(tobj->target, GL_TEXTURE_BORDER_COLOR, (const GLfloat *) f);
646#ifdef CR_EXT_texture_filter_anisotropic
647 if (fromCtx->extensions.EXT_texture_filter_anisotropic) {
648 diff_api.TexParameterf(tobj->target, GL_TEXTURE_MAX_ANISOTROPY_EXT, tobj->maxAnisotropy);
649 }
650#endif
651#ifdef CR_ARB_depth_texture
652 if (fromCtx->extensions.ARB_depth_texture)
653 diff_api.TexParameteri(tobj->target, GL_DEPTH_TEXTURE_MODE_ARB, tobj->depthMode);
654#endif
655#ifdef CR_ARB_shadow
656 if (fromCtx->extensions.ARB_shadow) {
657 diff_api.TexParameteri(tobj->target, GL_TEXTURE_COMPARE_MODE_ARB, tobj->compareMode);
658 diff_api.TexParameteri(tobj->target, GL_TEXTURE_COMPARE_FUNC_ARB, tobj->compareFunc);
659 }
660#endif
661#ifdef CR_ARB_shadow_ambient
662 if (fromCtx->extensions.ARB_shadow_ambient) {
663 diff_api.TexParameterf(tobj->target, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, tobj->compareFailValue);
664 }
665#endif
666#ifdef CR_SGIS_generate_mipmap
667 if (fromCtx->extensions.SGIS_generate_mipmap) {
668 diff_api.TexParameteri(tobj->target, GL_GENERATE_MIPMAP_SGIS, tobj->generateMipmap);
669 }
670#endif
671 if (!alwaysDirty)
672 CLEARDIRTY(tobj->paramsBit[u], nbitID);
673 }
674
675 /* now, if the texture images are dirty */
676 if (alwaysDirty || CHECKDIRTY(tobj->imageBit, bitID))
677 {
678 int lvl;
679 int face;
680
681 switch (tobj->target)
682 {
683 case GL_TEXTURE_1D:
684 for (lvl = 0; lvl <= from->maxLevel; lvl++)
685 {
686 CRTextureLevel *tl = &(tobj->level[0][lvl]);
687 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
688 {
689 if (tl->generateMipmap) {
690 diff_api.TexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
691 }
692 if (tl->width)
693 {
694 if (tl->compressed) {
695 diff_api.CompressedTexImage1DARB(GL_TEXTURE_1D, lvl,
696 tl->internalFormat, tl->width,
697 tl->border, tl->bytes, tl->img);
698 }
699 else {
700 /* alignment must be one */
701 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
702 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
703 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
704 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
705 if (tl->generateMipmap) {
706 diff_api.TexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, 1);
707 }
708 diff_api.TexImage1D(GL_TEXTURE_1D, lvl,
709 tl->internalFormat,
710 tl->width, tl->border,
711 tl->format, tl->type, tl->img);
712 }
713 }
714 if (!alwaysDirty)
715 {
716 CLEARDIRTY(tl->dirty, nbitID);
717 }
718#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
719 else
720 {
721 crFree(tl->img);
722 tl->img = NULL;
723 }
724#endif
725 }
726 }
727 break;
728 case GL_TEXTURE_2D:
729 for (lvl = 0; lvl <= from->maxLevel; lvl++)
730 {
731 CRTextureLevel *tl = &(tobj->level[0][lvl]);
732 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
733 {
734 if (tl->generateMipmap) {
735 diff_api.TexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
736 }
737
738 if (tl->width && tl->height)
739 {
740 if (tl->compressed) {
741 diff_api.CompressedTexImage2DARB(GL_TEXTURE_2D, lvl,
742 tl->internalFormat, tl->width,
743 tl->height, tl->border,
744 tl->bytes, tl->img);
745 }
746 else {
747 /* alignment must be one */
748 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
749 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
750 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
751 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
752 diff_api.TexImage2D(GL_TEXTURE_2D, lvl,
753 tl->internalFormat,
754 tl->width, tl->height, tl->border,
755 tl->format, tl->type, tl->img);
756 }
757 }
758
759 if (!alwaysDirty)
760 {
761 CLEARDIRTY(tl->dirty, nbitID);
762 }
763#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
764 else
765 {
766 crFree(tl->img);
767 tl->img = NULL;
768 }
769#endif
770 }
771 }
772 break;
773#ifdef CR_OPENGL_VERSION_1_2
774 case GL_TEXTURE_3D:
775 for (lvl = 0; lvl <= from->max3DLevel; lvl++)
776 {
777 CRTextureLevel *tl = &(tobj->level[0][lvl]);
778 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
779 {
780 if (tl->generateMipmap) {
781 diff_api.TexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP_SGIS, 1);
782 }
783
784 if (tl->width && tl->height)
785 {
786 if (tl->compressed) {
787 diff_api.CompressedTexImage3DARB(GL_TEXTURE_3D, lvl,
788 tl->internalFormat, tl->width,
789 tl->height, tl->depth,
790 tl->border, tl->bytes, tl->img);
791 }
792 else {
793 /* alignment must be one */
794 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
795 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
796 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
797 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
798 diff_api.TexImage3D(GL_TEXTURE_3D, lvl,
799 tl->internalFormat,
800 tl->width, tl->height, tl->depth,
801 tl->border, tl->format,
802 tl->type, tl->img);
803 }
804 }
805
806 if (!alwaysDirty)
807 {
808 CLEARDIRTY(tl->dirty, nbitID);
809 }
810#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
811 else
812 {
813 crFree(tl->img);
814 tl->img = NULL;
815 }
816#endif
817 }
818 }
819 break;
820#endif
821#ifdef CR_NV_texture_rectangle
822 case GL_TEXTURE_RECTANGLE_NV:
823 /* only one level */
824 for (lvl = 0; lvl <= from->maxRectLevel; lvl++)
825 {
826 CRTextureLevel *tl = &(tobj->level[0][lvl]);
827 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
828 {
829 if (tl->width && tl->height)
830 {
831 if (tl->compressed) {
832 diff_api.CompressedTexImage2DARB(GL_TEXTURE_RECTANGLE_NV, lvl,
833 tl->internalFormat, tl->width,
834 tl->height, tl->border,
835 tl->bytes, tl->img);
836 }
837 else {
838 /* alignment must be one */
839 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
840 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
841 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
842 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
843 diff_api.TexImage2D(GL_TEXTURE_RECTANGLE_NV, lvl,
844 tl->internalFormat,
845 tl->width, tl->height, tl->border,
846 tl->format, tl->type, tl->img);
847 }
848 }
849
850 if (!alwaysDirty)
851 {
852 CLEARDIRTY(tl->dirty, nbitID);
853 }
854#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
855 else
856 {
857 crFree(tl->img);
858 tl->img = NULL;
859 }
860#endif
861 }
862 }
863 break;
864#endif
865#ifdef CR_ARB_texture_cube_map
866 case GL_TEXTURE_CUBE_MAP_ARB:
867 for (face = 0; face < 6; face++)
868 {
869 const GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
870 for (lvl = 0; lvl <= from->maxCubeMapLevel; lvl++)
871 {
872 CRTextureLevel *tl = &(tobj->level[face][lvl]);
873 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
874 {
875 if (tl->generateMipmap) {
876 diff_api.TexParameteri(GL_TEXTURE_CUBE_MAP_ARB,
877 GL_GENERATE_MIPMAP_SGIS, 1);
878 }
879
880 if (tl->width && tl->height)
881 {
882 if (tl->compressed) {
883 diff_api.CompressedTexImage2DARB(target,
884 lvl, tl->internalFormat,
885 tl->width, tl->height,
886 tl->border, tl->bytes, tl->img);
887 }
888 else {
889 /* alignment must be one */
890 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
891 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
892 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
893 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
894 diff_api.TexImage2D(target, lvl,
895 tl->internalFormat,
896 tl->width, tl->height, tl->border,
897 tl->format, tl->type, tl->img);
898 }
899 }
900
901 if (!alwaysDirty)
902 {
903 CLEARDIRTY(tl->dirty, nbitID);
904 }
905#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
906 else
907 {
908 crFree(tl->img);
909 tl->img = NULL;
910 }
911#endif
912 }
913 } /* for lvl */
914 } /* for face */
915 break;
916#endif
917 default:
918 UNIMPLEMENTED();
919
920 } /* switch */
921 } /* if (CHECKDIRTY(tobj->imageBit, bitID)) */
922}
923
924
925
926void
927crStateTextureDiff( CRTextureBits *tb, CRbitvalue *bitID,
928 CRContext *fromCtx, CRContext *toCtx )
929{
930 CRTextureState *from = &(fromCtx->texture);
931 CRTextureState *to = &(toCtx->texture);
932 unsigned int u, t, j;
933 glAble able[2];
934 CRbitvalue nbitID[CR_MAX_BITARRAY];
935 const GLboolean haveFragProg = fromCtx->extensions.ARB_fragment_program || fromCtx->extensions.NV_fragment_program;
936
937 for (j=0;j<CR_MAX_BITARRAY;j++)
938 nbitID[j] = ~bitID[j];
939
940 able[0] = diff_api.Disable;
941 able[1] = diff_api.Enable;
942
943 /* loop over texture units */
944 for (u = 0; u < fromCtx->limits.maxTextureUnits; u++)
945 {
946 CRTextureObj **fromBinding = NULL;
947 CRTextureObj *tobj;
948
949 /* take care of enables/disables */
950 if (CHECKDIRTY(tb->enable[u], bitID))
951 {
952
953 /* Activate texture unit u if needed */
954 if (fromCtx->texture.curTextureUnit != u) {
955 diff_api.ActiveTextureARB( GL_TEXTURE0_ARB + u);
956 fromCtx->texture.curTextureUnit = u;
957 }
958
959 if (from->unit[u].enabled1D != to->unit[u].enabled1D)
960 {
961 able[to->unit[u].enabled1D](GL_TEXTURE_1D);
962 from->unit[u].enabled1D = to->unit[u].enabled1D;
963 }
964 if (from->unit[u].enabled2D != to->unit[u].enabled2D)
965 {
966 able[to->unit[u].enabled2D](GL_TEXTURE_2D);
967 from->unit[u].enabled2D = to->unit[u].enabled2D;
968 }
969#ifdef CR_OPENGL_VERSION_1_2
970 if (from->unit[u].enabled3D != to->unit[u].enabled3D)
971 {
972 able[to->unit[u].enabled3D](GL_TEXTURE_3D);
973 from->unit[u].enabled3D = to->unit[u].enabled3D;
974 }
975#endif
976#ifdef CR_ARB_texture_cube_map
977 if (fromCtx->extensions.ARB_texture_cube_map &&
978 from->unit[u].enabledCubeMap != to->unit[u].enabledCubeMap)
979 {
980 able[to->unit[u].enabledCubeMap](GL_TEXTURE_CUBE_MAP_ARB);
981 from->unit[u].enabledCubeMap = to->unit[u].enabledCubeMap;
982 }
983#endif
984#ifdef CR_NV_texture_rectangle
985 if (fromCtx->extensions.NV_texture_rectangle &&
986 from->unit[u].enabledRect != to->unit[u].enabledRect)
987 {
988 able[to->unit[u].enabledRect](GL_TEXTURE_RECTANGLE_NV);
989 from->unit[u].enabledRect = to->unit[u].enabledRect;
990 }
991#endif
992
993 /* texgen enables */
994 if (from->unit[u].textureGen.s != to->unit[u].textureGen.s ||
995 from->unit[u].textureGen.t != to->unit[u].textureGen.t ||
996 from->unit[u].textureGen.r != to->unit[u].textureGen.r ||
997 from->unit[u].textureGen.q != to->unit[u].textureGen.q)
998 {
999 able[to->unit[u].textureGen.s](GL_TEXTURE_GEN_S);
1000 able[to->unit[u].textureGen.t](GL_TEXTURE_GEN_T);
1001 able[to->unit[u].textureGen.r](GL_TEXTURE_GEN_R);
1002 able[to->unit[u].textureGen.q](GL_TEXTURE_GEN_Q);
1003 from->unit[u].textureGen = to->unit[u].textureGen;
1004 }
1005 CLEARDIRTY(tb->enable[u], nbitID);
1006 }
1007
1008
1009 /* Texgen coefficients */
1010 if (CHECKDIRTY(tb->objGen[u], bitID))
1011 {
1012 if (fromCtx->texture.curTextureUnit != u) {
1013 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
1014 fromCtx->texture.curTextureUnit = u;
1015 }
1016 if (from->unit[u].objSCoeff.x != to->unit[u].objSCoeff.x ||
1017 from->unit[u].objSCoeff.y != to->unit[u].objSCoeff.y ||
1018 from->unit[u].objSCoeff.z != to->unit[u].objSCoeff.z ||
1019 from->unit[u].objSCoeff.w != to->unit[u].objSCoeff.w)
1020 {
1021 GLfloat f[4];
1022 f[0] = to->unit[u].objSCoeff.x;
1023 f[1] = to->unit[u].objSCoeff.y;
1024 f[2] = to->unit[u].objSCoeff.z;
1025 f[3] = to->unit[u].objSCoeff.w;
1026 diff_api.TexGenfv (GL_S, GL_OBJECT_PLANE, (const GLfloat *) f);
1027 from->unit[u].objSCoeff = to->unit[u].objSCoeff;
1028 }
1029 if (from->unit[u].objTCoeff.x != to->unit[u].objTCoeff.x ||
1030 from->unit[u].objTCoeff.y != to->unit[u].objTCoeff.y ||
1031 from->unit[u].objTCoeff.z != to->unit[u].objTCoeff.z ||
1032 from->unit[u].objTCoeff.w != to->unit[u].objTCoeff.w)
1033 {
1034 GLfloat f[4];
1035 f[0] = to->unit[u].objTCoeff.x;
1036 f[1] = to->unit[u].objTCoeff.y;
1037 f[2] = to->unit[u].objTCoeff.z;
1038 f[3] = to->unit[u].objTCoeff.w;
1039 diff_api.TexGenfv (GL_T, GL_OBJECT_PLANE, (const GLfloat *) f);
1040 from->unit[u].objTCoeff = to->unit[u].objTCoeff;
1041 }
1042 if (from->unit[u].objRCoeff.x != to->unit[u].objRCoeff.x ||
1043 from->unit[u].objRCoeff.y != to->unit[u].objRCoeff.y ||
1044 from->unit[u].objRCoeff.z != to->unit[u].objRCoeff.z ||
1045 from->unit[u].objRCoeff.w != to->unit[u].objRCoeff.w)
1046 {
1047 GLfloat f[4];
1048 f[0] = to->unit[u].objRCoeff.x;
1049 f[1] = to->unit[u].objRCoeff.y;
1050 f[2] = to->unit[u].objRCoeff.z;
1051 f[3] = to->unit[u].objRCoeff.w;
1052 diff_api.TexGenfv (GL_R, GL_OBJECT_PLANE, (const GLfloat *) f);
1053 from->unit[u].objRCoeff = to->unit[u].objRCoeff;
1054 }
1055 if (from->unit[u].objQCoeff.x != to->unit[u].objQCoeff.x ||
1056 from->unit[u].objQCoeff.y != to->unit[u].objQCoeff.y ||
1057 from->unit[u].objQCoeff.z != to->unit[u].objQCoeff.z ||
1058 from->unit[u].objQCoeff.w != to->unit[u].objQCoeff.w)
1059 {
1060 GLfloat f[4];
1061 f[0] = to->unit[u].objQCoeff.x;
1062 f[1] = to->unit[u].objQCoeff.y;
1063 f[2] = to->unit[u].objQCoeff.z;
1064 f[3] = to->unit[u].objQCoeff.w;
1065 diff_api.TexGenfv (GL_Q, GL_OBJECT_PLANE, (const GLfloat *) f);
1066 from->unit[u].objQCoeff = to->unit[u].objQCoeff;
1067 }
1068 CLEARDIRTY(tb->objGen[u], nbitID);
1069 }
1070 if (CHECKDIRTY(tb->eyeGen[u], bitID))
1071 {
1072 if (fromCtx->texture.curTextureUnit != u) {
1073 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
1074 fromCtx->texture.curTextureUnit = u;
1075 }
1076 if (fromCtx->transform.matrixMode != GL_MODELVIEW) {
1077 diff_api.MatrixMode(GL_MODELVIEW);
1078 fromCtx->transform.matrixMode = GL_MODELVIEW;
1079 }
1080 diff_api.PushMatrix();
1081 diff_api.LoadIdentity();
1082 if (from->unit[u].eyeSCoeff.x != to->unit[u].eyeSCoeff.x ||
1083 from->unit[u].eyeSCoeff.y != to->unit[u].eyeSCoeff.y ||
1084 from->unit[u].eyeSCoeff.z != to->unit[u].eyeSCoeff.z ||
1085 from->unit[u].eyeSCoeff.w != to->unit[u].eyeSCoeff.w)
1086 {
1087 GLfloat f[4];
1088 f[0] = to->unit[u].eyeSCoeff.x;
1089 f[1] = to->unit[u].eyeSCoeff.y;
1090 f[2] = to->unit[u].eyeSCoeff.z;
1091 f[3] = to->unit[u].eyeSCoeff.w;
1092 diff_api.TexGenfv (GL_S, GL_EYE_PLANE, (const GLfloat *) f);
1093 from->unit[u].eyeSCoeff = to->unit[u].eyeSCoeff;
1094 }
1095 if (from->unit[u].eyeTCoeff.x != to->unit[u].eyeTCoeff.x ||
1096 from->unit[u].eyeTCoeff.y != to->unit[u].eyeTCoeff.y ||
1097 from->unit[u].eyeTCoeff.z != to->unit[u].eyeTCoeff.z ||
1098 from->unit[u].eyeTCoeff.w != to->unit[u].eyeTCoeff.w)
1099 {
1100 GLfloat f[4];
1101 f[0] = to->unit[u].eyeTCoeff.x;
1102 f[1] = to->unit[u].eyeTCoeff.y;
1103 f[2] = to->unit[u].eyeTCoeff.z;
1104 f[3] = to->unit[u].eyeTCoeff.w;
1105 diff_api.TexGenfv (GL_T, GL_EYE_PLANE, (const GLfloat *) f);
1106 from->unit[u].eyeTCoeff = to->unit[u].eyeTCoeff;
1107 }
1108 if (from->unit[u].eyeRCoeff.x != to->unit[u].eyeRCoeff.x ||
1109 from->unit[u].eyeRCoeff.y != to->unit[u].eyeRCoeff.y ||
1110 from->unit[u].eyeRCoeff.z != to->unit[u].eyeRCoeff.z ||
1111 from->unit[u].eyeRCoeff.w != to->unit[u].eyeRCoeff.w)
1112 {
1113 GLfloat f[4];
1114 f[0] = to->unit[u].eyeRCoeff.x;
1115 f[1] = to->unit[u].eyeRCoeff.y;
1116 f[2] = to->unit[u].eyeRCoeff.z;
1117 f[3] = to->unit[u].eyeRCoeff.w;
1118 diff_api.TexGenfv (GL_R, GL_EYE_PLANE, (const GLfloat *) f);
1119 from->unit[u].eyeRCoeff = to->unit[u].eyeRCoeff;
1120 }
1121 if (from->unit[u].eyeQCoeff.x != to->unit[u].eyeQCoeff.x ||
1122 from->unit[u].eyeQCoeff.y != to->unit[u].eyeQCoeff.y ||
1123 from->unit[u].eyeQCoeff.z != to->unit[u].eyeQCoeff.z ||
1124 from->unit[u].eyeQCoeff.w != to->unit[u].eyeQCoeff.w)
1125 {
1126 GLfloat f[4];
1127 f[0] = to->unit[u].eyeQCoeff.x;
1128 f[1] = to->unit[u].eyeQCoeff.y;
1129 f[2] = to->unit[u].eyeQCoeff.z;
1130 f[3] = to->unit[u].eyeQCoeff.w;
1131 diff_api.TexGenfv (GL_Q, GL_EYE_PLANE, (const GLfloat *) f);
1132 from->unit[u].eyeQCoeff = to->unit[u].eyeQCoeff;
1133 }
1134 diff_api.PopMatrix();
1135 CLEARDIRTY(tb->eyeGen[u], nbitID);
1136 }
1137 if (CHECKDIRTY(tb->genMode[u], bitID))
1138 {
1139 if (fromCtx->texture.curTextureUnit != u) {
1140 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
1141 fromCtx->texture.curTextureUnit = u;
1142 }
1143 if (from->unit[u].gen.s != to->unit[u].gen.s ||
1144 from->unit[u].gen.t != to->unit[u].gen.t ||
1145 from->unit[u].gen.r != to->unit[u].gen.r ||
1146 from->unit[u].gen.q != to->unit[u].gen.q)
1147 {
1148 diff_api.TexGeni (GL_S, GL_TEXTURE_GEN_MODE, to->unit[u].gen.s);
1149 diff_api.TexGeni (GL_T, GL_TEXTURE_GEN_MODE, to->unit[u].gen.t);
1150 diff_api.TexGeni (GL_R, GL_TEXTURE_GEN_MODE, to->unit[u].gen.r);
1151 diff_api.TexGeni (GL_Q, GL_TEXTURE_GEN_MODE, to->unit[u].gen.q);
1152 from->unit[u].gen = to->unit[u].gen;
1153 }
1154 CLEARDIRTY(tb->genMode[u], nbitID);
1155 }
1156
1157 /* Texture enviroment */
1158 if (CHECKDIRTY(tb->envBit[u], bitID))
1159 {
1160 if (from->unit[u].envMode != to->unit[u].envMode)
1161 {
1162 diff_api.TexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, to->unit[u].envMode);
1163 from->unit[u].envMode = to->unit[u].envMode;
1164 }
1165 if (from->unit[u].envColor.r != to->unit[u].envColor.r ||
1166 from->unit[u].envColor.g != to->unit[u].envColor.g ||
1167 from->unit[u].envColor.b != to->unit[u].envColor.b ||
1168 from->unit[u].envColor.a != to->unit[u].envColor.a)
1169 {
1170 GLfloat f[4];
1171 f[0] = to->unit[u].envColor.r;
1172 f[1] = to->unit[u].envColor.g;
1173 f[2] = to->unit[u].envColor.b;
1174 f[3] = to->unit[u].envColor.a;
1175 diff_api.TexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const GLfloat *) f);
1176 from->unit[u].envColor = to->unit[u].envColor;
1177 }
1178#ifdef CR_ARB_texture_env_combine
1179 if (from->unit[u].combineModeRGB != to->unit[u].combineModeRGB)
1180 {
1181 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, to->unit[u].combineModeRGB);
1182 from->unit[u].combineModeRGB = to->unit[u].combineModeRGB;
1183 }
1184 if (from->unit[u].combineModeA != to->unit[u].combineModeA)
1185 {
1186 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, to->unit[u].combineModeA);
1187 from->unit[u].combineModeA = to->unit[u].combineModeA;
1188 }
1189 if (from->unit[u].combineSourceRGB[0] != to->unit[u].combineSourceRGB[0])
1190 {
1191 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, to->unit[u].combineSourceRGB[0]);
1192 from->unit[u].combineSourceRGB[0] = to->unit[u].combineSourceRGB[0];
1193 }
1194 if (from->unit[u].combineSourceRGB[1] != to->unit[u].combineSourceRGB[1])
1195 {
1196 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, to->unit[u].combineSourceRGB[1]);
1197 from->unit[u].combineSourceRGB[1] = to->unit[u].combineSourceRGB[1];
1198 }
1199 if (from->unit[u].combineSourceRGB[2] != to->unit[u].combineSourceRGB[2])
1200 {
1201 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, to->unit[u].combineSourceRGB[2]);
1202 from->unit[u].combineSourceRGB[2] = to->unit[u].combineSourceRGB[2];
1203 }
1204 if (from->unit[u].combineSourceA[0] != to->unit[u].combineSourceA[0])
1205 {
1206 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, to->unit[u].combineSourceA[0]);
1207 from->unit[u].combineSourceA[0] = to->unit[u].combineSourceA[0];
1208 }
1209 if (from->unit[u].combineSourceA[1] != to->unit[u].combineSourceA[1])
1210 {
1211 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, to->unit[u].combineSourceA[1]);
1212 from->unit[u].combineSourceA[1] = to->unit[u].combineSourceA[1];
1213 }
1214 if (from->unit[u].combineSourceA[2] != to->unit[u].combineSourceA[2])
1215 {
1216 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, to->unit[u].combineSourceA[2]);
1217 from->unit[u].combineSourceA[2] = to->unit[u].combineSourceA[2];
1218 }
1219 if (from->unit[u].combineOperandRGB[0] != to->unit[u].combineOperandRGB[0])
1220 {
1221 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, to->unit[u].combineOperandRGB[0]);
1222 from->unit[u].combineOperandRGB[0] = to->unit[u].combineOperandRGB[0];
1223 }
1224 if (from->unit[u].combineOperandRGB[1] != to->unit[u].combineOperandRGB[1])
1225 {
1226 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, to->unit[u].combineOperandRGB[1]);
1227 from->unit[u].combineOperandRGB[1] = to->unit[u].combineOperandRGB[1];
1228 }
1229 if (from->unit[u].combineOperandRGB[2] != to->unit[u].combineOperandRGB[2])
1230 {
1231 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, to->unit[u].combineOperandRGB[2]);
1232 from->unit[u].combineOperandRGB[2] = to->unit[u].combineOperandRGB[2];
1233 }
1234 if (from->unit[u].combineOperandA[0] != to->unit[u].combineOperandA[0])
1235 {
1236 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, to->unit[u].combineOperandA[0]);
1237 from->unit[u].combineOperandA[0] = to->unit[u].combineOperandA[0];
1238 }
1239 if (from->unit[u].combineOperandA[1] != to->unit[u].combineOperandA[1])
1240 {
1241 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, to->unit[u].combineOperandA[1]);
1242 from->unit[u].combineOperandA[1] = to->unit[u].combineOperandA[1];
1243 }
1244 if (from->unit[u].combineOperandA[2] != to->unit[u].combineOperandA[2])
1245 {
1246 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, to->unit[u].combineOperandA[2]);
1247 from->unit[u].combineOperandA[2] = to->unit[u].combineOperandA[2];
1248 }
1249 if (from->unit[u].combineScaleRGB != to->unit[u].combineScaleRGB)
1250 {
1251 diff_api.TexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, to->unit[u].combineScaleRGB);
1252 from->unit[u].combineScaleRGB = to->unit[u].combineScaleRGB;
1253 }
1254 if (from->unit[u].combineScaleA != to->unit[u].combineScaleA)
1255 {
1256 diff_api.TexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, to->unit[u].combineScaleA);
1257 from->unit[u].combineScaleA = to->unit[u].combineScaleA;
1258 }
1259#endif
1260#if CR_EXT_texture_lod_bias
1261 if (from->unit[u].lodBias != to->unit[u].lodBias)
1262 {
1263 diff_api.TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, to->unit[u].lodBias);
1264 from->unit[u].lodBias = to->unit[u].lodBias;
1265 }
1266#endif
1267 CLEARDIRTY(tb->envBit[u], nbitID);
1268 }
1269
1270 /* loop over texture targets */
1271 for (t = 0; t < 5; t++)
1272 {
1273 tobj = NULL;
1274
1275 switch (t) {
1276 case 0:
1277 if (to->unit[u].enabled1D || haveFragProg) {
1278 tobj = to->unit[u].currentTexture1D;
1279 fromBinding = &(from->unit[u].currentTexture1D);
1280 }
1281 break;
1282 case 1:
1283 if (to->unit[u].enabled2D || haveFragProg) {
1284 tobj = to->unit[u].currentTexture2D;
1285 fromBinding = &(from->unit[u].currentTexture2D);
1286 }
1287 break;
1288#ifdef CR_OPENGL_VERSION_1_2
1289 case 2:
1290 if (to->unit[u].enabled3D || haveFragProg) {
1291 tobj = to->unit[u].currentTexture3D;
1292 fromBinding = &(from->unit[u].currentTexture3D);
1293 }
1294 break;
1295#endif
1296#ifdef CR_ARB_texture_cube_map
1297 case 3:
1298 if (fromCtx->extensions.ARB_texture_cube_map &&
1299 (to->unit[u].enabledCubeMap || haveFragProg)) {
1300 tobj = to->unit[u].currentTextureCubeMap;
1301 fromBinding = &(from->unit[u].currentTextureCubeMap);
1302 }
1303 break;
1304#endif
1305#ifdef CR_NV_texture_rectangle
1306 case 4:
1307 if (fromCtx->extensions.NV_texture_rectangle &&
1308 (to->unit[u].enabledRect || haveFragProg)) {
1309 tobj = to->unit[u].currentTextureRect;
1310 fromBinding = &(from->unit[u].currentTextureRect);
1311 }
1312 break;
1313#endif
1314 default:
1315 /* maybe don't support cube maps or rects */
1316 continue;
1317 }
1318
1319 if (!tobj) {
1320 continue; /* with next target */
1321 }
1322
1323 /* Activate texture unit u if needed */
1324 if (fromCtx->texture.curTextureUnit != u) {
1325 diff_api.ActiveTextureARB( GL_TEXTURE0_ARB + u);
1326 fromCtx->texture.curTextureUnit = u;
1327 }
1328
1329 /* bind this texture if needed */
1330 if (CHECKDIRTY(tb->current[u], bitID))
1331 {
1332 if (*fromBinding != tobj)
1333 {
1334 diff_api.BindTexture(tobj->target, crStateGetTextureObjHWID(tobj));
1335 *fromBinding = tobj;
1336 }
1337 }
1338
1339 /* now, if the texture object is dirty */
1340 if (CHECKDIRTY(tobj->dirty, bitID))
1341 {
1342 crStateTextureObjectDiff(fromCtx, bitID, nbitID, tobj, GL_FALSE);
1343 }
1344 CLEARDIRTY(tobj->dirty, nbitID);
1345
1346 } /* loop over targets */
1347
1348 CLEARDIRTY(tb->current[u], nbitID);
1349
1350 } /* loop over units */
1351
1352 /* After possible fiddling with the active unit, put it back now */
1353 if (fromCtx->texture.curTextureUnit != toCtx->texture.curTextureUnit) {
1354 diff_api.ActiveTextureARB( toCtx->texture.curTextureUnit + GL_TEXTURE0_ARB );
1355 fromCtx->texture.curTextureUnit = toCtx->texture.curTextureUnit;
1356 }
1357 if (fromCtx->transform.matrixMode != toCtx->transform.matrixMode) {
1358 diff_api.MatrixMode(toCtx->transform.matrixMode);
1359 fromCtx->transform.matrixMode = toCtx->transform.matrixMode;
1360 }
1361
1362 CLEARDIRTY(tb->dirty, nbitID);
1363}
1364
1365
1366
1367struct callback_info
1368{
1369 CRbitvalue *bitID, *nbitID;
1370 CRContext *g;
1371 GLboolean bForceUpdate;
1372};
1373
1374
1375/* Called by crHashtableWalk() below */
1376static void
1377DiffTextureObjectCallback( unsigned long key, void *texObj , void *cbData)
1378{
1379 struct callback_info *info = (struct callback_info *) cbData;
1380 CRTextureObj *tobj = (CRTextureObj *) texObj;
1381 /*
1382 printf(" Checking %d 0x%x bitid=0x%x\n",tobj->name, tobj->dirty[0], info->bitID[0]);
1383 */
1384 if (info->bForceUpdate || CHECKDIRTY(tobj->dirty, info->bitID)) {
1385 /*
1386 printf(" Found Dirty! %d\n", tobj->name);
1387 */
1388 crStateTextureObjectDiff(info->g, info->bitID, info->nbitID, tobj, info->bForceUpdate);
1389 CLEARDIRTY(tobj->dirty, info->nbitID);
1390 }
1391}
1392
1393
1394/*
1395 * This isn't used right now, but will be used in the future to fix some
1396 * potential display list problems. Specifically, if glBindTexture is
1397 * in a display list, we have to be sure that all outstanding texture object
1398 * updates are resolved before the list is called. If we don't, we may
1399 * wind up binding texture objects that are stale.
1400 */
1401void
1402crStateDiffAllTextureObjects( CRContext *g, CRbitvalue *bitID, GLboolean bForceUpdate )
1403{
1404 CRbitvalue nbitID[CR_MAX_BITARRAY];
1405 struct callback_info info;
1406 int j;
1407 int origUnit, orig1D, orig2D, orig3D, origCube, origRect;
1408
1409 for (j = 0; j < CR_MAX_BITARRAY; j++)
1410 nbitID[j] = ~bitID[j];
1411
1412 info.bitID = bitID;
1413 info.nbitID = nbitID;
1414 info.g = g;
1415 info.bForceUpdate = bForceUpdate;
1416
1417 /* save current texture bindings */
1418 origUnit = g->texture.curTextureUnit;
1419 orig1D = crStateGetTextureObjHWID(g->texture.unit[0].currentTexture1D);
1420 orig2D = crStateGetTextureObjHWID(g->texture.unit[0].currentTexture2D);
1421 orig3D = crStateGetTextureObjHWID(g->texture.unit[0].currentTexture3D);
1422#ifdef CR_ARB_texture_cube_map
1423 origCube = crStateGetTextureObjHWID(g->texture.unit[0].currentTextureCubeMap);
1424#endif
1425#ifdef CR_NV_texture_rectangle
1426 origRect = crStateGetTextureObjHWID(g->texture.unit[0].currentTextureRect);
1427#endif
1428
1429 /* use texture unit 0 for updates */
1430 diff_api.ActiveTextureARB(GL_TEXTURE0_ARB);
1431
1432 /* diff all the textures */
1433 crHashtableWalk(g->shared->textureTable, DiffTextureObjectCallback, (void *) &info);
1434
1435 /* default ones */
1436 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base1D, GL_TRUE);
1437 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base2D, GL_TRUE);
1438 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base3D, GL_TRUE);
1439 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy1D, GL_TRUE);
1440 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy2D, GL_TRUE);
1441 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy3D, GL_TRUE);
1442#ifdef CR_ARB_texture_cube_map
1443 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.baseCubeMap, GL_TRUE);
1444 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxyCubeMap, GL_TRUE);
1445#endif
1446#ifdef CR_NV_texture_rectangle
1447 if (g->extensions.NV_texture_rectangle)
1448 {
1449 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.baseRect, GL_TRUE);
1450 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxyRect, GL_TRUE);
1451 }
1452#endif
1453
1454 /* restore bindings */
1455 /* first restore unit 0 bindings the unit 0 is active currently */
1456 diff_api.BindTexture(GL_TEXTURE_1D, orig1D);
1457 diff_api.BindTexture(GL_TEXTURE_2D, orig2D);
1458 diff_api.BindTexture(GL_TEXTURE_3D, orig3D);
1459#ifdef CR_ARB_texture_cube_map
1460 diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, origCube);
1461#endif
1462#ifdef CR_NV_texture_rectangle
1463 diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, origRect);
1464#endif
1465 /* now restore the proper active unit */
1466 diff_api.ActiveTextureARB(GL_TEXTURE0_ARB + origUnit);
1467}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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