- use new program option values from arbprogram.syn
[mesa.git] / src / mesa / main / api_arrayelt.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.1
4 *
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /* Author:
26 * Keith Whitwell <keith@tungstengraphics.com>
27 */
28
29 #include "glheader.h"
30 #include "api_arrayelt.h"
31 #include "context.h"
32 #include "glapi.h"
33 #include "imports.h"
34 #include "macros.h"
35 #include "mtypes.h"
36
37 typedef void (GLAPIENTRY *array_func)( const void * );
38
39 typedef struct {
40 const struct gl_client_array *array;
41 array_func func;
42 } AEarray;
43
44 typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data );
45
46 typedef struct {
47 const struct gl_client_array *array;
48 attrib_func func;
49 GLuint index;
50 } AEattrib;
51
52 typedef struct {
53 AEarray arrays[32];
54 AEattrib attribs[VERT_ATTRIB_MAX + 1];
55 GLuint NewState;
56 } AEcontext;
57
58 #define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context)
59
60 /*
61 * Convert GL_BYTE, GL_UNSIGNED_BYTE, .. GL_DOUBLE into an integer
62 * in the range [0, 7]. Luckily these type tokens are sequentially
63 * numbered in gl.h, except for GL_DOUBLE.
64 */
65 #define TYPE_IDX(t) ( (t) == GL_DOUBLE ? 7 : (t) & 7 )
66
67
68 static array_func ColorFuncs[2][8] = {
69 { (array_func)glColor3bv,
70 (array_func)glColor3ubv,
71 (array_func)glColor3sv,
72 (array_func)glColor3usv,
73 (array_func)glColor3iv,
74 (array_func)glColor3uiv,
75 (array_func)glColor3fv,
76 (array_func)glColor3dv },
77
78 { (array_func)glColor4bv,
79 (array_func)glColor4ubv,
80 (array_func)glColor4sv,
81 (array_func)glColor4usv,
82 (array_func)glColor4iv,
83 (array_func)glColor4uiv,
84 (array_func)glColor4fv,
85 (array_func)glColor4dv }
86 };
87
88 static array_func VertexFuncs[3][8] = {
89 { 0,
90 0,
91 (array_func)glVertex2sv,
92 0,
93 (array_func)glVertex2iv,
94 0,
95 (array_func)glVertex2fv,
96 (array_func)glVertex2dv },
97
98 { 0,
99 0,
100 (array_func)glVertex3sv,
101 0,
102 (array_func)glVertex3iv,
103 0,
104 (array_func)glVertex3fv,
105 (array_func)glVertex3dv },
106
107 { 0,
108 0,
109 (array_func)glVertex4sv,
110 0,
111 (array_func)glVertex4iv,
112 0,
113 (array_func)glVertex4fv,
114 (array_func)glVertex4dv }
115 };
116
117 static array_func IndexFuncs[8] = {
118 0,
119 (array_func)glIndexubv,
120 (array_func)glIndexsv,
121 0,
122 (array_func)glIndexiv,
123 0,
124 (array_func)glIndexfv,
125 (array_func)glIndexdv
126 };
127
128 static array_func NormalFuncs[8] = {
129 (array_func)glNormal3bv,
130 0,
131 (array_func)glNormal3sv,
132 0,
133 (array_func)glNormal3iv,
134 0,
135 (array_func)glNormal3fv,
136 (array_func)glNormal3dv,
137 };
138
139
140 /* Wrapper functions in case glSecondaryColor*EXT doesn't exist */
141 static void GLAPIENTRY SecondaryColor3bvEXT(const GLbyte *c)
142 {
143 GL_CALL(SecondaryColor3bvEXT)(c);
144 }
145
146 static void GLAPIENTRY SecondaryColor3ubvEXT(const GLubyte *c)
147 {
148 GL_CALL(SecondaryColor3ubvEXT)(c);
149 }
150
151 static void GLAPIENTRY SecondaryColor3svEXT(const GLshort *c)
152 {
153 GL_CALL(SecondaryColor3svEXT)(c);
154 }
155
156 static void GLAPIENTRY SecondaryColor3usvEXT(const GLushort *c)
157 {
158 GL_CALL(SecondaryColor3usvEXT)(c);
159 }
160
161 static void GLAPIENTRY SecondaryColor3ivEXT(const GLint *c)
162 {
163 GL_CALL(SecondaryColor3ivEXT)(c);
164 }
165
166 static void GLAPIENTRY SecondaryColor3uivEXT(const GLuint *c)
167 {
168 GL_CALL(SecondaryColor3uivEXT)(c);
169 }
170
171 static void GLAPIENTRY SecondaryColor3fvEXT(const GLfloat *c)
172 {
173 GL_CALL(SecondaryColor3fvEXT)(c);
174 }
175
176 static void GLAPIENTRY SecondaryColor3dvEXT(const GLdouble *c)
177 {
178 GL_CALL(SecondaryColor3dvEXT)(c);
179 }
180
181 static array_func SecondaryColorFuncs[8] = {
182 (array_func) SecondaryColor3bvEXT,
183 (array_func) SecondaryColor3ubvEXT,
184 (array_func) SecondaryColor3svEXT,
185 (array_func) SecondaryColor3usvEXT,
186 (array_func) SecondaryColor3ivEXT,
187 (array_func) SecondaryColor3uivEXT,
188 (array_func) SecondaryColor3fvEXT,
189 (array_func) SecondaryColor3dvEXT,
190 };
191
192
193 /* Again, wrapper functions in case glSecondaryColor*EXT doesn't exist */
194 static void GLAPIENTRY FogCoordfvEXT(const GLfloat *f)
195 {
196 GL_CALL(FogCoordfvEXT)(f);
197 }
198
199 static void GLAPIENTRY FogCoorddvEXT(const GLdouble *f)
200 {
201 GL_CALL(FogCoorddvEXT)(f);
202 }
203
204 static array_func FogCoordFuncs[8] = {
205 0,
206 0,
207 0,
208 0,
209 0,
210 0,
211 (array_func) FogCoordfvEXT,
212 (array_func) FogCoorddvEXT
213 };
214
215
216 /**********************************************************************/
217
218 /* GL_BYTE attributes */
219
220 static void GLAPIENTRY VertexAttrib1Nbv(GLuint index, const GLbyte *v)
221 {
222 GL_CALL(VertexAttrib1fNV)(index, BYTE_TO_FLOAT(v[0]));
223 }
224
225 static void GLAPIENTRY VertexAttrib1bv(GLuint index, const GLbyte *v)
226 {
227 GL_CALL(VertexAttrib1fNV)(index, v[0]);
228 }
229
230 static void GLAPIENTRY VertexAttrib2Nbv(GLuint index, const GLbyte *v)
231 {
232 GL_CALL(VertexAttrib2fNV)(index, BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1]));
233 }
234
235 static void GLAPIENTRY VertexAttrib2bv(GLuint index, const GLbyte *v)
236 {
237 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
238 }
239
240 static void GLAPIENTRY VertexAttrib3Nbv(GLuint index, const GLbyte *v)
241 {
242 GL_CALL(VertexAttrib3fNV)(index, BYTE_TO_FLOAT(v[0]),
243 BYTE_TO_FLOAT(v[1]),
244 BYTE_TO_FLOAT(v[2]));
245 }
246
247 static void GLAPIENTRY VertexAttrib3bv(GLuint index, const GLbyte *v)
248 {
249 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
250 }
251
252 static void GLAPIENTRY VertexAttrib4Nbv(GLuint index, const GLbyte *v)
253 {
254 GL_CALL(VertexAttrib4fNV)(index, BYTE_TO_FLOAT(v[0]),
255 BYTE_TO_FLOAT(v[1]),
256 BYTE_TO_FLOAT(v[2]),
257 BYTE_TO_FLOAT(v[3]));
258 }
259
260 static void GLAPIENTRY VertexAttrib4bv(GLuint index, const GLbyte *v)
261 {
262 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
263 }
264
265 /* GL_UNSIGNED_BYTE attributes */
266
267 static void GLAPIENTRY VertexAttrib1Nubv(GLuint index, const GLubyte *v)
268 {
269 GL_CALL(VertexAttrib1fNV)(index, UBYTE_TO_FLOAT(v[0]));
270 }
271
272 static void GLAPIENTRY VertexAttrib1ubv(GLuint index, const GLubyte *v)
273 {
274 GL_CALL(VertexAttrib1fNV)(index, v[0]);
275 }
276
277 static void GLAPIENTRY VertexAttrib2Nubv(GLuint index, const GLubyte *v)
278 {
279 GL_CALL(VertexAttrib2fNV)(index, UBYTE_TO_FLOAT(v[0]),
280 UBYTE_TO_FLOAT(v[1]));
281 }
282
283 static void GLAPIENTRY VertexAttrib2ubv(GLuint index, const GLubyte *v)
284 {
285 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
286 }
287
288 static void GLAPIENTRY VertexAttrib3Nubv(GLuint index, const GLubyte *v)
289 {
290 GL_CALL(VertexAttrib3fNV)(index, UBYTE_TO_FLOAT(v[0]),
291 UBYTE_TO_FLOAT(v[1]),
292 UBYTE_TO_FLOAT(v[2]));
293 }
294 static void GLAPIENTRY VertexAttrib3ubv(GLuint index, const GLubyte *v)
295 {
296 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
297 }
298
299 static void GLAPIENTRY VertexAttrib4Nubv(GLuint index, const GLubyte *v)
300 {
301 GL_CALL(VertexAttrib4fNV)(index, UBYTE_TO_FLOAT(v[0]),
302 UBYTE_TO_FLOAT(v[1]),
303 UBYTE_TO_FLOAT(v[2]),
304 UBYTE_TO_FLOAT(v[3]));
305 }
306
307 static void GLAPIENTRY VertexAttrib4ubv(GLuint index, const GLubyte *v)
308 {
309 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
310 }
311
312 /* GL_SHORT attributes */
313
314 static void GLAPIENTRY VertexAttrib1Nsv(GLuint index, const GLshort *v)
315 {
316 GL_CALL(VertexAttrib1fNV)(index, SHORT_TO_FLOAT(v[0]));
317 }
318
319 static void GLAPIENTRY VertexAttrib1sv(GLuint index, const GLshort *v)
320 {
321 GL_CALL(VertexAttrib1fNV)(index, v[0]);
322 }
323
324 static void GLAPIENTRY VertexAttrib2Nsv(GLuint index, const GLshort *v)
325 {
326 GL_CALL(VertexAttrib2fNV)(index, SHORT_TO_FLOAT(v[0]),
327 SHORT_TO_FLOAT(v[1]));
328 }
329
330 static void GLAPIENTRY VertexAttrib2sv(GLuint index, const GLshort *v)
331 {
332 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
333 }
334
335 static void GLAPIENTRY VertexAttrib3Nsv(GLuint index, const GLshort *v)
336 {
337 GL_CALL(VertexAttrib3fNV)(index, SHORT_TO_FLOAT(v[0]),
338 SHORT_TO_FLOAT(v[1]),
339 SHORT_TO_FLOAT(v[2]));
340 }
341
342 static void GLAPIENTRY VertexAttrib3sv(GLuint index, const GLshort *v)
343 {
344 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
345 }
346
347 static void GLAPIENTRY VertexAttrib4Nsv(GLuint index, const GLshort *v)
348 {
349 GL_CALL(VertexAttrib4fNV)(index, SHORT_TO_FLOAT(v[0]),
350 SHORT_TO_FLOAT(v[1]),
351 SHORT_TO_FLOAT(v[2]),
352 SHORT_TO_FLOAT(v[3]));
353 }
354
355 static void GLAPIENTRY VertexAttrib4sv(GLuint index, const GLshort *v)
356 {
357 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
358 }
359
360 /* GL_UNSIGNED_SHORT attributes */
361
362 static void GLAPIENTRY VertexAttrib1Nusv(GLuint index, const GLushort *v)
363 {
364 GL_CALL(VertexAttrib1fNV)(index, USHORT_TO_FLOAT(v[0]));
365 }
366
367 static void GLAPIENTRY VertexAttrib1usv(GLuint index, const GLushort *v)
368 {
369 GL_CALL(VertexAttrib1fNV)(index, v[0]);
370 }
371
372 static void GLAPIENTRY VertexAttrib2Nusv(GLuint index, const GLushort *v)
373 {
374 GL_CALL(VertexAttrib2fNV)(index, USHORT_TO_FLOAT(v[0]),
375 USHORT_TO_FLOAT(v[1]));
376 }
377
378 static void GLAPIENTRY VertexAttrib2usv(GLuint index, const GLushort *v)
379 {
380 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
381 }
382
383 static void GLAPIENTRY VertexAttrib3Nusv(GLuint index, const GLushort *v)
384 {
385 GL_CALL(VertexAttrib3fNV)(index, USHORT_TO_FLOAT(v[0]),
386 USHORT_TO_FLOAT(v[1]),
387 USHORT_TO_FLOAT(v[2]));
388 }
389
390 static void GLAPIENTRY VertexAttrib3usv(GLuint index, const GLushort *v)
391 {
392 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
393 }
394
395 static void GLAPIENTRY VertexAttrib4Nusv(GLuint index, const GLushort *v)
396 {
397 GL_CALL(VertexAttrib4fNV)(index, USHORT_TO_FLOAT(v[0]),
398 USHORT_TO_FLOAT(v[1]),
399 USHORT_TO_FLOAT(v[2]),
400 USHORT_TO_FLOAT(v[3]));
401 }
402
403 static void GLAPIENTRY VertexAttrib4usv(GLuint index, const GLushort *v)
404 {
405 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
406 }
407
408 /* GL_INT attributes */
409
410 static void GLAPIENTRY VertexAttrib1Niv(GLuint index, const GLint *v)
411 {
412 GL_CALL(VertexAttrib1fNV)(index, INT_TO_FLOAT(v[0]));
413 }
414
415 static void GLAPIENTRY VertexAttrib1iv(GLuint index, const GLint *v)
416 {
417 GL_CALL(VertexAttrib1fNV)(index, v[0]);
418 }
419
420 static void GLAPIENTRY VertexAttrib2Niv(GLuint index, const GLint *v)
421 {
422 GL_CALL(VertexAttrib2fNV)(index, INT_TO_FLOAT(v[0]),
423 INT_TO_FLOAT(v[1]));
424 }
425
426 static void GLAPIENTRY VertexAttrib2iv(GLuint index, const GLint *v)
427 {
428 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
429 }
430
431 static void GLAPIENTRY VertexAttrib3Niv(GLuint index, const GLint *v)
432 {
433 GL_CALL(VertexAttrib3fNV)(index, INT_TO_FLOAT(v[0]),
434 INT_TO_FLOAT(v[1]),
435 INT_TO_FLOAT(v[2]));
436 }
437
438 static void GLAPIENTRY VertexAttrib3iv(GLuint index, const GLint *v)
439 {
440 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
441 }
442
443 static void GLAPIENTRY VertexAttrib4Niv(GLuint index, const GLint *v)
444 {
445 GL_CALL(VertexAttrib4fNV)(index, INT_TO_FLOAT(v[0]),
446 INT_TO_FLOAT(v[1]),
447 INT_TO_FLOAT(v[2]),
448 INT_TO_FLOAT(v[3]));
449 }
450
451 static void GLAPIENTRY VertexAttrib4iv(GLuint index, const GLint *v)
452 {
453 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
454 }
455
456 /* GL_UNSIGNED_INT attributes */
457
458 static void GLAPIENTRY VertexAttrib1Nuiv(GLuint index, const GLuint *v)
459 {
460 GL_CALL(VertexAttrib1fNV)(index, UINT_TO_FLOAT(v[0]));
461 }
462
463 static void GLAPIENTRY VertexAttrib1uiv(GLuint index, const GLuint *v)
464 {
465 GL_CALL(VertexAttrib1fNV)(index, v[0]);
466 }
467
468 static void GLAPIENTRY VertexAttrib2Nuiv(GLuint index, const GLuint *v)
469 {
470 GL_CALL(VertexAttrib2fNV)(index, UINT_TO_FLOAT(v[0]),
471 UINT_TO_FLOAT(v[1]));
472 }
473
474 static void GLAPIENTRY VertexAttrib2uiv(GLuint index, const GLuint *v)
475 {
476 GL_CALL(VertexAttrib2fNV)(index, v[0], v[1]);
477 }
478
479 static void GLAPIENTRY VertexAttrib3Nuiv(GLuint index, const GLuint *v)
480 {
481 GL_CALL(VertexAttrib3fNV)(index, UINT_TO_FLOAT(v[0]),
482 UINT_TO_FLOAT(v[1]),
483 UINT_TO_FLOAT(v[2]));
484 }
485
486 static void GLAPIENTRY VertexAttrib3uiv(GLuint index, const GLuint *v)
487 {
488 GL_CALL(VertexAttrib3fNV)(index, v[0], v[1], v[2]);
489 }
490
491 static void GLAPIENTRY VertexAttrib4Nuiv(GLuint index, const GLuint *v)
492 {
493 GL_CALL(VertexAttrib4fNV)(index, UINT_TO_FLOAT(v[0]),
494 UINT_TO_FLOAT(v[1]),
495 UINT_TO_FLOAT(v[2]),
496 UINT_TO_FLOAT(v[3]));
497 }
498
499 static void GLAPIENTRY VertexAttrib4uiv(GLuint index, const GLuint *v)
500 {
501 GL_CALL(VertexAttrib4fNV)(index, v[0], v[1], v[2], v[3]);
502 }
503
504 /* GL_FLOAT attributes */
505
506 static void GLAPIENTRY VertexAttrib1fv(GLuint index, const GLfloat *v)
507 {
508 GL_CALL(VertexAttrib1fvNV)(index, v);
509 }
510
511 static void GLAPIENTRY VertexAttrib2fv(GLuint index, const GLfloat *v)
512 {
513 GL_CALL(VertexAttrib2fvNV)(index, v);
514 }
515
516 static void GLAPIENTRY VertexAttrib3fv(GLuint index, const GLfloat *v)
517 {
518 GL_CALL(VertexAttrib3fvNV)(index, v);
519 }
520
521 static void GLAPIENTRY VertexAttrib4fv(GLuint index, const GLfloat *v)
522 {
523 GL_CALL(VertexAttrib4fvNV)(index, v);
524 }
525
526 /* GL_DOUBLE attributes */
527
528 static void GLAPIENTRY VertexAttrib1dv(GLuint index, const GLdouble *v)
529 {
530 GL_CALL(VertexAttrib1dvNV)(index, v);
531 }
532
533 static void GLAPIENTRY VertexAttrib2dv(GLuint index, const GLdouble *v)
534 {
535 GL_CALL(VertexAttrib2dvNV)(index, v);
536 }
537
538 static void GLAPIENTRY VertexAttrib3dv(GLuint index, const GLdouble *v)
539 {
540 GL_CALL(VertexAttrib3dvNV)(index, v);
541 }
542
543 static void GLAPIENTRY VertexAttrib4dv(GLuint index, const GLdouble *v)
544 {
545 GL_CALL(VertexAttrib4dvNV)(index, v);
546 }
547
548
549 /*
550 * Array [size][type] of VertexAttrib functions
551 */
552 static attrib_func AttribFuncs[2][4][8] = {
553 {
554 /* non-normalized */
555 {
556 /* size 1 */
557 (attrib_func) VertexAttrib1bv,
558 (attrib_func) VertexAttrib1ubv,
559 (attrib_func) VertexAttrib1sv,
560 (attrib_func) VertexAttrib1usv,
561 (attrib_func) VertexAttrib1iv,
562 (attrib_func) VertexAttrib1uiv,
563 (attrib_func) VertexAttrib1fv,
564 (attrib_func) VertexAttrib1dv
565 },
566 {
567 /* size 2 */
568 (attrib_func) VertexAttrib2bv,
569 (attrib_func) VertexAttrib2ubv,
570 (attrib_func) VertexAttrib2sv,
571 (attrib_func) VertexAttrib2usv,
572 (attrib_func) VertexAttrib2iv,
573 (attrib_func) VertexAttrib2uiv,
574 (attrib_func) VertexAttrib2fv,
575 (attrib_func) VertexAttrib2dv
576 },
577 {
578 /* size 3 */
579 (attrib_func) VertexAttrib3bv,
580 (attrib_func) VertexAttrib3ubv,
581 (attrib_func) VertexAttrib3sv,
582 (attrib_func) VertexAttrib3usv,
583 (attrib_func) VertexAttrib3iv,
584 (attrib_func) VertexAttrib3uiv,
585 (attrib_func) VertexAttrib3fv,
586 (attrib_func) VertexAttrib3dv
587 },
588 {
589 /* size 4 */
590 (attrib_func) VertexAttrib4bv,
591 (attrib_func) VertexAttrib4ubv,
592 (attrib_func) VertexAttrib4sv,
593 (attrib_func) VertexAttrib4usv,
594 (attrib_func) VertexAttrib4iv,
595 (attrib_func) VertexAttrib4uiv,
596 (attrib_func) VertexAttrib4fv,
597 (attrib_func) VertexAttrib4dv
598 }
599 },
600 {
601 /* normalized (except for float/double) */
602 {
603 /* size 1 */
604 (attrib_func) VertexAttrib1Nbv,
605 (attrib_func) VertexAttrib1Nubv,
606 (attrib_func) VertexAttrib1Nsv,
607 (attrib_func) VertexAttrib1Nusv,
608 (attrib_func) VertexAttrib1Niv,
609 (attrib_func) VertexAttrib1Nuiv,
610 (attrib_func) VertexAttrib1fv,
611 (attrib_func) VertexAttrib1dv
612 },
613 {
614 /* size 2 */
615 (attrib_func) VertexAttrib2Nbv,
616 (attrib_func) VertexAttrib2Nubv,
617 (attrib_func) VertexAttrib2Nsv,
618 (attrib_func) VertexAttrib2Nusv,
619 (attrib_func) VertexAttrib2Niv,
620 (attrib_func) VertexAttrib2Nuiv,
621 (attrib_func) VertexAttrib2fv,
622 (attrib_func) VertexAttrib2dv
623 },
624 {
625 /* size 3 */
626 (attrib_func) VertexAttrib3Nbv,
627 (attrib_func) VertexAttrib3Nubv,
628 (attrib_func) VertexAttrib3Nsv,
629 (attrib_func) VertexAttrib3Nusv,
630 (attrib_func) VertexAttrib3Niv,
631 (attrib_func) VertexAttrib3Nuiv,
632 (attrib_func) VertexAttrib3fv,
633 (attrib_func) VertexAttrib3dv
634 },
635 {
636 /* size 4 */
637 (attrib_func) VertexAttrib4Nbv,
638 (attrib_func) VertexAttrib4Nubv,
639 (attrib_func) VertexAttrib4Nsv,
640 (attrib_func) VertexAttrib4Nusv,
641 (attrib_func) VertexAttrib4Niv,
642 (attrib_func) VertexAttrib4Nuiv,
643 (attrib_func) VertexAttrib4fv,
644 (attrib_func) VertexAttrib4dv
645 }
646 }
647 };
648
649 /**********************************************************************/
650
651
652 GLboolean _ae_create_context( GLcontext *ctx )
653 {
654 if (ctx->aelt_context)
655 return GL_TRUE;
656
657 ctx->aelt_context = MALLOC( sizeof(AEcontext) );
658 if (!ctx->aelt_context)
659 return GL_FALSE;
660
661 AE_CONTEXT(ctx)->NewState = ~0;
662 return GL_TRUE;
663 }
664
665
666 void _ae_destroy_context( GLcontext *ctx )
667 {
668 if ( AE_CONTEXT( ctx ) ) {
669 FREE( ctx->aelt_context );
670 ctx->aelt_context = 0;
671 }
672 }
673
674
675 /**
676 * Make a list of per-vertex functions to call for each glArrayElement call.
677 * These functions access the array data (i.e. glVertex, glColor, glNormal,
678 * etc).
679 * Note: this may be called during display list construction.
680 */
681 static void _ae_update_state( GLcontext *ctx )
682 {
683 AEcontext *actx = AE_CONTEXT(ctx);
684 AEarray *aa = actx->arrays;
685 AEattrib *at = actx->attribs;
686 GLuint i;
687
688 /* conventional vertex arrays */
689 if (ctx->Array.Index.Enabled) {
690 aa->array = &ctx->Array.Index;
691 aa->func = IndexFuncs[TYPE_IDX(aa->array->Type)];
692 aa++;
693 }
694 if (ctx->Array.EdgeFlag.Enabled) {
695 aa->array = &ctx->Array.EdgeFlag;
696 aa->func = (array_func) glEdgeFlagv;
697 aa++;
698 }
699 if (ctx->Array.Normal.Enabled) {
700 aa->array = &ctx->Array.Normal;
701 aa->func = NormalFuncs[TYPE_IDX(aa->array->Type)];
702 aa++;
703 }
704 if (ctx->Array.Color.Enabled) {
705 aa->array = &ctx->Array.Color;
706 aa->func = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
707 aa++;
708 }
709 if (ctx->Array.SecondaryColor.Enabled) {
710 aa->array = &ctx->Array.SecondaryColor;
711 aa->func = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
712 aa++;
713 }
714 if (ctx->Array.FogCoord.Enabled) {
715 aa->array = &ctx->Array.FogCoord;
716 aa->func = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
717 aa++;
718 }
719 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
720 if (ctx->Array.TexCoord[i].Enabled) {
721 /* NOTE: we use generic glVertexAttrib functions here.
722 * If we ever de-alias conventional/generic vertex attribs this
723 * will have to change.
724 */
725 struct gl_client_array *attribArray = &ctx->Array.TexCoord[i];
726 at->array = attribArray;
727 at->func = AttribFuncs[at->array->Normalized][at->array->Size-1][TYPE_IDX(at->array->Type)];
728 at->index = VERT_ATTRIB_TEX0 + i;
729 at++;
730 }
731 }
732
733 /* generic vertex attribute arrays */
734 for (i = 1; i < VERT_ATTRIB_MAX; i++) { /* skip zero! */
735 if (ctx->Array.VertexAttrib[i].Enabled) {
736 struct gl_client_array *attribArray = &ctx->Array.VertexAttrib[i];
737 at->array = attribArray;
738 /* Note: we can't grab the _glapi_Dispatch->VertexAttrib1fvNV
739 * function pointer here (for float arrays) since the pointer may
740 * change from one execution of _ae_loopback_array_elt() to
741 * the next. Doing so caused UT to break.
742 */
743 at->func = AttribFuncs[at->array->Normalized][at->array->Size-1][TYPE_IDX(at->array->Type)];
744 at->index = i;
745 at++;
746 }
747 }
748
749 /* finally, vertex position */
750 if (ctx->Array.VertexAttrib[0].Enabled) {
751 /* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's
752 * issued as the last (proviking) attribute).
753 */
754 aa->array = &ctx->Array.VertexAttrib[0];
755 assert(aa->array->Size >= 2); /* XXX fix someday? */
756 aa->func = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
757 aa++;
758 }
759 else if (ctx->Array.Vertex.Enabled) {
760 aa->array = &ctx->Array.Vertex;
761 aa->func = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
762 aa++;
763 }
764
765 ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);
766 ASSERT(aa - actx->arrays < 32);
767 at->func = NULL; /* terminate the list */
768 aa->func = NULL; /* terminate the list */
769
770 actx->NewState = 0;
771 }
772
773
774 /**
775 * Called via glArrayElement() and glDrawArrays().
776 * Issue the glNormal, glVertex, glColor, glVertexAttrib, etc functions
777 * for all enabled vertex arrays (for elt-th element).
778 * Note: this may be called during display list construction.
779 */
780 void GLAPIENTRY _ae_loopback_array_elt( GLint elt )
781 {
782 GET_CURRENT_CONTEXT(ctx);
783 const AEcontext *actx = AE_CONTEXT(ctx);
784 const AEarray *aa;
785 const AEattrib *at;
786
787 if (actx->NewState)
788 _ae_update_state( ctx );
789
790 /* generic attributes */
791 for (at = actx->attribs; at->func; at++) {
792 const GLubyte *src = at->array->BufferObj->Data
793 + (unsigned long) at->array->Ptr
794 + elt * at->array->StrideB;
795 at->func( at->index, src );
796 }
797
798 /* conventional arrays */
799 for (aa = actx->arrays; aa->func ; aa++) {
800 const GLubyte *src = aa->array->BufferObj->Data
801 + (unsigned long) aa->array->Ptr
802 + elt * aa->array->StrideB;
803 aa->func( src );
804 }
805 }
806
807
808
809 void _ae_invalidate_state( GLcontext *ctx, GLuint new_state )
810 {
811 AE_CONTEXT(ctx)->NewState |= new_state;
812 }