VirtualBox

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

Last change on this file since 16970 was 15532, checked in by vboxsync, 16 years ago

crOpenGL: export to OSE

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