VirtualBox

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

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

crOpenGL: don't allow locking arrays with a bound vbo

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