VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c@ 35912

Last change on this file since 35912 was 35912, checked in by vboxsync, 14 years ago

crOpenGL: fix sometimes missing textures and geometry

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 68.2 KB
Line 
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/*
8 * This file manages all the client-side state including:
9 * Pixel pack/unpack parameters
10 * Vertex arrays
11 */
12
13
14#include "cr_mem.h"
15#include "state.h"
16#include "state/cr_statetypes.h"
17#include "state/cr_statefuncs.h"
18#include "state_internals.h"
19
20const CRPixelPackState crStateNativePixelPacking = {
21 0, /* rowLength */
22 0, /* skipRows */
23 0, /* skipPixels */
24 1, /* alignment */
25 0, /* imageHeight */
26 0, /* skipImages */
27 GL_FALSE, /* swapBytes */
28 GL_FALSE, /* psLSBFirst */
29};
30
31
32void crStateClientInitBits (CRClientBits *c)
33{
34 int i;
35
36 /* XXX why GLCLIENT_BIT_ALLOC? */
37 c->v = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
38 c->n = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
39 c->c = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
40 c->s = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
41 c->i = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
42 for ( i = 0; i < CR_MAX_TEXTURE_UNITS; i++ )
43 c->t[i] = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
44 c->e = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
45 c->f = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
46
47#ifdef CR_NV_vertex_program
48 for ( i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++ )
49 c->a[i] = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
50#endif
51}
52
53void crStateClientDestroyBits (CRClientBits *c)
54{
55 int i;
56
57 crFree(c->v);
58 crFree(c->n);
59 crFree(c->c);
60 crFree(c->s);
61 crFree(c->i);
62
63 for ( i = 0; i < CR_MAX_TEXTURE_UNITS; i++ )
64 crFree(c->t[i]);
65
66 crFree(c->e);
67 crFree(c->f);
68
69#ifdef CR_NV_vertex_program
70 for ( i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++ )
71 crFree(c->a[i]);
72#endif
73}
74
75static void crStateUnlockClientPointer(CRClientPointer* cp)
76{
77 if (cp->locked)
78 {
79#ifndef IN_GUEST
80 if (cp->p) crFree(cp->p);
81#endif
82 cp->locked = GL_FALSE;
83 }
84}
85
86void crStateClientDestroy(CRClientState *c)
87{
88#ifdef CR_EXT_compiled_vertex_array
89 if (c->array.locked)
90 {
91 unsigned int i;
92
93 crStateUnlockClientPointer(&c->array.v);
94 crStateUnlockClientPointer(&c->array.c);
95 crStateUnlockClientPointer(&c->array.f);
96 crStateUnlockClientPointer(&c->array.s);
97 crStateUnlockClientPointer(&c->array.e);
98 crStateUnlockClientPointer(&c->array.i);
99 crStateUnlockClientPointer(&c->array.n);
100 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
101 {
102 crStateUnlockClientPointer(&c->array.t[i]);
103 }
104 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
105 {
106 crStateUnlockClientPointer(&c->array.a[i]);
107 }
108 }
109#endif
110}
111
112void crStateClientInit(CRClientState *c)
113{
114 CRContext *g = GetCurrentContext();
115 unsigned int i;
116
117 /* pixel pack/unpack */
118 c->unpack.rowLength = 0;
119 c->unpack.skipRows = 0;
120 c->unpack.skipPixels = 0;
121 c->unpack.skipImages = 0;
122 c->unpack.alignment = 4;
123 c->unpack.imageHeight = 0;
124 c->unpack.swapBytes = GL_FALSE;
125 c->unpack.psLSBFirst = GL_FALSE;
126 c->pack.rowLength = 0;
127 c->pack.skipRows = 0;
128 c->pack.skipPixels = 0;
129 c->pack.skipImages = 0;
130 c->pack.alignment = 4;
131 c->pack.imageHeight = 0;
132 c->pack.swapBytes = GL_FALSE;
133 c->pack.psLSBFirst = GL_FALSE;
134
135 /* ARB multitexture */
136 c->curClientTextureUnit = 0;
137
138#ifdef CR_EXT_compiled_vertex_array
139 c->array.lockFirst = 0;
140 c->array.lockCount = 0;
141 c->array.locked = GL_FALSE;
142# ifdef IN_GUEST
143 c->array.synced = GL_FALSE;
144# endif
145#endif
146
147 /* vertex array */
148 c->array.v.p = NULL;
149 c->array.v.size = 4;
150 c->array.v.type = GL_FLOAT;
151 c->array.v.stride = 0;
152 c->array.v.enabled = 0;
153#ifdef CR_ARB_vertex_buffer_object
154 c->array.v.buffer = g ? g->bufferobject.arrayBuffer : NULL;
155#endif
156#ifdef CR_EXT_compiled_vertex_array
157 c->array.v.locked = GL_FALSE;
158 c->array.v.prevPtr = NULL;
159 c->array.v.prevStride = 0;
160#endif
161
162 /* color array */
163 c->array.c.p = NULL;
164 c->array.c.size = 4;
165 c->array.c.type = GL_FLOAT;
166 c->array.c.stride = 0;
167 c->array.c.enabled = 0;
168#ifdef CR_ARB_vertex_buffer_object
169 c->array.c.buffer = g ? g->bufferobject.arrayBuffer : NULL;
170#endif
171#ifdef CR_EXT_compiled_vertex_array
172 c->array.c.locked = GL_FALSE;
173 c->array.c.prevPtr = NULL;
174 c->array.c.prevStride = 0;
175#endif
176
177 /* fog array */
178 c->array.f.p = NULL;
179 c->array.f.size = 0;
180 c->array.f.type = GL_FLOAT;
181 c->array.f.stride = 0;
182 c->array.f.enabled = 0;
183#ifdef CR_ARB_vertex_buffer_object
184 c->array.f.buffer = g ? g->bufferobject.arrayBuffer : NULL;
185#endif
186#ifdef CR_EXT_compiled_vertex_array
187 c->array.f.locked = GL_FALSE;
188 c->array.f.prevPtr = NULL;
189 c->array.f.prevStride = 0;
190#endif
191
192 /* secondary color array */
193 c->array.s.p = NULL;
194 c->array.s.size = 3;
195 c->array.s.type = GL_FLOAT;
196 c->array.s.stride = 0;
197 c->array.s.enabled = 0;
198#ifdef CR_ARB_vertex_buffer_object
199 c->array.s.buffer = g ? g->bufferobject.arrayBuffer : NULL;
200#endif
201#ifdef CR_EXT_compiled_vertex_array
202 c->array.s.locked = GL_FALSE;
203 c->array.s.prevPtr = NULL;
204 c->array.s.prevStride = 0;
205#endif
206
207 /* edge flag array */
208 c->array.e.p = NULL;
209 c->array.e.size = 0;
210 c->array.e.type = GL_FLOAT;
211 c->array.e.stride = 0;
212 c->array.e.enabled = 0;
213#ifdef CR_ARB_vertex_buffer_object
214 c->array.e.buffer = g ? g->bufferobject.arrayBuffer : NULL;
215#endif
216#ifdef CR_EXT_compiled_vertex_array
217 c->array.e.locked = GL_FALSE;
218 c->array.e.prevPtr = NULL;
219 c->array.e.prevStride = 0;
220#endif
221
222 /* color index array */
223 c->array.i.p = NULL;
224 c->array.i.size = 0;
225 c->array.i.type = GL_FLOAT;
226 c->array.i.stride = 0;
227 c->array.i.enabled = 0;
228#ifdef CR_ARB_vertex_buffer_object
229 c->array.i.buffer = g ? g->bufferobject.arrayBuffer : NULL;
230#endif
231#ifdef CR_EXT_compiled_vertex_array
232 c->array.i.locked = GL_FALSE;
233 c->array.i.prevPtr = NULL;
234 c->array.i.prevStride = 0;
235#endif
236
237 /* normal array */
238 c->array.n.p = NULL;
239 c->array.n.size = 4;
240 c->array.n.type = GL_FLOAT;
241 c->array.n.stride = 0;
242 c->array.n.enabled = 0;
243#ifdef CR_ARB_vertex_buffer_object
244 c->array.n.buffer = g ? g->bufferobject.arrayBuffer : NULL;
245#endif
246#ifdef CR_EXT_compiled_vertex_array
247 c->array.n.locked = GL_FALSE;
248 c->array.n.prevPtr = NULL;
249 c->array.n.prevStride = 0;
250#endif
251
252 /* texcoord arrays */
253 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
254 {
255 c->array.t[i].p = NULL;
256 c->array.t[i].size = 4;
257 c->array.t[i].type = GL_FLOAT;
258 c->array.t[i].stride = 0;
259 c->array.t[i].enabled = 0;
260#ifdef CR_ARB_vertex_buffer_object
261 c->array.t[i].buffer = g ? g->bufferobject.arrayBuffer : NULL;
262#endif
263#ifdef CR_EXT_compiled_vertex_array
264 c->array.t[i].locked = GL_FALSE;
265 c->array.t[i].prevPtr = NULL;
266 c->array.t[i].prevStride = 0;
267#endif
268 }
269
270 /* generic vertex attributes */
271#ifdef CR_NV_vertex_program
272 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++) {
273 c->array.a[i].enabled = GL_FALSE;
274 c->array.a[i].type = GL_FLOAT;
275 c->array.a[i].size = 4;
276 c->array.a[i].stride = 0;
277#ifdef CR_ARB_vertex_buffer_object
278 c->array.a[i].buffer = g ? g->bufferobject.arrayBuffer : NULL;
279#endif
280#ifdef CR_EXT_compiled_vertex_array
281 c->array.a[i].locked = GL_FALSE;
282 c->array.a[i].prevPtr = NULL;
283 c->array.a[i].prevStride = 0;
284#endif
285 }
286#endif
287}
288
289
290/*
291 * PixelStore functions are here, not in state_pixel.c because this
292 * is client-side state, like vertex arrays.
293 */
294
295void STATE_APIENTRY crStatePixelStoref (GLenum pname, GLfloat param)
296{
297
298 /* The GL SPEC says I can do this on page 76. */
299 switch( pname )
300 {
301 case GL_PACK_SWAP_BYTES:
302 case GL_PACK_LSB_FIRST:
303 case GL_UNPACK_SWAP_BYTES:
304 case GL_UNPACK_LSB_FIRST:
305 crStatePixelStorei( pname, param == 0.0f ? 0: 1 );
306 break;
307 default:
308 crStatePixelStorei( pname, (GLint) param );
309 break;
310 }
311}
312
313void STATE_APIENTRY crStatePixelStorei (GLenum pname, GLint param)
314{
315 CRContext *g = GetCurrentContext();
316 CRClientState *c = &(g->client);
317 CRStateBits *sb = GetCurrentBits();
318 CRClientBits *cb = &(sb->client);
319
320 if (g->current.inBeginEnd)
321 {
322 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "PixelStore{if} called in Begin/End");
323 return;
324 }
325
326 FLUSH();
327
328 switch(pname) {
329 case GL_PACK_SWAP_BYTES:
330 c->pack.swapBytes = (GLboolean) param;
331 DIRTY(cb->pack, g->neg_bitid);
332 break;
333 case GL_PACK_LSB_FIRST:
334 c->pack.psLSBFirst = (GLboolean) param;
335 DIRTY(cb->pack, g->neg_bitid);
336 break;
337 case GL_PACK_ROW_LENGTH:
338 if (param < 0.0f)
339 {
340 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Row Length: %f", param);
341 return;
342 }
343 c->pack.rowLength = param;
344 DIRTY(cb->pack, g->neg_bitid);
345 break;
346#ifdef CR_OPENGL_VERSION_1_2
347 case GL_PACK_IMAGE_HEIGHT:
348 if (param < 0.0f)
349 {
350 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Image Height: %f", param);
351 return;
352 }
353 c->pack.imageHeight = param;
354 DIRTY(cb->pack, g->neg_bitid);
355 break;
356#endif
357 case GL_PACK_SKIP_IMAGES:
358 if (param < 0.0f)
359 {
360 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Skip Images: %f", param);
361 return;
362 }
363 c->pack.skipImages = param;
364 DIRTY(cb->pack, g->neg_bitid);
365 break;
366 case GL_PACK_SKIP_PIXELS:
367 if (param < 0.0f)
368 {
369 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Skip Pixels: %f", param);
370 return;
371 }
372 c->pack.skipPixels = param;
373 DIRTY(cb->pack, g->neg_bitid);
374 break;
375 case GL_PACK_SKIP_ROWS:
376 if (param < 0.0f)
377 {
378 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Row Skip: %f", param);
379 return;
380 }
381 c->pack.skipRows = param;
382 DIRTY(cb->pack, g->neg_bitid);
383 break;
384 case GL_PACK_ALIGNMENT:
385 if (((GLint) param) != 1 &&
386 ((GLint) param) != 2 &&
387 ((GLint) param) != 4 &&
388 ((GLint) param) != 8)
389 {
390 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Invalid Alignment: %f", param);
391 return;
392 }
393 c->pack.alignment = param;
394 DIRTY(cb->pack, g->neg_bitid);
395 break;
396
397 case GL_UNPACK_SWAP_BYTES:
398 c->unpack.swapBytes = (GLboolean) param;
399 DIRTY(cb->unpack, g->neg_bitid);
400 break;
401 case GL_UNPACK_LSB_FIRST:
402 c->unpack.psLSBFirst = (GLboolean) param;
403 DIRTY(cb->unpack, g->neg_bitid);
404 break;
405 case GL_UNPACK_ROW_LENGTH:
406 if (param < 0.0f)
407 {
408 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Row Length: %f", param);
409 return;
410 }
411 c->unpack.rowLength = param;
412 DIRTY(cb->unpack, g->neg_bitid);
413 break;
414#ifdef CR_OPENGL_VERSION_1_2
415 case GL_UNPACK_IMAGE_HEIGHT:
416 if (param < 0.0f)
417 {
418 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Image Height: %f", param);
419 return;
420 }
421 c->unpack.imageHeight = param;
422 DIRTY(cb->unpack, g->neg_bitid);
423 break;
424#endif
425 case GL_UNPACK_SKIP_IMAGES:
426 if (param < 0.0f)
427 {
428 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Skip Images: %f", param);
429 return;
430 }
431 c->unpack.skipImages = param;
432 DIRTY(cb->unpack, g->neg_bitid);
433 break;
434 case GL_UNPACK_SKIP_PIXELS:
435 if (param < 0.0f)
436 {
437 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Skip Pixels: %f", param);
438 return;
439 }
440 c->unpack.skipPixels = param;
441 DIRTY(cb->unpack, g->neg_bitid);
442 break;
443 case GL_UNPACK_SKIP_ROWS:
444 if (param < 0.0f)
445 {
446 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Row Skip: %f", param);
447 return;
448 }
449 c->unpack.skipRows = param;
450 DIRTY(cb->unpack, g->neg_bitid);
451 break;
452 case GL_UNPACK_ALIGNMENT:
453 if (((GLint) param) != 1 &&
454 ((GLint) param) != 2 &&
455 ((GLint) param) != 4 &&
456 ((GLint) param) != 8)
457 {
458 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Invalid Alignment: %f", param);
459 return;
460 }
461 c->unpack.alignment = param;
462 DIRTY(cb->unpack, g->neg_bitid);
463 break;
464 default:
465 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Unknown glPixelStore Pname: %d", pname);
466 return;
467 }
468 DIRTY(cb->dirty, g->neg_bitid);
469}
470
471
472static void setClientState(CRClientState *c, CRClientBits *cb,
473 CRbitvalue *neg_bitid, GLenum array, GLboolean state)
474{
475 CRContext *g = GetCurrentContext();
476
477 switch (array)
478 {
479#ifdef CR_NV_vertex_program
480 case GL_VERTEX_ATTRIB_ARRAY0_NV:
481 case GL_VERTEX_ATTRIB_ARRAY1_NV:
482 case GL_VERTEX_ATTRIB_ARRAY2_NV:
483 case GL_VERTEX_ATTRIB_ARRAY3_NV:
484 case GL_VERTEX_ATTRIB_ARRAY4_NV:
485 case GL_VERTEX_ATTRIB_ARRAY5_NV:
486 case GL_VERTEX_ATTRIB_ARRAY6_NV:
487 case GL_VERTEX_ATTRIB_ARRAY7_NV:
488 case GL_VERTEX_ATTRIB_ARRAY8_NV:
489 case GL_VERTEX_ATTRIB_ARRAY9_NV:
490 case GL_VERTEX_ATTRIB_ARRAY10_NV:
491 case GL_VERTEX_ATTRIB_ARRAY11_NV:
492 case GL_VERTEX_ATTRIB_ARRAY12_NV:
493 case GL_VERTEX_ATTRIB_ARRAY13_NV:
494 case GL_VERTEX_ATTRIB_ARRAY14_NV:
495 case GL_VERTEX_ATTRIB_ARRAY15_NV:
496 {
497 const GLuint i = array - GL_VERTEX_ATTRIB_ARRAY0_NV;
498 c->array.a[i].enabled = state;
499 }
500 break;
501#endif
502 case GL_VERTEX_ARRAY:
503 c->array.v.enabled = state;
504 break;
505 case GL_COLOR_ARRAY:
506 c->array.c.enabled = state;
507 break;
508 case GL_NORMAL_ARRAY:
509 c->array.n.enabled = state;
510 break;
511 case GL_INDEX_ARRAY:
512 c->array.i.enabled = state;
513 break;
514 case GL_TEXTURE_COORD_ARRAY:
515 c->array.t[c->curClientTextureUnit].enabled = state;
516 break;
517 case GL_EDGE_FLAG_ARRAY:
518 c->array.e.enabled = state;
519 break;
520#ifdef CR_EXT_fog_coord
521 case GL_FOG_COORDINATE_ARRAY_EXT:
522 c->array.f.enabled = state;
523 break;
524#endif
525#ifdef CR_EXT_secondary_color
526 case GL_SECONDARY_COLOR_ARRAY_EXT:
527 if( g->extensions.EXT_secondary_color ){
528 c->array.s.enabled = state;
529 }
530 else {
531 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "Invalid Enum passed to Enable/Disable Client State: SECONDARY_COLOR_ARRAY_EXT - EXT_secondary_color is not enabled." );
532 return;
533 }
534 break;
535#endif
536 default:
537 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "Invalid Enum passed to Enable/Disable Client State: 0x%x", array );
538 return;
539 }
540 DIRTY(cb->dirty, neg_bitid);
541 DIRTY(cb->enableClientState, neg_bitid);
542}
543
544void STATE_APIENTRY crStateEnableClientState (GLenum array)
545{
546 CRContext *g = GetCurrentContext();
547 CRClientState *c = &(g->client);
548 CRStateBits *sb = GetCurrentBits();
549 CRClientBits *cb = &(sb->client);
550
551 FLUSH();
552
553 setClientState(c, cb, g->neg_bitid, array, GL_TRUE);
554}
555
556void STATE_APIENTRY crStateDisableClientState (GLenum array)
557{
558 CRContext *g = GetCurrentContext();
559 CRClientState *c = &(g->client);
560 CRStateBits *sb = GetCurrentBits();
561 CRClientBits *cb = &(sb->client);
562
563 FLUSH();
564
565 setClientState(c, cb, g->neg_bitid, array, GL_FALSE);
566}
567
568static void
569crStateClientSetPointer(CRClientPointer *cp, GLint size,
570 GLenum type, GLboolean normalized,
571 GLsizei stride, const GLvoid *pointer)
572{
573 CRContext *g = GetCurrentContext();
574
575#ifdef CR_EXT_compiled_vertex_array
576 crStateUnlockClientPointer(cp);
577 cp->prevPtr = cp->p;
578 cp->prevStride = cp->stride;
579#endif
580
581 cp->p = (unsigned char *) pointer;
582 cp->size = size;
583 cp->type = type;
584 cp->normalized = normalized;
585
586 /* Calculate the bytes per index for address calculation */
587 cp->bytesPerIndex = size;
588 switch (type)
589 {
590 case GL_BYTE:
591 case GL_UNSIGNED_BYTE:
592 break;
593 case GL_SHORT:
594 case GL_UNSIGNED_SHORT:
595 cp->bytesPerIndex *= sizeof(GLshort);
596 break;
597 case GL_INT:
598 case GL_UNSIGNED_INT:
599 cp->bytesPerIndex *= sizeof(GLint);
600 break;
601 case GL_FLOAT:
602 cp->bytesPerIndex *= sizeof(GLfloat);
603 break;
604 case GL_DOUBLE:
605 cp->bytesPerIndex *= sizeof(GLdouble);
606 break;
607 default:
608 crStateError( __LINE__, __FILE__, GL_INVALID_VALUE,
609 "Unknown type of vertex array: %d", type );
610 return;
611 }
612
613 /*
614 ** Note: If stride==0 then we set the
615 ** stride equal address offset
616 ** therefore stride can never equal
617 ** zero.
618 */
619 if (stride)
620 cp->stride = stride;
621 else
622 cp->stride = cp->bytesPerIndex;
623
624#ifdef CR_ARB_vertex_buffer_object
625 cp->buffer = g->bufferobject.arrayBuffer;
626#endif
627}
628
629void STATE_APIENTRY crStateVertexPointer(GLint size, GLenum type,
630 GLsizei stride, const GLvoid *p)
631{
632 CRContext *g = GetCurrentContext();
633 CRClientState *c = &(g->client);
634 CRStateBits *sb = GetCurrentBits();
635 CRClientBits *cb = &(sb->client);
636
637 FLUSH();
638
639 if (size != 2 && size != 3 && size != 4)
640 {
641 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glVertexPointer: invalid size: %d", size);
642 return;
643 }
644 if (type != GL_SHORT && type != GL_INT &&
645 type != GL_FLOAT && type != GL_DOUBLE)
646 {
647 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glVertexPointer: invalid type: 0x%x", type);
648 return;
649 }
650 if (stride < 0)
651 {
652 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glVertexPointer: stride was negative: %d", stride);
653 return;
654 }
655
656 crStateClientSetPointer(&(c->array.v), size, type, GL_FALSE, stride, p);
657 DIRTY(cb->dirty, g->neg_bitid);
658 DIRTY(cb->clientPointer, g->neg_bitid);
659 DIRTY(cb->v, g->neg_bitid);
660}
661
662void STATE_APIENTRY crStateColorPointer(GLint size, GLenum type,
663 GLsizei stride, const GLvoid *p)
664{
665 CRContext *g = GetCurrentContext();
666 CRClientState *c = &(g->client);
667 CRStateBits *sb = GetCurrentBits();
668 CRClientBits *cb = &(sb->client);
669
670 FLUSH();
671
672 if (size != 3 && size != 4)
673 {
674 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glColorPointer: invalid size: %d", size);
675 return;
676 }
677 if (type != GL_BYTE && type != GL_UNSIGNED_BYTE &&
678 type != GL_SHORT && type != GL_UNSIGNED_SHORT &&
679 type != GL_INT && type != GL_UNSIGNED_INT &&
680 type != GL_FLOAT && type != GL_DOUBLE)
681 {
682 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glColorPointer: invalid type: 0x%x", type);
683 return;
684 }
685 if (stride < 0)
686 {
687 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glColorPointer: stride was negative: %d", stride);
688 return;
689 }
690
691 crStateClientSetPointer(&(c->array.c), size, type, GL_TRUE, stride, p);
692 DIRTY(cb->dirty, g->neg_bitid);
693 DIRTY(cb->clientPointer, g->neg_bitid);
694 DIRTY(cb->c, g->neg_bitid);
695}
696
697void STATE_APIENTRY crStateSecondaryColorPointerEXT(GLint size,
698 GLenum type, GLsizei stride, const GLvoid *p)
699{
700 CRContext *g = GetCurrentContext();
701 CRClientState *c = &(g->client);
702 CRStateBits *sb = GetCurrentBits();
703 CRClientBits *cb = &(sb->client);
704
705 FLUSH();
706
707 if ( !g->extensions.EXT_secondary_color )
708 {
709 crError( "glSecondaryColorPointerEXT called but EXT_secondary_color is disabled." );
710 return;
711 }
712
713 /*Note: According to opengl spec, only size==3 should be accepted here.
714 *But it turns out that most drivers accept size==4 here as well, and 4th value
715 *could even be accessed in shaders code.
716 *Having a strict check here, leads to difference between guest and host gpu states, which
717 *in turn could lead to crashes when using server side VBOs.
718 *@todo: add error reporting to state's VBO related functions and abort dispatching to
719 *real gpu on any failure to prevent other possible issues.
720 */
721
722 if ((size != 3) && (size != 4))
723 {
724 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glSecondaryColorPointerEXT: invalid size: %d", size);
725 return;
726 }
727 if (type != GL_BYTE && type != GL_UNSIGNED_BYTE &&
728 type != GL_SHORT && type != GL_UNSIGNED_SHORT &&
729 type != GL_INT && type != GL_UNSIGNED_INT &&
730 type != GL_FLOAT && type != GL_DOUBLE)
731 {
732 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glSecondaryColorPointerEXT: invalid type: 0x%x", type);
733 return;
734 }
735 if (stride < 0)
736 {
737 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glSecondaryColorPointerEXT: stride was negative: %d", stride);
738 return;
739 }
740
741 crStateClientSetPointer(&(c->array.s), size, type, GL_TRUE, stride, p);
742 DIRTY(cb->dirty, g->neg_bitid);
743 DIRTY(cb->clientPointer, g->neg_bitid);
744 DIRTY(cb->s, g->neg_bitid);
745}
746
747void STATE_APIENTRY crStateIndexPointer(GLenum type, GLsizei stride,
748 const GLvoid *p)
749{
750 CRContext *g = GetCurrentContext();
751 CRClientState *c = &(g->client);
752 CRStateBits *sb = GetCurrentBits();
753 CRClientBits *cb = &(sb->client);
754
755 FLUSH();
756
757 if (type != GL_SHORT && type != GL_INT && type != GL_UNSIGNED_BYTE &&
758 type != GL_FLOAT && type != GL_DOUBLE)
759 {
760 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glIndexPointer: invalid type: 0x%x", type);
761 return;
762 }
763 if (stride < 0)
764 {
765 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glIndexPointer: stride was negative: %d", stride);
766 return;
767 }
768
769 crStateClientSetPointer(&(c->array.i), 1, type, GL_TRUE, stride, p);
770 DIRTY(cb->dirty, g->neg_bitid);
771 DIRTY(cb->clientPointer, g->neg_bitid);
772 DIRTY(cb->i, g->neg_bitid);
773}
774
775void STATE_APIENTRY crStateNormalPointer(GLenum type, GLsizei stride,
776 const GLvoid *p)
777{
778 CRContext *g = GetCurrentContext();
779 CRClientState *c = &(g->client);
780 CRStateBits *sb = GetCurrentBits();
781 CRClientBits *cb = &(sb->client);
782
783 FLUSH();
784
785 if (type != GL_BYTE && type != GL_SHORT &&
786 type != GL_INT && type != GL_FLOAT &&
787 type != GL_DOUBLE)
788 {
789 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glNormalPointer: invalid type: 0x%x", type);
790 return;
791 }
792 if (stride < 0)
793 {
794 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glNormalPointer: stride was negative: %d", stride);
795 return;
796 }
797
798 crStateClientSetPointer(&(c->array.n), 3, type, GL_TRUE, stride, p);
799 DIRTY(cb->dirty, g->neg_bitid);
800 DIRTY(cb->clientPointer, g->neg_bitid);
801 DIRTY(cb->n, g->neg_bitid);
802}
803
804void STATE_APIENTRY crStateTexCoordPointer(GLint size, GLenum type,
805 GLsizei stride, const GLvoid *p)
806{
807 CRContext *g = GetCurrentContext();
808 CRClientState *c = &(g->client);
809 CRStateBits *sb = GetCurrentBits();
810 CRClientBits *cb = &(sb->client);
811
812 FLUSH();
813
814 if (size != 1 && size != 2 && size != 3 && size != 4)
815 {
816 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glTexCoordPointer: invalid size: %d", size);
817 return;
818 }
819 if (type != GL_SHORT && type != GL_INT &&
820 type != GL_FLOAT && type != GL_DOUBLE)
821 {
822 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glTexCoordPointer: invalid type: 0x%x", type);
823 return;
824 }
825 if (stride < 0)
826 {
827 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glTexCoordPointer: stride was negative: %d", stride);
828 return;
829 }
830
831 crStateClientSetPointer(&(c->array.t[c->curClientTextureUnit]), size, type, GL_FALSE, stride, p);
832 DIRTY(cb->dirty, g->neg_bitid);
833 DIRTY(cb->clientPointer, g->neg_bitid);
834 DIRTY(cb->t[c->curClientTextureUnit], g->neg_bitid);
835}
836
837void STATE_APIENTRY crStateEdgeFlagPointer(GLsizei stride, const GLvoid *p)
838{
839 CRContext *g = GetCurrentContext();
840 CRClientState *c = &(g->client);
841 CRStateBits *sb = GetCurrentBits();
842 CRClientBits *cb = &(sb->client);
843
844 FLUSH();
845
846 if (stride < 0)
847 {
848 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glTexCoordPointer: stride was negative: %d", stride);
849 return;
850 }
851
852 crStateClientSetPointer(&(c->array.e), 1, GL_UNSIGNED_BYTE, GL_FALSE, stride, p);
853 DIRTY(cb->dirty, g->neg_bitid);
854 DIRTY(cb->clientPointer, g->neg_bitid);
855 DIRTY(cb->e, g->neg_bitid);
856}
857
858void STATE_APIENTRY crStateFogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *p)
859{
860 CRContext *g = GetCurrentContext();
861 CRClientState *c = &(g->client);
862 CRStateBits *sb = GetCurrentBits();
863 CRClientBits *cb = &(sb->client);
864
865 FLUSH();
866
867 if (type != GL_BYTE && type != GL_UNSIGNED_BYTE &&
868 type != GL_SHORT && type != GL_UNSIGNED_SHORT &&
869 type != GL_INT && type != GL_UNSIGNED_INT &&
870 type != GL_FLOAT && type != GL_DOUBLE)
871 {
872 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glFogCoordPointerEXT: invalid type: 0x%x", type);
873 return;
874 }
875 if (stride < 0)
876 {
877 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glFogCoordPointerEXT: stride was negative: %d", stride);
878 return;
879 }
880
881 crStateClientSetPointer(&(c->array.f), 1, type, GL_FALSE, stride, p);
882 DIRTY(cb->dirty, g->neg_bitid);
883 DIRTY(cb->clientPointer, g->neg_bitid);
884 DIRTY(cb->f, g->neg_bitid);
885}
886
887
888void STATE_APIENTRY crStateVertexAttribPointerNV(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *p)
889{
890 GLboolean normalized = GL_FALSE;
891 /* Extra error checking for NV arrays */
892 if (type != GL_UNSIGNED_BYTE && type != GL_SHORT &&
893 type != GL_FLOAT && type != GL_DOUBLE) {
894 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
895 "glVertexAttribPointerNV: invalid type: 0x%x", type);
896 return;
897 }
898 crStateVertexAttribPointerARB(index, size, type, normalized, stride, p);
899}
900
901
902void STATE_APIENTRY crStateVertexAttribPointerARB(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *p)
903{
904 CRContext *g = GetCurrentContext();
905 CRClientState *c = &(g->client);
906 CRStateBits *sb = GetCurrentBits();
907 CRClientBits *cb = &(sb->client);
908
909 FLUSH();
910
911 if (index > CR_MAX_VERTEX_ATTRIBS)
912 {
913 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glVertexAttribPointerARB: invalid index: %d", (int) index);
914 return;
915 }
916 if (size != 1 && size != 2 && size != 3 && size != 4)
917 {
918 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glVertexAttribPointerARB: invalid size: %d", size);
919 return;
920 }
921 if (type != GL_BYTE && type != GL_UNSIGNED_BYTE &&
922 type != GL_SHORT && type != GL_UNSIGNED_SHORT &&
923 type != GL_INT && type != GL_UNSIGNED_INT &&
924 type != GL_FLOAT && type != GL_DOUBLE)
925 {
926 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glVertexAttribPointerARB: invalid type: 0x%x", type);
927 return;
928 }
929 if (stride < 0)
930 {
931 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glVertexAttribPointerARB: stride was negative: %d", stride);
932 return;
933 }
934
935 crStateClientSetPointer(&(c->array.a[index]), size, type, normalized, stride, p);
936 DIRTY(cb->dirty, g->neg_bitid);
937 DIRTY(cb->clientPointer, g->neg_bitid);
938 DIRTY(cb->a[index], g->neg_bitid);
939}
940
941
942void STATE_APIENTRY crStateGetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer)
943{
944 CRContext *g = GetCurrentContext();
945
946 if (g->current.inBeginEnd) {
947 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
948 "glGetVertexAttribPointervNV called in Begin/End");
949 return;
950 }
951
952 if (index >= CR_MAX_VERTEX_ATTRIBS) {
953 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
954 "glGetVertexAttribPointervNV(index)");
955 return;
956 }
957
958 if (pname != GL_ATTRIB_ARRAY_POINTER_NV) {
959 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
960 "glGetVertexAttribPointervNV(pname)");
961 return;
962 }
963
964 *pointer = g->client.array.a[index].p;
965}
966
967
968void STATE_APIENTRY crStateGetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
969{
970 crStateGetVertexAttribPointervNV(index, pname, pointer);
971}
972
973
974
975/*
976** Currently I treat Interleaved Arrays as if the
977** user uses them as separate arrays.
978** Certainly not the most efficient method but it
979** lets me use the same glDrawArrays method.
980*/
981void STATE_APIENTRY crStateInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *p)
982{
983 CRContext *g = GetCurrentContext();
984 CRClientState *c = &(g->client);
985 CRStateBits *sb = GetCurrentBits();
986 CRClientBits *cb = &(sb->client);
987 CRClientPointer *cp;
988 unsigned char *base = (unsigned char *) p;
989
990 if (g->current.inBeginEnd)
991 {
992 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glInterleavedArrays called in begin/end");
993 return;
994 }
995
996 FLUSH();
997
998 if (stride < 0)
999 {
1000 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glInterleavedArrays: stride < 0: %d", stride);
1001 return;
1002 }
1003
1004 switch (format)
1005 {
1006 case GL_T4F_C4F_N3F_V4F:
1007 case GL_T2F_C4F_N3F_V3F:
1008 case GL_C4F_N3F_V3F:
1009 case GL_T4F_V4F:
1010 case GL_T2F_C3F_V3F:
1011 case GL_T2F_N3F_V3F:
1012 case GL_C3F_V3F:
1013 case GL_N3F_V3F:
1014 case GL_T2F_C4UB_V3F:
1015 case GL_T2F_V3F:
1016 case GL_C4UB_V3F:
1017 case GL_V3F:
1018 case GL_C4UB_V2F:
1019 case GL_V2F:
1020 break;
1021 default:
1022 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glInterleavedArrays: Unrecognized format: %d", format);
1023 return;
1024 }
1025
1026 DIRTY(cb->dirty, g->neg_bitid);
1027 DIRTY(cb->clientPointer, g->neg_bitid);
1028
1029/* p, size, type, stride, enabled, bytesPerIndex */
1030/*
1031** VertexPointer
1032*/
1033
1034 cp = &(c->array.v);
1035 cp->type = GL_FLOAT;
1036 cp->enabled = GL_TRUE;
1037
1038#ifdef CR_EXT_compiled_vertex_array
1039 crStateUnlockClientPointer(cp);
1040#endif
1041
1042 switch (format)
1043 {
1044 case GL_T4F_C4F_N3F_V4F:
1045 cp->p = base+4*sizeof(GLfloat)+4*sizeof(GLfloat)+3*sizeof(GLfloat);
1046 cp->size = 4;
1047 break;
1048 case GL_T2F_C4F_N3F_V3F:
1049 cp->p = base+2*sizeof(GLfloat)+4*sizeof(GLfloat)+3*sizeof(GLfloat);
1050 cp->size = 3;
1051 break;
1052 case GL_C4F_N3F_V3F:
1053 cp->p = base+4*sizeof(GLfloat)+3*sizeof(GLfloat);
1054 cp->size = 3;
1055 break;
1056 case GL_T4F_V4F:
1057 cp->p = base+4*sizeof(GLfloat);
1058 cp->size = 4;
1059 break;
1060 case GL_T2F_C3F_V3F:
1061 cp->p = base+2*sizeof(GLfloat)+3*sizeof(GLfloat);
1062 cp->size = 3;
1063 break;
1064 case GL_T2F_N3F_V3F:
1065 cp->p = base+2*sizeof(GLfloat)+3*sizeof(GLfloat);
1066 cp->size = 3;
1067 break;
1068 case GL_C3F_V3F:
1069 cp->p = base+3*sizeof(GLfloat);
1070 cp->size = 3;
1071 break;
1072 case GL_N3F_V3F:
1073 cp->p = base+3*sizeof(GLfloat);
1074 cp->size = 3;
1075 break;
1076 case GL_T2F_C4UB_V3F:
1077 cp->p = base+2*sizeof(GLfloat)+4*sizeof(GLubyte);
1078 cp->size = 3;
1079 break;
1080 case GL_T2F_V3F:
1081 cp->p = base+2*sizeof(GLfloat);
1082 cp->size = 3;
1083 break;
1084 case GL_C4UB_V3F:
1085 cp->p = base+4*sizeof(GLubyte);
1086 cp->size = 3;
1087 break;
1088 case GL_V3F:
1089 cp->p = base;
1090 cp->size = 3;
1091 break;
1092 case GL_C4UB_V2F:
1093 cp->p = base+4*sizeof(GLubyte);
1094 cp->size = 2;
1095 break;
1096 case GL_V2F:
1097 cp->p = base;
1098 cp->size = 2;
1099 break;
1100 default:
1101 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glInterleavedArrays: Unrecognized format: %d", format);
1102 return;
1103 }
1104
1105 cp->bytesPerIndex = cp->size * sizeof (GLfloat);
1106
1107 if (stride==0)
1108 stride = cp->bytesPerIndex + (cp->p - base);
1109 cp->stride = stride;
1110
1111/*
1112** NormalPointer
1113*/
1114
1115 cp = &(c->array.n);
1116 cp->enabled = GL_TRUE;
1117 cp->stride = stride;
1118#ifdef CR_EXT_compiled_vertex_array
1119 crStateUnlockClientPointer(cp);
1120#endif
1121
1122 switch (format)
1123 {
1124 case GL_T4F_C4F_N3F_V4F:
1125 cp->p = base+4*sizeof(GLfloat)+4*sizeof(GLfloat);
1126 break;
1127 case GL_T2F_C4F_N3F_V3F:
1128 cp->p = base+2*sizeof(GLfloat)+4*sizeof(GLfloat);
1129 break;
1130 case GL_C4F_N3F_V3F:
1131 cp->p = base+4*sizeof(GLfloat);
1132 break;
1133 case GL_T2F_N3F_V3F:
1134 cp->p = base+2*sizeof(GLfloat);
1135 break;
1136 case GL_N3F_V3F:
1137 cp->p = base;
1138 break;
1139 case GL_T4F_V4F:
1140 case GL_T2F_C3F_V3F:
1141 case GL_C3F_V3F:
1142 case GL_T2F_C4UB_V3F:
1143 case GL_T2F_V3F:
1144 case GL_C4UB_V3F:
1145 case GL_V3F:
1146 case GL_C4UB_V2F:
1147 case GL_V2F:
1148 cp->enabled = GL_FALSE;
1149 break;
1150 default:
1151 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glInterleavedArrays: Unrecognized format: %d", format);
1152 return;
1153 }
1154
1155 if (cp->enabled)
1156 {
1157 cp->type = GL_FLOAT;
1158 cp->size = 3;
1159 cp->bytesPerIndex = cp->size * sizeof (GLfloat);
1160 }
1161
1162/*
1163** ColorPointer
1164*/
1165
1166 cp = &(c->array.c);
1167 cp->enabled = GL_TRUE;
1168 cp->stride = stride;
1169#ifdef CR_EXT_compiled_vertex_array
1170 crStateUnlockClientPointer(cp);
1171#endif
1172
1173 switch (format)
1174 {
1175 case GL_T4F_C4F_N3F_V4F:
1176 cp->size = 4;
1177 cp->type = GL_FLOAT;
1178 cp->bytesPerIndex = cp->size * sizeof(GLfloat);
1179 cp->p = base+4*sizeof(GLfloat);
1180 break;
1181 case GL_T2F_C4F_N3F_V3F:
1182 cp->size = 4;
1183 cp->type = GL_FLOAT;
1184 cp->bytesPerIndex = cp->size * sizeof(GLfloat);
1185 cp->p = base+2*sizeof(GLfloat);
1186 break;
1187 case GL_C4F_N3F_V3F:
1188 cp->size = 4;
1189 cp->type = GL_FLOAT;
1190 cp->bytesPerIndex = cp->size * sizeof(GLfloat);
1191 cp->p = base;
1192 break;
1193 case GL_T2F_C3F_V3F:
1194 cp->size = 3;
1195 cp->type = GL_FLOAT;
1196 cp->bytesPerIndex = cp->size * sizeof(GLfloat);
1197 cp->p = base+2*sizeof(GLfloat);
1198 break;
1199 case GL_C3F_V3F:
1200 cp->size = 3;
1201 cp->type = GL_FLOAT;
1202 cp->bytesPerIndex = cp->size * sizeof(GLfloat);
1203 cp->p = base;
1204 break;
1205 case GL_T2F_C4UB_V3F:
1206 cp->size = 4;
1207 cp->type = GL_UNSIGNED_BYTE;
1208 cp->bytesPerIndex = cp->size * sizeof(GLubyte);
1209 cp->p = base+2*sizeof(GLfloat);
1210 break;
1211 case GL_C4UB_V3F:
1212 cp->size = 4;
1213 cp->type = GL_UNSIGNED_BYTE;
1214 cp->bytesPerIndex = cp->size * sizeof(GLubyte);
1215 cp->p = base;
1216 break;
1217 case GL_C4UB_V2F:
1218 cp->size = 4;
1219 cp->type = GL_UNSIGNED_BYTE;
1220 cp->bytesPerIndex = cp->size * sizeof(GLubyte);
1221 cp->p = base;
1222 break;
1223 case GL_T2F_N3F_V3F:
1224 case GL_N3F_V3F:
1225 case GL_T4F_V4F:
1226 case GL_T2F_V3F:
1227 case GL_V3F:
1228 case GL_V2F:
1229 cp->enabled = GL_FALSE;
1230 break;
1231 default:
1232 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glInterleavedArrays: Unrecognized format: %d", format);
1233 return;
1234 }
1235
1236/*
1237** TexturePointer
1238*/
1239
1240 cp = &(c->array.t[c->curClientTextureUnit]);
1241 cp->enabled = GL_TRUE;
1242 cp->stride = stride;
1243#ifdef CR_EXT_compiled_vertex_array
1244 crStateUnlockClientPointer(cp);
1245#endif
1246
1247 switch (format)
1248 {
1249 case GL_T4F_C4F_N3F_V4F:
1250 cp->size = 4;
1251 cp->p = base;
1252 break;
1253 case GL_T2F_C4F_N3F_V3F:
1254 cp->size = 3;
1255 cp->p = base;
1256 break;
1257 case GL_T2F_C3F_V3F:
1258 case GL_T2F_N3F_V3F:
1259 cp->size = 3;
1260 cp->p = base;
1261 break;
1262 case GL_T2F_C4UB_V3F:
1263 cp->size = 3;
1264 cp->p = base;
1265 break;
1266 case GL_T4F_V4F:
1267 cp->size = 4;
1268 cp->p = base;
1269 break;
1270 case GL_T2F_V3F:
1271 cp->size = 3;
1272 cp->p = base;
1273 break;
1274 case GL_C4UB_V3F:
1275 case GL_C4UB_V2F:
1276 case GL_C3F_V3F:
1277 case GL_C4F_N3F_V3F:
1278 case GL_N3F_V3F:
1279 case GL_V3F:
1280 case GL_V2F:
1281 cp->enabled = GL_FALSE;
1282 break;
1283 default:
1284 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glInterleavedArrays: Unrecognized format: %d", format);
1285 return;
1286 }
1287
1288 if (cp->enabled)
1289 {
1290 cp->type = GL_FLOAT;
1291 cp->bytesPerIndex = cp->size * sizeof (GLfloat);
1292 }
1293}
1294
1295void STATE_APIENTRY crStateGetPointerv(GLenum pname, GLvoid * * params)
1296{
1297 CRContext *g = GetCurrentContext();
1298 CRClientState *c = &(g->client);
1299
1300 if (g->current.inBeginEnd)
1301 {
1302 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1303 "GetPointerv called in begin/end");
1304 return;
1305 }
1306
1307 switch (pname)
1308 {
1309 case GL_VERTEX_ARRAY_POINTER:
1310 *params = (GLvoid *) c->array.v.p;
1311 break;
1312 case GL_COLOR_ARRAY_POINTER:
1313 *params = (GLvoid *) c->array.c.p;
1314 break;
1315 case GL_NORMAL_ARRAY_POINTER:
1316 *params = (GLvoid *) c->array.n.p;
1317 break;
1318 case GL_INDEX_ARRAY_POINTER:
1319 *params = (GLvoid *) c->array.i.p;
1320 break;
1321 case GL_TEXTURE_COORD_ARRAY_POINTER:
1322 *params = (GLvoid *) c->array.t[c->curClientTextureUnit].p;
1323 break;
1324 case GL_EDGE_FLAG_ARRAY_POINTER:
1325 *params = (GLvoid *) c->array.e.p;
1326 break;
1327#ifdef CR_EXT_fog_coord
1328 case GL_FOG_COORDINATE_ARRAY_POINTER_EXT:
1329 *params = (GLvoid *) c->array.f.p;
1330 break;
1331#endif
1332#ifdef CR_EXT_secondary_color
1333 case GL_SECONDARY_COLOR_ARRAY_POINTER_EXT:
1334 if( g->extensions.EXT_secondary_color ){
1335 *params = (GLvoid *) c->array.s.p;
1336 }
1337 else {
1338 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "Invalid Enum passed to glGetPointerv: SECONDARY_COLOR_ARRAY_EXT - EXT_secondary_color is not enabled." );
1339 return;
1340 }
1341 break;
1342#endif
1343 case GL_FEEDBACK_BUFFER_POINTER:
1344 case GL_SELECTION_BUFFER_POINTER:
1345 /* do nothing - API switching should pick this up */
1346 break;
1347 default:
1348 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1349 "glGetPointerv: invalid pname: %d", pname);
1350 return;
1351 }
1352}
1353
1354
1355void STATE_APIENTRY crStatePushClientAttrib( GLbitfield mask )
1356{
1357 CRContext *g = GetCurrentContext();
1358 CRClientState *c = &(g->client);
1359
1360 if (g->current.inBeginEnd) {
1361 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1362 "glPushClientAttrib called in Begin/End");
1363 return;
1364 }
1365
1366 if (c->attribStackDepth == CR_MAX_CLIENT_ATTRIB_STACK_DEPTH - 1) {
1367 crStateError(__LINE__, __FILE__, GL_STACK_OVERFLOW,
1368 "glPushClientAttrib called with a full stack!" );
1369 return;
1370 }
1371
1372 FLUSH();
1373
1374 c->pushMaskStack[c->attribStackDepth++] = mask;
1375
1376 if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
1377 c->pixelPackStoreStack[c->pixelStoreStackDepth] = c->pack;
1378 c->pixelUnpackStoreStack[c->pixelStoreStackDepth] = c->unpack;
1379 c->pixelStoreStackDepth++;
1380 }
1381 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
1382 c->vertexArrayStack[c->vertexArrayStackDepth] = c->array;
1383 c->vertexArrayStackDepth++;
1384 }
1385
1386 /* dirty? - no, because we haven't really changed any state */
1387}
1388
1389
1390void STATE_APIENTRY crStatePopClientAttrib( void )
1391{
1392 CRContext *g = GetCurrentContext();
1393 CRClientState *c = &(g->client);
1394 CRStateBits *sb = GetCurrentBits();
1395 CRClientBits *cb = &(sb->client);
1396 CRbitvalue mask;
1397
1398 if (g->current.inBeginEnd) {
1399 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1400 "glPopClientAttrib called in Begin/End");
1401 return;
1402 }
1403
1404 if (c->attribStackDepth == 0) {
1405 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW,
1406 "glPopClientAttrib called with an empty stack!" );
1407 return;
1408 }
1409
1410 FLUSH();
1411
1412 mask = c->pushMaskStack[--c->attribStackDepth];
1413
1414 if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
1415 if (c->pixelStoreStackDepth == 0) {
1416 crError("bug in glPopClientAttrib (pixel store) ");
1417 return;
1418 }
1419 c->pixelStoreStackDepth--;
1420 c->pack = c->pixelPackStoreStack[c->pixelStoreStackDepth];
1421 c->unpack = c->pixelUnpackStoreStack[c->pixelStoreStackDepth];
1422 DIRTY(cb->pack, g->neg_bitid);
1423 }
1424
1425 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
1426 if (c->vertexArrayStackDepth == 0) {
1427 crError("bug in glPopClientAttrib (vertex array) ");
1428 return;
1429 }
1430 c->vertexArrayStackDepth--;
1431 c->array = c->vertexArrayStack[c->vertexArrayStackDepth];
1432 DIRTY(cb->clientPointer, g->neg_bitid);
1433 }
1434
1435 DIRTY(cb->dirty, g->neg_bitid);
1436}
1437
1438static void crStateLockClientPointer(CRClientPointer* cp)
1439{
1440 crStateUnlockClientPointer(cp);
1441 if (cp->enabled)
1442 {
1443 cp->locked = GL_TRUE;
1444 }
1445}
1446
1447static GLboolean crStateCanLockClientPointer(CRClientPointer* cp)
1448{
1449 return !(cp->enabled && cp->buffer && cp->buffer->id);
1450}
1451
1452void STATE_APIENTRY crStateLockArraysEXT(GLint first, GLint count)
1453{
1454 CRContext *g = GetCurrentContext();
1455 CRClientState *c = &(g->client);
1456 int i;
1457
1458 for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
1459 {
1460 if (!crStateCanLockClientPointer(crStateGetClientPointerByIndex(i, &c->array)))
1461 {
1462 break;
1463 }
1464 }
1465 if (i<CRSTATECLIENT_MAX_VERTEXARRAYS)
1466 {
1467 crDebug("crStateLockArraysEXT ignored because array %i have a bound VBO", i);
1468 return;
1469 }
1470
1471 c->array.locked = GL_TRUE;
1472 c->array.lockFirst = first;
1473 c->array.lockCount = count;
1474#ifdef IN_GUEST
1475 c->array.synced = GL_FALSE;
1476#endif
1477
1478 for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
1479 {
1480 crStateLockClientPointer(crStateGetClientPointerByIndex(i, &c->array));
1481 }
1482}
1483
1484void STATE_APIENTRY crStateUnlockArraysEXT()
1485{
1486 CRContext *g = GetCurrentContext();
1487 CRClientState *c = &(g->client);
1488 int i;
1489
1490 if (!c->array.locked)
1491 {
1492 crDebug("crStateUnlockArraysEXT ignored because arrays aren't locked");
1493 return;
1494 }
1495
1496 c->array.locked = GL_FALSE;
1497#ifdef IN_GUEST
1498 c->array.synced = GL_FALSE;
1499#endif
1500
1501 for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
1502 {
1503 crStateUnlockClientPointer(crStateGetClientPointerByIndex(i, &c->array));
1504 }
1505}
1506
1507void STATE_APIENTRY crStateVertexArrayRangeNV(GLsizei length, const GLvoid *pointer)
1508{
1509 /* XXX todo */
1510 crWarning("crStateVertexArrayRangeNV not implemented");
1511}
1512
1513
1514void STATE_APIENTRY crStateFlushVertexArrayRangeNV(void)
1515{
1516 /* XXX todo */
1517 crWarning("crStateFlushVertexArrayRangeNV not implemented");
1518}
1519
1520/*Returns if the given clientpointer could be used on server side directly*/
1521#define CRSTATE_IS_SERVER_CP(cp) (!(cp).enabled || !(cp).p || ((cp).buffer && (cp).buffer->id) || ((cp).locked))
1522
1523static void crStateDumpClientPointer(CRClientPointer *cp, const char *name, int i)
1524{
1525 if (i<0 && cp->enabled)
1526 {
1527 crDebug("CP(%s): enabled:%d ptr:%p buffer:%p buffer.name:%i locked: %i %s",
1528 name, cp->enabled, cp->p, cp->buffer, cp->buffer? cp->buffer->id:-1, (int)cp->locked,
1529 CRSTATE_IS_SERVER_CP(*cp) ? "":"!FAIL!");
1530 }
1531 else if (0==i || cp->enabled)
1532 {
1533 crDebug("CP(%s%i): enabled:%d ptr:%p buffer:%p buffer.name:%i locked: %i %s",
1534 name, i, cp->enabled, cp->p, cp->buffer, cp->buffer? cp->buffer->id:-1, (int)cp->locked,
1535 CRSTATE_IS_SERVER_CP(*cp) ? "":"!FAIL!");
1536 }
1537}
1538
1539/*
1540 * Determine if the enabled arrays all live on the server
1541 * (via GL_ARB_vertex_buffer_object).
1542 */
1543GLboolean crStateUseServerArrays(void)
1544{
1545#ifdef CR_ARB_vertex_buffer_object
1546 CRContext *g = GetCurrentContext();
1547 CRClientState *c = &(g->client);
1548 int i;
1549 GLboolean res;
1550
1551 res = CRSTATE_IS_SERVER_CP(c->array.v)
1552 && CRSTATE_IS_SERVER_CP(c->array.n)
1553 && CRSTATE_IS_SERVER_CP(c->array.c)
1554 && CRSTATE_IS_SERVER_CP(c->array.i)
1555 && CRSTATE_IS_SERVER_CP(c->array.e)
1556 && CRSTATE_IS_SERVER_CP(c->array.s)
1557 && CRSTATE_IS_SERVER_CP(c->array.f);
1558
1559 if (res)
1560 {
1561 for (i = 0; (unsigned int)i < g->limits.maxTextureUnits; i++)
1562 if (!CRSTATE_IS_SERVER_CP(c->array.t[i]))
1563 {
1564 res = GL_FALSE;
1565 break;
1566 }
1567 }
1568
1569 if (res)
1570 {
1571 for (i = 0; (unsigned int)i < g->limits.maxVertexProgramAttribs; i++)
1572 if (!CRSTATE_IS_SERVER_CP(c->array.a[i]))
1573 {
1574 res = GL_FALSE;
1575 break;
1576 }
1577 }
1578
1579#if defined(DEBUG) && 0
1580 if (!res)
1581 {
1582 crStateDumpClientPointer(&c->array.v, "v", -1);
1583 crStateDumpClientPointer(&c->array.n, "n", -1);
1584 crStateDumpClientPointer(&c->array.c, "c", -1);
1585 crStateDumpClientPointer(&c->array.i, "i", -1);
1586 crStateDumpClientPointer(&c->array.e, "e", -1);
1587 crStateDumpClientPointer(&c->array.s, "s", -1);
1588 crStateDumpClientPointer(&c->array.f, "f", -1);
1589 for (i = 0; (unsigned int)i < g->limits.maxTextureUnits; i++)
1590 crStateDumpClientPointer(&c->array.t[i], "tex", i);
1591 for (i = 0; (unsigned int)i < g->limits.maxVertexProgramAttribs; i++)
1592 crStateDumpClientPointer(&c->array.a[i], "attrib", i);
1593 crDebug("crStateUseServerArrays->%d", res);
1594 }
1595#endif
1596
1597 return res;
1598#else
1599 return GL_FALSE;
1600#endif
1601}
1602
1603
1604/**
1605 * Determine if there's a server-side array element buffer.
1606 * Called by glDrawElements() in packing SPUs to determine if glDrawElements
1607 * should be evaluated (unrolled) locally or if glDrawElements should be
1608 * packed and sent to the server.
1609 */
1610GLboolean
1611crStateUseServerArrayElements(void)
1612{
1613#ifdef CR_ARB_vertex_buffer_object
1614 CRContext *g = GetCurrentContext();
1615 if (g->bufferobject.elementsBuffer &&
1616 g->bufferobject.elementsBuffer->id > 0)
1617 return GL_TRUE;
1618 else
1619 return GL_FALSE;
1620#else
1621 return GL_FALSE;
1622#endif
1623}
1624
1625
1626void
1627crStateClientDiff(CRClientBits *cb, CRbitvalue *bitID,
1628 CRContext *fromCtx, CRContext *toCtx)
1629{
1630 CRClientState *from = &(fromCtx->client);
1631 const CRClientState *to = &(toCtx->client);
1632 GLint curClientTextureUnit = from->curClientTextureUnit;
1633 int i;
1634
1635 if (CHECKDIRTY(cb->clientPointer, bitID)) {
1636 /* one or more vertex pointers is dirty */
1637 if (CHECKDIRTY(cb->v, bitID)) {
1638 if (from->array.v.size != to->array.v.size ||
1639 from->array.v.type != to->array.v.type ||
1640 from->array.v.stride != to->array.v.stride ||
1641 from->array.v.buffer != to->array.v.buffer) {
1642 diff_api.VertexPointer(to->array.v.size, to->array.v.type,
1643 to->array.v.stride, to->array.v.p);
1644 from->array.v.size = to->array.v.size;
1645 from->array.v.type = to->array.v.type;
1646 from->array.v.stride = to->array.v.stride;
1647 from->array.v.p = to->array.v.p;
1648 from->array.v.buffer = to->array.v.buffer;
1649 }
1650 CLEARDIRTY2(cb->v, bitID);
1651 }
1652 /* normal */
1653 if (CHECKDIRTY(cb->n, bitID)) {
1654 if (from->array.n.type != to->array.n.type ||
1655 from->array.n.stride != to->array.n.stride ||
1656 from->array.n.buffer != to->array.n.buffer) {
1657 diff_api.NormalPointer(to->array.n.type,
1658 to->array.n.stride, to->array.n.p);
1659 from->array.n.type = to->array.n.type;
1660 from->array.n.stride = to->array.n.stride;
1661 from->array.n.p = to->array.n.p;
1662 from->array.n.buffer = to->array.n.buffer;
1663 }
1664 CLEARDIRTY2(cb->n, bitID);
1665 }
1666 /* color */
1667 if (CHECKDIRTY(cb->c, bitID)) {
1668 if (from->array.c.size != to->array.c.size ||
1669 from->array.c.type != to->array.c.type ||
1670 from->array.c.stride != to->array.c.stride ||
1671 from->array.c.buffer != to->array.c.buffer) {
1672 diff_api.ColorPointer(to->array.c.size, to->array.c.type,
1673 to->array.c.stride, to->array.c.p);
1674 from->array.c.size = to->array.c.size;
1675 from->array.c.type = to->array.c.type;
1676 from->array.c.stride = to->array.c.stride;
1677 from->array.c.p = to->array.c.p;
1678 from->array.c.buffer = to->array.c.buffer;
1679 }
1680 CLEARDIRTY2(cb->c, bitID);
1681 }
1682 /* index */
1683 if (CHECKDIRTY(cb->i, bitID)) {
1684 if (from->array.i.type != to->array.i.type ||
1685 from->array.i.stride != to->array.i.stride ||
1686 from->array.i.buffer != to->array.i.buffer) {
1687 diff_api.IndexPointer(to->array.i.type,
1688 to->array.i.stride, to->array.i.p);
1689 from->array.i.type = to->array.i.type;
1690 from->array.i.stride = to->array.i.stride;
1691 from->array.i.p = to->array.i.p;
1692 from->array.i.buffer = to->array.i.buffer;
1693 }
1694 CLEARDIRTY2(cb->i, bitID);
1695 }
1696 /* texcoords */
1697 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
1698 if (CHECKDIRTY(cb->t[i], bitID)) {
1699 if (from->array.t[i].size != to->array.t[i].size ||
1700 from->array.t[i].type != to->array.t[i].type ||
1701 from->array.t[i].stride != to->array.t[i].stride ||
1702 from->array.t[i].buffer != to->array.t[i].buffer) {
1703 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
1704 curClientTextureUnit = i;
1705 diff_api.TexCoordPointer(to->array.t[i].size, to->array.t[i].type,
1706 to->array.t[i].stride, to->array.t[i].p);
1707 from->array.t[i].size = to->array.t[i].size;
1708 from->array.t[i].type = to->array.t[i].type;
1709 from->array.t[i].stride = to->array.t[i].stride;
1710 from->array.t[i].p = to->array.t[i].p;
1711 from->array.t[i].buffer = to->array.t[i].buffer;
1712 }
1713 CLEARDIRTY2(cb->t[i], bitID);
1714 }
1715 }
1716 /* edge flag */
1717 if (CHECKDIRTY(cb->e, bitID)) {
1718 if (from->array.e.stride != to->array.e.stride ||
1719 from->array.e.buffer != to->array.e.buffer) {
1720 diff_api.EdgeFlagPointer(to->array.e.stride, to->array.e.p);
1721 from->array.e.stride = to->array.e.stride;
1722 from->array.e.p = to->array.e.p;
1723 from->array.e.buffer = to->array.e.buffer;
1724 }
1725 CLEARDIRTY2(cb->e, bitID);
1726 }
1727 /* secondary color */
1728 if (CHECKDIRTY(cb->s, bitID)) {
1729 if (from->array.s.size != to->array.s.size ||
1730 from->array.s.type != to->array.s.type ||
1731 from->array.s.stride != to->array.s.stride ||
1732 from->array.s.buffer != to->array.s.buffer) {
1733 diff_api.SecondaryColorPointerEXT(to->array.s.size, to->array.s.type,
1734 to->array.s.stride, to->array.s.p);
1735 from->array.s.size = to->array.s.size;
1736 from->array.s.type = to->array.s.type;
1737 from->array.s.stride = to->array.s.stride;
1738 from->array.s.p = to->array.s.p;
1739 from->array.s.buffer = to->array.s.buffer;
1740 }
1741 CLEARDIRTY2(cb->s, bitID);
1742 }
1743 /* fog coord */
1744 if (CHECKDIRTY(cb->f, bitID)) {
1745 if (from->array.f.type != to->array.f.type ||
1746 from->array.f.stride != to->array.f.stride ||
1747 from->array.f.buffer != to->array.f.buffer) {
1748 diff_api.FogCoordPointerEXT(to->array.f.type,
1749 to->array.f.stride, to->array.f.p);
1750 from->array.f.type = to->array.f.type;
1751 from->array.f.stride = to->array.f.stride;
1752 from->array.f.p = to->array.f.p;
1753 from->array.f.buffer = to->array.f.buffer;
1754 }
1755 CLEARDIRTY2(cb->f, bitID);
1756 }
1757#if defined(CR_NV_vertex_program) || defined(CR_ARB_vertex_program)
1758 /* vertex attributes */
1759 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
1760 if (CHECKDIRTY(cb->a[i], bitID)) {
1761 if (from->array.a[i].size != to->array.a[i].size ||
1762 from->array.a[i].type != to->array.a[i].type ||
1763 from->array.a[i].stride != to->array.a[i].stride ||
1764 from->array.a[i].normalized != to->array.a[i].normalized ||
1765 from->array.a[i].buffer != to->array.a[i].buffer) {
1766 diff_api.VertexAttribPointerARB(i, to->array.a[i].size,
1767 to->array.a[i].type,
1768 to->array.a[i].normalized,
1769 to->array.a[i].stride,
1770 to->array.a[i].p);
1771 from->array.a[i].size = to->array.a[i].size;
1772 from->array.a[i].type = to->array.a[i].type;
1773 from->array.a[i].stride = to->array.a[i].stride;
1774 from->array.a[i].normalized = to->array.a[i].normalized;
1775 from->array.a[i].p = to->array.a[i].p;
1776 from->array.a[i].buffer = to->array.a[i].buffer;
1777 }
1778 CLEARDIRTY2(cb->a[i], bitID);
1779 }
1780 }
1781#endif
1782 }
1783
1784 if (CHECKDIRTY(cb->enableClientState, bitID)) {
1785 /* update vertex array enable/disable flags */
1786 glAble able[2];
1787 able[0] = diff_api.Disable;
1788 able[1] = diff_api.Enable;
1789 if (from->array.v.enabled != to->array.v.enabled) {
1790 able[to->array.v.enabled](GL_VERTEX_ARRAY);
1791 from->array.v.enabled = to->array.v.enabled;
1792 }
1793 if (from->array.n.enabled != to->array.n.enabled) {
1794 able[to->array.n.enabled](GL_NORMAL_ARRAY);
1795 from->array.n.enabled = to->array.n.enabled;
1796 }
1797 if (from->array.c.enabled != to->array.c.enabled) {
1798 able[to->array.c.enabled](GL_COLOR_ARRAY);
1799 from->array.c.enabled = to->array.c.enabled;
1800 }
1801 if (from->array.i.enabled != to->array.i.enabled) {
1802 able[to->array.i.enabled](GL_INDEX_ARRAY);
1803 from->array.i.enabled = to->array.i.enabled;
1804 }
1805 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
1806 if (from->array.t[i].enabled != to->array.t[i].enabled) {
1807 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
1808 curClientTextureUnit = i;
1809 able[to->array.t[i].enabled](GL_TEXTURE_COORD_ARRAY);
1810 from->array.t[i].enabled = to->array.t[i].enabled;
1811 }
1812 }
1813 if (from->array.e.enabled != to->array.e.enabled) {
1814 able[to->array.e.enabled](GL_EDGE_FLAG_ARRAY);
1815 from->array.e.enabled = to->array.e.enabled;
1816 }
1817 if (from->array.s.enabled != to->array.s.enabled) {
1818 able[to->array.s.enabled](GL_SECONDARY_COLOR_ARRAY_EXT);
1819 from->array.s.enabled = to->array.s.enabled;
1820 }
1821 if (from->array.f.enabled != to->array.f.enabled) {
1822 able[to->array.f.enabled](GL_FOG_COORDINATE_ARRAY_EXT);
1823 from->array.f.enabled = to->array.f.enabled;
1824 }
1825 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
1826 if (from->array.a[i].enabled != to->array.a[i].enabled) {
1827 if (to->array.a[i].enabled)
1828 diff_api.EnableVertexAttribArrayARB(i);
1829 else
1830 diff_api.DisableVertexAttribArrayARB(i);
1831 from->array.a[i].enabled = to->array.a[i].enabled;
1832 }
1833 }
1834 CLEARDIRTY2(cb->enableClientState, bitID);
1835 }
1836
1837 if (to->curClientTextureUnit != curClientTextureUnit)
1838 {
1839 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + to->curClientTextureUnit);
1840 }
1841}
1842
1843
1844void
1845crStateClientSwitch(CRClientBits *cb, CRbitvalue *bitID,
1846 CRContext *fromCtx, CRContext *toCtx)
1847{
1848 const CRClientState *from = &(fromCtx->client);
1849 const CRClientState *to = &(toCtx->client);
1850 GLint curClientTextureUnit = from->curClientTextureUnit;
1851 int i;
1852
1853 if (CHECKDIRTY(cb->clientPointer, bitID)) {
1854 /* one or more vertex pointers is dirty */
1855 if (CHECKDIRTY(cb->v, bitID)) {
1856 if (from->array.v.size != to->array.v.size ||
1857 from->array.v.type != to->array.v.type ||
1858 from->array.v.stride != to->array.v.stride ||
1859 from->array.v.buffer != to->array.v.buffer) {
1860 diff_api.VertexPointer(to->array.v.size, to->array.v.type,
1861 to->array.v.stride, to->array.v.p);
1862 FILLDIRTY(cb->v);
1863 FILLDIRTY(cb->clientPointer);
1864 FILLDIRTY(cb->dirty);
1865 }
1866 CLEARDIRTY2(cb->v, bitID);
1867 }
1868 /* normal */
1869 if (CHECKDIRTY(cb->n, bitID)) {
1870 if (from->array.n.type != to->array.n.type ||
1871 from->array.n.stride != to->array.n.stride ||
1872 from->array.n.buffer != to->array.n.buffer) {
1873 diff_api.NormalPointer(to->array.n.type,
1874 to->array.n.stride, to->array.n.p);
1875 FILLDIRTY(cb->n);
1876 FILLDIRTY(cb->clientPointer);
1877 FILLDIRTY(cb->dirty);
1878 }
1879 CLEARDIRTY2(cb->n, bitID);
1880 }
1881 /* color */
1882 if (CHECKDIRTY(cb->c, bitID)) {
1883 if (from->array.c.size != to->array.c.size ||
1884 from->array.c.type != to->array.c.type ||
1885 from->array.c.stride != to->array.c.stride ||
1886 from->array.c.buffer != to->array.c.buffer) {
1887 diff_api.ColorPointer(to->array.c.size, to->array.c.type,
1888 to->array.c.stride, to->array.c.p);
1889 FILLDIRTY(cb->c);
1890 FILLDIRTY(cb->clientPointer);
1891 FILLDIRTY(cb->dirty);
1892 }
1893 CLEARDIRTY2(cb->c, bitID);
1894 }
1895 /* index */
1896 if (CHECKDIRTY(cb->i, bitID)) {
1897 if (from->array.i.type != to->array.i.type ||
1898 from->array.i.stride != to->array.i.stride ||
1899 from->array.i.buffer != to->array.i.buffer) {
1900 diff_api.IndexPointer(to->array.i.type,
1901 to->array.i.stride, to->array.i.p);
1902 FILLDIRTY(cb->i);
1903 FILLDIRTY(cb->dirty);
1904 FILLDIRTY(cb->clientPointer);
1905 }
1906 CLEARDIRTY2(cb->i, bitID);
1907 }
1908 /* texcoords */
1909 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
1910 if (CHECKDIRTY(cb->t[i], bitID)) {
1911 if (from->array.t[i].size != to->array.t[i].size ||
1912 from->array.t[i].type != to->array.t[i].type ||
1913 from->array.t[i].stride != to->array.t[i].stride ||
1914 from->array.t[i].buffer != to->array.t[i].buffer) {
1915 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
1916 curClientTextureUnit = i;
1917 diff_api.TexCoordPointer(to->array.t[i].size, to->array.t[i].type,
1918 to->array.t[i].stride, to->array.t[i].p);
1919 FILLDIRTY(cb->t[i]);
1920 FILLDIRTY(cb->clientPointer);
1921 FILLDIRTY(cb->dirty);
1922 }
1923 CLEARDIRTY2(cb->t[i], bitID);
1924 }
1925 }
1926 /* edge flag */
1927 if (CHECKDIRTY(cb->e, bitID)) {
1928 if (from->array.e.stride != to->array.e.stride ||
1929 from->array.e.buffer != to->array.e.buffer) {
1930 diff_api.EdgeFlagPointer(to->array.e.stride, to->array.e.p);
1931 FILLDIRTY(cb->e);
1932 FILLDIRTY(cb->clientPointer);
1933 FILLDIRTY(cb->dirty);
1934 }
1935 CLEARDIRTY2(cb->e, bitID);
1936 }
1937 /* secondary color */
1938 if (CHECKDIRTY(cb->s, bitID)) {
1939 if (from->array.s.size != to->array.s.size ||
1940 from->array.s.type != to->array.s.type ||
1941 from->array.s.stride != to->array.s.stride ||
1942 from->array.s.buffer != to->array.s.buffer) {
1943 diff_api.SecondaryColorPointerEXT(to->array.s.size, to->array.s.type,
1944 to->array.s.stride, to->array.s.p);
1945 FILLDIRTY(cb->s);
1946 FILLDIRTY(cb->clientPointer);
1947 FILLDIRTY(cb->dirty);
1948 }
1949 CLEARDIRTY2(cb->s, bitID);
1950 }
1951 /* fog coord */
1952 if (CHECKDIRTY(cb->f, bitID)) {
1953 if (from->array.f.type != to->array.f.type ||
1954 from->array.f.stride != to->array.f.stride ||
1955 from->array.f.buffer != to->array.f.buffer) {
1956 diff_api.FogCoordPointerEXT(to->array.f.type,
1957 to->array.f.stride, to->array.f.p);
1958 FILLDIRTY(cb->f);
1959 FILLDIRTY(cb->clientPointer);
1960 FILLDIRTY(cb->dirty);
1961 }
1962 CLEARDIRTY2(cb->f, bitID);
1963 }
1964#if defined(CR_NV_vertex_program) || defined(CR_ARB_vertex_program)
1965 /* vertex attributes */
1966 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
1967 if (CHECKDIRTY(cb->a[i], bitID)) {
1968 if (from->array.a[i].size != to->array.a[i].size ||
1969 from->array.a[i].type != to->array.a[i].type ||
1970 from->array.a[i].stride != to->array.a[i].stride ||
1971 from->array.a[i].normalized != to->array.a[i].normalized ||
1972 from->array.a[i].buffer != to->array.a[i].buffer) {
1973 diff_api.VertexAttribPointerARB(i, to->array.a[i].size,
1974 to->array.a[i].type,
1975 to->array.a[i].normalized,
1976 to->array.a[i].stride,
1977 to->array.a[i].p);
1978 FILLDIRTY(cb->a[i]);
1979 FILLDIRTY(cb->clientPointer);
1980 FILLDIRTY(cb->dirty);
1981 }
1982 CLEARDIRTY2(cb->a[i], bitID);
1983 }
1984 }
1985#endif
1986 }
1987
1988 if (CHECKDIRTY(cb->enableClientState, bitID)) {
1989 /* update vertex array enable/disable flags */
1990 glAble able[2];
1991 able[0] = diff_api.Disable;
1992 able[1] = diff_api.Enable;
1993 if (from->array.v.enabled != to->array.v.enabled) {
1994 able[to->array.v.enabled](GL_VERTEX_ARRAY);
1995 FILLDIRTY(cb->enableClientState);
1996 FILLDIRTY(cb->dirty);
1997 }
1998 if (from->array.n.enabled != to->array.n.enabled) {
1999 able[to->array.n.enabled](GL_NORMAL_ARRAY);
2000 FILLDIRTY(cb->enableClientState);
2001 FILLDIRTY(cb->dirty);
2002 }
2003 if (from->array.c.enabled != to->array.c.enabled) {
2004 able[to->array.c.enabled](GL_COLOR_ARRAY);
2005 FILLDIRTY(cb->enableClientState);
2006 FILLDIRTY(cb->dirty);
2007 }
2008 if (from->array.i.enabled != to->array.i.enabled) {
2009 able[to->array.i.enabled](GL_INDEX_ARRAY);
2010 FILLDIRTY(cb->enableClientState);
2011 FILLDIRTY(cb->dirty);
2012 }
2013 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
2014 if (from->array.t[i].enabled != to->array.t[i].enabled) {
2015 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
2016 curClientTextureUnit = i;
2017 able[to->array.t[i].enabled](GL_TEXTURE_COORD_ARRAY);
2018 FILLDIRTY(cb->enableClientState);
2019 FILLDIRTY(cb->dirty);
2020 }
2021 }
2022 if (from->array.e.enabled != to->array.e.enabled) {
2023 able[to->array.e.enabled](GL_EDGE_FLAG_ARRAY);
2024 FILLDIRTY(cb->enableClientState);
2025 FILLDIRTY(cb->dirty);
2026 }
2027 if (from->array.s.enabled != to->array.s.enabled) {
2028 able[to->array.s.enabled](GL_SECONDARY_COLOR_ARRAY_EXT);
2029 FILLDIRTY(cb->enableClientState);
2030 FILLDIRTY(cb->dirty);
2031 }
2032 if (from->array.f.enabled != to->array.f.enabled) {
2033 able[to->array.f.enabled](GL_FOG_COORDINATE_ARRAY_EXT);
2034 FILLDIRTY(cb->enableClientState);
2035 FILLDIRTY(cb->dirty);
2036 }
2037 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
2038 if (from->array.a[i].enabled != to->array.a[i].enabled) {
2039 if (to->array.a[i].enabled)
2040 diff_api.EnableVertexAttribArrayARB(i);
2041 else
2042 diff_api.DisableVertexAttribArrayARB(i);
2043 FILLDIRTY(cb->enableClientState);
2044 FILLDIRTY(cb->dirty);
2045 }
2046 }
2047 CLEARDIRTY2(cb->enableClientState, bitID);
2048 }
2049
2050 if (to->curClientTextureUnit != curClientTextureUnit)
2051 {
2052 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + to->curClientTextureUnit);
2053 }
2054
2055 CLEARDIRTY2(cb->dirty, bitID);
2056}
2057
2058CRClientPointer* crStateGetClientPointerByIndex(int index, CRVertexArrays *array)
2059{
2060 CRASSERT(array && index>=0 && index<CRSTATECLIENT_MAX_VERTEXARRAYS);
2061
2062 if (index<7)
2063 {
2064 switch (index)
2065 {
2066 case 0: return &array->v;
2067 case 1: return &array->c;
2068 case 2: return &array->f;
2069 case 3: return &array->s;
2070 case 4: return &array->e;
2071 case 5: return &array->i;
2072 case 6: return &array->n;
2073 }
2074 }
2075 else if (index<(7+CR_MAX_TEXTURE_UNITS))
2076 {
2077 return &array->t[index-7];
2078 }
2079 else
2080 {
2081 return &array->a[index-7-CR_MAX_TEXTURE_UNITS];
2082 }
2083
2084 /*silence the compiler warning*/
2085 CRASSERT(false);
2086 return NULL;
2087}
Note: See TracBrowser for help on using the repository browser.

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