2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 #include "bufferobj.h"
38 #include "main/dispatch.h"
42 * Set the fields of a vertex array.
43 * Also do an error check for GL_ARB_vertex_array_object: check that
44 * all arrays reside in VBOs when using a vertex array object.
46 * \param array the array to update
47 * \param dirtyBit which bit to set in ctx->Array.NewState for this array
48 * \param elementSize size of each array element, in bytes
49 * \param size components per element (1, 2, 3 or 4)
50 * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
51 * \param format either GL_RGBA or GL_BGRA
52 * \param stride stride between elements, in elements
53 * \param normalized are integer types converted to floats in [-1, 1]?
54 * \param ptr the address (or offset inside VBO) of the array data
57 update_array(GLcontext
*ctx
, struct gl_client_array
*array
,
58 GLbitfield dirtyBit
, GLsizei elementSize
,
59 GLint size
, GLenum type
, GLenum format
,
60 GLsizei stride
, GLboolean normalized
, const GLvoid
*ptr
)
62 ASSERT(format
== GL_RGBA
|| format
== GL_BGRA
);
64 if (ctx
->Array
.ArrayObj
->VBOonly
&&
65 ctx
->Array
.ArrayBufferObj
->Name
== 0) {
66 /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs.
67 * Generate GL_INVALID_OPERATION if that's not true.
69 _mesa_error(ctx
, GL_INVALID_OPERATION
,
70 "glVertex/Normal/EtcPointer(non-VBO array)");
76 array
->Format
= format
;
77 array
->Stride
= stride
;
78 array
->StrideB
= stride
? stride
: elementSize
;
79 array
->Normalized
= normalized
;
80 array
->Ptr
= (const GLubyte
*) ptr
;
81 array
->_ElementSize
= elementSize
;
83 _mesa_reference_buffer_object(ctx
, &array
->BufferObj
,
84 ctx
->Array
.ArrayBufferObj
);
86 ctx
->NewState
|= _NEW_ARRAY
;
87 ctx
->Array
.NewState
|= dirtyBit
;
92 _mesa_VertexPointer(GLint size
, GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
95 GET_CURRENT_CONTEXT(ctx
);
96 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
98 if (size
< 2 || size
> 4) {
99 _mesa_error( ctx
, GL_INVALID_VALUE
, "glVertexPointer(size)" );
103 _mesa_error( ctx
, GL_INVALID_VALUE
, "glVertexPointer(stride)" );
107 if (MESA_VERBOSE
&(VERBOSE_VARRAY
|VERBOSE_API
))
108 _mesa_debug(ctx
, "glVertexPointer( sz %d type %s stride %d )\n", size
,
109 _mesa_lookup_enum_by_nr( type
), stride
);
111 /* always need to check that <type> is legal */
114 elementSize
= size
* sizeof(GLshort
);
117 elementSize
= size
* sizeof(GLint
);
120 elementSize
= size
* sizeof(GLfloat
);
123 elementSize
= size
* sizeof(GLdouble
);
126 elementSize
= size
* sizeof(GLhalfARB
);
130 elementSize
= size
* sizeof(GLfixed
);
133 #if FEATURE_vertex_array_byte
135 elementSize
= size
* sizeof(GLbyte
);
139 _mesa_error( ctx
, GL_INVALID_ENUM
, "glVertexPointer(type=%s)",
140 _mesa_lookup_enum_by_nr(type
));
144 update_array(ctx
, &ctx
->Array
.ArrayObj
->Vertex
, _NEW_ARRAY_VERTEX
,
145 elementSize
, size
, type
, GL_RGBA
, stride
, GL_FALSE
, ptr
);
150 _mesa_NormalPointer(GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
153 GET_CURRENT_CONTEXT(ctx
);
154 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
157 _mesa_error( ctx
, GL_INVALID_VALUE
, "glNormalPointer(stride)" );
161 if (MESA_VERBOSE
&(VERBOSE_VARRAY
|VERBOSE_API
))
162 _mesa_debug(ctx
, "glNormalPointer( type %s stride %d )\n",
163 _mesa_lookup_enum_by_nr( type
), stride
);
167 elementSize
= 3 * sizeof(GLbyte
);
170 elementSize
= 3 * sizeof(GLshort
);
173 elementSize
= 3 * sizeof(GLint
);
176 elementSize
= 3 * sizeof(GLfloat
);
179 elementSize
= 3 * sizeof(GLdouble
);
182 elementSize
= 3 * sizeof(GLhalfARB
);
186 elementSize
= 3 * sizeof(GLfixed
);
190 _mesa_error( ctx
, GL_INVALID_ENUM
, "glNormalPointer(type=%s)",
191 _mesa_lookup_enum_by_nr(type
));
195 update_array(ctx
, &ctx
->Array
.ArrayObj
->Normal
, _NEW_ARRAY_NORMAL
,
196 elementSize
, 3, type
, GL_RGBA
, stride
, GL_TRUE
, ptr
);
201 _mesa_ColorPointer(GLint size
, GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
205 GET_CURRENT_CONTEXT(ctx
);
206 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
208 if (size
< 3 || size
> 4) {
209 if (!ctx
->Extensions
.EXT_vertex_array_bgra
|| size
!= GL_BGRA
) {
210 _mesa_error(ctx
, GL_INVALID_VALUE
, "glColorPointer(size)");
215 _mesa_error( ctx
, GL_INVALID_VALUE
, "glColorPointer(stride)" );
219 if (MESA_VERBOSE
&(VERBOSE_VARRAY
|VERBOSE_API
))
220 _mesa_debug(ctx
, "glColorPointer( sz %d type %s stride %d )\n", size
,
221 _mesa_lookup_enum_by_nr( type
), stride
);
223 if (size
== GL_BGRA
) {
224 if (type
!= GL_UNSIGNED_BYTE
) {
225 _mesa_error(ctx
, GL_INVALID_VALUE
, "glColorPointer(GL_BGRA/GLubyte)");
237 elementSize
= size
* sizeof(GLbyte
);
239 case GL_UNSIGNED_BYTE
:
240 elementSize
= size
* sizeof(GLubyte
);
243 elementSize
= size
* sizeof(GLshort
);
245 case GL_UNSIGNED_SHORT
:
246 elementSize
= size
* sizeof(GLushort
);
249 elementSize
= size
* sizeof(GLint
);
251 case GL_UNSIGNED_INT
:
252 elementSize
= size
* sizeof(GLuint
);
255 elementSize
= size
* sizeof(GLfloat
);
258 elementSize
= size
* sizeof(GLdouble
);
261 elementSize
= size
* sizeof(GLhalfARB
);
265 elementSize
= size
* sizeof(GLfixed
);
269 _mesa_error( ctx
, GL_INVALID_ENUM
, "glColorPointer(type=%s)",
270 _mesa_lookup_enum_by_nr(type
));
274 update_array(ctx
, &ctx
->Array
.ArrayObj
->Color
, _NEW_ARRAY_COLOR0
,
275 elementSize
, size
, type
, format
, stride
, GL_TRUE
, ptr
);
280 _mesa_FogCoordPointerEXT(GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
283 GET_CURRENT_CONTEXT(ctx
);
284 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
287 _mesa_error( ctx
, GL_INVALID_VALUE
, "glFogCoordPointer(stride)" );
293 elementSize
= sizeof(GLfloat
);
296 elementSize
= sizeof(GLdouble
);
299 elementSize
= sizeof(GLhalfARB
);
302 _mesa_error( ctx
, GL_INVALID_ENUM
, "glFogCoordPointer(type)" );
306 update_array(ctx
, &ctx
->Array
.ArrayObj
->FogCoord
, _NEW_ARRAY_FOGCOORD
,
307 elementSize
, 1, type
, GL_RGBA
, stride
, GL_FALSE
, ptr
);
312 _mesa_IndexPointer(GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
315 GET_CURRENT_CONTEXT(ctx
);
316 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
319 _mesa_error( ctx
, GL_INVALID_VALUE
, "glIndexPointer(stride)" );
324 case GL_UNSIGNED_BYTE
:
325 elementSize
= sizeof(GLubyte
);
328 elementSize
= sizeof(GLshort
);
331 elementSize
= sizeof(GLint
);
334 elementSize
= sizeof(GLfloat
);
337 elementSize
= sizeof(GLdouble
);
340 _mesa_error( ctx
, GL_INVALID_ENUM
, "glIndexPointer(type)" );
344 update_array(ctx
, &ctx
->Array
.ArrayObj
->Index
, _NEW_ARRAY_INDEX
,
345 elementSize
, 1, type
, GL_RGBA
, stride
, GL_FALSE
, ptr
);
350 _mesa_SecondaryColorPointerEXT(GLint size
, GLenum type
,
351 GLsizei stride
, const GLvoid
*ptr
)
355 GET_CURRENT_CONTEXT(ctx
);
356 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
358 if (size
!= 3 && size
!= 4) {
359 if (!ctx
->Extensions
.EXT_vertex_array_bgra
|| size
!= GL_BGRA
) {
360 _mesa_error(ctx
, GL_INVALID_VALUE
, "glSecondaryColorPointer(size)");
365 _mesa_error( ctx
, GL_INVALID_VALUE
, "glSecondaryColorPointer(stride)" );
369 if (MESA_VERBOSE
&(VERBOSE_VARRAY
|VERBOSE_API
))
370 _mesa_debug(ctx
, "glSecondaryColorPointer( sz %d type %s stride %d )\n",
371 size
, _mesa_lookup_enum_by_nr( type
), stride
);
373 if (size
== GL_BGRA
) {
374 if (type
!= GL_UNSIGNED_BYTE
) {
375 _mesa_error(ctx
, GL_INVALID_VALUE
, "glColorPointer(GL_BGRA/GLubyte)");
387 elementSize
= size
* sizeof(GLbyte
);
389 case GL_UNSIGNED_BYTE
:
390 elementSize
= size
* sizeof(GLubyte
);
393 elementSize
= size
* sizeof(GLshort
);
395 case GL_UNSIGNED_SHORT
:
396 elementSize
= size
* sizeof(GLushort
);
399 elementSize
= size
* sizeof(GLint
);
401 case GL_UNSIGNED_INT
:
402 elementSize
= size
* sizeof(GLuint
);
405 elementSize
= size
* sizeof(GLfloat
);
408 elementSize
= size
* sizeof(GLdouble
);
411 elementSize
= size
* sizeof(GLhalfARB
);
414 _mesa_error( ctx
, GL_INVALID_ENUM
, "glSecondaryColorPointer(type=%s)",
415 _mesa_lookup_enum_by_nr(type
));
419 update_array(ctx
, &ctx
->Array
.ArrayObj
->SecondaryColor
, _NEW_ARRAY_COLOR1
,
420 elementSize
, size
, type
, format
, stride
, GL_TRUE
, ptr
);
425 _mesa_TexCoordPointer(GLint size
, GLenum type
, GLsizei stride
,
429 GET_CURRENT_CONTEXT(ctx
);
430 const GLuint unit
= ctx
->Array
.ActiveTexture
;
431 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
433 if (size
< 1 || size
> 4) {
434 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexCoordPointer(size)" );
438 _mesa_error( ctx
, GL_INVALID_VALUE
, "glTexCoordPointer(stride)" );
442 if (MESA_VERBOSE
&(VERBOSE_VARRAY
|VERBOSE_API
))
443 _mesa_debug(ctx
, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n",
444 unit
, size
, _mesa_lookup_enum_by_nr( type
), stride
);
446 /* always need to check that <type> is legal */
449 elementSize
= size
* sizeof(GLshort
);
452 elementSize
= size
* sizeof(GLint
);
455 elementSize
= size
* sizeof(GLfloat
);
458 elementSize
= size
* sizeof(GLdouble
);
461 elementSize
= size
* sizeof(GLhalfARB
);
465 elementSize
= size
* sizeof(GLfixed
);
468 #if FEATURE_vertex_array_byte
470 elementSize
= size
* sizeof(GLbyte
);
474 _mesa_error( ctx
, GL_INVALID_ENUM
, "glTexCoordPointer(type=%s)",
475 _mesa_lookup_enum_by_nr(type
));
479 ASSERT(unit
< Elements(ctx
->Array
.ArrayObj
->TexCoord
));
481 update_array(ctx
, &ctx
->Array
.ArrayObj
->TexCoord
[unit
],
482 _NEW_ARRAY_TEXCOORD(unit
),
483 elementSize
, size
, type
, GL_RGBA
, stride
, GL_FALSE
, ptr
);
488 _mesa_EdgeFlagPointer(GLsizei stride
, const GLvoid
*ptr
)
490 GET_CURRENT_CONTEXT(ctx
);
491 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
494 _mesa_error( ctx
, GL_INVALID_VALUE
, "glEdgeFlagPointer(stride)" );
498 update_array(ctx
, &ctx
->Array
.ArrayObj
->EdgeFlag
, _NEW_ARRAY_EDGEFLAG
,
499 sizeof(GLboolean
), 1, GL_UNSIGNED_BYTE
, GL_RGBA
,
500 stride
, GL_FALSE
, ptr
);
505 _mesa_PointSizePointer(GLenum type
, GLsizei stride
, const GLvoid
*ptr
)
508 GET_CURRENT_CONTEXT(ctx
);
509 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
512 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPointSizePointer(stride)" );
518 elementSize
= sizeof(GLfloat
);
522 elementSize
= sizeof(GLfixed
);
526 _mesa_error( ctx
, GL_INVALID_ENUM
, "glPointSizePointer(type)" );
530 update_array(ctx
, &ctx
->Array
.ArrayObj
->PointSize
, _NEW_ARRAY_POINT_SIZE
,
531 elementSize
, 1, type
, GL_RGBA
, stride
, GL_FALSE
, ptr
);
535 #if FEATURE_NV_vertex_program
537 * Set a vertex attribute array.
538 * Note that these arrays DO alias the conventional GL vertex arrays
539 * (position, normal, color, fog, texcoord, etc).
540 * The generic attribute slots at #16 and above are not touched.
543 _mesa_VertexAttribPointerNV(GLuint index
, GLint size
, GLenum type
,
544 GLsizei stride
, const GLvoid
*ptr
)
546 GLboolean normalized
= GL_FALSE
;
549 GET_CURRENT_CONTEXT(ctx
);
550 ASSERT_OUTSIDE_BEGIN_END(ctx
);
552 if (index
>= MAX_NV_VERTEX_PROGRAM_INPUTS
) {
553 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerNV(index)");
557 if (size
< 1 || size
> 4) {
558 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerNV(size)");
563 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerNV(stride)");
567 if (type
== GL_UNSIGNED_BYTE
&& size
!= 4) {
568 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerNV(size!=4)");
572 if (size
== GL_BGRA
) {
573 if (type
!= GL_UNSIGNED_BYTE
) {
574 _mesa_error(ctx
, GL_INVALID_VALUE
,
575 "glVertexAttribPointerNV(GL_BGRA/type)");
581 normalized
= GL_TRUE
;
587 /* check for valid 'type' and compute StrideB right away */
589 case GL_UNSIGNED_BYTE
:
590 normalized
= GL_TRUE
;
591 elementSize
= size
* sizeof(GLubyte
);
594 elementSize
= size
* sizeof(GLshort
);
597 elementSize
= size
* sizeof(GLfloat
);
600 elementSize
= size
* sizeof(GLdouble
);
603 _mesa_error( ctx
, GL_INVALID_ENUM
, "glVertexAttribPointerNV(type=%s)",
604 _mesa_lookup_enum_by_nr(type
));
608 update_array(ctx
, &ctx
->Array
.ArrayObj
->VertexAttrib
[index
],
609 _NEW_ARRAY_ATTRIB(index
),
610 elementSize
, size
, type
, format
, stride
, normalized
, ptr
);
615 #if FEATURE_ARB_vertex_program
617 * Set a generic vertex attribute array.
618 * Note that these arrays DO NOT alias the conventional GL vertex arrays
619 * (position, normal, color, fog, texcoord, etc).
622 _mesa_VertexAttribPointerARB(GLuint index
, GLint size
, GLenum type
,
623 GLboolean normalized
,
624 GLsizei stride
, const GLvoid
*ptr
)
628 GET_CURRENT_CONTEXT(ctx
);
629 ASSERT_OUTSIDE_BEGIN_END(ctx
);
631 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
632 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerARB(index)");
636 if (size
< 1 || size
> 4) {
637 if (!ctx
->Extensions
.EXT_vertex_array_bgra
|| size
!= GL_BGRA
) {
638 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerARB(size)");
644 _mesa_error(ctx
, GL_INVALID_VALUE
, "glVertexAttribPointerARB(stride)");
648 if (size
== GL_BGRA
) {
649 if (type
!= GL_UNSIGNED_BYTE
) {
650 _mesa_error(ctx
, GL_INVALID_VALUE
,
651 "glVertexAttribPointerARB(GL_BGRA/type)");
654 if (normalized
!= GL_TRUE
) {
655 _mesa_error(ctx
, GL_INVALID_VALUE
,
656 "glVertexAttribPointerARB(GL_BGRA/normalized)");
667 /* check for valid 'type' and compute StrideB right away */
668 /* NOTE: more types are supported here than in the NV extension */
671 elementSize
= size
* sizeof(GLbyte
);
673 case GL_UNSIGNED_BYTE
:
674 elementSize
= size
* sizeof(GLubyte
);
677 elementSize
= size
* sizeof(GLshort
);
679 case GL_UNSIGNED_SHORT
:
680 elementSize
= size
* sizeof(GLushort
);
683 elementSize
= size
* sizeof(GLint
);
685 case GL_UNSIGNED_INT
:
686 elementSize
= size
* sizeof(GLuint
);
689 elementSize
= size
* sizeof(GLfloat
);
692 elementSize
= size
* sizeof(GLdouble
);
695 elementSize
= size
* sizeof(GLhalfARB
);
699 elementSize
= size
* sizeof(GLfixed
);
703 _mesa_error( ctx
, GL_INVALID_ENUM
, "glVertexAttribPointerARB(type)" );
707 update_array(ctx
, &ctx
->Array
.ArrayObj
->VertexAttrib
[index
],
708 _NEW_ARRAY_ATTRIB(index
),
709 elementSize
, size
, type
, format
, stride
, normalized
, ptr
);
716 * Set an integer-valued vertex attribute array.
717 * Note that these arrays DO NOT alias the conventional GL vertex arrays
718 * (position, normal, color, fog, texcoord, etc).
721 _mesa_VertexAttribIPointer(GLuint index
, GLint size
, GLenum type
,
722 GLboolean normalized
,
723 GLsizei stride
, const GLvoid
*ptr
)
725 /* NOTE: until we have integer-valued vertex attributes, just
726 * route this through the regular glVertexAttribPointer() function.
728 _mesa_VertexAttribPointerARB(index
, size
, type
, normalized
, stride
, ptr
);
734 _mesa_EnableVertexAttribArrayARB(GLuint index
)
736 GET_CURRENT_CONTEXT(ctx
);
737 ASSERT_OUTSIDE_BEGIN_END(ctx
);
739 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
740 _mesa_error(ctx
, GL_INVALID_VALUE
,
741 "glEnableVertexAttribArrayARB(index)");
745 ASSERT(index
< Elements(ctx
->Array
.ArrayObj
->VertexAttrib
));
747 FLUSH_VERTICES(ctx
, _NEW_ARRAY
);
748 ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Enabled
= GL_TRUE
;
749 ctx
->Array
.ArrayObj
->_Enabled
|= _NEW_ARRAY_ATTRIB(index
);
750 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
755 _mesa_DisableVertexAttribArrayARB(GLuint index
)
757 GET_CURRENT_CONTEXT(ctx
);
758 ASSERT_OUTSIDE_BEGIN_END(ctx
);
760 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
761 _mesa_error(ctx
, GL_INVALID_VALUE
,
762 "glEnableVertexAttribArrayARB(index)");
766 ASSERT(index
< Elements(ctx
->Array
.ArrayObj
->VertexAttrib
));
768 FLUSH_VERTICES(ctx
, _NEW_ARRAY
);
769 ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Enabled
= GL_FALSE
;
770 ctx
->Array
.ArrayObj
->_Enabled
&= ~_NEW_ARRAY_ATTRIB(index
);
771 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
776 * Return info for a vertex attribute array (no alias with legacy
777 * vertex attributes (pos, normal, color, etc)). This function does
778 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
781 get_vertex_array_attrib(GLcontext
*ctx
, GLuint index
, GLenum pname
,
784 const struct gl_client_array
*array
;
786 if (index
>= MAX_VERTEX_GENERIC_ATTRIBS
) {
787 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(index=%u)", caller
, index
);
791 ASSERT(index
< Elements(ctx
->Array
.ArrayObj
->VertexAttrib
));
793 array
= &ctx
->Array
.ArrayObj
->VertexAttrib
[index
];
796 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB
:
797 return array
->Enabled
;
798 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB
:
800 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB
:
801 return array
->Stride
;
802 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB
:
804 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB
:
805 return array
->Normalized
;
806 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB
:
807 return array
->BufferObj
->Name
;
809 _mesa_error(ctx
, GL_INVALID_ENUM
, "%s(pname=0x%x)", caller
, pname
);
816 _mesa_GetVertexAttribfvARB(GLuint index
, GLenum pname
, GLfloat
*params
)
818 GET_CURRENT_CONTEXT(ctx
);
819 ASSERT_OUTSIDE_BEGIN_END(ctx
);
821 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
823 _mesa_error(ctx
, GL_INVALID_OPERATION
,
824 "glGetVertexAttribfv(index==0)");
827 const GLfloat
*v
= ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
];
828 FLUSH_CURRENT(ctx
, 0);
833 params
[0] = (GLfloat
) get_vertex_array_attrib(ctx
, index
, pname
,
834 "glGetVertexAttribfv");
840 _mesa_GetVertexAttribdvARB(GLuint index
, GLenum pname
, GLdouble
*params
)
842 GET_CURRENT_CONTEXT(ctx
);
843 ASSERT_OUTSIDE_BEGIN_END(ctx
);
845 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
847 _mesa_error(ctx
, GL_INVALID_OPERATION
,
848 "glGetVertexAttribdv(index==0)");
851 const GLfloat
*v
= ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
];
852 FLUSH_CURRENT(ctx
, 0);
853 params
[0] = (GLdouble
) v
[0];
854 params
[1] = (GLdouble
) v
[1];
855 params
[2] = (GLdouble
) v
[2];
856 params
[3] = (GLdouble
) v
[3];
860 params
[0] = (GLdouble
) get_vertex_array_attrib(ctx
, index
, pname
,
861 "glGetVertexAttribdv");
867 _mesa_GetVertexAttribivARB(GLuint index
, GLenum pname
, GLint
*params
)
869 GET_CURRENT_CONTEXT(ctx
);
870 ASSERT_OUTSIDE_BEGIN_END(ctx
);
872 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
874 _mesa_error(ctx
, GL_INVALID_OPERATION
,
875 "glGetVertexAttribiv(index==0)");
878 const GLfloat
*v
= ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
];
879 FLUSH_CURRENT(ctx
, 0);
880 /* XXX should floats in[0,1] be scaled to full int range? */
881 params
[0] = (GLint
) v
[0];
882 params
[1] = (GLint
) v
[1];
883 params
[2] = (GLint
) v
[2];
884 params
[3] = (GLint
) v
[3];
888 params
[0] = (GLint
) get_vertex_array_attrib(ctx
, index
, pname
,
889 "glGetVertexAttribiv");
896 _mesa_GetVertexAttribIiv(GLuint index
, GLenum pname
, GLint
*params
)
898 GET_CURRENT_CONTEXT(ctx
);
899 ASSERT_OUTSIDE_BEGIN_END(ctx
);
901 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
903 _mesa_error(ctx
, GL_INVALID_OPERATION
,
904 "glGetVertexAttribIiv(index==0)");
907 const GLfloat
*v
= ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
];
908 FLUSH_CURRENT(ctx
, 0);
909 /* XXX we don't have true integer-valued vertex attribs yet */
910 params
[0] = (GLint
) v
[0];
911 params
[1] = (GLint
) v
[1];
912 params
[2] = (GLint
) v
[2];
913 params
[3] = (GLint
) v
[3];
917 params
[0] = (GLint
) get_vertex_array_attrib(ctx
, index
, pname
,
918 "glGetVertexAttribIiv");
925 _mesa_GetVertexAttribIuiv(GLuint index
, GLenum pname
, GLuint
*params
)
927 GET_CURRENT_CONTEXT(ctx
);
928 ASSERT_OUTSIDE_BEGIN_END(ctx
);
930 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
932 _mesa_error(ctx
, GL_INVALID_OPERATION
,
933 "glGetVertexAttribIuiv(index==0)");
936 const GLfloat
*v
= ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
];
937 FLUSH_CURRENT(ctx
, 0);
938 /* XXX we don't have true integer-valued vertex attribs yet */
939 params
[0] = (GLuint
) v
[0];
940 params
[1] = (GLuint
) v
[1];
941 params
[2] = (GLuint
) v
[2];
942 params
[3] = (GLuint
) v
[3];
946 params
[0] = get_vertex_array_attrib(ctx
, index
, pname
,
947 "glGetVertexAttribIuiv");
953 _mesa_GetVertexAttribPointervARB(GLuint index
, GLenum pname
, GLvoid
**pointer
)
955 GET_CURRENT_CONTEXT(ctx
);
956 ASSERT_OUTSIDE_BEGIN_END(ctx
);
958 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
959 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribPointerARB(index)");
963 if (pname
!= GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB
) {
964 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribPointerARB(pname)");
968 ASSERT(index
< Elements(ctx
->Array
.ArrayObj
->VertexAttrib
));
970 *pointer
= (GLvoid
*) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Ptr
;
975 _mesa_VertexPointerEXT(GLint size
, GLenum type
, GLsizei stride
,
976 GLsizei count
, const GLvoid
*ptr
)
979 _mesa_VertexPointer(size
, type
, stride
, ptr
);
984 _mesa_NormalPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
,
988 _mesa_NormalPointer(type
, stride
, ptr
);
993 _mesa_ColorPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
,
997 _mesa_ColorPointer(size
, type
, stride
, ptr
);
1002 _mesa_IndexPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
,
1006 _mesa_IndexPointer(type
, stride
, ptr
);
1011 _mesa_TexCoordPointerEXT(GLint size
, GLenum type
, GLsizei stride
,
1012 GLsizei count
, const GLvoid
*ptr
)
1015 _mesa_TexCoordPointer(size
, type
, stride
, ptr
);
1020 _mesa_EdgeFlagPointerEXT(GLsizei stride
, GLsizei count
, const GLboolean
*ptr
)
1023 _mesa_EdgeFlagPointer(stride
, ptr
);
1028 _mesa_InterleavedArrays(GLenum format
, GLsizei stride
, const GLvoid
*pointer
)
1030 GET_CURRENT_CONTEXT(ctx
);
1031 GLboolean tflag
, cflag
, nflag
; /* enable/disable flags */
1032 GLint tcomps
, ccomps
, vcomps
; /* components per texcoord, color, vertex */
1033 GLenum ctype
= 0; /* color type */
1034 GLint coffset
= 0, noffset
= 0, voffset
;/* color, normal, vertex offsets */
1035 const GLint toffset
= 0; /* always zero */
1036 GLint defstride
; /* default stride */
1039 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1041 f
= sizeof(GLfloat
);
1042 c
= f
* ((4 * sizeof(GLubyte
) + (f
- 1)) / f
);
1045 _mesa_error( ctx
, GL_INVALID_VALUE
, "glInterleavedArrays(stride)" );
1051 tflag
= GL_FALSE
; cflag
= GL_FALSE
; nflag
= GL_FALSE
;
1052 tcomps
= 0; ccomps
= 0; vcomps
= 2;
1057 tflag
= GL_FALSE
; cflag
= GL_FALSE
; nflag
= GL_FALSE
;
1058 tcomps
= 0; ccomps
= 0; vcomps
= 3;
1063 tflag
= GL_FALSE
; cflag
= GL_TRUE
; nflag
= GL_FALSE
;
1064 tcomps
= 0; ccomps
= 4; vcomps
= 2;
1065 ctype
= GL_UNSIGNED_BYTE
;
1068 defstride
= c
+ 2*f
;
1071 tflag
= GL_FALSE
; cflag
= GL_TRUE
; nflag
= GL_FALSE
;
1072 tcomps
= 0; ccomps
= 4; vcomps
= 3;
1073 ctype
= GL_UNSIGNED_BYTE
;
1076 defstride
= c
+ 3*f
;
1079 tflag
= GL_FALSE
; cflag
= GL_TRUE
; nflag
= GL_FALSE
;
1080 tcomps
= 0; ccomps
= 3; vcomps
= 3;
1087 tflag
= GL_FALSE
; cflag
= GL_FALSE
; nflag
= GL_TRUE
;
1088 tcomps
= 0; ccomps
= 0; vcomps
= 3;
1093 case GL_C4F_N3F_V3F
:
1094 tflag
= GL_FALSE
; cflag
= GL_TRUE
; nflag
= GL_TRUE
;
1095 tcomps
= 0; ccomps
= 4; vcomps
= 3;
1103 tflag
= GL_TRUE
; cflag
= GL_FALSE
; nflag
= GL_FALSE
;
1104 tcomps
= 2; ccomps
= 0; vcomps
= 3;
1109 tflag
= GL_TRUE
; cflag
= GL_FALSE
; nflag
= GL_FALSE
;
1110 tcomps
= 4; ccomps
= 0; vcomps
= 4;
1114 case GL_T2F_C4UB_V3F
:
1115 tflag
= GL_TRUE
; cflag
= GL_TRUE
; nflag
= GL_FALSE
;
1116 tcomps
= 2; ccomps
= 4; vcomps
= 3;
1117 ctype
= GL_UNSIGNED_BYTE
;
1122 case GL_T2F_C3F_V3F
:
1123 tflag
= GL_TRUE
; cflag
= GL_TRUE
; nflag
= GL_FALSE
;
1124 tcomps
= 2; ccomps
= 3; vcomps
= 3;
1130 case GL_T2F_N3F_V3F
:
1131 tflag
= GL_TRUE
; cflag
= GL_FALSE
; nflag
= GL_TRUE
;
1132 tcomps
= 2; ccomps
= 0; vcomps
= 3;
1137 case GL_T2F_C4F_N3F_V3F
:
1138 tflag
= GL_TRUE
; cflag
= GL_TRUE
; nflag
= GL_TRUE
;
1139 tcomps
= 2; ccomps
= 4; vcomps
= 3;
1146 case GL_T4F_C4F_N3F_V4F
:
1147 tflag
= GL_TRUE
; cflag
= GL_TRUE
; nflag
= GL_TRUE
;
1148 tcomps
= 4; ccomps
= 4; vcomps
= 4;
1156 _mesa_error( ctx
, GL_INVALID_ENUM
, "glInterleavedArrays(format)" );
1164 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY
);
1165 _mesa_DisableClientState( GL_INDEX_ARRAY
);
1166 /* XXX also disable secondary color and generic arrays? */
1170 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY
);
1171 _mesa_TexCoordPointer( tcomps
, GL_FLOAT
, stride
,
1172 (GLubyte
*) pointer
+ toffset
);
1175 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY
);
1180 _mesa_EnableClientState( GL_COLOR_ARRAY
);
1181 _mesa_ColorPointer( ccomps
, ctype
, stride
,
1182 (GLubyte
*) pointer
+ coffset
);
1185 _mesa_DisableClientState( GL_COLOR_ARRAY
);
1191 _mesa_EnableClientState( GL_NORMAL_ARRAY
);
1192 _mesa_NormalPointer( GL_FLOAT
, stride
, (GLubyte
*) pointer
+ noffset
);
1195 _mesa_DisableClientState( GL_NORMAL_ARRAY
);
1199 _mesa_EnableClientState( GL_VERTEX_ARRAY
);
1200 _mesa_VertexPointer( vcomps
, GL_FLOAT
, stride
,
1201 (GLubyte
*) pointer
+ voffset
);
1206 _mesa_LockArraysEXT(GLint first
, GLsizei count
)
1208 GET_CURRENT_CONTEXT(ctx
);
1209 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1211 if (MESA_VERBOSE
& VERBOSE_API
)
1212 _mesa_debug(ctx
, "glLockArrays %d %d\n", first
, count
);
1215 _mesa_error( ctx
, GL_INVALID_VALUE
, "glLockArraysEXT(first)" );
1219 _mesa_error( ctx
, GL_INVALID_VALUE
, "glLockArraysEXT(count)" );
1222 if (ctx
->Array
.LockCount
!= 0) {
1223 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glLockArraysEXT(reentry)" );
1227 ctx
->Array
.LockFirst
= first
;
1228 ctx
->Array
.LockCount
= count
;
1230 ctx
->NewState
|= _NEW_ARRAY
;
1231 ctx
->Array
.NewState
|= _NEW_ARRAY_ALL
;
1236 _mesa_UnlockArraysEXT( void )
1238 GET_CURRENT_CONTEXT(ctx
);
1239 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1241 if (MESA_VERBOSE
& VERBOSE_API
)
1242 _mesa_debug(ctx
, "glUnlockArrays\n");
1244 if (ctx
->Array
.LockCount
== 0) {
1245 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glUnlockArraysEXT(reexit)" );
1249 ctx
->Array
.LockFirst
= 0;
1250 ctx
->Array
.LockCount
= 0;
1251 ctx
->NewState
|= _NEW_ARRAY
;
1252 ctx
->Array
.NewState
|= _NEW_ARRAY_ALL
;
1256 /* GL_EXT_multi_draw_arrays */
1257 /* Somebody forgot to spec the first and count parameters as const! <sigh> */
1259 _mesa_MultiDrawArraysEXT( GLenum mode
, GLint
*first
,
1260 GLsizei
*count
, GLsizei primcount
)
1262 GET_CURRENT_CONTEXT(ctx
);
1265 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1267 for (i
= 0; i
< primcount
; i
++) {
1269 CALL_DrawArrays(ctx
->Exec
, (mode
, first
[i
], count
[i
]));
1275 /* GL_IBM_multimode_draw_arrays */
1277 _mesa_MultiModeDrawArraysIBM( const GLenum
* mode
, const GLint
* first
,
1278 const GLsizei
* count
,
1279 GLsizei primcount
, GLint modestride
)
1281 GET_CURRENT_CONTEXT(ctx
);
1284 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1286 for ( i
= 0 ; i
< primcount
; i
++ ) {
1287 if ( count
[i
] > 0 ) {
1288 GLenum m
= *((GLenum
*) ((GLubyte
*) mode
+ i
* modestride
));
1289 CALL_DrawArrays(ctx
->Exec
, ( m
, first
[i
], count
[i
] ));
1295 /* GL_IBM_multimode_draw_arrays */
1297 _mesa_MultiModeDrawElementsIBM( const GLenum
* mode
, const GLsizei
* count
,
1298 GLenum type
, const GLvoid
* const * indices
,
1299 GLsizei primcount
, GLint modestride
)
1301 GET_CURRENT_CONTEXT(ctx
);
1304 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1306 /* XXX not sure about ARB_vertex_buffer_object handling here */
1308 for ( i
= 0 ; i
< primcount
; i
++ ) {
1309 if ( count
[i
] > 0 ) {
1310 GLenum m
= *((GLenum
*) ((GLubyte
*) mode
+ i
* modestride
));
1311 CALL_DrawElements(ctx
->Exec
, ( m
, count
[i
], type
, indices
[i
] ));
1318 * GL 3.1 glPrimitiveRestartIndex().
1321 _mesa_PrimitiveRestartIndex(GLuint index
)
1323 GET_CURRENT_CONTEXT(ctx
);
1325 if (ctx
->VersionMajor
* 10 + ctx
->VersionMinor
< 31) {
1326 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glPrimitiveRestartIndex()");
1330 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1332 FLUSH_VERTICES(ctx
, _NEW_TRANSFORM
);
1334 ctx
->Array
.RestartIndex
= index
;
1339 * Copy one client vertex array to another.
1342 _mesa_copy_client_array(GLcontext
*ctx
,
1343 struct gl_client_array
*dst
,
1344 struct gl_client_array
*src
)
1346 dst
->Size
= src
->Size
;
1347 dst
->Type
= src
->Type
;
1348 dst
->Format
= src
->Format
;
1349 dst
->Stride
= src
->Stride
;
1350 dst
->StrideB
= src
->StrideB
;
1351 dst
->Ptr
= src
->Ptr
;
1352 dst
->Enabled
= src
->Enabled
;
1353 dst
->Normalized
= src
->Normalized
;
1354 dst
->_ElementSize
= src
->_ElementSize
;
1355 _mesa_reference_buffer_object(ctx
, &dst
->BufferObj
, src
->BufferObj
);
1356 dst
->_MaxElement
= src
->_MaxElement
;
1362 * Print vertex array's fields.
1365 print_array(const char *name
, GLint index
, const struct gl_client_array
*array
)
1368 printf(" %s[%d]: ", name
, index
);
1370 printf(" %s: ", name
);
1371 printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu), MaxElem=%u\n",
1372 array
->Ptr
, array
->Type
, array
->Size
,
1373 array
->_ElementSize
, array
->StrideB
,
1374 array
->BufferObj
->Name
, (unsigned long) array
->BufferObj
->Size
,
1375 array
->_MaxElement
);
1380 * Print current vertex object/array info. For debug.
1383 _mesa_print_arrays(GLcontext
*ctx
)
1385 struct gl_array_object
*arrayObj
= ctx
->Array
.ArrayObj
;
1388 _mesa_update_array_object_max_element(ctx
, arrayObj
);
1390 printf("Array Object %u\n", arrayObj
->Name
);
1391 if (arrayObj
->Vertex
.Enabled
)
1392 print_array("Vertex", -1, &arrayObj
->Vertex
);
1393 if (arrayObj
->Normal
.Enabled
)
1394 print_array("Normal", -1, &arrayObj
->Normal
);
1395 if (arrayObj
->Color
.Enabled
)
1396 print_array("Color", -1, &arrayObj
->Color
);
1397 for (i
= 0; i
< Elements(arrayObj
->TexCoord
); i
++)
1398 if (arrayObj
->TexCoord
[i
].Enabled
)
1399 print_array("TexCoord", i
, &arrayObj
->TexCoord
[i
]);
1400 for (i
= 0; i
< Elements(arrayObj
->VertexAttrib
); i
++)
1401 if (arrayObj
->VertexAttrib
[i
].Enabled
)
1402 print_array("Attrib", i
, &arrayObj
->VertexAttrib
[i
]);
1403 printf(" _MaxElement = %u\n", arrayObj
->_MaxElement
);
1408 * Initialize vertex array state for given context.
1411 _mesa_init_varray(GLcontext
*ctx
)
1413 ctx
->Array
.DefaultArrayObj
= _mesa_new_array_object(ctx
, 0);
1414 _mesa_reference_array_object(ctx
, &ctx
->Array
.ArrayObj
,
1415 ctx
->Array
.DefaultArrayObj
);
1416 ctx
->Array
.ActiveTexture
= 0; /* GL_ARB_multitexture */
1418 ctx
->Array
.Objects
= _mesa_NewHashTable();
1423 * Callback for deleting an array object. Called by _mesa_HashDeleteAll().
1426 delete_arrayobj_cb(GLuint id
, void *data
, void *userData
)
1428 struct gl_array_object
*arrayObj
= (struct gl_array_object
*) data
;
1429 GLcontext
*ctx
= (GLcontext
*) userData
;
1430 _mesa_delete_array_object(ctx
, arrayObj
);
1435 * Free vertex array state for given context.
1438 _mesa_free_varray_data(GLcontext
*ctx
)
1440 _mesa_HashDeleteAll(ctx
->Array
.Objects
, delete_arrayobj_cb
, ctx
);
1441 _mesa_DeleteHashTable(ctx
->Array
.Objects
);