fb410540b6c429a0f13bea0459398c16af89ab94
[mesa.git] / src / mesa / main / varray.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2003 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
26 #include "glheader.h"
27 #include "imports.h"
28 #include "context.h"
29 #include "enable.h"
30 #include "enums.h"
31 #include "dlist.h"
32 #include "texstate.h"
33 #include "mtypes.h"
34 #include "varray.h"
35
36
37 void
38 _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
39 {
40 GET_CURRENT_CONTEXT(ctx);
41 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
42
43 if (size < 2 || size > 4) {
44 _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
45 return;
46 }
47 if (stride < 0) {
48 _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
49 return;
50 }
51
52 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
53 _mesa_debug(ctx, "glVertexPointer( sz %d type %s stride %d )\n", size,
54 _mesa_lookup_enum_by_nr( type ), stride);
55
56 /* always need to check that <type> is legal */
57 switch (type) {
58 case GL_SHORT:
59 ctx->Array.Vertex.StrideB = size * sizeof(GLshort);
60 break;
61 case GL_INT:
62 ctx->Array.Vertex.StrideB = size * sizeof(GLint);
63 break;
64 case GL_FLOAT:
65 ctx->Array.Vertex.StrideB = size * sizeof(GLfloat);
66 break;
67 case GL_DOUBLE:
68 ctx->Array.Vertex.StrideB = size * sizeof(GLdouble);
69 break;
70 default:
71 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
72 return;
73 }
74
75 if (stride)
76 ctx->Array.Vertex.StrideB = stride;
77
78 ctx->Array.Vertex.Size = size;
79 ctx->Array.Vertex.Type = type;
80 ctx->Array.Vertex.Stride = stride;
81 ctx->Array.Vertex.Ptr = (GLubyte *) ptr;
82 #if FEATURE_ARB_vertex_buffer_object
83 ctx->Array.Vertex.BufferObj = ctx->Array.ArrayBufferObj;
84 #endif
85 ctx->NewState |= _NEW_ARRAY;
86 ctx->Array.NewState |= _NEW_ARRAY_VERTEX;
87
88 if (ctx->Driver.VertexPointer)
89 ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );
90 }
91
92
93 void
94 _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
95 {
96 GET_CURRENT_CONTEXT(ctx);
97 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
98
99 if (stride < 0) {
100 _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
101 return;
102 }
103
104 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
105 _mesa_debug(ctx, "glNormalPointer( type %s stride %d )\n",
106 _mesa_lookup_enum_by_nr( type ), stride);
107
108 switch (type) {
109 case GL_BYTE:
110 ctx->Array.Normal.StrideB = 3 * sizeof(GLbyte);
111 break;
112 case GL_SHORT:
113 ctx->Array.Normal.StrideB = 3 * sizeof(GLshort);
114 break;
115 case GL_INT:
116 ctx->Array.Normal.StrideB = 3 * sizeof(GLint);
117 break;
118 case GL_FLOAT:
119 ctx->Array.Normal.StrideB = 3 * sizeof(GLfloat);
120 break;
121 case GL_DOUBLE:
122 ctx->Array.Normal.StrideB = 3 * sizeof(GLdouble);
123 break;
124 default:
125 _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
126 return;
127 }
128 if (stride)
129 ctx->Array.Normal.StrideB = stride;
130
131 ctx->Array.Normal.Size = 3;
132 ctx->Array.Normal.Type = type;
133 ctx->Array.Normal.Stride = stride;
134 ctx->Array.Normal.Ptr = (GLubyte *) ptr;
135 #if FEATURE_ARB_vertex_buffer_object
136 ctx->Array.Normal.BufferObj = ctx->Array.ArrayBufferObj;
137 #endif
138 ctx->NewState |= _NEW_ARRAY;
139 ctx->Array.NewState |= _NEW_ARRAY_NORMAL;
140
141 if (ctx->Driver.NormalPointer)
142 ctx->Driver.NormalPointer( ctx, type, stride, ptr );
143 }
144
145
146 void
147 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
148 {
149 GET_CURRENT_CONTEXT(ctx);
150 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
151
152 if (size < 3 || size > 4) {
153 _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
154 return;
155 }
156 if (stride<0) {
157 _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
158 return;
159 }
160
161 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
162 _mesa_debug(ctx, "glColorPointer( sz %d type %s stride %d )\n", size,
163 _mesa_lookup_enum_by_nr( type ), stride);
164
165 switch (type) {
166 case GL_BYTE:
167 ctx->Array.Color.StrideB = size * sizeof(GLbyte);
168 break;
169 case GL_UNSIGNED_BYTE:
170 ctx->Array.Color.StrideB = size * sizeof(GLubyte);
171 break;
172 case GL_SHORT:
173 ctx->Array.Color.StrideB = size * sizeof(GLshort);
174 break;
175 case GL_UNSIGNED_SHORT:
176 ctx->Array.Color.StrideB = size * sizeof(GLushort);
177 break;
178 case GL_INT:
179 ctx->Array.Color.StrideB = size * sizeof(GLint);
180 break;
181 case GL_UNSIGNED_INT:
182 ctx->Array.Color.StrideB = size * sizeof(GLuint);
183 break;
184 case GL_FLOAT:
185 ctx->Array.Color.StrideB = size * sizeof(GLfloat);
186 break;
187 case GL_DOUBLE:
188 ctx->Array.Color.StrideB = size * sizeof(GLdouble);
189 break;
190 default:
191 _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
192 return;
193 }
194
195 if (stride)
196 ctx->Array.Color.StrideB = stride;
197
198 ctx->Array.Color.Size = size;
199 ctx->Array.Color.Type = type;
200 ctx->Array.Color.Stride = stride;
201 ctx->Array.Color.Ptr = (GLubyte *) ptr;
202 #if FEATURE_ARB_vertex_buffer_object
203 ctx->Array.Color.BufferObj = ctx->Array.ArrayBufferObj;
204 #endif
205 ctx->NewState |= _NEW_ARRAY;
206 ctx->Array.NewState |= _NEW_ARRAY_COLOR0;
207
208 if (ctx->Driver.ColorPointer)
209 ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
210 }
211
212
213 void
214 _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
215 {
216 GET_CURRENT_CONTEXT(ctx);
217 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
218
219 if (stride < 0) {
220 _mesa_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" );
221 return;
222 }
223
224 switch (type) {
225 case GL_FLOAT:
226 ctx->Array.FogCoord.StrideB = sizeof(GLfloat);
227 break;
228 case GL_DOUBLE:
229 ctx->Array.FogCoord.StrideB = sizeof(GLdouble);
230 break;
231 default:
232 _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" );
233 return;
234 }
235
236 if (stride)
237 ctx->Array.FogCoord.StrideB = stride;
238
239 ctx->Array.FogCoord.Size = 1;
240 ctx->Array.FogCoord.Type = type;
241 ctx->Array.FogCoord.Stride = stride;
242 ctx->Array.FogCoord.Ptr = (GLubyte *) ptr;
243 #if FEATURE_ARB_vertex_buffer_object
244 ctx->Array.FogCoord.BufferObj = ctx->Array.ArrayBufferObj;
245 #endif
246 ctx->NewState |= _NEW_ARRAY;
247 ctx->Array.NewState |= _NEW_ARRAY_FOGCOORD;
248
249 if (ctx->Driver.FogCoordPointer)
250 ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );
251 }
252
253
254 void
255 _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
256 {
257 GET_CURRENT_CONTEXT(ctx);
258 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
259
260 if (stride < 0) {
261 _mesa_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
262 return;
263 }
264
265 switch (type) {
266 case GL_UNSIGNED_BYTE:
267 ctx->Array.Index.StrideB = sizeof(GLubyte);
268 break;
269 case GL_SHORT:
270 ctx->Array.Index.StrideB = sizeof(GLshort);
271 break;
272 case GL_INT:
273 ctx->Array.Index.StrideB = sizeof(GLint);
274 break;
275 case GL_FLOAT:
276 ctx->Array.Index.StrideB = sizeof(GLfloat);
277 break;
278 case GL_DOUBLE:
279 ctx->Array.Index.StrideB = sizeof(GLdouble);
280 break;
281 default:
282 _mesa_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
283 return;
284 }
285
286 if (stride)
287 ctx->Array.Index.StrideB = stride;
288
289 ctx->Array.Index.Size = 1;
290 ctx->Array.Index.Type = type;
291 ctx->Array.Index.Stride = stride;
292 ctx->Array.Index.Ptr = (GLubyte *) ptr;
293 #if FEATURE_ARB_vertex_buffer_object
294 ctx->Array.Index.BufferObj = ctx->Array.ArrayBufferObj;
295 #endif
296 ctx->NewState |= _NEW_ARRAY;
297 ctx->Array.NewState |= _NEW_ARRAY_INDEX;
298
299 if (ctx->Driver.IndexPointer)
300 ctx->Driver.IndexPointer( ctx, type, stride, ptr );
301 }
302
303
304 void
305 _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
306 GLsizei stride, const GLvoid *ptr)
307 {
308 GET_CURRENT_CONTEXT(ctx);
309 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
310
311 if (size != 3 && size != 4) {
312 _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(size)" );
313 return;
314 }
315 if (stride < 0) {
316 _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(stride)" );
317 return;
318 }
319
320 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
321 _mesa_debug(ctx, "glSecondaryColorPointer( sz %d type %s stride %d )\n",
322 size, _mesa_lookup_enum_by_nr( type ), stride);
323
324 switch (type) {
325 case GL_BYTE:
326 ctx->Array.SecondaryColor.StrideB = size * sizeof(GLbyte);
327 break;
328 case GL_UNSIGNED_BYTE:
329 ctx->Array.SecondaryColor.StrideB = size * sizeof(GLubyte);
330 break;
331 case GL_SHORT:
332 ctx->Array.SecondaryColor.StrideB = size * sizeof(GLshort);
333 break;
334 case GL_UNSIGNED_SHORT:
335 ctx->Array.SecondaryColor.StrideB = size * sizeof(GLushort);
336 break;
337 case GL_INT:
338 ctx->Array.SecondaryColor.StrideB = size * sizeof(GLint);
339 break;
340 case GL_UNSIGNED_INT:
341 ctx->Array.SecondaryColor.StrideB = size * sizeof(GLuint);
342 break;
343 case GL_FLOAT:
344 ctx->Array.SecondaryColor.StrideB = size * sizeof(GLfloat);
345 break;
346 case GL_DOUBLE:
347 ctx->Array.SecondaryColor.StrideB = size * sizeof(GLdouble);
348 break;
349 default:
350 _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
351 return;
352 }
353
354 if (stride)
355 ctx->Array.SecondaryColor.StrideB = stride;
356
357 ctx->Array.SecondaryColor.Size = 3; /* hardwire */
358 ctx->Array.SecondaryColor.Type = type;
359 ctx->Array.SecondaryColor.Stride = stride;
360 ctx->Array.SecondaryColor.Ptr = (GLubyte *) ptr;
361 #if FEATURE_ARB_vertex_buffer_object
362 ctx->Array.SecondaryColor.BufferObj = ctx->Array.ArrayBufferObj;
363 #endif
364 ctx->NewState |= _NEW_ARRAY;
365 ctx->Array.NewState |= _NEW_ARRAY_COLOR1;
366
367 if (ctx->Driver.SecondaryColorPointer)
368 ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
369 }
370
371
372 void
373 _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
374 const GLvoid *ptr)
375 {
376 GET_CURRENT_CONTEXT(ctx);
377 GLuint texUnit = ctx->Array.ActiveTexture;
378 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
379
380 if (size < 1 || size > 4) {
381 _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
382 return;
383 }
384 if (stride < 0) {
385 _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
386 return;
387 }
388
389 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
390 _mesa_debug(ctx, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n",
391 texUnit, size, _mesa_lookup_enum_by_nr( type ), stride);
392
393 /* always need to check that <type> is legal */
394 switch (type) {
395 case GL_SHORT:
396 ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLshort);
397 break;
398 case GL_INT:
399 ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLint);
400 break;
401 case GL_FLOAT:
402 ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLfloat);
403 break;
404 case GL_DOUBLE:
405 ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLdouble);
406 break;
407 default:
408 _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
409 return;
410 }
411
412 if (stride)
413 ctx->Array.TexCoord[texUnit].StrideB = stride;
414
415 ctx->Array.TexCoord[texUnit].Size = size;
416 ctx->Array.TexCoord[texUnit].Type = type;
417 ctx->Array.TexCoord[texUnit].Stride = stride;
418 ctx->Array.TexCoord[texUnit].Ptr = (GLubyte *) ptr;
419 #if FEATURE_ARB_vertex_buffer_object
420 ctx->Array.TexCoord[texUnit].BufferObj = ctx->Array.ArrayBufferObj;
421 #endif
422 ctx->NewState |= _NEW_ARRAY;
423 ctx->Array.NewState |= _NEW_ARRAY_TEXCOORD(texUnit);
424
425 if (ctx->Driver.TexCoordPointer)
426 ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
427 }
428
429
430 void
431 _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *vptr)
432 {
433 GET_CURRENT_CONTEXT(ctx);
434 const GLboolean *ptr = (GLboolean *)vptr;
435 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
436
437 if (stride<0) {
438 _mesa_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
439 return;
440 }
441 ctx->Array.EdgeFlag.Stride = stride;
442 ctx->Array.EdgeFlag.StrideB = stride ? stride : sizeof(GLboolean);
443 ctx->Array.EdgeFlag.Ptr = (GLboolean *) ptr;
444 #if FEATURE_ARB_vertex_buffer_object
445 ctx->Array.EdgeFlag.BufferObj = ctx->Array.ArrayBufferObj;
446 #endif
447 ctx->NewState |= _NEW_ARRAY;
448 ctx->Array.NewState |= _NEW_ARRAY_EDGEFLAG;
449
450 if (ctx->Driver.EdgeFlagPointer)
451 ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
452 }
453
454
455 #if FEATURE_NV_vertex_program
456 void
457 _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
458 GLsizei stride, const GLvoid *ptr)
459 {
460 GET_CURRENT_CONTEXT(ctx);
461 ASSERT_OUTSIDE_BEGIN_END(ctx);
462
463 if (index >= VERT_ATTRIB_MAX) {
464 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
465 return;
466 }
467
468 if (size < 1 || size > 4) {
469 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size)");
470 return;
471 }
472
473 if (stride < 0) {
474 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(stride)");
475 return;
476 }
477
478 if (type == GL_UNSIGNED_BYTE && size != 4) {
479 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)");
480 return;
481 }
482
483 /* check for valid 'type' and compute StrideB right away */
484 switch (type) {
485 case GL_UNSIGNED_BYTE:
486 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLubyte);
487 break;
488 case GL_SHORT:
489 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLshort);
490 break;
491 case GL_FLOAT:
492 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLfloat);
493 break;
494 case GL_DOUBLE:
495 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLdouble);
496 break;
497 default:
498 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" );
499 return;
500 }
501
502 if (stride)
503 ctx->Array.VertexAttrib[index].StrideB = stride;
504
505 ctx->Array.VertexAttrib[index].Stride = stride;
506 ctx->Array.VertexAttrib[index].Size = size;
507 ctx->Array.VertexAttrib[index].Type = type;
508 ctx->Array.VertexAttrib[index].Ptr = (GLubyte *) ptr;
509 #if FEATURE_ARB_vertex_buffer_object
510 ctx->Array.VertexAttrib[index].BufferObj = ctx->Array.ArrayBufferObj;
511 #endif
512 ctx->NewState |= _NEW_ARRAY;
513 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
514
515 if (ctx->Driver.VertexAttribPointer)
516 ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
517 }
518 #endif
519
520
521 #if FEATURE_ARB_vertex_program
522 void
523 _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
524 GLboolean normalized,
525 GLsizei stride, const GLvoid *ptr)
526 {
527 GET_CURRENT_CONTEXT(ctx);
528 ASSERT_OUTSIDE_BEGIN_END(ctx);
529
530 if (index >= ctx->Const.MaxVertexProgramAttribs) {
531 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)");
532 return;
533 }
534
535 if (size < 1 || size > 4) {
536 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size)");
537 return;
538 }
539
540 if (stride < 0) {
541 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(stride)");
542 return;
543 }
544
545 if (type == GL_UNSIGNED_BYTE && size != 4) {
546 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size!=4)");
547 return;
548 }
549
550 /* check for valid 'type' and compute StrideB right away */
551 /* NOTE: more types are supported here than in the NV extension */
552 switch (type) {
553 case GL_BYTE:
554 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLbyte);
555 break;
556 case GL_UNSIGNED_BYTE:
557 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLubyte);
558 break;
559 case GL_SHORT:
560 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLshort);
561 break;
562 case GL_UNSIGNED_SHORT:
563 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLushort);
564 break;
565 case GL_INT:
566 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLint);
567 break;
568 case GL_UNSIGNED_INT:
569 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLuint);
570 break;
571 case GL_FLOAT:
572 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLfloat);
573 break;
574 case GL_DOUBLE:
575 ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLdouble);
576 break;
577 default:
578 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerARB(type)" );
579 return;
580 }
581
582 if (stride)
583 ctx->Array.VertexAttrib[index].StrideB = stride;
584
585 ctx->Array.VertexAttrib[index].Stride = stride;
586 ctx->Array.VertexAttrib[index].Size = size;
587 ctx->Array.VertexAttrib[index].Type = type;
588 ctx->Array.VertexAttrib[index].Normalized = normalized;
589 ctx->Array.VertexAttrib[index].Ptr = (GLubyte *) ptr;
590 #if FEATURE_ARB_vertex_buffer_object
591 ctx->Array.VertexAttrib[index].BufferObj = ctx->Array.ArrayBufferObj;
592 #endif
593 ctx->NewState |= _NEW_ARRAY;
594 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
595
596 /* XXX fix
597 if (ctx->Driver.VertexAttribPointer)
598 ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
599 */
600 }
601 #endif
602
603
604 void
605 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
606 GLsizei count, const GLvoid *ptr)
607 {
608 (void) count;
609 _mesa_VertexPointer(size, type, stride, ptr);
610 }
611
612
613 void
614 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
615 const GLvoid *ptr)
616 {
617 (void) count;
618 _mesa_NormalPointer(type, stride, ptr);
619 }
620
621
622 void
623 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
624 const GLvoid *ptr)
625 {
626 (void) count;
627 _mesa_ColorPointer(size, type, stride, ptr);
628 }
629
630
631 void
632 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
633 const GLvoid *ptr)
634 {
635 (void) count;
636 _mesa_IndexPointer(type, stride, ptr);
637 }
638
639
640 void
641 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
642 GLsizei count, const GLvoid *ptr)
643 {
644 (void) count;
645 _mesa_TexCoordPointer(size, type, stride, ptr);
646 }
647
648
649 void
650 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
651 {
652 (void) count;
653 _mesa_EdgeFlagPointer(stride, ptr);
654 }
655
656
657 void
658 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
659 {
660 GET_CURRENT_CONTEXT(ctx);
661 GLboolean tflag, cflag, nflag; /* enable/disable flags */
662 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
663
664 GLenum ctype = 0; /* color type */
665 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
666 GLint defstride; /* default stride */
667 GLint c, f;
668 GLint coordUnitSave;
669
670 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
671
672 f = sizeof(GLfloat);
673 c = f * ((4*sizeof(GLubyte) + (f-1)) / f);
674
675 if (stride<0) {
676 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
677 return;
678 }
679
680 switch (format) {
681 case GL_V2F:
682 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
683 tcomps = 0; ccomps = 0; vcomps = 2;
684 voffset = 0;
685 defstride = 2*f;
686 break;
687 case GL_V3F:
688 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
689 tcomps = 0; ccomps = 0; vcomps = 3;
690 voffset = 0;
691 defstride = 3*f;
692 break;
693 case GL_C4UB_V2F:
694 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
695 tcomps = 0; ccomps = 4; vcomps = 2;
696 ctype = GL_UNSIGNED_BYTE;
697 coffset = 0;
698 voffset = c;
699 defstride = c + 2*f;
700 break;
701 case GL_C4UB_V3F:
702 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
703 tcomps = 0; ccomps = 4; vcomps = 3;
704 ctype = GL_UNSIGNED_BYTE;
705 coffset = 0;
706 voffset = c;
707 defstride = c + 3*f;
708 break;
709 case GL_C3F_V3F:
710 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
711 tcomps = 0; ccomps = 3; vcomps = 3;
712 ctype = GL_FLOAT;
713 coffset = 0;
714 voffset = 3*f;
715 defstride = 6*f;
716 break;
717 case GL_N3F_V3F:
718 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
719 tcomps = 0; ccomps = 0; vcomps = 3;
720 noffset = 0;
721 voffset = 3*f;
722 defstride = 6*f;
723 break;
724 case GL_C4F_N3F_V3F:
725 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
726 tcomps = 0; ccomps = 4; vcomps = 3;
727 ctype = GL_FLOAT;
728 coffset = 0;
729 noffset = 4*f;
730 voffset = 7*f;
731 defstride = 10*f;
732 break;
733 case GL_T2F_V3F:
734 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
735 tcomps = 2; ccomps = 0; vcomps = 3;
736 voffset = 2*f;
737 defstride = 5*f;
738 break;
739 case GL_T4F_V4F:
740 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
741 tcomps = 4; ccomps = 0; vcomps = 4;
742 voffset = 4*f;
743 defstride = 8*f;
744 break;
745 case GL_T2F_C4UB_V3F:
746 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
747 tcomps = 2; ccomps = 4; vcomps = 3;
748 ctype = GL_UNSIGNED_BYTE;
749 coffset = 2*f;
750 voffset = c+2*f;
751 defstride = c+5*f;
752 break;
753 case GL_T2F_C3F_V3F:
754 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
755 tcomps = 2; ccomps = 3; vcomps = 3;
756 ctype = GL_FLOAT;
757 coffset = 2*f;
758 voffset = 5*f;
759 defstride = 8*f;
760 break;
761 case GL_T2F_N3F_V3F:
762 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
763 tcomps = 2; ccomps = 0; vcomps = 3;
764 noffset = 2*f;
765 voffset = 5*f;
766 defstride = 8*f;
767 break;
768 case GL_T2F_C4F_N3F_V3F:
769 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
770 tcomps = 2; ccomps = 4; vcomps = 3;
771 ctype = GL_FLOAT;
772 coffset = 2*f;
773 noffset = 6*f;
774 voffset = 9*f;
775 defstride = 12*f;
776 break;
777 case GL_T4F_C4F_N3F_V4F:
778 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
779 tcomps = 4; ccomps = 4; vcomps = 4;
780 ctype = GL_FLOAT;
781 coffset = 4*f;
782 noffset = 8*f;
783 voffset = 11*f;
784 defstride = 15*f;
785 break;
786 default:
787 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
788 return;
789 }
790
791 if (stride==0) {
792 stride = defstride;
793 }
794
795 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
796 _mesa_DisableClientState( GL_INDEX_ARRAY );
797
798 /* Texcoords */
799 coordUnitSave = ctx->Array.ActiveTexture;
800 if (tflag) {
801 GLint i;
802 GLint factor = ctx->Array.TexCoordInterleaveFactor;
803 for (i = 0; i < factor; i++) {
804 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
805 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
806 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
807 (GLubyte *) pointer + i * coffset );
808 }
809 for (i = factor; i < (GLint) ctx->Const.MaxTextureCoordUnits; i++) {
810 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
811 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
812 }
813 }
814 else {
815 GLint i;
816 for (i = 0; i < (GLint) ctx->Const.MaxTextureCoordUnits; i++) {
817 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
818 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
819 }
820 }
821 /* Restore texture coordinate unit index */
822 _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + coordUnitSave) );
823
824
825 /* Color */
826 if (cflag) {
827 _mesa_EnableClientState( GL_COLOR_ARRAY );
828 _mesa_ColorPointer( ccomps, ctype, stride,
829 (GLubyte*) pointer + coffset );
830 }
831 else {
832 _mesa_DisableClientState( GL_COLOR_ARRAY );
833 }
834
835
836 /* Normals */
837 if (nflag) {
838 _mesa_EnableClientState( GL_NORMAL_ARRAY );
839 _mesa_NormalPointer( GL_FLOAT, stride,
840 (GLubyte*) pointer + noffset );
841 }
842 else {
843 _mesa_DisableClientState( GL_NORMAL_ARRAY );
844 }
845
846 _mesa_EnableClientState( GL_VERTEX_ARRAY );
847 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
848 (GLubyte *) pointer + voffset );
849 }
850
851
852 void
853 _mesa_LockArraysEXT(GLint first, GLsizei count)
854 {
855 GET_CURRENT_CONTEXT(ctx);
856 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
857
858 if (MESA_VERBOSE & VERBOSE_API)
859 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
860
861 if (first == 0 && count > 0 &&
862 count <= (GLint) ctx->Const.MaxArrayLockSize) {
863 ctx->Array.LockFirst = first;
864 ctx->Array.LockCount = count;
865 }
866 else {
867 ctx->Array.LockFirst = 0;
868 ctx->Array.LockCount = 0;
869 }
870
871 ctx->NewState |= _NEW_ARRAY;
872 ctx->Array.NewState |= _NEW_ARRAY_ALL;
873
874 if (ctx->Driver.LockArraysEXT)
875 ctx->Driver.LockArraysEXT( ctx, first, count );
876 }
877
878
879 void
880 _mesa_UnlockArraysEXT( void )
881 {
882 GET_CURRENT_CONTEXT(ctx);
883 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
884
885 if (MESA_VERBOSE & VERBOSE_API)
886 _mesa_debug(ctx, "glUnlockArrays\n");
887
888 ctx->Array.LockFirst = 0;
889 ctx->Array.LockCount = 0;
890 ctx->NewState |= _NEW_ARRAY;
891 ctx->Array.NewState |= _NEW_ARRAY_ALL;
892
893 if (ctx->Driver.UnlockArraysEXT)
894 ctx->Driver.UnlockArraysEXT( ctx );
895 }
896
897
898 /* GL_EXT_multi_draw_arrays */
899 /* Somebody forgot to spec the first and count parameters as const! <sigh> */
900 void
901 _mesa_MultiDrawArraysEXT( GLenum mode, GLint *first,
902 GLsizei *count, GLsizei primcount )
903 {
904 GET_CURRENT_CONTEXT(ctx);
905 GLint i;
906
907 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
908
909 for (i = 0; i < primcount; i++) {
910 if (count[i] > 0) {
911 (ctx->Exec->DrawArrays)(mode, first[i], count[i]);
912 }
913 }
914 }
915
916
917 /* GL_EXT_multi_draw_arrays */
918 void
919 _mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
920 const GLvoid **indices, GLsizei primcount )
921 {
922 GET_CURRENT_CONTEXT(ctx);
923 GLint i;
924
925 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
926
927 if (ctx->Array.ElementArrayBufferObj->Name) {
928 /* use indices in the buffer object */
929 ASSERT(ctx->Array.ElementArrayBufferObj->Data);
930 indices = (const GLvoid **) ctx->Array.ElementArrayBufferObj->Data;
931 }
932
933 for (i = 0; i < primcount; i++) {
934 if (count[i] > 0) {
935 (ctx->Exec->DrawElements)(mode, count[i], type, indices[i]);
936 }
937 }
938 }
939
940
941 /* GL_IBM_multimode_draw_arrays */
942 void
943 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
944 const GLsizei * count,
945 GLsizei primcount, GLint modestride )
946 {
947 GET_CURRENT_CONTEXT(ctx);
948 GLint i;
949
950 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
951
952 for ( i = 0 ; i < primcount ; i++ ) {
953 if ( count[i] > 0 ) {
954 (ctx->Exec->DrawArrays)( *(GLenum *) ((char *) mode + (i * modestride)),
955 first[i], count[i] );
956 }
957 }
958 }
959
960
961 /* GL_IBM_multimode_draw_arrays */
962 void
963 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
964 GLenum type, const GLvoid * const * indices,
965 GLsizei primcount, GLint modestride )
966 {
967 GET_CURRENT_CONTEXT(ctx);
968 GLint i;
969
970 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
971
972 /* XXX not sure about ARB_vertex_buffer_object handling here */
973
974 for ( i = 0 ; i < primcount ; i++ ) {
975 if ( count[i] > 0 ) {
976 (ctx->Exec->DrawElements)( *(GLenum *) ((char *) mode + (i * modestride)),
977 count[i], type, indices[i] );
978 }
979 }
980 }
981
982
983 /**********************************************************************/
984 /***** Initialization *****/
985 /**********************************************************************/
986
987 void
988 _mesa_init_varray( GLcontext * ctx )
989 {
990 GLuint i;
991
992 /* Vertex arrays */
993 ctx->Array.Vertex.Size = 4;
994 ctx->Array.Vertex.Type = GL_FLOAT;
995 ctx->Array.Vertex.Stride = 0;
996 ctx->Array.Vertex.StrideB = 0;
997 ctx->Array.Vertex.Ptr = NULL;
998 ctx->Array.Vertex.Enabled = GL_FALSE;
999 ctx->Array.Vertex.Flags = CA_CLIENT_DATA;
1000 ctx->Array.Normal.Type = GL_FLOAT;
1001 ctx->Array.Normal.Stride = 0;
1002 ctx->Array.Normal.StrideB = 0;
1003 ctx->Array.Normal.Ptr = NULL;
1004 ctx->Array.Normal.Enabled = GL_FALSE;
1005 ctx->Array.Normal.Flags = CA_CLIENT_DATA;
1006 ctx->Array.Color.Size = 4;
1007 ctx->Array.Color.Type = GL_FLOAT;
1008 ctx->Array.Color.Stride = 0;
1009 ctx->Array.Color.StrideB = 0;
1010 ctx->Array.Color.Ptr = NULL;
1011 ctx->Array.Color.Enabled = GL_FALSE;
1012 ctx->Array.Color.Flags = CA_CLIENT_DATA;
1013 ctx->Array.SecondaryColor.Size = 4;
1014 ctx->Array.SecondaryColor.Type = GL_FLOAT;
1015 ctx->Array.SecondaryColor.Stride = 0;
1016 ctx->Array.SecondaryColor.StrideB = 0;
1017 ctx->Array.SecondaryColor.Ptr = NULL;
1018 ctx->Array.SecondaryColor.Enabled = GL_FALSE;
1019 ctx->Array.SecondaryColor.Flags = CA_CLIENT_DATA;
1020 ctx->Array.FogCoord.Size = 1;
1021 ctx->Array.FogCoord.Type = GL_FLOAT;
1022 ctx->Array.FogCoord.Stride = 0;
1023 ctx->Array.FogCoord.StrideB = 0;
1024 ctx->Array.FogCoord.Ptr = NULL;
1025 ctx->Array.FogCoord.Enabled = GL_FALSE;
1026 ctx->Array.FogCoord.Flags = CA_CLIENT_DATA;
1027 ctx->Array.Index.Type = GL_FLOAT;
1028 ctx->Array.Index.Stride = 0;
1029 ctx->Array.Index.StrideB = 0;
1030 ctx->Array.Index.Ptr = NULL;
1031 ctx->Array.Index.Enabled = GL_FALSE;
1032 ctx->Array.Index.Flags = CA_CLIENT_DATA;
1033 for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
1034 ctx->Array.TexCoord[i].Size = 4;
1035 ctx->Array.TexCoord[i].Type = GL_FLOAT;
1036 ctx->Array.TexCoord[i].Stride = 0;
1037 ctx->Array.TexCoord[i].StrideB = 0;
1038 ctx->Array.TexCoord[i].Ptr = NULL;
1039 ctx->Array.TexCoord[i].Enabled = GL_FALSE;
1040 ctx->Array.TexCoord[i].Flags = CA_CLIENT_DATA;
1041 }
1042 ctx->Array.TexCoordInterleaveFactor = 1;
1043 ctx->Array.EdgeFlag.Stride = 0;
1044 ctx->Array.EdgeFlag.StrideB = 0;
1045 ctx->Array.EdgeFlag.Ptr = NULL;
1046 ctx->Array.EdgeFlag.Enabled = GL_FALSE;
1047 ctx->Array.EdgeFlag.Flags = CA_CLIENT_DATA;
1048 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
1049 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
1050 ctx->Array.TexCoord[i].Size = 4;
1051 ctx->Array.TexCoord[i].Type = GL_FLOAT;
1052 ctx->Array.TexCoord[i].Stride = 0;
1053 ctx->Array.TexCoord[i].StrideB = 0;
1054 ctx->Array.TexCoord[i].Ptr = NULL;
1055 ctx->Array.TexCoord[i].Enabled = GL_FALSE;
1056 ctx->Array.TexCoord[i].Flags = CA_CLIENT_DATA;
1057 }
1058 }