VirtualBox

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

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

crOpenGL: resource sharing between contexts

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 67.8 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
1447void STATE_APIENTRY crStateLockArraysEXT(GLint first, GLint count)
1448{
1449 CRContext *g = GetCurrentContext();
1450 CRClientState *c = &(g->client);
1451 unsigned int i;
1452
1453 c->array.locked = GL_TRUE;
1454 c->array.lockFirst = first;
1455 c->array.lockCount = count;
1456#ifdef IN_GUEST
1457 c->array.synced = GL_FALSE;
1458#endif
1459
1460 crStateLockClientPointer(&c->array.v);
1461 crStateLockClientPointer(&c->array.c);
1462 crStateLockClientPointer(&c->array.f);
1463 crStateLockClientPointer(&c->array.s);
1464 crStateLockClientPointer(&c->array.e);
1465 crStateLockClientPointer(&c->array.i);
1466 crStateLockClientPointer(&c->array.n);
1467 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
1468 {
1469 crStateLockClientPointer(&c->array.t[i]);
1470 }
1471 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
1472 {
1473 crStateLockClientPointer(&c->array.a[i]);
1474 }
1475}
1476
1477void STATE_APIENTRY crStateUnlockArraysEXT()
1478{
1479 CRContext *g = GetCurrentContext();
1480 CRClientState *c = &(g->client);
1481 unsigned int i;
1482
1483 c->array.locked = GL_FALSE;
1484#ifdef IN_GUEST
1485 c->array.synced = GL_FALSE;
1486#endif
1487
1488 crStateUnlockClientPointer(&c->array.v);
1489 crStateUnlockClientPointer(&c->array.c);
1490 crStateUnlockClientPointer(&c->array.f);
1491 crStateUnlockClientPointer(&c->array.s);
1492 crStateUnlockClientPointer(&c->array.e);
1493 crStateUnlockClientPointer(&c->array.i);
1494 crStateUnlockClientPointer(&c->array.n);
1495 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
1496 {
1497 crStateUnlockClientPointer(&c->array.t[i]);
1498 }
1499 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
1500 {
1501 crStateUnlockClientPointer(&c->array.a[i]);
1502 }
1503}
1504
1505void STATE_APIENTRY crStateVertexArrayRangeNV(GLsizei length, const GLvoid *pointer)
1506{
1507 /* XXX todo */
1508 crWarning("crStateVertexArrayRangeNV not implemented");
1509}
1510
1511
1512void STATE_APIENTRY crStateFlushVertexArrayRangeNV(void)
1513{
1514 /* XXX todo */
1515 crWarning("crStateFlushVertexArrayRangeNV not implemented");
1516}
1517
1518/*Returns if the given clientpointer could be used on server side directly*/
1519#define CRSTATE_IS_SERVER_CP(cp) (!(cp).enabled || !(cp).p || ((cp).buffer && (cp).buffer->id) || ((cp).locked))
1520
1521static void crStateDumpClientPointer(CRClientPointer *cp, const char *name, int i)
1522{
1523 if (i<0 && cp->enabled)
1524 {
1525 crDebug("CP(%s): enabled:%d ptr:%p buffer:%p buffer.name:%i locked: %i %s",
1526 name, cp->enabled, cp->p, cp->buffer, cp->buffer? cp->buffer->id:-1, (int)cp->locked,
1527 CRSTATE_IS_SERVER_CP(*cp) ? "":"!FAIL!");
1528 }
1529 else if (0==i || cp->enabled)
1530 {
1531 crDebug("CP(%s%i): enabled:%d ptr:%p buffer:%p buffer.name:%i locked: %i %s",
1532 name, i, cp->enabled, cp->p, cp->buffer, cp->buffer? cp->buffer->id:-1, (int)cp->locked,
1533 CRSTATE_IS_SERVER_CP(*cp) ? "":"!FAIL!");
1534 }
1535}
1536
1537/*
1538 * Determine if the enabled arrays all live on the server
1539 * (via GL_ARB_vertex_buffer_object).
1540 */
1541GLboolean crStateUseServerArrays(void)
1542{
1543#ifdef CR_ARB_vertex_buffer_object
1544 CRContext *g = GetCurrentContext();
1545 CRClientState *c = &(g->client);
1546 int i;
1547 GLboolean res;
1548
1549 res = CRSTATE_IS_SERVER_CP(c->array.v)
1550 && CRSTATE_IS_SERVER_CP(c->array.n)
1551 && CRSTATE_IS_SERVER_CP(c->array.c)
1552 && CRSTATE_IS_SERVER_CP(c->array.i)
1553 && CRSTATE_IS_SERVER_CP(c->array.e)
1554 && CRSTATE_IS_SERVER_CP(c->array.s)
1555 && CRSTATE_IS_SERVER_CP(c->array.f);
1556
1557 if (res)
1558 {
1559 for (i = 0; (unsigned int)i < g->limits.maxTextureUnits; i++)
1560 if (!CRSTATE_IS_SERVER_CP(c->array.t[i]))
1561 {
1562 res = GL_FALSE;
1563 break;
1564 }
1565 }
1566
1567 if (res)
1568 {
1569 for (i = 0; (unsigned int)i < g->limits.maxVertexProgramAttribs; i++)
1570 if (!CRSTATE_IS_SERVER_CP(c->array.a[i]))
1571 {
1572 res = GL_FALSE;
1573 break;
1574 }
1575 }
1576
1577#if defined(DEBUG) && 0
1578 if (!res)
1579 {
1580 crStateDumpClientPointer(&c->array.v, "v", -1);
1581 crStateDumpClientPointer(&c->array.n, "n", -1);
1582 crStateDumpClientPointer(&c->array.c, "c", -1);
1583 crStateDumpClientPointer(&c->array.i, "i", -1);
1584 crStateDumpClientPointer(&c->array.e, "e", -1);
1585 crStateDumpClientPointer(&c->array.s, "s", -1);
1586 crStateDumpClientPointer(&c->array.f, "f", -1);
1587 for (i = 0; (unsigned int)i < g->limits.maxTextureUnits; i++)
1588 crStateDumpClientPointer(&c->array.t[i], "tex", i);
1589 for (i = 0; (unsigned int)i < g->limits.maxVertexProgramAttribs; i++)
1590 crStateDumpClientPointer(&c->array.a[i], "attrib", i);
1591 crDebug("crStateUseServerArrays->%d", res);
1592 }
1593#endif
1594
1595 return res;
1596#else
1597 return GL_FALSE;
1598#endif
1599}
1600
1601
1602/**
1603 * Determine if there's a server-side array element buffer.
1604 * Called by glDrawElements() in packing SPUs to determine if glDrawElements
1605 * should be evaluated (unrolled) locally or if glDrawElements should be
1606 * packed and sent to the server.
1607 */
1608GLboolean
1609crStateUseServerArrayElements(void)
1610{
1611#ifdef CR_ARB_vertex_buffer_object
1612 CRContext *g = GetCurrentContext();
1613 if (g->bufferobject.elementsBuffer &&
1614 g->bufferobject.elementsBuffer->id > 0)
1615 return GL_TRUE;
1616 else
1617 return GL_FALSE;
1618#else
1619 return GL_FALSE;
1620#endif
1621}
1622
1623
1624void
1625crStateClientDiff(CRClientBits *cb, CRbitvalue *bitID,
1626 CRContext *fromCtx, CRContext *toCtx)
1627{
1628 CRClientState *from = &(fromCtx->client);
1629 const CRClientState *to = &(toCtx->client);
1630 int i;
1631
1632 if (CHECKDIRTY(cb->clientPointer, bitID)) {
1633 /* one or more vertex pointers is dirty */
1634 if (CHECKDIRTY(cb->v, bitID)) {
1635 if (from->array.v.size != to->array.v.size ||
1636 from->array.v.type != to->array.v.type ||
1637 from->array.v.stride != to->array.v.stride ||
1638 from->array.v.buffer != to->array.v.buffer) {
1639 diff_api.VertexPointer(to->array.v.size, to->array.v.type,
1640 to->array.v.stride, to->array.v.p);
1641 from->array.v.size = to->array.v.size;
1642 from->array.v.type = to->array.v.type;
1643 from->array.v.stride = to->array.v.stride;
1644 from->array.v.p = to->array.v.p;
1645 from->array.v.buffer = to->array.v.buffer;
1646 }
1647 CLEARDIRTY2(cb->v, bitID);
1648 }
1649 /* normal */
1650 if (CHECKDIRTY(cb->n, bitID)) {
1651 if (from->array.n.type != to->array.n.type ||
1652 from->array.n.stride != to->array.n.stride ||
1653 from->array.n.buffer != to->array.n.buffer) {
1654 diff_api.NormalPointer(to->array.n.type,
1655 to->array.n.stride, to->array.n.p);
1656 from->array.n.type = to->array.n.type;
1657 from->array.n.stride = to->array.n.stride;
1658 from->array.n.p = to->array.n.p;
1659 from->array.n.buffer = to->array.n.buffer;
1660 }
1661 CLEARDIRTY2(cb->n, bitID);
1662 }
1663 /* color */
1664 if (CHECKDIRTY(cb->c, bitID)) {
1665 if (from->array.c.size != to->array.c.size ||
1666 from->array.c.type != to->array.c.type ||
1667 from->array.c.stride != to->array.c.stride ||
1668 from->array.c.buffer != to->array.c.buffer) {
1669 diff_api.ColorPointer(to->array.c.size, to->array.c.type,
1670 to->array.c.stride, to->array.c.p);
1671 from->array.c.size = to->array.c.size;
1672 from->array.c.type = to->array.c.type;
1673 from->array.c.stride = to->array.c.stride;
1674 from->array.c.p = to->array.c.p;
1675 from->array.c.buffer = to->array.c.buffer;
1676 }
1677 CLEARDIRTY2(cb->c, bitID);
1678 }
1679 /* index */
1680 if (CHECKDIRTY(cb->i, bitID)) {
1681 if (from->array.i.type != to->array.i.type ||
1682 from->array.i.stride != to->array.i.stride ||
1683 from->array.i.buffer != to->array.i.buffer) {
1684 diff_api.IndexPointer(to->array.i.type,
1685 to->array.i.stride, to->array.i.p);
1686 from->array.i.type = to->array.i.type;
1687 from->array.i.stride = to->array.i.stride;
1688 from->array.i.p = to->array.i.p;
1689 from->array.i.buffer = to->array.i.buffer;
1690 }
1691 CLEARDIRTY2(cb->i, bitID);
1692 }
1693 /* texcoords */
1694 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
1695 if (CHECKDIRTY(cb->t[i], bitID)) {
1696 if (from->array.t[i].size != to->array.t[i].size ||
1697 from->array.t[i].type != to->array.t[i].type ||
1698 from->array.t[i].stride != to->array.t[i].stride ||
1699 from->array.t[i].buffer != to->array.t[i].buffer) {
1700 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
1701 diff_api.TexCoordPointer(to->array.t[i].size, to->array.t[i].type,
1702 to->array.t[i].stride, to->array.t[i].p);
1703 from->array.t[i].size = to->array.t[i].size;
1704 from->array.t[i].type = to->array.t[i].type;
1705 from->array.t[i].stride = to->array.t[i].stride;
1706 from->array.t[i].p = to->array.t[i].p;
1707 from->array.t[i].buffer = to->array.t[i].buffer;
1708 }
1709 CLEARDIRTY2(cb->t[i], bitID);
1710 }
1711 }
1712 /* edge flag */
1713 if (CHECKDIRTY(cb->e, bitID)) {
1714 if (from->array.e.stride != to->array.e.stride ||
1715 from->array.e.buffer != to->array.e.buffer) {
1716 diff_api.EdgeFlagPointer(to->array.e.stride, to->array.e.p);
1717 from->array.e.stride = to->array.e.stride;
1718 from->array.e.p = to->array.e.p;
1719 from->array.e.buffer = to->array.e.buffer;
1720 }
1721 CLEARDIRTY2(cb->e, bitID);
1722 }
1723 /* secondary color */
1724 if (CHECKDIRTY(cb->s, bitID)) {
1725 if (from->array.s.size != to->array.s.size ||
1726 from->array.s.type != to->array.s.type ||
1727 from->array.s.stride != to->array.s.stride ||
1728 from->array.s.buffer != to->array.s.buffer) {
1729 diff_api.SecondaryColorPointerEXT(to->array.s.size, to->array.s.type,
1730 to->array.s.stride, to->array.s.p);
1731 from->array.s.size = to->array.s.size;
1732 from->array.s.type = to->array.s.type;
1733 from->array.s.stride = to->array.s.stride;
1734 from->array.s.p = to->array.s.p;
1735 from->array.s.buffer = to->array.s.buffer;
1736 }
1737 CLEARDIRTY2(cb->s, bitID);
1738 }
1739 /* fog coord */
1740 if (CHECKDIRTY(cb->f, bitID)) {
1741 if (from->array.f.type != to->array.f.type ||
1742 from->array.f.stride != to->array.f.stride ||
1743 from->array.f.buffer != to->array.f.buffer) {
1744 diff_api.FogCoordPointerEXT(to->array.f.type,
1745 to->array.f.stride, to->array.f.p);
1746 from->array.f.type = to->array.f.type;
1747 from->array.f.stride = to->array.f.stride;
1748 from->array.f.p = to->array.f.p;
1749 from->array.f.buffer = to->array.f.buffer;
1750 }
1751 CLEARDIRTY2(cb->f, bitID);
1752 }
1753#if defined(CR_NV_vertex_program) || defined(CR_ARB_vertex_program)
1754 /* vertex attributes */
1755 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
1756 if (CHECKDIRTY(cb->a[i], bitID)) {
1757 if (from->array.a[i].size != to->array.a[i].size ||
1758 from->array.a[i].type != to->array.a[i].type ||
1759 from->array.a[i].stride != to->array.a[i].stride ||
1760 from->array.a[i].normalized != to->array.a[i].normalized ||
1761 from->array.a[i].buffer != to->array.a[i].buffer) {
1762 diff_api.VertexAttribPointerARB(i, to->array.a[i].size,
1763 to->array.a[i].type,
1764 to->array.a[i].normalized,
1765 to->array.a[i].stride,
1766 to->array.a[i].p);
1767 from->array.a[i].size = to->array.a[i].size;
1768 from->array.a[i].type = to->array.a[i].type;
1769 from->array.a[i].stride = to->array.a[i].stride;
1770 from->array.a[i].normalized = to->array.a[i].normalized;
1771 from->array.a[i].p = to->array.a[i].p;
1772 from->array.a[i].buffer = to->array.a[i].buffer;
1773 }
1774 CLEARDIRTY2(cb->a[i], bitID);
1775 }
1776 }
1777#endif
1778 }
1779
1780 if (CHECKDIRTY(cb->enableClientState, bitID)) {
1781 /* update vertex array enable/disable flags */
1782 glAble able[2];
1783 able[0] = diff_api.Disable;
1784 able[1] = diff_api.Enable;
1785 if (from->array.v.enabled != to->array.v.enabled) {
1786 able[to->array.v.enabled](GL_VERTEX_ARRAY);
1787 from->array.v.enabled = to->array.v.enabled;
1788 }
1789 if (from->array.n.enabled != to->array.n.enabled) {
1790 able[to->array.n.enabled](GL_NORMAL_ARRAY);
1791 from->array.n.enabled = to->array.n.enabled;
1792 }
1793 if (from->array.c.enabled != to->array.c.enabled) {
1794 able[to->array.c.enabled](GL_COLOR_ARRAY);
1795 from->array.c.enabled = to->array.c.enabled;
1796 }
1797 if (from->array.i.enabled != to->array.i.enabled) {
1798 able[to->array.i.enabled](GL_INDEX_ARRAY);
1799 from->array.i.enabled = to->array.i.enabled;
1800 }
1801 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
1802 if (from->array.t[i].enabled != to->array.t[i].enabled) {
1803 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
1804 able[to->array.t[i].enabled](GL_TEXTURE_COORD_ARRAY);
1805 from->array.t[i].enabled = to->array.t[i].enabled;
1806 }
1807 }
1808 if (from->array.e.enabled != to->array.e.enabled) {
1809 able[to->array.e.enabled](GL_EDGE_FLAG_ARRAY);
1810 from->array.e.enabled = to->array.e.enabled;
1811 }
1812 if (from->array.s.enabled != to->array.s.enabled) {
1813 able[to->array.s.enabled](GL_SECONDARY_COLOR_ARRAY_EXT);
1814 from->array.s.enabled = to->array.s.enabled;
1815 }
1816 if (from->array.f.enabled != to->array.f.enabled) {
1817 able[to->array.f.enabled](GL_FOG_COORDINATE_ARRAY_EXT);
1818 from->array.f.enabled = to->array.f.enabled;
1819 }
1820 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
1821 if (from->array.a[i].enabled != to->array.a[i].enabled) {
1822 if (to->array.a[i].enabled)
1823 diff_api.EnableVertexAttribArrayARB(i);
1824 else
1825 diff_api.DisableVertexAttribArrayARB(i);
1826 from->array.a[i].enabled = to->array.a[i].enabled;
1827 }
1828 }
1829 CLEARDIRTY2(cb->enableClientState, bitID);
1830 }
1831}
1832
1833
1834void
1835crStateClientSwitch(CRClientBits *cb, CRbitvalue *bitID,
1836 CRContext *fromCtx, CRContext *toCtx)
1837{
1838 const CRClientState *from = &(fromCtx->client);
1839 const CRClientState *to = &(toCtx->client);
1840 int i;
1841
1842 if (CHECKDIRTY(cb->clientPointer, bitID)) {
1843 /* one or more vertex pointers is dirty */
1844 if (CHECKDIRTY(cb->v, bitID)) {
1845 if (from->array.v.size != to->array.v.size ||
1846 from->array.v.type != to->array.v.type ||
1847 from->array.v.stride != to->array.v.stride ||
1848 from->array.v.buffer != to->array.v.buffer) {
1849 diff_api.VertexPointer(to->array.v.size, to->array.v.type,
1850 to->array.v.stride, to->array.v.p);
1851 FILLDIRTY(cb->v);
1852 FILLDIRTY(cb->clientPointer);
1853 FILLDIRTY(cb->dirty);
1854 }
1855 CLEARDIRTY2(cb->v, bitID);
1856 }
1857 /* normal */
1858 if (CHECKDIRTY(cb->n, bitID)) {
1859 if (from->array.n.type != to->array.n.type ||
1860 from->array.n.stride != to->array.n.stride ||
1861 from->array.n.buffer != to->array.n.buffer) {
1862 diff_api.NormalPointer(to->array.n.type,
1863 to->array.n.stride, to->array.n.p);
1864 FILLDIRTY(cb->n);
1865 FILLDIRTY(cb->clientPointer);
1866 FILLDIRTY(cb->dirty);
1867 }
1868 CLEARDIRTY2(cb->n, bitID);
1869 }
1870 /* color */
1871 if (CHECKDIRTY(cb->c, bitID)) {
1872 if (from->array.c.size != to->array.c.size ||
1873 from->array.c.type != to->array.c.type ||
1874 from->array.c.stride != to->array.c.stride ||
1875 from->array.c.buffer != to->array.c.buffer) {
1876 diff_api.ColorPointer(to->array.c.size, to->array.c.type,
1877 to->array.c.stride, to->array.c.p);
1878 FILLDIRTY(cb->c);
1879 FILLDIRTY(cb->clientPointer);
1880 FILLDIRTY(cb->dirty);
1881 }
1882 CLEARDIRTY2(cb->c, bitID);
1883 }
1884 /* index */
1885 if (CHECKDIRTY(cb->i, bitID)) {
1886 if (from->array.i.type != to->array.i.type ||
1887 from->array.i.stride != to->array.i.stride ||
1888 from->array.i.buffer != to->array.i.buffer) {
1889 diff_api.IndexPointer(to->array.i.type,
1890 to->array.i.stride, to->array.i.p);
1891 FILLDIRTY(cb->i);
1892 FILLDIRTY(cb->dirty);
1893 FILLDIRTY(cb->clientPointer);
1894 }
1895 CLEARDIRTY2(cb->i, bitID);
1896 }
1897 /* texcoords */
1898 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
1899 if (CHECKDIRTY(cb->t[i], bitID)) {
1900 if (from->array.t[i].size != to->array.t[i].size ||
1901 from->array.t[i].type != to->array.t[i].type ||
1902 from->array.t[i].stride != to->array.t[i].stride ||
1903 from->array.t[i].buffer != to->array.t[i].buffer) {
1904 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
1905 diff_api.TexCoordPointer(to->array.t[i].size, to->array.t[i].type,
1906 to->array.t[i].stride, to->array.t[i].p);
1907 FILLDIRTY(cb->t[i]);
1908 FILLDIRTY(cb->clientPointer);
1909 FILLDIRTY(cb->dirty);
1910 }
1911 CLEARDIRTY2(cb->t[i], bitID);
1912 }
1913 }
1914 /* edge flag */
1915 if (CHECKDIRTY(cb->e, bitID)) {
1916 if (from->array.e.stride != to->array.e.stride ||
1917 from->array.e.buffer != to->array.e.buffer) {
1918 diff_api.EdgeFlagPointer(to->array.e.stride, to->array.e.p);
1919 FILLDIRTY(cb->e);
1920 FILLDIRTY(cb->clientPointer);
1921 FILLDIRTY(cb->dirty);
1922 }
1923 CLEARDIRTY2(cb->e, bitID);
1924 }
1925 /* secondary color */
1926 if (CHECKDIRTY(cb->s, bitID)) {
1927 if (from->array.s.size != to->array.s.size ||
1928 from->array.s.type != to->array.s.type ||
1929 from->array.s.stride != to->array.s.stride ||
1930 from->array.s.buffer != to->array.s.buffer) {
1931 diff_api.SecondaryColorPointerEXT(to->array.s.size, to->array.s.type,
1932 to->array.s.stride, to->array.s.p);
1933 FILLDIRTY(cb->s);
1934 FILLDIRTY(cb->clientPointer);
1935 FILLDIRTY(cb->dirty);
1936 }
1937 CLEARDIRTY2(cb->s, bitID);
1938 }
1939 /* fog coord */
1940 if (CHECKDIRTY(cb->f, bitID)) {
1941 if (from->array.f.type != to->array.f.type ||
1942 from->array.f.stride != to->array.f.stride ||
1943 from->array.f.buffer != to->array.f.buffer) {
1944 diff_api.FogCoordPointerEXT(to->array.f.type,
1945 to->array.f.stride, to->array.f.p);
1946 FILLDIRTY(cb->f);
1947 FILLDIRTY(cb->clientPointer);
1948 FILLDIRTY(cb->dirty);
1949 }
1950 CLEARDIRTY2(cb->f, bitID);
1951 }
1952#if defined(CR_NV_vertex_program) || defined(CR_ARB_vertex_program)
1953 /* vertex attributes */
1954 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
1955 if (CHECKDIRTY(cb->a[i], bitID)) {
1956 if (from->array.a[i].size != to->array.a[i].size ||
1957 from->array.a[i].type != to->array.a[i].type ||
1958 from->array.a[i].stride != to->array.a[i].stride ||
1959 from->array.a[i].normalized != to->array.a[i].normalized ||
1960 from->array.a[i].buffer != to->array.a[i].buffer) {
1961 diff_api.VertexAttribPointerARB(i, to->array.a[i].size,
1962 to->array.a[i].type,
1963 to->array.a[i].normalized,
1964 to->array.a[i].stride,
1965 to->array.a[i].p);
1966 FILLDIRTY(cb->a[i]);
1967 FILLDIRTY(cb->clientPointer);
1968 FILLDIRTY(cb->dirty);
1969 }
1970 CLEARDIRTY2(cb->a[i], bitID);
1971 }
1972 }
1973#endif
1974 }
1975
1976 if (CHECKDIRTY(cb->enableClientState, bitID)) {
1977 /* update vertex array enable/disable flags */
1978 glAble able[2];
1979 able[0] = diff_api.Disable;
1980 able[1] = diff_api.Enable;
1981 if (from->array.v.enabled != to->array.v.enabled) {
1982 able[to->array.v.enabled](GL_VERTEX_ARRAY);
1983 FILLDIRTY(cb->enableClientState);
1984 FILLDIRTY(cb->dirty);
1985 }
1986 if (from->array.n.enabled != to->array.n.enabled) {
1987 able[to->array.n.enabled](GL_NORMAL_ARRAY);
1988 FILLDIRTY(cb->enableClientState);
1989 FILLDIRTY(cb->dirty);
1990 }
1991 if (from->array.c.enabled != to->array.c.enabled) {
1992 able[to->array.c.enabled](GL_COLOR_ARRAY);
1993 FILLDIRTY(cb->enableClientState);
1994 FILLDIRTY(cb->dirty);
1995 }
1996 if (from->array.i.enabled != to->array.i.enabled) {
1997 able[to->array.i.enabled](GL_INDEX_ARRAY);
1998 FILLDIRTY(cb->enableClientState);
1999 FILLDIRTY(cb->dirty);
2000 }
2001 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
2002 if (from->array.t[i].enabled != to->array.t[i].enabled) {
2003 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
2004 able[to->array.t[i].enabled](GL_TEXTURE_COORD_ARRAY);
2005 FILLDIRTY(cb->enableClientState);
2006 FILLDIRTY(cb->dirty);
2007 }
2008 }
2009 if (from->array.e.enabled != to->array.e.enabled) {
2010 able[to->array.e.enabled](GL_EDGE_FLAG_ARRAY);
2011 FILLDIRTY(cb->enableClientState);
2012 FILLDIRTY(cb->dirty);
2013 }
2014 if (from->array.s.enabled != to->array.s.enabled) {
2015 able[to->array.s.enabled](GL_SECONDARY_COLOR_ARRAY_EXT);
2016 FILLDIRTY(cb->enableClientState);
2017 FILLDIRTY(cb->dirty);
2018 }
2019 if (from->array.f.enabled != to->array.f.enabled) {
2020 able[to->array.f.enabled](GL_FOG_COORDINATE_ARRAY_EXT);
2021 FILLDIRTY(cb->enableClientState);
2022 FILLDIRTY(cb->dirty);
2023 }
2024 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
2025 if (from->array.a[i].enabled != to->array.a[i].enabled) {
2026 if (to->array.a[i].enabled)
2027 diff_api.EnableVertexAttribArrayARB(i);
2028 else
2029 diff_api.DisableVertexAttribArrayARB(i);
2030 FILLDIRTY(cb->enableClientState);
2031 FILLDIRTY(cb->dirty);
2032 }
2033 }
2034 CLEARDIRTY2(cb->enableClientState, bitID);
2035 }
2036
2037 CLEARDIRTY2(cb->dirty, bitID);
2038}
2039
2040CRClientPointer* crStateGetClientPointerByIndex(int index, CRVertexArrays *array)
2041{
2042 CRASSERT(array && index>=0 && index<CRSTATECLIENT_MAX_VERTEXARRAYS);
2043
2044 if (index<7)
2045 {
2046 switch (index)
2047 {
2048 case 0: return &array->v;
2049 case 1: return &array->c;
2050 case 2: return &array->f;
2051 case 3: return &array->s;
2052 case 4: return &array->e;
2053 case 5: return &array->i;
2054 case 6: return &array->n;
2055 }
2056 }
2057 else if (index<(7+CR_MAX_TEXTURE_UNITS))
2058 {
2059 return &array->t[index-7];
2060 }
2061 else
2062 {
2063 return &array->a[index-7-CR_MAX_TEXTURE_UNITS];
2064 }
2065
2066 /*silence the compiler warning*/
2067 CRASSERT(false);
2068 return NULL;
2069}
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