3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2003 Brian Paul 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.
28 * eval.c was written by
29 * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and
30 * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de).
32 * My original implementation of evaluators was simplistic and didn't
33 * compute surface normal vectors properly. Bernd and Volker applied
34 * used more sophisticated methods to get better results.
46 #include "mfeatures.h"
48 #include "main/dispatch.h"
52 * Return the number of components per control point for any type of
53 * evaluator. Return 0 if bad target.
54 * See table 5.1 in the OpenGL 1.2 spec.
56 GLuint
_mesa_evaluator_components( GLenum target
)
59 case GL_MAP1_VERTEX_3
: return 3;
60 case GL_MAP1_VERTEX_4
: return 4;
61 case GL_MAP1_INDEX
: return 1;
62 case GL_MAP1_COLOR_4
: return 4;
63 case GL_MAP1_NORMAL
: return 3;
64 case GL_MAP1_TEXTURE_COORD_1
: return 1;
65 case GL_MAP1_TEXTURE_COORD_2
: return 2;
66 case GL_MAP1_TEXTURE_COORD_3
: return 3;
67 case GL_MAP1_TEXTURE_COORD_4
: return 4;
68 case GL_MAP2_VERTEX_3
: return 3;
69 case GL_MAP2_VERTEX_4
: return 4;
70 case GL_MAP2_INDEX
: return 1;
71 case GL_MAP2_COLOR_4
: return 4;
72 case GL_MAP2_NORMAL
: return 3;
73 case GL_MAP2_TEXTURE_COORD_1
: return 1;
74 case GL_MAP2_TEXTURE_COORD_2
: return 2;
75 case GL_MAP2_TEXTURE_COORD_3
: return 3;
76 case GL_MAP2_TEXTURE_COORD_4
: return 4;
80 /* XXX need to check for the vertex program extension
81 if (!ctx->Extensions.NV_vertex_program)
85 if (target
>= GL_MAP1_VERTEX_ATTRIB0_4_NV
&&
86 target
<= GL_MAP1_VERTEX_ATTRIB15_4_NV
)
89 if (target
>= GL_MAP2_VERTEX_ATTRIB0_4_NV
&&
90 target
<= GL_MAP2_VERTEX_ATTRIB15_4_NV
)
98 * Return pointer to the gl_1d_map struct for the named target.
100 static struct gl_1d_map
*
101 get_1d_map( struct gl_context
*ctx
, GLenum target
)
104 case GL_MAP1_VERTEX_3
:
105 return &ctx
->EvalMap
.Map1Vertex3
;
106 case GL_MAP1_VERTEX_4
:
107 return &ctx
->EvalMap
.Map1Vertex4
;
109 return &ctx
->EvalMap
.Map1Index
;
110 case GL_MAP1_COLOR_4
:
111 return &ctx
->EvalMap
.Map1Color4
;
113 return &ctx
->EvalMap
.Map1Normal
;
114 case GL_MAP1_TEXTURE_COORD_1
:
115 return &ctx
->EvalMap
.Map1Texture1
;
116 case GL_MAP1_TEXTURE_COORD_2
:
117 return &ctx
->EvalMap
.Map1Texture2
;
118 case GL_MAP1_TEXTURE_COORD_3
:
119 return &ctx
->EvalMap
.Map1Texture3
;
120 case GL_MAP1_TEXTURE_COORD_4
:
121 return &ctx
->EvalMap
.Map1Texture4
;
122 case GL_MAP1_VERTEX_ATTRIB0_4_NV
:
123 case GL_MAP1_VERTEX_ATTRIB1_4_NV
:
124 case GL_MAP1_VERTEX_ATTRIB2_4_NV
:
125 case GL_MAP1_VERTEX_ATTRIB3_4_NV
:
126 case GL_MAP1_VERTEX_ATTRIB4_4_NV
:
127 case GL_MAP1_VERTEX_ATTRIB5_4_NV
:
128 case GL_MAP1_VERTEX_ATTRIB6_4_NV
:
129 case GL_MAP1_VERTEX_ATTRIB7_4_NV
:
130 case GL_MAP1_VERTEX_ATTRIB8_4_NV
:
131 case GL_MAP1_VERTEX_ATTRIB9_4_NV
:
132 case GL_MAP1_VERTEX_ATTRIB10_4_NV
:
133 case GL_MAP1_VERTEX_ATTRIB11_4_NV
:
134 case GL_MAP1_VERTEX_ATTRIB12_4_NV
:
135 case GL_MAP1_VERTEX_ATTRIB13_4_NV
:
136 case GL_MAP1_VERTEX_ATTRIB14_4_NV
:
137 case GL_MAP1_VERTEX_ATTRIB15_4_NV
:
138 if (!ctx
->Extensions
.NV_vertex_program
)
140 return &ctx
->EvalMap
.Map1Attrib
[target
- GL_MAP1_VERTEX_ATTRIB0_4_NV
];
148 * Return pointer to the gl_2d_map struct for the named target.
150 static struct gl_2d_map
*
151 get_2d_map( struct gl_context
*ctx
, GLenum target
)
154 case GL_MAP2_VERTEX_3
:
155 return &ctx
->EvalMap
.Map2Vertex3
;
156 case GL_MAP2_VERTEX_4
:
157 return &ctx
->EvalMap
.Map2Vertex4
;
159 return &ctx
->EvalMap
.Map2Index
;
160 case GL_MAP2_COLOR_4
:
161 return &ctx
->EvalMap
.Map2Color4
;
163 return &ctx
->EvalMap
.Map2Normal
;
164 case GL_MAP2_TEXTURE_COORD_1
:
165 return &ctx
->EvalMap
.Map2Texture1
;
166 case GL_MAP2_TEXTURE_COORD_2
:
167 return &ctx
->EvalMap
.Map2Texture2
;
168 case GL_MAP2_TEXTURE_COORD_3
:
169 return &ctx
->EvalMap
.Map2Texture3
;
170 case GL_MAP2_TEXTURE_COORD_4
:
171 return &ctx
->EvalMap
.Map2Texture4
;
172 case GL_MAP2_VERTEX_ATTRIB0_4_NV
:
173 case GL_MAP2_VERTEX_ATTRIB1_4_NV
:
174 case GL_MAP2_VERTEX_ATTRIB2_4_NV
:
175 case GL_MAP2_VERTEX_ATTRIB3_4_NV
:
176 case GL_MAP2_VERTEX_ATTRIB4_4_NV
:
177 case GL_MAP2_VERTEX_ATTRIB5_4_NV
:
178 case GL_MAP2_VERTEX_ATTRIB6_4_NV
:
179 case GL_MAP2_VERTEX_ATTRIB7_4_NV
:
180 case GL_MAP2_VERTEX_ATTRIB8_4_NV
:
181 case GL_MAP2_VERTEX_ATTRIB9_4_NV
:
182 case GL_MAP2_VERTEX_ATTRIB10_4_NV
:
183 case GL_MAP2_VERTEX_ATTRIB11_4_NV
:
184 case GL_MAP2_VERTEX_ATTRIB12_4_NV
:
185 case GL_MAP2_VERTEX_ATTRIB13_4_NV
:
186 case GL_MAP2_VERTEX_ATTRIB14_4_NV
:
187 case GL_MAP2_VERTEX_ATTRIB15_4_NV
:
188 if (!ctx
->Extensions
.NV_vertex_program
)
190 return &ctx
->EvalMap
.Map2Attrib
[target
- GL_MAP2_VERTEX_ATTRIB0_4_NV
];
197 /**********************************************************************/
198 /*** Copy and deallocate control points ***/
199 /**********************************************************************/
203 * Copy 1-parametric evaluator control points from user-specified
204 * memory space to a buffer of contiguous control points.
205 * \param see glMap1f for details
206 * \return pointer to buffer of contiguous control points or NULL if out
209 GLfloat
*_mesa_copy_map_points1f( GLenum target
, GLint ustride
, GLint uorder
,
210 const GLfloat
*points
)
213 GLint i
, k
, size
= _mesa_evaluator_components(target
);
215 if (!points
|| !size
)
218 buffer
= malloc(uorder
* size
* sizeof(GLfloat
));
221 for (i
= 0, p
= buffer
; i
< uorder
; i
++, points
+= ustride
)
222 for (k
= 0; k
< size
; k
++)
231 * Same as above but convert doubles to floats.
233 GLfloat
*_mesa_copy_map_points1d( GLenum target
, GLint ustride
, GLint uorder
,
234 const GLdouble
*points
)
237 GLint i
, k
, size
= _mesa_evaluator_components(target
);
239 if (!points
|| !size
)
242 buffer
= malloc(uorder
* size
* sizeof(GLfloat
));
245 for (i
= 0, p
= buffer
; i
< uorder
; i
++, points
+= ustride
)
246 for (k
= 0; k
< size
; k
++)
247 *p
++ = (GLfloat
) points
[k
];
255 * Copy 2-parametric evaluator control points from user-specified
256 * memory space to a buffer of contiguous control points.
257 * Additional memory is allocated to be used by the horner and
258 * de Casteljau evaluation schemes.
260 * \param see glMap2f for details
261 * \return pointer to buffer of contiguous control points or NULL if out
264 GLfloat
*_mesa_copy_map_points2f( GLenum target
,
265 GLint ustride
, GLint uorder
,
266 GLint vstride
, GLint vorder
,
267 const GLfloat
*points
)
270 GLint i
, j
, k
, size
, dsize
, hsize
;
273 size
= _mesa_evaluator_components(target
);
275 if (!points
|| size
==0) {
279 /* max(uorder, vorder) additional points are used in */
280 /* horner evaluation and uorder*vorder additional */
281 /* values are needed for de Casteljau */
282 dsize
= (uorder
== 2 && vorder
== 2)? 0 : uorder
*vorder
;
283 hsize
= (uorder
> vorder
? uorder
: vorder
)*size
;
286 buffer
= malloc((uorder
*vorder
*size
+hsize
)*sizeof(GLfloat
));
288 buffer
= malloc((uorder
*vorder
*size
+dsize
)*sizeof(GLfloat
));
290 /* compute the increment value for the u-loop */
291 uinc
= ustride
- vorder
*vstride
;
294 for (i
=0, p
=buffer
; i
<uorder
; i
++, points
+= uinc
)
295 for (j
=0; j
<vorder
; j
++, points
+= vstride
)
296 for (k
=0; k
<size
; k
++)
305 * Same as above but convert doubles to floats.
307 GLfloat
*_mesa_copy_map_points2d(GLenum target
,
308 GLint ustride
, GLint uorder
,
309 GLint vstride
, GLint vorder
,
310 const GLdouble
*points
)
313 GLint i
, j
, k
, size
, hsize
, dsize
;
316 size
= _mesa_evaluator_components(target
);
318 if (!points
|| size
==0) {
322 /* max(uorder, vorder) additional points are used in */
323 /* horner evaluation and uorder*vorder additional */
324 /* values are needed for de Casteljau */
325 dsize
= (uorder
== 2 && vorder
== 2)? 0 : uorder
*vorder
;
326 hsize
= (uorder
> vorder
? uorder
: vorder
)*size
;
329 buffer
= malloc((uorder
*vorder
*size
+hsize
)*sizeof(GLfloat
));
331 buffer
= malloc((uorder
*vorder
*size
+dsize
)*sizeof(GLfloat
));
333 /* compute the increment value for the u-loop */
334 uinc
= ustride
- vorder
*vstride
;
337 for (i
=0, p
=buffer
; i
<uorder
; i
++, points
+= uinc
)
338 for (j
=0; j
<vorder
; j
++, points
+= vstride
)
339 for (k
=0; k
<size
; k
++)
340 *p
++ = (GLfloat
) points
[k
];
348 /**********************************************************************/
349 /*** API entry points ***/
350 /**********************************************************************/
354 * This does the work of glMap1[fd].
357 map1(GLenum target
, GLfloat u1
, GLfloat u2
, GLint ustride
,
358 GLint uorder
, const GLvoid
*points
, GLenum type
)
360 GET_CURRENT_CONTEXT(ctx
);
363 struct gl_1d_map
*map
= NULL
;
365 ASSERT_OUTSIDE_BEGIN_END(ctx
);
366 ASSERT(type
== GL_FLOAT
|| type
== GL_DOUBLE
);
369 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMap1(u1,u2)" );
372 if (uorder
< 1 || uorder
> MAX_EVAL_ORDER
) {
373 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMap1(order)" );
377 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMap1(points)" );
381 k
= _mesa_evaluator_components( target
);
383 _mesa_error( ctx
, GL_INVALID_ENUM
, "glMap1(target)" );
388 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMap1(stride)" );
392 if (ctx
->Texture
.CurrentUnit
!= 0) {
393 /* See OpenGL 1.2.1 spec, section F.2.13 */
394 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glMap2(ACTIVE_TEXTURE != 0)" );
398 map
= get_1d_map(ctx
, target
);
400 _mesa_error( ctx
, GL_INVALID_ENUM
, "glMap1(target)" );
404 /* make copy of the control points */
405 if (type
== GL_FLOAT
)
406 pnts
= _mesa_copy_map_points1f(target
, ustride
, uorder
, (GLfloat
*) points
);
408 pnts
= _mesa_copy_map_points1d(target
, ustride
, uorder
, (GLdouble
*) points
);
411 FLUSH_VERTICES(ctx
, _NEW_EVAL
);
415 map
->du
= 1.0F
/ (u2
- u1
);
422 static void GLAPIENTRY
423 _mesa_Map1f( GLenum target
, GLfloat u1
, GLfloat u2
, GLint stride
,
424 GLint order
, const GLfloat
*points
)
426 map1(target
, u1
, u2
, stride
, order
, points
, GL_FLOAT
);
430 static void GLAPIENTRY
431 _mesa_Map1d( GLenum target
, GLdouble u1
, GLdouble u2
, GLint stride
,
432 GLint order
, const GLdouble
*points
)
434 map1(target
, (GLfloat
) u1
, (GLfloat
) u2
, stride
, order
, points
, GL_DOUBLE
);
439 map2( GLenum target
, GLfloat u1
, GLfloat u2
, GLint ustride
, GLint uorder
,
440 GLfloat v1
, GLfloat v2
, GLint vstride
, GLint vorder
,
441 const GLvoid
*points
, GLenum type
)
443 GET_CURRENT_CONTEXT(ctx
);
446 struct gl_2d_map
*map
= NULL
;
448 ASSERT_OUTSIDE_BEGIN_END(ctx
);
449 ASSERT(type
== GL_FLOAT
|| type
== GL_DOUBLE
);
452 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMap2(u1,u2)" );
457 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMap2(v1,v2)" );
461 if (uorder
<1 || uorder
>MAX_EVAL_ORDER
) {
462 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMap2(uorder)" );
466 if (vorder
<1 || vorder
>MAX_EVAL_ORDER
) {
467 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMap2(vorder)" );
471 k
= _mesa_evaluator_components( target
);
473 _mesa_error( ctx
, GL_INVALID_ENUM
, "glMap2(target)" );
478 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMap2(ustride)" );
482 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMap2(vstride)" );
486 if (ctx
->Texture
.CurrentUnit
!= 0) {
487 /* See OpenGL 1.2.1 spec, section F.2.13 */
488 _mesa_error( ctx
, GL_INVALID_OPERATION
, "glMap2(ACTIVE_TEXTURE != 0)" );
492 map
= get_2d_map(ctx
, target
);
494 _mesa_error( ctx
, GL_INVALID_ENUM
, "glMap2(target)" );
498 /* make copy of the control points */
499 if (type
== GL_FLOAT
)
500 pnts
= _mesa_copy_map_points2f(target
, ustride
, uorder
,
501 vstride
, vorder
, (GLfloat
*) points
);
503 pnts
= _mesa_copy_map_points2d(target
, ustride
, uorder
,
504 vstride
, vorder
, (GLdouble
*) points
);
507 FLUSH_VERTICES(ctx
, _NEW_EVAL
);
508 map
->Uorder
= uorder
;
511 map
->du
= 1.0F
/ (u2
- u1
);
512 map
->Vorder
= vorder
;
515 map
->dv
= 1.0F
/ (v2
- v1
);
521 static void GLAPIENTRY
522 _mesa_Map2f( GLenum target
,
523 GLfloat u1
, GLfloat u2
, GLint ustride
, GLint uorder
,
524 GLfloat v1
, GLfloat v2
, GLint vstride
, GLint vorder
,
525 const GLfloat
*points
)
527 map2(target
, u1
, u2
, ustride
, uorder
, v1
, v2
, vstride
, vorder
,
532 static void GLAPIENTRY
533 _mesa_Map2d( GLenum target
,
534 GLdouble u1
, GLdouble u2
, GLint ustride
, GLint uorder
,
535 GLdouble v1
, GLdouble v2
, GLint vstride
, GLint vorder
,
536 const GLdouble
*points
)
538 map2(target
, (GLfloat
) u1
, (GLfloat
) u2
, ustride
, uorder
,
539 (GLfloat
) v1
, (GLfloat
) v2
, vstride
, vorder
, points
, GL_DOUBLE
);
544 static void GLAPIENTRY
545 _mesa_GetnMapdvARB( GLenum target
, GLenum query
, GLsizei bufSize
, GLdouble
*v
)
547 GET_CURRENT_CONTEXT(ctx
);
548 struct gl_1d_map
*map1d
;
549 struct gl_2d_map
*map2d
;
555 ASSERT_OUTSIDE_BEGIN_END(ctx
);
557 comps
= _mesa_evaluator_components(target
);
559 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMapdv(target)" );
563 map1d
= get_1d_map(ctx
, target
);
564 map2d
= get_2d_map(ctx
, target
);
565 ASSERT(map1d
|| map2d
);
570 data
= map1d
->Points
;
571 n
= map1d
->Order
* comps
;
574 data
= map2d
->Points
;
575 n
= map2d
->Uorder
* map2d
->Vorder
* comps
;
578 numBytes
= n
* sizeof *v
;
579 if (bufSize
< numBytes
)
588 numBytes
= 1 * sizeof *v
;
589 if (bufSize
< numBytes
)
591 v
[0] = (GLdouble
) map1d
->Order
;
594 numBytes
= 2 * sizeof *v
;
595 if (bufSize
< numBytes
)
597 v
[0] = (GLdouble
) map2d
->Uorder
;
598 v
[1] = (GLdouble
) map2d
->Vorder
;
603 numBytes
= 2 * sizeof *v
;
604 if (bufSize
< numBytes
)
606 v
[0] = (GLdouble
) map1d
->u1
;
607 v
[1] = (GLdouble
) map1d
->u2
;
610 numBytes
= 4 * sizeof *v
;
611 if (bufSize
< numBytes
)
613 v
[0] = (GLdouble
) map2d
->u1
;
614 v
[1] = (GLdouble
) map2d
->u2
;
615 v
[2] = (GLdouble
) map2d
->v1
;
616 v
[3] = (GLdouble
) map2d
->v2
;
620 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMapdv(query)" );
625 _mesa_error( ctx
, GL_INVALID_OPERATION
,
626 "glGetnMapdvARB(out of bounds: bufSize is %d,"
627 " but %d bytes are required)", bufSize
, numBytes
);
630 static void GLAPIENTRY
631 _mesa_GetMapdv( GLenum target
, GLenum query
, GLdouble
*v
)
633 _mesa_GetnMapdvARB(target
, query
, INT_MAX
, v
);
636 static void GLAPIENTRY
637 _mesa_GetnMapfvARB( GLenum target
, GLenum query
, GLsizei bufSize
, GLfloat
*v
)
639 GET_CURRENT_CONTEXT(ctx
);
640 struct gl_1d_map
*map1d
;
641 struct gl_2d_map
*map2d
;
647 ASSERT_OUTSIDE_BEGIN_END(ctx
);
649 comps
= _mesa_evaluator_components(target
);
651 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMapfv(target)" );
655 map1d
= get_1d_map(ctx
, target
);
656 map2d
= get_2d_map(ctx
, target
);
657 ASSERT(map1d
|| map2d
);
662 data
= map1d
->Points
;
663 n
= map1d
->Order
* comps
;
666 data
= map2d
->Points
;
667 n
= map2d
->Uorder
* map2d
->Vorder
* comps
;
670 numBytes
= n
* sizeof *v
;
671 if (bufSize
< numBytes
)
680 numBytes
= 1 * sizeof *v
;
681 if (bufSize
< numBytes
)
683 v
[0] = (GLfloat
) map1d
->Order
;
686 numBytes
= 2 * sizeof *v
;
687 if (bufSize
< numBytes
)
689 v
[0] = (GLfloat
) map2d
->Uorder
;
690 v
[1] = (GLfloat
) map2d
->Vorder
;
695 numBytes
= 2 * sizeof *v
;
696 if (bufSize
< numBytes
)
702 numBytes
= 4 * sizeof *v
;
703 if (bufSize
< numBytes
)
712 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMapfv(query)" );
717 _mesa_error( ctx
, GL_INVALID_OPERATION
,
718 "glGetnMapfvARB(out of bounds: bufSize is %d,"
719 " but %d bytes are required)", bufSize
, numBytes
);
723 static void GLAPIENTRY
724 _mesa_GetMapfv( GLenum target
, GLenum query
, GLfloat
*v
)
726 _mesa_GetnMapfvARB(target
, query
, INT_MAX
, v
);
730 static void GLAPIENTRY
731 _mesa_GetnMapivARB( GLenum target
, GLenum query
, GLsizei bufSize
, GLint
*v
)
733 GET_CURRENT_CONTEXT(ctx
);
734 struct gl_1d_map
*map1d
;
735 struct gl_2d_map
*map2d
;
741 ASSERT_OUTSIDE_BEGIN_END(ctx
);
743 comps
= _mesa_evaluator_components(target
);
745 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMapiv(target)" );
749 map1d
= get_1d_map(ctx
, target
);
750 map2d
= get_2d_map(ctx
, target
);
751 ASSERT(map1d
|| map2d
);
756 data
= map1d
->Points
;
757 n
= map1d
->Order
* comps
;
760 data
= map2d
->Points
;
761 n
= map2d
->Uorder
* map2d
->Vorder
* comps
;
764 numBytes
= n
* sizeof *v
;
765 if (bufSize
< numBytes
)
768 v
[i
] = IROUND(data
[i
]);
774 numBytes
= 1 * sizeof *v
;
775 if (bufSize
< numBytes
)
780 numBytes
= 2 * sizeof *v
;
781 if (bufSize
< numBytes
)
783 v
[0] = map2d
->Uorder
;
784 v
[1] = map2d
->Vorder
;
789 numBytes
= 2 * sizeof *v
;
790 if (bufSize
< numBytes
)
792 v
[0] = IROUND(map1d
->u1
);
793 v
[1] = IROUND(map1d
->u2
);
796 numBytes
= 4 * sizeof *v
;
797 if (bufSize
< numBytes
)
799 v
[0] = IROUND(map2d
->u1
);
800 v
[1] = IROUND(map2d
->u2
);
801 v
[2] = IROUND(map2d
->v1
);
802 v
[3] = IROUND(map2d
->v2
);
806 _mesa_error( ctx
, GL_INVALID_ENUM
, "glGetMapiv(query)" );
811 _mesa_error( ctx
, GL_INVALID_OPERATION
,
812 "glGetnMapivARB(out of bounds: bufSize is %d,"
813 " but %d bytes are required)", bufSize
, numBytes
);
817 static void GLAPIENTRY
818 _mesa_GetMapiv( GLenum target
, GLenum query
, GLint
*v
)
820 _mesa_GetnMapivARB(target
, query
, INT_MAX
, v
);
824 static void GLAPIENTRY
825 _mesa_MapGrid1f( GLint un
, GLfloat u1
, GLfloat u2
)
827 GET_CURRENT_CONTEXT(ctx
);
828 ASSERT_OUTSIDE_BEGIN_END(ctx
);
831 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMapGrid1f" );
834 FLUSH_VERTICES(ctx
, _NEW_EVAL
);
835 ctx
->Eval
.MapGrid1un
= un
;
836 ctx
->Eval
.MapGrid1u1
= u1
;
837 ctx
->Eval
.MapGrid1u2
= u2
;
838 ctx
->Eval
.MapGrid1du
= (u2
- u1
) / (GLfloat
) un
;
842 static void GLAPIENTRY
843 _mesa_MapGrid1d( GLint un
, GLdouble u1
, GLdouble u2
)
845 _mesa_MapGrid1f( un
, (GLfloat
) u1
, (GLfloat
) u2
);
849 static void GLAPIENTRY
850 _mesa_MapGrid2f( GLint un
, GLfloat u1
, GLfloat u2
,
851 GLint vn
, GLfloat v1
, GLfloat v2
)
853 GET_CURRENT_CONTEXT(ctx
);
854 ASSERT_OUTSIDE_BEGIN_END(ctx
);
857 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMapGrid2f(un)" );
861 _mesa_error( ctx
, GL_INVALID_VALUE
, "glMapGrid2f(vn)" );
865 FLUSH_VERTICES(ctx
, _NEW_EVAL
);
866 ctx
->Eval
.MapGrid2un
= un
;
867 ctx
->Eval
.MapGrid2u1
= u1
;
868 ctx
->Eval
.MapGrid2u2
= u2
;
869 ctx
->Eval
.MapGrid2du
= (u2
- u1
) / (GLfloat
) un
;
870 ctx
->Eval
.MapGrid2vn
= vn
;
871 ctx
->Eval
.MapGrid2v1
= v1
;
872 ctx
->Eval
.MapGrid2v2
= v2
;
873 ctx
->Eval
.MapGrid2dv
= (v2
- v1
) / (GLfloat
) vn
;
877 static void GLAPIENTRY
878 _mesa_MapGrid2d( GLint un
, GLdouble u1
, GLdouble u2
,
879 GLint vn
, GLdouble v1
, GLdouble v2
)
881 _mesa_MapGrid2f( un
, (GLfloat
) u1
, (GLfloat
) u2
,
882 vn
, (GLfloat
) v1
, (GLfloat
) v2
);
887 _mesa_install_eval_vtxfmt(struct _glapi_table
*disp
,
888 const GLvertexformat
*vfmt
)
890 SET_EvalCoord1f(disp
, vfmt
->EvalCoord1f
);
891 SET_EvalCoord1fv(disp
, vfmt
->EvalCoord1fv
);
892 SET_EvalCoord2f(disp
, vfmt
->EvalCoord2f
);
893 SET_EvalCoord2fv(disp
, vfmt
->EvalCoord2fv
);
894 SET_EvalPoint1(disp
, vfmt
->EvalPoint1
);
895 SET_EvalPoint2(disp
, vfmt
->EvalPoint2
);
897 SET_EvalMesh1(disp
, vfmt
->EvalMesh1
);
898 SET_EvalMesh2(disp
, vfmt
->EvalMesh2
);
903 _mesa_init_eval_dispatch(struct _glapi_table
*disp
)
905 SET_GetMapdv(disp
, _mesa_GetMapdv
);
906 SET_GetMapfv(disp
, _mesa_GetMapfv
);
907 SET_GetMapiv(disp
, _mesa_GetMapiv
);
908 SET_Map1d(disp
, _mesa_Map1d
);
909 SET_Map1f(disp
, _mesa_Map1f
);
910 SET_Map2d(disp
, _mesa_Map2d
);
911 SET_Map2f(disp
, _mesa_Map2f
);
912 SET_MapGrid1d(disp
, _mesa_MapGrid1d
);
913 SET_MapGrid1f(disp
, _mesa_MapGrid1f
);
914 SET_MapGrid2d(disp
, _mesa_MapGrid2d
);
915 SET_MapGrid2f(disp
, _mesa_MapGrid2f
);
917 /* GL_ARB_robustness */
918 SET_GetnMapdvARB(disp
, _mesa_GetnMapdvARB
);
919 SET_GetnMapfvARB(disp
, _mesa_GetnMapfvARB
);
920 SET_GetnMapivARB(disp
, _mesa_GetnMapivARB
);
924 /**********************************************************************/
925 /***** Initialization *****/
926 /**********************************************************************/
929 * Initialize a 1-D evaluator map.
932 init_1d_map( struct gl_1d_map
*map
, int n
, const float *initial
)
937 map
->Points
= malloc(n
* sizeof(GLfloat
));
941 map
->Points
[i
] = initial
[i
];
947 * Initialize a 2-D evaluator map
950 init_2d_map( struct gl_2d_map
*map
, int n
, const float *initial
)
958 map
->Points
= malloc(n
* sizeof(GLfloat
));
962 map
->Points
[i
] = initial
[i
];
967 void _mesa_init_eval( struct gl_context
*ctx
)
971 /* Evaluators group */
972 ctx
->Eval
.Map1Color4
= GL_FALSE
;
973 ctx
->Eval
.Map1Index
= GL_FALSE
;
974 ctx
->Eval
.Map1Normal
= GL_FALSE
;
975 ctx
->Eval
.Map1TextureCoord1
= GL_FALSE
;
976 ctx
->Eval
.Map1TextureCoord2
= GL_FALSE
;
977 ctx
->Eval
.Map1TextureCoord3
= GL_FALSE
;
978 ctx
->Eval
.Map1TextureCoord4
= GL_FALSE
;
979 ctx
->Eval
.Map1Vertex3
= GL_FALSE
;
980 ctx
->Eval
.Map1Vertex4
= GL_FALSE
;
981 memset(ctx
->Eval
.Map1Attrib
, 0, sizeof(ctx
->Eval
.Map1Attrib
));
982 ctx
->Eval
.Map2Color4
= GL_FALSE
;
983 ctx
->Eval
.Map2Index
= GL_FALSE
;
984 ctx
->Eval
.Map2Normal
= GL_FALSE
;
985 ctx
->Eval
.Map2TextureCoord1
= GL_FALSE
;
986 ctx
->Eval
.Map2TextureCoord2
= GL_FALSE
;
987 ctx
->Eval
.Map2TextureCoord3
= GL_FALSE
;
988 ctx
->Eval
.Map2TextureCoord4
= GL_FALSE
;
989 ctx
->Eval
.Map2Vertex3
= GL_FALSE
;
990 ctx
->Eval
.Map2Vertex4
= GL_FALSE
;
991 memset(ctx
->Eval
.Map2Attrib
, 0, sizeof(ctx
->Eval
.Map2Attrib
));
992 ctx
->Eval
.AutoNormal
= GL_FALSE
;
993 ctx
->Eval
.MapGrid1un
= 1;
994 ctx
->Eval
.MapGrid1u1
= 0.0;
995 ctx
->Eval
.MapGrid1u2
= 1.0;
996 ctx
->Eval
.MapGrid2un
= 1;
997 ctx
->Eval
.MapGrid2vn
= 1;
998 ctx
->Eval
.MapGrid2u1
= 0.0;
999 ctx
->Eval
.MapGrid2u2
= 1.0;
1000 ctx
->Eval
.MapGrid2v1
= 0.0;
1001 ctx
->Eval
.MapGrid2v2
= 1.0;
1003 /* Evaluator data */
1005 static GLfloat vertex
[4] = { 0.0, 0.0, 0.0, 1.0 };
1006 static GLfloat normal
[3] = { 0.0, 0.0, 1.0 };
1007 static GLfloat index
[1] = { 1.0 };
1008 static GLfloat color
[4] = { 1.0, 1.0, 1.0, 1.0 };
1009 static GLfloat texcoord
[4] = { 0.0, 0.0, 0.0, 1.0 };
1010 static GLfloat attrib
[4] = { 0.0, 0.0, 0.0, 1.0 };
1012 init_1d_map( &ctx
->EvalMap
.Map1Vertex3
, 3, vertex
);
1013 init_1d_map( &ctx
->EvalMap
.Map1Vertex4
, 4, vertex
);
1014 init_1d_map( &ctx
->EvalMap
.Map1Index
, 1, index
);
1015 init_1d_map( &ctx
->EvalMap
.Map1Color4
, 4, color
);
1016 init_1d_map( &ctx
->EvalMap
.Map1Normal
, 3, normal
);
1017 init_1d_map( &ctx
->EvalMap
.Map1Texture1
, 1, texcoord
);
1018 init_1d_map( &ctx
->EvalMap
.Map1Texture2
, 2, texcoord
);
1019 init_1d_map( &ctx
->EvalMap
.Map1Texture3
, 3, texcoord
);
1020 init_1d_map( &ctx
->EvalMap
.Map1Texture4
, 4, texcoord
);
1021 for (i
= 0; i
< 16; i
++)
1022 init_1d_map( ctx
->EvalMap
.Map1Attrib
+ i
, 4, attrib
);
1024 init_2d_map( &ctx
->EvalMap
.Map2Vertex3
, 3, vertex
);
1025 init_2d_map( &ctx
->EvalMap
.Map2Vertex4
, 4, vertex
);
1026 init_2d_map( &ctx
->EvalMap
.Map2Index
, 1, index
);
1027 init_2d_map( &ctx
->EvalMap
.Map2Color4
, 4, color
);
1028 init_2d_map( &ctx
->EvalMap
.Map2Normal
, 3, normal
);
1029 init_2d_map( &ctx
->EvalMap
.Map2Texture1
, 1, texcoord
);
1030 init_2d_map( &ctx
->EvalMap
.Map2Texture2
, 2, texcoord
);
1031 init_2d_map( &ctx
->EvalMap
.Map2Texture3
, 3, texcoord
);
1032 init_2d_map( &ctx
->EvalMap
.Map2Texture4
, 4, texcoord
);
1033 for (i
= 0; i
< 16; i
++)
1034 init_2d_map( ctx
->EvalMap
.Map2Attrib
+ i
, 4, attrib
);
1039 void _mesa_free_eval_data( struct gl_context
*ctx
)
1043 /* Free evaluator data */
1044 free(ctx
->EvalMap
.Map1Vertex3
.Points
);
1045 free(ctx
->EvalMap
.Map1Vertex4
.Points
);
1046 free(ctx
->EvalMap
.Map1Index
.Points
);
1047 free(ctx
->EvalMap
.Map1Color4
.Points
);
1048 free(ctx
->EvalMap
.Map1Normal
.Points
);
1049 free(ctx
->EvalMap
.Map1Texture1
.Points
);
1050 free(ctx
->EvalMap
.Map1Texture2
.Points
);
1051 free(ctx
->EvalMap
.Map1Texture3
.Points
);
1052 free(ctx
->EvalMap
.Map1Texture4
.Points
);
1053 for (i
= 0; i
< Elements(ctx
->EvalMap
.Map1Attrib
); i
++)
1054 free(ctx
->EvalMap
.Map1Attrib
[i
].Points
);
1056 free(ctx
->EvalMap
.Map2Vertex3
.Points
);
1057 free(ctx
->EvalMap
.Map2Vertex4
.Points
);
1058 free(ctx
->EvalMap
.Map2Index
.Points
);
1059 free(ctx
->EvalMap
.Map2Color4
.Points
);
1060 free(ctx
->EvalMap
.Map2Normal
.Points
);
1061 free(ctx
->EvalMap
.Map2Texture1
.Points
);
1062 free(ctx
->EvalMap
.Map2Texture2
.Points
);
1063 free(ctx
->EvalMap
.Map2Texture3
.Points
);
1064 free(ctx
->EvalMap
.Map2Texture4
.Points
);
1065 for (i
= 0; i
< Elements(ctx
->EvalMap
.Map2Attrib
); i
++)
1066 free((ctx
->EvalMap
.Map2Attrib
[i
].Points
));