Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1901 | serge | 1 | /* |
2 | * Mesa 3-D graphics library |
||
3 | * Version: 7.6 |
||
4 | * |
||
5 | * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. |
||
6 | * Copyright (C) 2009 VMware, Inc. All Rights Reserved. |
||
7 | * |
||
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: |
||
14 | * |
||
15 | * The above copyright notice and this permission notice shall be included |
||
16 | * in all copies or substantial portions of the Software. |
||
17 | * |
||
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. |
||
24 | */ |
||
25 | |||
26 | |||
27 | #include "glheader.h" |
||
28 | #include "imports.h" |
||
29 | #include "bufferobj.h" |
||
30 | #include "context.h" |
||
31 | #include "enable.h" |
||
32 | #include "enums.h" |
||
33 | #include "hash.h" |
||
34 | #include "image.h" |
||
35 | #include "macros.h" |
||
36 | #include "mtypes.h" |
||
37 | #include "varray.h" |
||
38 | #include "arrayobj.h" |
||
39 | #include "main/dispatch.h" |
||
40 | |||
41 | |||
42 | /** Used to do error checking for GL_EXT_vertex_array_bgra */ |
||
43 | #define BGRA_OR_4 5 |
||
44 | |||
45 | |||
46 | /** Used to indicate which GL datatypes are accepted by each of the |
||
47 | * glVertex/Color/Attrib/EtcPointer() functions. |
||
48 | */ |
||
49 | #define BOOL_BIT 0x1 |
||
50 | #define BYTE_BIT 0x2 |
||
51 | #define UNSIGNED_BYTE_BIT 0x4 |
||
52 | #define SHORT_BIT 0x8 |
||
53 | #define UNSIGNED_SHORT_BIT 0x10 |
||
54 | #define INT_BIT 0x20 |
||
55 | #define UNSIGNED_INT_BIT 0x40 |
||
56 | #define HALF_BIT 0x80 |
||
57 | #define FLOAT_BIT 0x100 |
||
58 | #define DOUBLE_BIT 0x200 |
||
59 | #define FIXED_BIT 0x400 |
||
60 | |||
61 | |||
62 | |||
63 | /** Convert GL datatype enum into a |
||
64 | static GLbitfield |
||
65 | type_to_bit(const struct gl_context *ctx, GLenum type) |
||
66 | { |
||
67 | switch (type) { |
||
68 | case GL_BOOL: |
||
69 | return BOOL_BIT; |
||
70 | case GL_BYTE: |
||
71 | return BYTE_BIT; |
||
72 | case GL_UNSIGNED_BYTE: |
||
73 | return UNSIGNED_BYTE_BIT; |
||
74 | case GL_SHORT: |
||
75 | return SHORT_BIT; |
||
76 | case GL_UNSIGNED_SHORT: |
||
77 | return UNSIGNED_SHORT_BIT; |
||
78 | case GL_INT: |
||
79 | return INT_BIT; |
||
80 | case GL_UNSIGNED_INT: |
||
81 | return UNSIGNED_INT_BIT; |
||
82 | case GL_HALF_FLOAT: |
||
83 | if (ctx->Extensions.ARB_half_float_vertex) |
||
84 | return HALF_BIT; |
||
85 | else |
||
86 | return 0x0; |
||
87 | case GL_FLOAT: |
||
88 | return FLOAT_BIT; |
||
89 | case GL_DOUBLE: |
||
90 | return DOUBLE_BIT; |
||
91 | case GL_FIXED: |
||
92 | return FIXED_BIT; |
||
93 | default: |
||
94 | return 0; |
||
95 | } |
||
96 | } |
||
97 | |||
98 | |||
99 | /** |
||
100 | * Do error checking and update state for glVertex/Color/TexCoord/...Pointer |
||
101 | * functions. |
||
102 | * |
||
103 | * \param func name of calling function used for error reporting |
||
104 | * \param array the array to update |
||
105 | * \param dirtyBit which bit to set in ctx->Array.NewState for this array |
||
106 | * \param legalTypes bitmask of *_BIT above indicating legal datatypes |
||
107 | * \param sizeMin min allowable size value |
||
108 | * \param sizeMax max allowable size value (may also be BGRA_OR_4) |
||
109 | * \param size components per element (1, 2, 3 or 4) |
||
110 | * \param type datatype of each component (GL_FLOAT, GL_INT, etc) |
||
111 | * \param stride stride between elements, in elements |
||
112 | * \param normalized are integer types converted to floats in [-1, 1]? |
||
113 | * \param integer integer-valued values (will not be normalized to [-1,1]) |
||
114 | * \param ptr the address (or offset inside VBO) of the array data |
||
115 | */ |
||
116 | static void |
||
117 | update_array(struct gl_context *ctx, |
||
118 | const char *func, |
||
119 | struct gl_client_array *array, |
||
120 | GLbitfield dirtyBit, GLbitfield legalTypesMask, |
||
121 | GLint sizeMin, GLint sizeMax, |
||
122 | GLint size, GLenum type, GLsizei stride, |
||
123 | GLboolean normalized, GLboolean integer, |
||
124 | const GLvoid *ptr) |
||
125 | { |
||
126 | GLbitfield typeBit; |
||
127 | GLsizei elementSize; |
||
128 | GLenum format = GL_RGBA; |
||
129 | |||
130 | if (ctx->API != API_OPENGLES && ctx->API != API_OPENGLES2) { |
||
131 | /* fixed point arrays / data is only allowed with OpenGL ES 1.x/2.0 */ |
||
132 | legalTypesMask &= ~FIXED_BIT; |
||
133 | } |
||
134 | |||
135 | typeBit = type_to_bit(ctx, type); |
||
136 | if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) { |
||
137 | _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", |
||
138 | func, _mesa_lookup_enum_by_nr(type)); |
||
139 | return; |
||
140 | } |
||
141 | |||
142 | /* Do size parameter checking. |
||
143 | * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and |
||
144 | * must be handled specially. |
||
145 | */ |
||
146 | if (ctx->Extensions.EXT_vertex_array_bgra && |
||
147 | sizeMax == BGRA_OR_4 && |
||
148 | size == GL_BGRA) { |
||
149 | if (type != GL_UNSIGNED_BYTE) { |
||
150 | _mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func); |
||
151 | return; |
||
152 | } |
||
153 | format = GL_BGRA; |
||
154 | size = 4; |
||
155 | } |
||
156 | else if (size < sizeMin || size > sizeMax || size > 4) { |
||
157 | _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size); |
||
158 | return; |
||
159 | } |
||
160 | |||
161 | ASSERT(size <= 4); |
||
162 | |||
163 | if (stride < 0) { |
||
164 | _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride ); |
||
165 | return; |
||
166 | } |
||
167 | |||
168 | if (ctx->Array.ArrayObj->VBOonly && |
||
169 | ctx->Array.ArrayBufferObj->Name == 0) { |
||
170 | /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs. |
||
171 | * Generate GL_INVALID_OPERATION if that's not true. |
||
172 | */ |
||
173 | _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func); |
||
174 | return; |
||
175 | } |
||
176 | |||
177 | elementSize = _mesa_sizeof_type(type) * size; |
||
178 | |||
179 | array->Size = size; |
||
180 | array->Type = type; |
||
181 | array->Format = format; |
||
182 | array->Stride = stride; |
||
183 | array->StrideB = stride ? stride : elementSize; |
||
184 | array->Normalized = normalized; |
||
185 | array->Ptr = (const GLubyte *) ptr; |
||
186 | array->_ElementSize = elementSize; |
||
187 | |||
188 | _mesa_reference_buffer_object(ctx, &array->BufferObj, |
||
189 | ctx->Array.ArrayBufferObj); |
||
190 | |||
191 | ctx->NewState |= _NEW_ARRAY; |
||
192 | ctx->Array.NewState |= dirtyBit; |
||
193 | } |
||
194 | |||
195 | |||
196 | void GLAPIENTRY |
||
197 | _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) |
||
198 | { |
||
199 | GLbitfield legalTypes = (SHORT_BIT | INT_BIT | FLOAT_BIT | |
||
200 | DOUBLE_BIT | HALF_BIT | FIXED_BIT); |
||
201 | GET_CURRENT_CONTEXT(ctx); |
||
202 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
203 | |||
204 | if (ctx->API == API_OPENGLES) |
||
205 | legalTypes |= BYTE_BIT; |
||
206 | |||
207 | update_array(ctx, "glVertexPointer", |
||
208 | &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX, |
||
209 | legalTypes, 2, 4, |
||
210 | size, type, stride, GL_FALSE, GL_FALSE, ptr); |
||
211 | } |
||
212 | |||
213 | |||
214 | void GLAPIENTRY |
||
215 | _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) |
||
216 | { |
||
217 | const GLbitfield legalTypes = (BYTE_BIT | SHORT_BIT | INT_BIT | |
||
218 | HALF_BIT | FLOAT_BIT | DOUBLE_BIT | |
||
219 | FIXED_BIT); |
||
220 | GET_CURRENT_CONTEXT(ctx); |
||
221 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
222 | |||
223 | update_array(ctx, "glNormalPointer", |
||
224 | &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL, |
||
225 | legalTypes, 3, 3, |
||
226 | 3, type, stride, GL_TRUE, GL_FALSE, ptr); |
||
227 | } |
||
228 | |||
229 | |||
230 | void GLAPIENTRY |
||
231 | _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) |
||
232 | { |
||
233 | const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | |
||
234 | SHORT_BIT | UNSIGNED_SHORT_BIT | |
||
235 | INT_BIT | UNSIGNED_INT_BIT | |
||
236 | HALF_BIT | FLOAT_BIT | DOUBLE_BIT | |
||
237 | FIXED_BIT); |
||
238 | GET_CURRENT_CONTEXT(ctx); |
||
239 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
240 | |||
241 | update_array(ctx, "glColorPointer", |
||
242 | &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0, |
||
243 | legalTypes, 3, BGRA_OR_4, |
||
244 | size, type, stride, GL_TRUE, GL_FALSE, ptr); |
||
245 | } |
||
246 | |||
247 | |||
248 | void GLAPIENTRY |
||
249 | _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr) |
||
250 | { |
||
251 | const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT); |
||
252 | GET_CURRENT_CONTEXT(ctx); |
||
253 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
254 | |||
255 | update_array(ctx, "glFogCoordPointer", |
||
256 | &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD, |
||
257 | legalTypes, 1, 1, |
||
258 | 1, type, stride, GL_FALSE, GL_FALSE, ptr); |
||
259 | } |
||
260 | |||
261 | |||
262 | void GLAPIENTRY |
||
263 | _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) |
||
264 | { |
||
265 | const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT | |
||
266 | FLOAT_BIT | DOUBLE_BIT); |
||
267 | GET_CURRENT_CONTEXT(ctx); |
||
268 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
269 | |||
270 | update_array(ctx, "glIndexPointer", |
||
271 | &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX, |
||
272 | legalTypes, 1, 1, |
||
273 | 1, type, stride, GL_FALSE, GL_FALSE, ptr); |
||
274 | } |
||
275 | |||
276 | |||
277 | void GLAPIENTRY |
||
278 | _mesa_SecondaryColorPointerEXT(GLint size, GLenum type, |
||
279 | GLsizei stride, const GLvoid *ptr) |
||
280 | { |
||
281 | const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | |
||
282 | SHORT_BIT | UNSIGNED_SHORT_BIT | |
||
283 | INT_BIT | UNSIGNED_INT_BIT | |
||
284 | HALF_BIT | FLOAT_BIT | DOUBLE_BIT); |
||
285 | GET_CURRENT_CONTEXT(ctx); |
||
286 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
287 | |||
288 | update_array(ctx, "glSecondaryColorPointer", |
||
289 | &ctx->Array.ArrayObj->SecondaryColor, _NEW_ARRAY_COLOR1, |
||
290 | legalTypes, 3, BGRA_OR_4, |
||
291 | size, type, stride, GL_TRUE, GL_FALSE, ptr); |
||
292 | } |
||
293 | |||
294 | |||
295 | void GLAPIENTRY |
||
296 | _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, |
||
297 | const GLvoid *ptr) |
||
298 | { |
||
299 | GLbitfield legalTypes = (SHORT_BIT | INT_BIT | |
||
300 | HALF_BIT | FLOAT_BIT | DOUBLE_BIT | |
||
301 | FIXED_BIT); |
||
302 | GET_CURRENT_CONTEXT(ctx); |
||
303 | const GLuint unit = ctx->Array.ActiveTexture; |
||
304 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
305 | |||
306 | if (ctx->API == API_OPENGLES) |
||
307 | legalTypes |= BYTE_BIT; |
||
308 | |||
309 | ASSERT(unit < Elements(ctx->Array.ArrayObj->TexCoord)); |
||
310 | |||
311 | update_array(ctx, "glTexCoordPointer", |
||
312 | &ctx->Array.ArrayObj->TexCoord[unit], |
||
313 | _NEW_ARRAY_TEXCOORD(unit), |
||
314 | legalTypes, 1, 4, |
||
315 | size, type, stride, GL_FALSE, GL_FALSE, |
||
316 | ptr); |
||
317 | } |
||
318 | |||
319 | |||
320 | void GLAPIENTRY |
||
321 | _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr) |
||
322 | { |
||
323 | const GLbitfield legalTypes = UNSIGNED_BYTE_BIT; |
||
324 | /* see table 2.4 edits in GL_EXT_gpu_shader4 spec: */ |
||
325 | const GLboolean integer = GL_TRUE; |
||
326 | GET_CURRENT_CONTEXT(ctx); |
||
327 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
328 | |||
329 | update_array(ctx, "glEdgeFlagPointer", |
||
330 | &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG, |
||
331 | legalTypes, 1, 1, |
||
332 | 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, ptr); |
||
333 | } |
||
334 | |||
335 | |||
336 | void GLAPIENTRY |
||
337 | _mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr) |
||
338 | { |
||
339 | const GLbitfield legalTypes = (FLOAT_BIT | FIXED_BIT); |
||
340 | GET_CURRENT_CONTEXT(ctx); |
||
341 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
342 | |||
343 | if (ctx->API != API_OPENGLES) { |
||
344 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
345 | "glPointSizePointer(ES 1.x only)"); |
||
346 | return; |
||
347 | } |
||
348 | |||
349 | update_array(ctx, "glPointSizePointer", |
||
350 | &ctx->Array.ArrayObj->PointSize, _NEW_ARRAY_POINT_SIZE, |
||
351 | legalTypes, 1, 1, |
||
352 | 1, type, stride, GL_FALSE, GL_FALSE, ptr); |
||
353 | } |
||
354 | |||
355 | |||
356 | #if FEATURE_NV_vertex_program |
||
357 | /** |
||
358 | * Set a vertex attribute array. |
||
359 | * Note that these arrays DO alias the conventional GL vertex arrays |
||
360 | * (position, normal, color, fog, texcoord, etc). |
||
361 | * The generic attribute slots at #16 and above are not touched. |
||
362 | */ |
||
363 | void GLAPIENTRY |
||
364 | _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type, |
||
365 | GLsizei stride, const GLvoid *ptr) |
||
366 | { |
||
367 | const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | |
||
368 | FLOAT_BIT | DOUBLE_BIT); |
||
369 | GLboolean normalized = GL_FALSE; |
||
370 | GET_CURRENT_CONTEXT(ctx); |
||
371 | ASSERT_OUTSIDE_BEGIN_END(ctx); |
||
372 | |||
373 | if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { |
||
374 | _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)"); |
||
375 | return; |
||
376 | } |
||
377 | |||
378 | if (type == GL_UNSIGNED_BYTE && size != 4) { |
||
379 | _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)"); |
||
380 | return; |
||
381 | } |
||
382 | |||
383 | update_array(ctx, "glVertexAttribPointerNV", |
||
384 | &ctx->Array.ArrayObj->VertexAttrib[index], |
||
385 | _NEW_ARRAY_ATTRIB(index), |
||
386 | legalTypes, 1, BGRA_OR_4, |
||
387 | size, type, stride, normalized, GL_FALSE, ptr); |
||
388 | } |
||
389 | #endif |
||
390 | |||
391 | |||
392 | #if FEATURE_ARB_vertex_program |
||
393 | /** |
||
394 | * Set a generic vertex attribute array. |
||
395 | * Note that these arrays DO NOT alias the conventional GL vertex arrays |
||
396 | * (position, normal, color, fog, texcoord, etc). |
||
397 | */ |
||
398 | void GLAPIENTRY |
||
399 | _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type, |
||
400 | GLboolean normalized, |
||
401 | GLsizei stride, const GLvoid *ptr) |
||
402 | { |
||
403 | const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | |
||
404 | SHORT_BIT | UNSIGNED_SHORT_BIT | |
||
405 | INT_BIT | UNSIGNED_INT_BIT | |
||
406 | HALF_BIT | FLOAT_BIT | DOUBLE_BIT | |
||
407 | FIXED_BIT); |
||
408 | GET_CURRENT_CONTEXT(ctx); |
||
409 | ASSERT_OUTSIDE_BEGIN_END(ctx); |
||
410 | |||
411 | if (index >= ctx->Const.VertexProgram.MaxAttribs) { |
||
412 | _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)"); |
||
413 | return; |
||
414 | } |
||
415 | |||
416 | update_array(ctx, "glVertexAttribPointer", |
||
417 | &ctx->Array.ArrayObj->VertexAttrib[index], |
||
418 | _NEW_ARRAY_ATTRIB(index), |
||
419 | legalTypes, 1, BGRA_OR_4, |
||
420 | size, type, stride, normalized, GL_FALSE, ptr); |
||
421 | } |
||
422 | #endif |
||
423 | |||
424 | |||
425 | /** |
||
426 | * GL_EXT_gpu_shader4 / GL 3.0. |
||
427 | * Set an integer-valued vertex attribute array. |
||
428 | * Note that these arrays DO NOT alias the conventional GL vertex arrays |
||
429 | * (position, normal, color, fog, texcoord, etc). |
||
430 | */ |
||
431 | void GLAPIENTRY |
||
432 | _mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type, |
||
433 | GLsizei stride, const GLvoid *ptr) |
||
434 | { |
||
435 | const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT | |
||
436 | SHORT_BIT | UNSIGNED_SHORT_BIT | |
||
437 | INT_BIT | UNSIGNED_INT_BIT); |
||
438 | const GLboolean normalized = GL_FALSE; |
||
439 | const GLboolean integer = GL_TRUE; |
||
440 | GET_CURRENT_CONTEXT(ctx); |
||
441 | ASSERT_OUTSIDE_BEGIN_END(ctx); |
||
442 | |||
443 | if (index >= ctx->Const.VertexProgram.MaxAttribs) { |
||
444 | _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)"); |
||
445 | return; |
||
446 | } |
||
447 | |||
448 | update_array(ctx, "glVertexAttribIPointer", |
||
449 | &ctx->Array.ArrayObj->VertexAttrib[index], |
||
450 | _NEW_ARRAY_ATTRIB(index), |
||
451 | legalTypes, 1, 4, |
||
452 | size, type, stride, normalized, integer, ptr); |
||
453 | } |
||
454 | |||
455 | |||
456 | |||
457 | void GLAPIENTRY |
||
458 | _mesa_EnableVertexAttribArrayARB(GLuint index) |
||
459 | { |
||
460 | GET_CURRENT_CONTEXT(ctx); |
||
461 | ASSERT_OUTSIDE_BEGIN_END(ctx); |
||
462 | |||
463 | if (index >= ctx->Const.VertexProgram.MaxAttribs) { |
||
464 | _mesa_error(ctx, GL_INVALID_VALUE, |
||
465 | "glEnableVertexAttribArrayARB(index)"); |
||
466 | return; |
||
467 | } |
||
468 | |||
469 | ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); |
||
470 | |||
471 | FLUSH_VERTICES(ctx, _NEW_ARRAY); |
||
472 | ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_TRUE; |
||
473 | ctx->Array.ArrayObj->_Enabled |= _NEW_ARRAY_ATTRIB(index); |
||
474 | ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index); |
||
475 | } |
||
476 | |||
477 | |||
478 | void GLAPIENTRY |
||
479 | _mesa_DisableVertexAttribArrayARB(GLuint index) |
||
480 | { |
||
481 | GET_CURRENT_CONTEXT(ctx); |
||
482 | ASSERT_OUTSIDE_BEGIN_END(ctx); |
||
483 | |||
484 | if (index >= ctx->Const.VertexProgram.MaxAttribs) { |
||
485 | _mesa_error(ctx, GL_INVALID_VALUE, |
||
486 | "glEnableVertexAttribArrayARB(index)"); |
||
487 | return; |
||
488 | } |
||
489 | |||
490 | ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); |
||
491 | |||
492 | FLUSH_VERTICES(ctx, _NEW_ARRAY); |
||
493 | ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_FALSE; |
||
494 | ctx->Array.ArrayObj->_Enabled &= ~_NEW_ARRAY_ATTRIB(index); |
||
495 | ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index); |
||
496 | } |
||
497 | |||
498 | |||
499 | /** |
||
500 | * Return info for a vertex attribute array (no alias with legacy |
||
501 | * vertex attributes (pos, normal, color, etc)). This function does |
||
502 | * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query. |
||
503 | */ |
||
504 | static GLuint |
||
505 | get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname, |
||
506 | const char *caller) |
||
507 | { |
||
508 | const struct gl_client_array *array; |
||
509 | |||
510 | if (index >= ctx->Const.VertexProgram.MaxAttribs) { |
||
511 | _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index); |
||
512 | return 0; |
||
513 | } |
||
514 | |||
515 | ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); |
||
516 | |||
517 | array = &ctx->Array.ArrayObj->VertexAttrib[index]; |
||
518 | |||
519 | switch (pname) { |
||
520 | case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: |
||
521 | return array->Enabled; |
||
522 | case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: |
||
523 | return array->Size; |
||
524 | case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: |
||
525 | return array->Stride; |
||
526 | case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: |
||
527 | return array->Type; |
||
528 | case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: |
||
529 | return array->Normalized; |
||
530 | case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: |
||
531 | return array->BufferObj->Name; |
||
532 | case GL_VERTEX_ATTRIB_ARRAY_INTEGER: |
||
533 | if (ctx->Extensions.EXT_gpu_shader4) { |
||
534 | return array->Integer; |
||
535 | } |
||
536 | /* fall-through */ |
||
537 | default: |
||
538 | _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname); |
||
539 | return 0; |
||
540 | } |
||
541 | } |
||
542 | |||
543 | |||
544 | static const GLfloat * |
||
545 | get_current_attrib(struct gl_context *ctx, GLuint index, const char *function) |
||
546 | { |
||
547 | if (index == 0) { |
||
548 | if (ctx->API != API_OPENGLES2) { |
||
549 | _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function); |
||
550 | return NULL; |
||
551 | } |
||
552 | } |
||
553 | else if (index >= ctx->Const.VertexProgram.MaxAttribs) { |
||
554 | _mesa_error(ctx, GL_INVALID_VALUE, |
||
555 | "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function); |
||
556 | return NULL; |
||
557 | } |
||
558 | |||
559 | FLUSH_CURRENT(ctx, 0); |
||
560 | return ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]; |
||
561 | } |
||
562 | |||
563 | void GLAPIENTRY |
||
564 | _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) |
||
565 | { |
||
566 | GET_CURRENT_CONTEXT(ctx); |
||
567 | ASSERT_OUTSIDE_BEGIN_END(ctx); |
||
568 | |||
569 | if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { |
||
570 | const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv"); |
||
571 | if (v != NULL) { |
||
572 | COPY_4V(params, v); |
||
573 | } |
||
574 | } |
||
575 | else { |
||
576 | params[0] = (GLfloat) get_vertex_array_attrib(ctx, index, pname, |
||
577 | "glGetVertexAttribfv"); |
||
578 | } |
||
579 | } |
||
580 | |||
581 | |||
582 | void GLAPIENTRY |
||
583 | _mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params) |
||
584 | { |
||
585 | GET_CURRENT_CONTEXT(ctx); |
||
586 | ASSERT_OUTSIDE_BEGIN_END(ctx); |
||
587 | |||
588 | if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { |
||
589 | const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv"); |
||
590 | if (v != NULL) { |
||
591 | params[0] = (GLdouble) v[0]; |
||
592 | params[1] = (GLdouble) v[1]; |
||
593 | params[2] = (GLdouble) v[2]; |
||
594 | params[3] = (GLdouble) v[3]; |
||
595 | } |
||
596 | } |
||
597 | else { |
||
598 | params[0] = (GLdouble) get_vertex_array_attrib(ctx, index, pname, |
||
599 | "glGetVertexAttribdv"); |
||
600 | } |
||
601 | } |
||
602 | |||
603 | |||
604 | void GLAPIENTRY |
||
605 | _mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params) |
||
606 | { |
||
607 | GET_CURRENT_CONTEXT(ctx); |
||
608 | ASSERT_OUTSIDE_BEGIN_END(ctx); |
||
609 | |||
610 | if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { |
||
611 | const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv"); |
||
612 | if (v != NULL) { |
||
613 | /* XXX should floats in[0,1] be scaled to full int range? */ |
||
614 | params[0] = (GLint) v[0]; |
||
615 | params[1] = (GLint) v[1]; |
||
616 | params[2] = (GLint) v[2]; |
||
617 | params[3] = (GLint) v[3]; |
||
618 | } |
||
619 | } |
||
620 | else { |
||
621 | params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname, |
||
622 | "glGetVertexAttribiv"); |
||
623 | } |
||
624 | } |
||
625 | |||
626 | |||
627 | /** GL 3.0 */ |
||
628 | void GLAPIENTRY |
||
629 | _mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params) |
||
630 | { |
||
631 | GET_CURRENT_CONTEXT(ctx); |
||
632 | ASSERT_OUTSIDE_BEGIN_END(ctx); |
||
633 | |||
634 | if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { |
||
635 | const GLfloat *v = |
||
636 | get_current_attrib(ctx, index, "glGetVertexAttribIiv"); |
||
637 | if (v != NULL) { |
||
638 | /* XXX we don't have true integer-valued vertex attribs yet */ |
||
639 | params[0] = (GLint) v[0]; |
||
640 | params[1] = (GLint) v[1]; |
||
641 | params[2] = (GLint) v[2]; |
||
642 | params[3] = (GLint) v[3]; |
||
643 | } |
||
644 | } |
||
645 | else { |
||
646 | params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname, |
||
647 | "glGetVertexAttribIiv"); |
||
648 | } |
||
649 | } |
||
650 | |||
651 | |||
652 | /** GL 3.0 */ |
||
653 | void GLAPIENTRY |
||
654 | _mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params) |
||
655 | { |
||
656 | GET_CURRENT_CONTEXT(ctx); |
||
657 | ASSERT_OUTSIDE_BEGIN_END(ctx); |
||
658 | |||
659 | if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { |
||
660 | const GLfloat *v = |
||
661 | get_current_attrib(ctx, index, "glGetVertexAttribIuiv"); |
||
662 | if (v != NULL) { |
||
663 | /* XXX we don't have true integer-valued vertex attribs yet */ |
||
664 | params[0] = (GLuint) v[0]; |
||
665 | params[1] = (GLuint) v[1]; |
||
666 | params[2] = (GLuint) v[2]; |
||
667 | params[3] = (GLuint) v[3]; |
||
668 | } |
||
669 | } |
||
670 | else { |
||
671 | params[0] = get_vertex_array_attrib(ctx, index, pname, |
||
672 | "glGetVertexAttribIuiv"); |
||
673 | } |
||
674 | } |
||
675 | |||
676 | |||
677 | void GLAPIENTRY |
||
678 | _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer) |
||
679 | { |
||
680 | GET_CURRENT_CONTEXT(ctx); |
||
681 | ASSERT_OUTSIDE_BEGIN_END(ctx); |
||
682 | |||
683 | if (index >= ctx->Const.VertexProgram.MaxAttribs) { |
||
684 | _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)"); |
||
685 | return; |
||
686 | } |
||
687 | |||
688 | if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) { |
||
689 | _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)"); |
||
690 | return; |
||
691 | } |
||
692 | |||
693 | ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); |
||
694 | |||
695 | *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr; |
||
696 | } |
||
697 | |||
698 | |||
699 | void GLAPIENTRY |
||
700 | _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride, |
||
701 | GLsizei count, const GLvoid *ptr) |
||
702 | { |
||
703 | (void) count; |
||
704 | _mesa_VertexPointer(size, type, stride, ptr); |
||
705 | } |
||
706 | |||
707 | |||
708 | void GLAPIENTRY |
||
709 | _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, |
||
710 | const GLvoid *ptr) |
||
711 | { |
||
712 | (void) count; |
||
713 | _mesa_NormalPointer(type, stride, ptr); |
||
714 | } |
||
715 | |||
716 | |||
717 | void GLAPIENTRY |
||
718 | _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, |
||
719 | const GLvoid *ptr) |
||
720 | { |
||
721 | (void) count; |
||
722 | _mesa_ColorPointer(size, type, stride, ptr); |
||
723 | } |
||
724 | |||
725 | |||
726 | void GLAPIENTRY |
||
727 | _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, |
||
728 | const GLvoid *ptr) |
||
729 | { |
||
730 | (void) count; |
||
731 | _mesa_IndexPointer(type, stride, ptr); |
||
732 | } |
||
733 | |||
734 | |||
735 | void GLAPIENTRY |
||
736 | _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, |
||
737 | GLsizei count, const GLvoid *ptr) |
||
738 | { |
||
739 | (void) count; |
||
740 | _mesa_TexCoordPointer(size, type, stride, ptr); |
||
741 | } |
||
742 | |||
743 | |||
744 | void GLAPIENTRY |
||
745 | _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) |
||
746 | { |
||
747 | (void) count; |
||
748 | _mesa_EdgeFlagPointer(stride, ptr); |
||
749 | } |
||
750 | |||
751 | |||
752 | void GLAPIENTRY |
||
753 | _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) |
||
754 | { |
||
755 | GET_CURRENT_CONTEXT(ctx); |
||
756 | GLboolean tflag, cflag, nflag; /* enable/disable flags */ |
||
757 | GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */ |
||
758 | GLenum ctype = 0; /* color type */ |
||
759 | GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */ |
||
760 | const GLint toffset = 0; /* always zero */ |
||
761 | GLint defstride; /* default stride */ |
||
762 | GLint c, f; |
||
763 | |||
764 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
765 | |||
766 | f = sizeof(GLfloat); |
||
767 | c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f); |
||
768 | |||
769 | if (stride < 0) { |
||
770 | _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" ); |
||
771 | return; |
||
772 | } |
||
773 | |||
774 | switch (format) { |
||
775 | case GL_V2F: |
||
776 | tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; |
||
777 | tcomps = 0; ccomps = 0; vcomps = 2; |
||
778 | voffset = 0; |
||
779 | defstride = 2*f; |
||
780 | break; |
||
781 | case GL_V3F: |
||
782 | tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; |
||
783 | tcomps = 0; ccomps = 0; vcomps = 3; |
||
784 | voffset = 0; |
||
785 | defstride = 3*f; |
||
786 | break; |
||
787 | case GL_C4UB_V2F: |
||
788 | tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; |
||
789 | tcomps = 0; ccomps = 4; vcomps = 2; |
||
790 | ctype = GL_UNSIGNED_BYTE; |
||
791 | coffset = 0; |
||
792 | voffset = c; |
||
793 | defstride = c + 2*f; |
||
794 | break; |
||
795 | case GL_C4UB_V3F: |
||
796 | tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; |
||
797 | tcomps = 0; ccomps = 4; vcomps = 3; |
||
798 | ctype = GL_UNSIGNED_BYTE; |
||
799 | coffset = 0; |
||
800 | voffset = c; |
||
801 | defstride = c + 3*f; |
||
802 | break; |
||
803 | case GL_C3F_V3F: |
||
804 | tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; |
||
805 | tcomps = 0; ccomps = 3; vcomps = 3; |
||
806 | ctype = GL_FLOAT; |
||
807 | coffset = 0; |
||
808 | voffset = 3*f; |
||
809 | defstride = 6*f; |
||
810 | break; |
||
811 | case GL_N3F_V3F: |
||
812 | tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE; |
||
813 | tcomps = 0; ccomps = 0; vcomps = 3; |
||
814 | noffset = 0; |
||
815 | voffset = 3*f; |
||
816 | defstride = 6*f; |
||
817 | break; |
||
818 | case GL_C4F_N3F_V3F: |
||
819 | tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE; |
||
820 | tcomps = 0; ccomps = 4; vcomps = 3; |
||
821 | ctype = GL_FLOAT; |
||
822 | coffset = 0; |
||
823 | noffset = 4*f; |
||
824 | voffset = 7*f; |
||
825 | defstride = 10*f; |
||
826 | break; |
||
827 | case GL_T2F_V3F: |
||
828 | tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; |
||
829 | tcomps = 2; ccomps = 0; vcomps = 3; |
||
830 | voffset = 2*f; |
||
831 | defstride = 5*f; |
||
832 | break; |
||
833 | case GL_T4F_V4F: |
||
834 | tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; |
||
835 | tcomps = 4; ccomps = 0; vcomps = 4; |
||
836 | voffset = 4*f; |
||
837 | defstride = 8*f; |
||
838 | break; |
||
839 | case GL_T2F_C4UB_V3F: |
||
840 | tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; |
||
841 | tcomps = 2; ccomps = 4; vcomps = 3; |
||
842 | ctype = GL_UNSIGNED_BYTE; |
||
843 | coffset = 2*f; |
||
844 | voffset = c+2*f; |
||
845 | defstride = c+5*f; |
||
846 | break; |
||
847 | case GL_T2F_C3F_V3F: |
||
848 | tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; |
||
849 | tcomps = 2; ccomps = 3; vcomps = 3; |
||
850 | ctype = GL_FLOAT; |
||
851 | coffset = 2*f; |
||
852 | voffset = 5*f; |
||
853 | defstride = 8*f; |
||
854 | break; |
||
855 | case GL_T2F_N3F_V3F: |
||
856 | tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE; |
||
857 | tcomps = 2; ccomps = 0; vcomps = 3; |
||
858 | noffset = 2*f; |
||
859 | voffset = 5*f; |
||
860 | defstride = 8*f; |
||
861 | break; |
||
862 | case GL_T2F_C4F_N3F_V3F: |
||
863 | tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; |
||
864 | tcomps = 2; ccomps = 4; vcomps = 3; |
||
865 | ctype = GL_FLOAT; |
||
866 | coffset = 2*f; |
||
867 | noffset = 6*f; |
||
868 | voffset = 9*f; |
||
869 | defstride = 12*f; |
||
870 | break; |
||
871 | case GL_T4F_C4F_N3F_V4F: |
||
872 | tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; |
||
873 | tcomps = 4; ccomps = 4; vcomps = 4; |
||
874 | ctype = GL_FLOAT; |
||
875 | coffset = 4*f; |
||
876 | noffset = 8*f; |
||
877 | voffset = 11*f; |
||
878 | defstride = 15*f; |
||
879 | break; |
||
880 | default: |
||
881 | _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" ); |
||
882 | return; |
||
883 | } |
||
884 | |||
885 | if (stride==0) { |
||
886 | stride = defstride; |
||
887 | } |
||
888 | |||
889 | _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY ); |
||
890 | _mesa_DisableClientState( GL_INDEX_ARRAY ); |
||
891 | /* XXX also disable secondary color and generic arrays? */ |
||
892 | |||
893 | /* Texcoords */ |
||
894 | if (tflag) { |
||
895 | _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY ); |
||
896 | _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride, |
||
897 | (GLubyte *) pointer + toffset ); |
||
898 | } |
||
899 | else { |
||
900 | _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY ); |
||
901 | } |
||
902 | |||
903 | /* Color */ |
||
904 | if (cflag) { |
||
905 | _mesa_EnableClientState( GL_COLOR_ARRAY ); |
||
906 | _mesa_ColorPointer( ccomps, ctype, stride, |
||
907 | (GLubyte *) pointer + coffset ); |
||
908 | } |
||
909 | else { |
||
910 | _mesa_DisableClientState( GL_COLOR_ARRAY ); |
||
911 | } |
||
912 | |||
913 | |||
914 | /* Normals */ |
||
915 | if (nflag) { |
||
916 | _mesa_EnableClientState( GL_NORMAL_ARRAY ); |
||
917 | _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset ); |
||
918 | } |
||
919 | else { |
||
920 | _mesa_DisableClientState( GL_NORMAL_ARRAY ); |
||
921 | } |
||
922 | |||
923 | /* Vertices */ |
||
924 | _mesa_EnableClientState( GL_VERTEX_ARRAY ); |
||
925 | _mesa_VertexPointer( vcomps, GL_FLOAT, stride, |
||
926 | (GLubyte *) pointer + voffset ); |
||
927 | } |
||
928 | |||
929 | |||
930 | void GLAPIENTRY |
||
931 | _mesa_LockArraysEXT(GLint first, GLsizei count) |
||
932 | { |
||
933 | GET_CURRENT_CONTEXT(ctx); |
||
934 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
935 | |||
936 | if (MESA_VERBOSE & VERBOSE_API) |
||
937 | _mesa_debug(ctx, "glLockArrays %d %d\n", first, count); |
||
938 | |||
939 | if (first < 0) { |
||
940 | _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" ); |
||
941 | return; |
||
942 | } |
||
943 | if (count <= 0) { |
||
944 | _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" ); |
||
945 | return; |
||
946 | } |
||
947 | if (ctx->Array.LockCount != 0) { |
||
948 | _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" ); |
||
949 | return; |
||
950 | } |
||
951 | |||
952 | ctx->Array.LockFirst = first; |
||
953 | ctx->Array.LockCount = count; |
||
954 | |||
955 | ctx->NewState |= _NEW_ARRAY; |
||
956 | ctx->Array.NewState |= _NEW_ARRAY_ALL; |
||
957 | } |
||
958 | |||
959 | |||
960 | void GLAPIENTRY |
||
961 | _mesa_UnlockArraysEXT( void ) |
||
962 | { |
||
963 | GET_CURRENT_CONTEXT(ctx); |
||
964 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
965 | |||
966 | if (MESA_VERBOSE & VERBOSE_API) |
||
967 | _mesa_debug(ctx, "glUnlockArrays\n"); |
||
968 | |||
969 | if (ctx->Array.LockCount == 0) { |
||
970 | _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" ); |
||
971 | return; |
||
972 | } |
||
973 | |||
974 | ctx->Array.LockFirst = 0; |
||
975 | ctx->Array.LockCount = 0; |
||
976 | ctx->NewState |= _NEW_ARRAY; |
||
977 | ctx->Array.NewState |= _NEW_ARRAY_ALL; |
||
978 | } |
||
979 | |||
980 | |||
981 | /* GL_EXT_multi_draw_arrays */ |
||
982 | void GLAPIENTRY |
||
983 | _mesa_MultiDrawArraysEXT( GLenum mode, const GLint *first, |
||
984 | const GLsizei *count, GLsizei primcount ) |
||
985 | { |
||
986 | GET_CURRENT_CONTEXT(ctx); |
||
987 | GLint i; |
||
988 | |||
989 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
990 | |||
991 | for (i = 0; i < primcount; i++) { |
||
992 | if (count[i] > 0) { |
||
993 | CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i])); |
||
994 | } |
||
995 | } |
||
996 | } |
||
997 | |||
998 | |||
999 | /* GL_IBM_multimode_draw_arrays */ |
||
1000 | void GLAPIENTRY |
||
1001 | _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first, |
||
1002 | const GLsizei * count, |
||
1003 | GLsizei primcount, GLint modestride ) |
||
1004 | { |
||
1005 | GET_CURRENT_CONTEXT(ctx); |
||
1006 | GLint i; |
||
1007 | |||
1008 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
1009 | |||
1010 | for ( i = 0 ; i < primcount ; i++ ) { |
||
1011 | if ( count[i] > 0 ) { |
||
1012 | GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); |
||
1013 | CALL_DrawArrays(ctx->Exec, ( m, first[i], count[i] )); |
||
1014 | } |
||
1015 | } |
||
1016 | } |
||
1017 | |||
1018 | |||
1019 | /* GL_IBM_multimode_draw_arrays */ |
||
1020 | void GLAPIENTRY |
||
1021 | _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count, |
||
1022 | GLenum type, const GLvoid * const * indices, |
||
1023 | GLsizei primcount, GLint modestride ) |
||
1024 | { |
||
1025 | GET_CURRENT_CONTEXT(ctx); |
||
1026 | GLint i; |
||
1027 | |||
1028 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
1029 | |||
1030 | /* XXX not sure about ARB_vertex_buffer_object handling here */ |
||
1031 | |||
1032 | for ( i = 0 ; i < primcount ; i++ ) { |
||
1033 | if ( count[i] > 0 ) { |
||
1034 | GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); |
||
1035 | CALL_DrawElements(ctx->Exec, ( m, count[i], type, indices[i] )); |
||
1036 | } |
||
1037 | } |
||
1038 | } |
||
1039 | |||
1040 | |||
1041 | /** |
||
1042 | * GL_NV_primitive_restart and GL 3.1 |
||
1043 | */ |
||
1044 | void GLAPIENTRY |
||
1045 | _mesa_PrimitiveRestartIndex(GLuint index) |
||
1046 | { |
||
1047 | GET_CURRENT_CONTEXT(ctx); |
||
1048 | |||
1049 | if (!ctx->Extensions.NV_primitive_restart && |
||
1050 | ctx->VersionMajor * 10 + ctx->VersionMinor < 31) { |
||
1051 | _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()"); |
||
1052 | return; |
||
1053 | } |
||
1054 | |||
1055 | ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); |
||
1056 | |||
1057 | FLUSH_VERTICES(ctx, _NEW_TRANSFORM); |
||
1058 | |||
1059 | ctx->Array.RestartIndex = index; |
||
1060 | } |
||
1061 | |||
1062 | |||
1063 | /** |
||
1064 | * Copy one client vertex array to another. |
||
1065 | */ |
||
1066 | void |
||
1067 | _mesa_copy_client_array(struct gl_context *ctx, |
||
1068 | struct gl_client_array *dst, |
||
1069 | struct gl_client_array *src) |
||
1070 | { |
||
1071 | dst->Size = src->Size; |
||
1072 | dst->Type = src->Type; |
||
1073 | dst->Format = src->Format; |
||
1074 | dst->Stride = src->Stride; |
||
1075 | dst->StrideB = src->StrideB; |
||
1076 | dst->Ptr = src->Ptr; |
||
1077 | dst->Enabled = src->Enabled; |
||
1078 | dst->Normalized = src->Normalized; |
||
1079 | dst->Integer = src->Integer; |
||
1080 | dst->_ElementSize = src->_ElementSize; |
||
1081 | _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj); |
||
1082 | dst->_MaxElement = src->_MaxElement; |
||
1083 | } |
||
1084 | |||
1085 | |||
1086 | |||
1087 | /** |
||
1088 | * Print vertex array's fields. |
||
1089 | */ |
||
1090 | static void |
||
1091 | print_array(const char *name, GLint index, const struct gl_client_array *array) |
||
1092 | { |
||
1093 | if (index >= 0) |
||
1094 | printf(" %s[%d]: ", name, index); |
||
1095 | else |
||
1096 | printf(" %s: ", name); |
||
1097 | printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu), MaxElem=%u\n", |
||
1098 | array->Ptr, array->Type, array->Size, |
||
1099 | array->_ElementSize, array->StrideB, |
||
1100 | array->BufferObj->Name, (unsigned long) array->BufferObj->Size, |
||
1101 | array->_MaxElement); |
||
1102 | } |
||
1103 | |||
1104 | |||
1105 | /** |
||
1106 | * Print current vertex object/array info. For debug. |
||
1107 | */ |
||
1108 | void |
||
1109 | _mesa_print_arrays(struct gl_context *ctx) |
||
1110 | { |
||
1111 | struct gl_array_object *arrayObj = ctx->Array.ArrayObj; |
||
1112 | GLuint i; |
||
1113 | |||
1114 | _mesa_update_array_object_max_element(ctx, arrayObj); |
||
1115 | |||
1116 | printf("Array Object %u\n", arrayObj->Name); |
||
1117 | if (arrayObj->Vertex.Enabled) |
||
1118 | print_array("Vertex", -1, &arrayObj->Vertex); |
||
1119 | if (arrayObj->Normal.Enabled) |
||
1120 | print_array("Normal", -1, &arrayObj->Normal); |
||
1121 | if (arrayObj->Color.Enabled) |
||
1122 | print_array("Color", -1, &arrayObj->Color); |
||
1123 | for (i = 0; i < Elements(arrayObj->TexCoord); i++) |
||
1124 | if (arrayObj->TexCoord[i].Enabled) |
||
1125 | print_array("TexCoord", i, &arrayObj->TexCoord[i]); |
||
1126 | for (i = 0; i < Elements(arrayObj->VertexAttrib); i++) |
||
1127 | if (arrayObj->VertexAttrib[i].Enabled) |
||
1128 | print_array("Attrib", i, &arrayObj->VertexAttrib[i]); |
||
1129 | printf(" _MaxElement = %u\n", arrayObj->_MaxElement); |
||
1130 | } |
||
1131 | |||
1132 | |||
1133 | /** |
||
1134 | * Initialize vertex array state for given context. |
||
1135 | */ |
||
1136 | void |
||
1137 | _mesa_init_varray(struct gl_context *ctx) |
||
1138 | { |
||
1139 | ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0); |
||
1140 | _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, |
||
1141 | ctx->Array.DefaultArrayObj); |
||
1142 | ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ |
||
1143 | |||
1144 | ctx->Array.Objects = _mesa_NewHashTable(); |
||
1145 | } |
||
1146 | |||
1147 | |||
1148 | /** |
||
1149 | * Callback for deleting an array object. Called by _mesa_HashDeleteAll(). |
||
1150 | */ |
||
1151 | static void |
||
1152 | delete_arrayobj_cb(GLuint id, void *data, void *userData) |
||
1153 | { |
||
1154 | struct gl_array_object *arrayObj = (struct gl_array_object *) data; |
||
1155 | struct gl_context *ctx = (struct gl_context *) userData; |
||
1156 | _mesa_delete_array_object(ctx, arrayObj); |
||
1157 | } |
||
1158 | |||
1159 | |||
1160 | /** |
||
1161 | * Free vertex array state for given context. |
||
1162 | */ |
||
1163 | void |
||
1164 | _mesa_free_varray_data(struct gl_context *ctx) |
||
1165 | { |
||
1166 | _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx); |
||
1167 | _mesa_DeleteHashTable(ctx->Array.Objects); |
||
1168 | }>>>>>>=>>>>>>>>>=>> |