1bf215546Sopenharmony_ci
2bf215546Sopenharmony_ci/*
3bf215546Sopenharmony_ci * Mesa 3-D graphics library
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included
15bf215546Sopenharmony_ci * in all copies or substantial portions of the Software.
16bf215546Sopenharmony_ci *
17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
24bf215546Sopenharmony_ci */
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci/*
28bf215546Sopenharmony_ci * eval.c was written by
29bf215546Sopenharmony_ci * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and
30bf215546Sopenharmony_ci * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de).
31bf215546Sopenharmony_ci *
32bf215546Sopenharmony_ci * My original implementation of evaluators was simplistic and didn't
33bf215546Sopenharmony_ci * compute surface normal vectors properly.  Bernd and Volker applied
34bf215546Sopenharmony_ci * used more sophisticated methods to get better results.
35bf215546Sopenharmony_ci *
36bf215546Sopenharmony_ci * Thanks guys!
37bf215546Sopenharmony_ci */
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci#include "glheader.h"
41bf215546Sopenharmony_ci#include "context.h"
42bf215546Sopenharmony_ci#include "eval.h"
43bf215546Sopenharmony_ci#include "macros.h"
44bf215546Sopenharmony_ci#include "mtypes.h"
45bf215546Sopenharmony_ci#include "main/dispatch.h"
46bf215546Sopenharmony_ci#include "api_exec_decl.h"
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci/*
50bf215546Sopenharmony_ci * Return the number of components per control point for any type of
51bf215546Sopenharmony_ci * evaluator.  Return 0 if bad target.
52bf215546Sopenharmony_ci * See table 5.1 in the OpenGL 1.2 spec.
53bf215546Sopenharmony_ci */
54bf215546Sopenharmony_ciGLuint _mesa_evaluator_components( GLenum target )
55bf215546Sopenharmony_ci{
56bf215546Sopenharmony_ci   switch (target) {
57bf215546Sopenharmony_ci      case GL_MAP1_VERTEX_3:		return 3;
58bf215546Sopenharmony_ci      case GL_MAP1_VERTEX_4:		return 4;
59bf215546Sopenharmony_ci      case GL_MAP1_INDEX:		return 1;
60bf215546Sopenharmony_ci      case GL_MAP1_COLOR_4:		return 4;
61bf215546Sopenharmony_ci      case GL_MAP1_NORMAL:		return 3;
62bf215546Sopenharmony_ci      case GL_MAP1_TEXTURE_COORD_1:	return 1;
63bf215546Sopenharmony_ci      case GL_MAP1_TEXTURE_COORD_2:	return 2;
64bf215546Sopenharmony_ci      case GL_MAP1_TEXTURE_COORD_3:	return 3;
65bf215546Sopenharmony_ci      case GL_MAP1_TEXTURE_COORD_4:	return 4;
66bf215546Sopenharmony_ci      case GL_MAP2_VERTEX_3:		return 3;
67bf215546Sopenharmony_ci      case GL_MAP2_VERTEX_4:		return 4;
68bf215546Sopenharmony_ci      case GL_MAP2_INDEX:		return 1;
69bf215546Sopenharmony_ci      case GL_MAP2_COLOR_4:		return 4;
70bf215546Sopenharmony_ci      case GL_MAP2_NORMAL:		return 3;
71bf215546Sopenharmony_ci      case GL_MAP2_TEXTURE_COORD_1:	return 1;
72bf215546Sopenharmony_ci      case GL_MAP2_TEXTURE_COORD_2:	return 2;
73bf215546Sopenharmony_ci      case GL_MAP2_TEXTURE_COORD_3:	return 3;
74bf215546Sopenharmony_ci      case GL_MAP2_TEXTURE_COORD_4:	return 4;
75bf215546Sopenharmony_ci      default:				break;
76bf215546Sopenharmony_ci   }
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_ci   return 0;
79bf215546Sopenharmony_ci}
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_ci/*
83bf215546Sopenharmony_ci * Return pointer to the gl_1d_map struct for the named target.
84bf215546Sopenharmony_ci */
85bf215546Sopenharmony_cistatic struct gl_1d_map *
86bf215546Sopenharmony_ciget_1d_map( struct gl_context *ctx, GLenum target )
87bf215546Sopenharmony_ci{
88bf215546Sopenharmony_ci   switch (target) {
89bf215546Sopenharmony_ci      case GL_MAP1_VERTEX_3:
90bf215546Sopenharmony_ci         return &ctx->EvalMap.Map1Vertex3;
91bf215546Sopenharmony_ci      case GL_MAP1_VERTEX_4:
92bf215546Sopenharmony_ci         return &ctx->EvalMap.Map1Vertex4;
93bf215546Sopenharmony_ci      case GL_MAP1_INDEX:
94bf215546Sopenharmony_ci         return &ctx->EvalMap.Map1Index;
95bf215546Sopenharmony_ci      case GL_MAP1_COLOR_4:
96bf215546Sopenharmony_ci         return &ctx->EvalMap.Map1Color4;
97bf215546Sopenharmony_ci      case GL_MAP1_NORMAL:
98bf215546Sopenharmony_ci         return &ctx->EvalMap.Map1Normal;
99bf215546Sopenharmony_ci      case GL_MAP1_TEXTURE_COORD_1:
100bf215546Sopenharmony_ci         return &ctx->EvalMap.Map1Texture1;
101bf215546Sopenharmony_ci      case GL_MAP1_TEXTURE_COORD_2:
102bf215546Sopenharmony_ci         return &ctx->EvalMap.Map1Texture2;
103bf215546Sopenharmony_ci      case GL_MAP1_TEXTURE_COORD_3:
104bf215546Sopenharmony_ci         return &ctx->EvalMap.Map1Texture3;
105bf215546Sopenharmony_ci      case GL_MAP1_TEXTURE_COORD_4:
106bf215546Sopenharmony_ci         return &ctx->EvalMap.Map1Texture4;
107bf215546Sopenharmony_ci      default:
108bf215546Sopenharmony_ci         return NULL;
109bf215546Sopenharmony_ci   }
110bf215546Sopenharmony_ci}
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci/*
114bf215546Sopenharmony_ci * Return pointer to the gl_2d_map struct for the named target.
115bf215546Sopenharmony_ci */
116bf215546Sopenharmony_cistatic struct gl_2d_map *
117bf215546Sopenharmony_ciget_2d_map( struct gl_context *ctx, GLenum target )
118bf215546Sopenharmony_ci{
119bf215546Sopenharmony_ci   switch (target) {
120bf215546Sopenharmony_ci      case GL_MAP2_VERTEX_3:
121bf215546Sopenharmony_ci         return &ctx->EvalMap.Map2Vertex3;
122bf215546Sopenharmony_ci      case GL_MAP2_VERTEX_4:
123bf215546Sopenharmony_ci         return &ctx->EvalMap.Map2Vertex4;
124bf215546Sopenharmony_ci      case GL_MAP2_INDEX:
125bf215546Sopenharmony_ci         return &ctx->EvalMap.Map2Index;
126bf215546Sopenharmony_ci      case GL_MAP2_COLOR_4:
127bf215546Sopenharmony_ci         return &ctx->EvalMap.Map2Color4;
128bf215546Sopenharmony_ci      case GL_MAP2_NORMAL:
129bf215546Sopenharmony_ci         return &ctx->EvalMap.Map2Normal;
130bf215546Sopenharmony_ci      case GL_MAP2_TEXTURE_COORD_1:
131bf215546Sopenharmony_ci         return &ctx->EvalMap.Map2Texture1;
132bf215546Sopenharmony_ci      case GL_MAP2_TEXTURE_COORD_2:
133bf215546Sopenharmony_ci         return &ctx->EvalMap.Map2Texture2;
134bf215546Sopenharmony_ci      case GL_MAP2_TEXTURE_COORD_3:
135bf215546Sopenharmony_ci         return &ctx->EvalMap.Map2Texture3;
136bf215546Sopenharmony_ci      case GL_MAP2_TEXTURE_COORD_4:
137bf215546Sopenharmony_ci         return &ctx->EvalMap.Map2Texture4;
138bf215546Sopenharmony_ci      default:
139bf215546Sopenharmony_ci         return NULL;
140bf215546Sopenharmony_ci   }
141bf215546Sopenharmony_ci}
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci/**********************************************************************/
145bf215546Sopenharmony_ci/***            Copy and deallocate control points                  ***/
146bf215546Sopenharmony_ci/**********************************************************************/
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_ci/*
150bf215546Sopenharmony_ci * Copy 1-parametric evaluator control points from user-specified
151bf215546Sopenharmony_ci * memory space to a buffer of contiguous control points.
152bf215546Sopenharmony_ci * \param see glMap1f for details
153bf215546Sopenharmony_ci * \return pointer to buffer of contiguous control points or NULL if out
154bf215546Sopenharmony_ci *          of memory.
155bf215546Sopenharmony_ci */
156bf215546Sopenharmony_ciGLfloat *_mesa_copy_map_points1f( GLenum target, GLint ustride, GLint uorder,
157bf215546Sopenharmony_ci                                  const GLfloat *points )
158bf215546Sopenharmony_ci{
159bf215546Sopenharmony_ci   GLfloat *buffer, *p;
160bf215546Sopenharmony_ci   GLint i, k, size = _mesa_evaluator_components(target);
161bf215546Sopenharmony_ci
162bf215546Sopenharmony_ci   if (!points || !size)
163bf215546Sopenharmony_ci      return NULL;
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci   buffer = malloc(uorder * size * sizeof(GLfloat));
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci   if (buffer)
168bf215546Sopenharmony_ci      for (i = 0, p = buffer; i < uorder; i++, points += ustride)
169bf215546Sopenharmony_ci	for (k = 0; k < size; k++)
170bf215546Sopenharmony_ci	  *p++ = points[k];
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci   return buffer;
173bf215546Sopenharmony_ci}
174bf215546Sopenharmony_ci
175bf215546Sopenharmony_ci
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci/*
178bf215546Sopenharmony_ci * Same as above but convert doubles to floats.
179bf215546Sopenharmony_ci */
180bf215546Sopenharmony_ciGLfloat *_mesa_copy_map_points1d( GLenum target, GLint ustride, GLint uorder,
181bf215546Sopenharmony_ci                                  const GLdouble *points )
182bf215546Sopenharmony_ci{
183bf215546Sopenharmony_ci   GLfloat *buffer, *p;
184bf215546Sopenharmony_ci   GLint i, k, size = _mesa_evaluator_components(target);
185bf215546Sopenharmony_ci
186bf215546Sopenharmony_ci   if (!points || !size)
187bf215546Sopenharmony_ci      return NULL;
188bf215546Sopenharmony_ci
189bf215546Sopenharmony_ci   buffer = malloc(uorder * size * sizeof(GLfloat));
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_ci   if (buffer)
192bf215546Sopenharmony_ci      for (i = 0, p = buffer; i < uorder; i++, points += ustride)
193bf215546Sopenharmony_ci	for (k = 0; k < size; k++)
194bf215546Sopenharmony_ci	  *p++ = (GLfloat) points[k];
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci   return buffer;
197bf215546Sopenharmony_ci}
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci
201bf215546Sopenharmony_ci/*
202bf215546Sopenharmony_ci * Copy 2-parametric evaluator control points from user-specified
203bf215546Sopenharmony_ci * memory space to a buffer of contiguous control points.
204bf215546Sopenharmony_ci * Additional memory is allocated to be used by the horner and
205bf215546Sopenharmony_ci * de Casteljau evaluation schemes.
206bf215546Sopenharmony_ci *
207bf215546Sopenharmony_ci * \param see glMap2f for details
208bf215546Sopenharmony_ci * \return pointer to buffer of contiguous control points or NULL if out
209bf215546Sopenharmony_ci *          of memory.
210bf215546Sopenharmony_ci */
211bf215546Sopenharmony_ciGLfloat *_mesa_copy_map_points2f( GLenum target,
212bf215546Sopenharmony_ci                                  GLint ustride, GLint uorder,
213bf215546Sopenharmony_ci                                  GLint vstride, GLint vorder,
214bf215546Sopenharmony_ci                                  const GLfloat *points )
215bf215546Sopenharmony_ci{
216bf215546Sopenharmony_ci   GLfloat *buffer, *p;
217bf215546Sopenharmony_ci   GLint i, j, k, size, dsize, hsize;
218bf215546Sopenharmony_ci   GLint uinc;
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_ci   size = _mesa_evaluator_components(target);
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci   if (!points || size==0) {
223bf215546Sopenharmony_ci      return NULL;
224bf215546Sopenharmony_ci   }
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci   /* max(uorder, vorder) additional points are used in      */
227bf215546Sopenharmony_ci   /* horner evaluation and uorder*vorder additional */
228bf215546Sopenharmony_ci   /* values are needed for de Casteljau                     */
229bf215546Sopenharmony_ci   dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
230bf215546Sopenharmony_ci   hsize = (uorder > vorder ? uorder : vorder)*size;
231bf215546Sopenharmony_ci
232bf215546Sopenharmony_ci   if(hsize>dsize)
233bf215546Sopenharmony_ci     buffer = malloc((uorder*vorder*size+hsize)*sizeof(GLfloat));
234bf215546Sopenharmony_ci   else
235bf215546Sopenharmony_ci     buffer = malloc((uorder*vorder*size+dsize)*sizeof(GLfloat));
236bf215546Sopenharmony_ci
237bf215546Sopenharmony_ci   /* compute the increment value for the u-loop */
238bf215546Sopenharmony_ci   uinc = ustride - vorder*vstride;
239bf215546Sopenharmony_ci
240bf215546Sopenharmony_ci   if (buffer)
241bf215546Sopenharmony_ci      for (i=0, p=buffer; i<uorder; i++, points += uinc)
242bf215546Sopenharmony_ci	 for (j=0; j<vorder; j++, points += vstride)
243bf215546Sopenharmony_ci	    for (k=0; k<size; k++)
244bf215546Sopenharmony_ci	       *p++ = points[k];
245bf215546Sopenharmony_ci
246bf215546Sopenharmony_ci   return buffer;
247bf215546Sopenharmony_ci}
248bf215546Sopenharmony_ci
249bf215546Sopenharmony_ci
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_ci/*
252bf215546Sopenharmony_ci * Same as above but convert doubles to floats.
253bf215546Sopenharmony_ci */
254bf215546Sopenharmony_ciGLfloat *_mesa_copy_map_points2d(GLenum target,
255bf215546Sopenharmony_ci                                 GLint ustride, GLint uorder,
256bf215546Sopenharmony_ci                                 GLint vstride, GLint vorder,
257bf215546Sopenharmony_ci                                 const GLdouble *points )
258bf215546Sopenharmony_ci{
259bf215546Sopenharmony_ci   GLfloat *buffer, *p;
260bf215546Sopenharmony_ci   GLint i, j, k, size, hsize, dsize;
261bf215546Sopenharmony_ci   GLint uinc;
262bf215546Sopenharmony_ci
263bf215546Sopenharmony_ci   size = _mesa_evaluator_components(target);
264bf215546Sopenharmony_ci
265bf215546Sopenharmony_ci   if (!points || size==0) {
266bf215546Sopenharmony_ci      return NULL;
267bf215546Sopenharmony_ci   }
268bf215546Sopenharmony_ci
269bf215546Sopenharmony_ci   /* max(uorder, vorder) additional points are used in      */
270bf215546Sopenharmony_ci   /* horner evaluation and uorder*vorder additional */
271bf215546Sopenharmony_ci   /* values are needed for de Casteljau                     */
272bf215546Sopenharmony_ci   dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder;
273bf215546Sopenharmony_ci   hsize = (uorder > vorder ? uorder : vorder)*size;
274bf215546Sopenharmony_ci
275bf215546Sopenharmony_ci   if(hsize>dsize)
276bf215546Sopenharmony_ci     buffer = malloc((uorder*vorder*size+hsize)*sizeof(GLfloat));
277bf215546Sopenharmony_ci   else
278bf215546Sopenharmony_ci     buffer = malloc((uorder*vorder*size+dsize)*sizeof(GLfloat));
279bf215546Sopenharmony_ci
280bf215546Sopenharmony_ci   /* compute the increment value for the u-loop */
281bf215546Sopenharmony_ci   uinc = ustride - vorder*vstride;
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ci   if (buffer)
284bf215546Sopenharmony_ci      for (i=0, p=buffer; i<uorder; i++, points += uinc)
285bf215546Sopenharmony_ci	 for (j=0; j<vorder; j++, points += vstride)
286bf215546Sopenharmony_ci	    for (k=0; k<size; k++)
287bf215546Sopenharmony_ci	       *p++ = (GLfloat) points[k];
288bf215546Sopenharmony_ci
289bf215546Sopenharmony_ci   return buffer;
290bf215546Sopenharmony_ci}
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci
294bf215546Sopenharmony_ci
295bf215546Sopenharmony_ci/**********************************************************************/
296bf215546Sopenharmony_ci/***                      API entry points                          ***/
297bf215546Sopenharmony_ci/**********************************************************************/
298bf215546Sopenharmony_ci
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ci/*
301bf215546Sopenharmony_ci * This does the work of glMap1[fd].
302bf215546Sopenharmony_ci */
303bf215546Sopenharmony_cistatic void
304bf215546Sopenharmony_cimap1(GLenum target, GLfloat u1, GLfloat u2, GLint ustride,
305bf215546Sopenharmony_ci     GLint uorder, const GLvoid *points, GLenum type )
306bf215546Sopenharmony_ci{
307bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
308bf215546Sopenharmony_ci   GLint k;
309bf215546Sopenharmony_ci   GLfloat *pnts;
310bf215546Sopenharmony_ci   struct gl_1d_map *map = NULL;
311bf215546Sopenharmony_ci
312bf215546Sopenharmony_ci   assert(type == GL_FLOAT || type == GL_DOUBLE);
313bf215546Sopenharmony_ci
314bf215546Sopenharmony_ci   if (u1 == u2) {
315bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(u1,u2)" );
316bf215546Sopenharmony_ci      return;
317bf215546Sopenharmony_ci   }
318bf215546Sopenharmony_ci   if (uorder < 1 || uorder > MAX_EVAL_ORDER) {
319bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(order)" );
320bf215546Sopenharmony_ci      return;
321bf215546Sopenharmony_ci   }
322bf215546Sopenharmony_ci   if (!points) {
323bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(points)" );
324bf215546Sopenharmony_ci      return;
325bf215546Sopenharmony_ci   }
326bf215546Sopenharmony_ci
327bf215546Sopenharmony_ci   k = _mesa_evaluator_components( target );
328bf215546Sopenharmony_ci   if (k == 0) {
329bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
330bf215546Sopenharmony_ci      return;
331bf215546Sopenharmony_ci   }
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_ci   if (ustride < k) {
334bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" );
335bf215546Sopenharmony_ci      return;
336bf215546Sopenharmony_ci   }
337bf215546Sopenharmony_ci
338bf215546Sopenharmony_ci   if (ctx->Texture.CurrentUnit != 0) {
339bf215546Sopenharmony_ci      /* See OpenGL 1.2.1 spec, section F.2.13 */
340bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" );
341bf215546Sopenharmony_ci      return;
342bf215546Sopenharmony_ci   }
343bf215546Sopenharmony_ci
344bf215546Sopenharmony_ci   map = get_1d_map(ctx, target);
345bf215546Sopenharmony_ci   if (!map) {
346bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
347bf215546Sopenharmony_ci      return;
348bf215546Sopenharmony_ci   }
349bf215546Sopenharmony_ci
350bf215546Sopenharmony_ci   /* make copy of the control points */
351bf215546Sopenharmony_ci   if (type == GL_FLOAT)
352bf215546Sopenharmony_ci      pnts = _mesa_copy_map_points1f(target, ustride, uorder, (GLfloat*) points);
353bf215546Sopenharmony_ci   else
354bf215546Sopenharmony_ci      pnts = _mesa_copy_map_points1d(target, ustride, uorder, (GLdouble*) points);
355bf215546Sopenharmony_ci
356bf215546Sopenharmony_ci
357bf215546Sopenharmony_ci   FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT);
358bf215546Sopenharmony_ci   vbo_exec_update_eval_maps(ctx);
359bf215546Sopenharmony_ci   map->Order = uorder;
360bf215546Sopenharmony_ci   map->u1 = u1;
361bf215546Sopenharmony_ci   map->u2 = u2;
362bf215546Sopenharmony_ci   map->du = 1.0F / (u2 - u1);
363bf215546Sopenharmony_ci   free(map->Points);
364bf215546Sopenharmony_ci   map->Points = pnts;
365bf215546Sopenharmony_ci}
366bf215546Sopenharmony_ci
367bf215546Sopenharmony_ci
368bf215546Sopenharmony_ci
369bf215546Sopenharmony_civoid GLAPIENTRY
370bf215546Sopenharmony_ci_mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride,
371bf215546Sopenharmony_ci             GLint order, const GLfloat *points )
372bf215546Sopenharmony_ci{
373bf215546Sopenharmony_ci   map1(target, u1, u2, stride, order, points, GL_FLOAT);
374bf215546Sopenharmony_ci}
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_ci
377bf215546Sopenharmony_civoid GLAPIENTRY
378bf215546Sopenharmony_ci_mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride,
379bf215546Sopenharmony_ci             GLint order, const GLdouble *points )
380bf215546Sopenharmony_ci{
381bf215546Sopenharmony_ci   map1(target, (GLfloat) u1, (GLfloat) u2, stride, order, points, GL_DOUBLE);
382bf215546Sopenharmony_ci}
383bf215546Sopenharmony_ci
384bf215546Sopenharmony_ci
385bf215546Sopenharmony_cistatic void
386bf215546Sopenharmony_cimap2( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
387bf215546Sopenharmony_ci      GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
388bf215546Sopenharmony_ci      const GLvoid *points, GLenum type )
389bf215546Sopenharmony_ci{
390bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
391bf215546Sopenharmony_ci   GLint k;
392bf215546Sopenharmony_ci   GLfloat *pnts;
393bf215546Sopenharmony_ci   struct gl_2d_map *map = NULL;
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_ci   assert(type == GL_FLOAT || type == GL_DOUBLE);
396bf215546Sopenharmony_ci
397bf215546Sopenharmony_ci   if (u1==u2) {
398bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(u1,u2)" );
399bf215546Sopenharmony_ci      return;
400bf215546Sopenharmony_ci   }
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci   if (v1==v2) {
403bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(v1,v2)" );
404bf215546Sopenharmony_ci      return;
405bf215546Sopenharmony_ci   }
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_ci   if (uorder<1 || uorder>MAX_EVAL_ORDER) {
408bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(uorder)" );
409bf215546Sopenharmony_ci      return;
410bf215546Sopenharmony_ci   }
411bf215546Sopenharmony_ci
412bf215546Sopenharmony_ci   if (vorder<1 || vorder>MAX_EVAL_ORDER) {
413bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vorder)" );
414bf215546Sopenharmony_ci      return;
415bf215546Sopenharmony_ci   }
416bf215546Sopenharmony_ci
417bf215546Sopenharmony_ci   k = _mesa_evaluator_components( target );
418bf215546Sopenharmony_ci   if (k==0) {
419bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
420bf215546Sopenharmony_ci      return;
421bf215546Sopenharmony_ci   }
422bf215546Sopenharmony_ci
423bf215546Sopenharmony_ci   if (ustride < k) {
424bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(ustride)" );
425bf215546Sopenharmony_ci      return;
426bf215546Sopenharmony_ci   }
427bf215546Sopenharmony_ci   if (vstride < k) {
428bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vstride)" );
429bf215546Sopenharmony_ci      return;
430bf215546Sopenharmony_ci   }
431bf215546Sopenharmony_ci
432bf215546Sopenharmony_ci   if (ctx->Texture.CurrentUnit != 0) {
433bf215546Sopenharmony_ci      /* See OpenGL 1.2.1 spec, section F.2.13 */
434bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" );
435bf215546Sopenharmony_ci      return;
436bf215546Sopenharmony_ci   }
437bf215546Sopenharmony_ci
438bf215546Sopenharmony_ci   map = get_2d_map(ctx, target);
439bf215546Sopenharmony_ci   if (!map) {
440bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
441bf215546Sopenharmony_ci      return;
442bf215546Sopenharmony_ci   }
443bf215546Sopenharmony_ci
444bf215546Sopenharmony_ci   /* make copy of the control points */
445bf215546Sopenharmony_ci   if (type == GL_FLOAT)
446bf215546Sopenharmony_ci      pnts = _mesa_copy_map_points2f(target, ustride, uorder,
447bf215546Sopenharmony_ci                                  vstride, vorder, (GLfloat*) points);
448bf215546Sopenharmony_ci   else
449bf215546Sopenharmony_ci      pnts = _mesa_copy_map_points2d(target, ustride, uorder,
450bf215546Sopenharmony_ci                                  vstride, vorder, (GLdouble*) points);
451bf215546Sopenharmony_ci
452bf215546Sopenharmony_ci
453bf215546Sopenharmony_ci   FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT);
454bf215546Sopenharmony_ci   vbo_exec_update_eval_maps(ctx);
455bf215546Sopenharmony_ci   map->Uorder = uorder;
456bf215546Sopenharmony_ci   map->u1 = u1;
457bf215546Sopenharmony_ci   map->u2 = u2;
458bf215546Sopenharmony_ci   map->du = 1.0F / (u2 - u1);
459bf215546Sopenharmony_ci   map->Vorder = vorder;
460bf215546Sopenharmony_ci   map->v1 = v1;
461bf215546Sopenharmony_ci   map->v2 = v2;
462bf215546Sopenharmony_ci   map->dv = 1.0F / (v2 - v1);
463bf215546Sopenharmony_ci   free(map->Points);
464bf215546Sopenharmony_ci   map->Points = pnts;
465bf215546Sopenharmony_ci}
466bf215546Sopenharmony_ci
467bf215546Sopenharmony_ci
468bf215546Sopenharmony_civoid GLAPIENTRY
469bf215546Sopenharmony_ci_mesa_Map2f( GLenum target,
470bf215546Sopenharmony_ci             GLfloat u1, GLfloat u2, GLint ustride, GLint uorder,
471bf215546Sopenharmony_ci             GLfloat v1, GLfloat v2, GLint vstride, GLint vorder,
472bf215546Sopenharmony_ci             const GLfloat *points)
473bf215546Sopenharmony_ci{
474bf215546Sopenharmony_ci   map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder,
475bf215546Sopenharmony_ci        points, GL_FLOAT);
476bf215546Sopenharmony_ci}
477bf215546Sopenharmony_ci
478bf215546Sopenharmony_ci
479bf215546Sopenharmony_civoid GLAPIENTRY
480bf215546Sopenharmony_ci_mesa_Map2d( GLenum target,
481bf215546Sopenharmony_ci             GLdouble u1, GLdouble u2, GLint ustride, GLint uorder,
482bf215546Sopenharmony_ci             GLdouble v1, GLdouble v2, GLint vstride, GLint vorder,
483bf215546Sopenharmony_ci             const GLdouble *points )
484bf215546Sopenharmony_ci{
485bf215546Sopenharmony_ci   map2(target, (GLfloat) u1, (GLfloat) u2, ustride, uorder,
486bf215546Sopenharmony_ci	(GLfloat) v1, (GLfloat) v2, vstride, vorder, points, GL_DOUBLE);
487bf215546Sopenharmony_ci}
488bf215546Sopenharmony_ci
489bf215546Sopenharmony_ci
490bf215546Sopenharmony_ci
491bf215546Sopenharmony_civoid GLAPIENTRY
492bf215546Sopenharmony_ci_mesa_GetnMapdvARB( GLenum target, GLenum query, GLsizei bufSize, GLdouble *v )
493bf215546Sopenharmony_ci{
494bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
495bf215546Sopenharmony_ci   struct gl_1d_map *map1d;
496bf215546Sopenharmony_ci   struct gl_2d_map *map2d;
497bf215546Sopenharmony_ci   GLint i, n;
498bf215546Sopenharmony_ci   GLfloat *data;
499bf215546Sopenharmony_ci   GLuint comps;
500bf215546Sopenharmony_ci   GLsizei numBytes;
501bf215546Sopenharmony_ci
502bf215546Sopenharmony_ci   comps = _mesa_evaluator_components(target);
503bf215546Sopenharmony_ci   if (!comps) {
504bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
505bf215546Sopenharmony_ci      return;
506bf215546Sopenharmony_ci   }
507bf215546Sopenharmony_ci
508bf215546Sopenharmony_ci   map1d = get_1d_map(ctx, target);
509bf215546Sopenharmony_ci   map2d = get_2d_map(ctx, target);
510bf215546Sopenharmony_ci   assert(map1d || map2d);
511bf215546Sopenharmony_ci
512bf215546Sopenharmony_ci   switch (query) {
513bf215546Sopenharmony_ci      case GL_COEFF:
514bf215546Sopenharmony_ci         if (map1d) {
515bf215546Sopenharmony_ci            data = map1d->Points;
516bf215546Sopenharmony_ci            n = map1d->Order * comps;
517bf215546Sopenharmony_ci         }
518bf215546Sopenharmony_ci         else {
519bf215546Sopenharmony_ci            data = map2d->Points;
520bf215546Sopenharmony_ci            n = map2d->Uorder * map2d->Vorder * comps;
521bf215546Sopenharmony_ci         }
522bf215546Sopenharmony_ci	 if (data) {
523bf215546Sopenharmony_ci            numBytes = n * sizeof *v;
524bf215546Sopenharmony_ci            if (bufSize < numBytes)
525bf215546Sopenharmony_ci               goto overflow;
526bf215546Sopenharmony_ci	    for (i=0;i<n;i++) {
527bf215546Sopenharmony_ci	       v[i] = data[i];
528bf215546Sopenharmony_ci	    }
529bf215546Sopenharmony_ci	 }
530bf215546Sopenharmony_ci         break;
531bf215546Sopenharmony_ci      case GL_ORDER:
532bf215546Sopenharmony_ci         if (map1d) {
533bf215546Sopenharmony_ci            numBytes = 1 * sizeof *v;
534bf215546Sopenharmony_ci            if (bufSize < numBytes)
535bf215546Sopenharmony_ci               goto overflow;
536bf215546Sopenharmony_ci            v[0] = (GLdouble) map1d->Order;
537bf215546Sopenharmony_ci         }
538bf215546Sopenharmony_ci         else {
539bf215546Sopenharmony_ci            numBytes = 2 * sizeof *v;
540bf215546Sopenharmony_ci            if (bufSize < numBytes)
541bf215546Sopenharmony_ci               goto overflow;
542bf215546Sopenharmony_ci            v[0] = (GLdouble) map2d->Uorder;
543bf215546Sopenharmony_ci            v[1] = (GLdouble) map2d->Vorder;
544bf215546Sopenharmony_ci         }
545bf215546Sopenharmony_ci         break;
546bf215546Sopenharmony_ci      case GL_DOMAIN:
547bf215546Sopenharmony_ci         if (map1d) {
548bf215546Sopenharmony_ci            numBytes = 2 * sizeof *v;
549bf215546Sopenharmony_ci            if (bufSize < numBytes)
550bf215546Sopenharmony_ci              goto overflow;
551bf215546Sopenharmony_ci            v[0] = (GLdouble) map1d->u1;
552bf215546Sopenharmony_ci            v[1] = (GLdouble) map1d->u2;
553bf215546Sopenharmony_ci         }
554bf215546Sopenharmony_ci         else {
555bf215546Sopenharmony_ci            numBytes = 4 * sizeof *v;
556bf215546Sopenharmony_ci            if (bufSize < numBytes)
557bf215546Sopenharmony_ci               goto overflow;
558bf215546Sopenharmony_ci            v[0] = (GLdouble) map2d->u1;
559bf215546Sopenharmony_ci            v[1] = (GLdouble) map2d->u2;
560bf215546Sopenharmony_ci            v[2] = (GLdouble) map2d->v1;
561bf215546Sopenharmony_ci            v[3] = (GLdouble) map2d->v2;
562bf215546Sopenharmony_ci         }
563bf215546Sopenharmony_ci         break;
564bf215546Sopenharmony_ci      default:
565bf215546Sopenharmony_ci         _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" );
566bf215546Sopenharmony_ci   }
567bf215546Sopenharmony_ci   return;
568bf215546Sopenharmony_ci
569bf215546Sopenharmony_cioverflow:
570bf215546Sopenharmony_ci   _mesa_error( ctx, GL_INVALID_OPERATION,
571bf215546Sopenharmony_ci               "glGetnMapdvARB(out of bounds: bufSize is %d,"
572bf215546Sopenharmony_ci               " but %d bytes are required)", bufSize, numBytes );
573bf215546Sopenharmony_ci}
574bf215546Sopenharmony_ci
575bf215546Sopenharmony_civoid GLAPIENTRY
576bf215546Sopenharmony_ci_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
577bf215546Sopenharmony_ci{
578bf215546Sopenharmony_ci   _mesa_GetnMapdvARB(target, query, INT_MAX, v);
579bf215546Sopenharmony_ci}
580bf215546Sopenharmony_ci
581bf215546Sopenharmony_civoid GLAPIENTRY
582bf215546Sopenharmony_ci_mesa_GetnMapfvARB( GLenum target, GLenum query, GLsizei bufSize, GLfloat *v )
583bf215546Sopenharmony_ci{
584bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
585bf215546Sopenharmony_ci   struct gl_1d_map *map1d;
586bf215546Sopenharmony_ci   struct gl_2d_map *map2d;
587bf215546Sopenharmony_ci   GLint i, n;
588bf215546Sopenharmony_ci   GLfloat *data;
589bf215546Sopenharmony_ci   GLuint comps;
590bf215546Sopenharmony_ci   GLsizei numBytes;
591bf215546Sopenharmony_ci
592bf215546Sopenharmony_ci   comps = _mesa_evaluator_components(target);
593bf215546Sopenharmony_ci   if (!comps) {
594bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
595bf215546Sopenharmony_ci      return;
596bf215546Sopenharmony_ci   }
597bf215546Sopenharmony_ci
598bf215546Sopenharmony_ci   map1d = get_1d_map(ctx, target);
599bf215546Sopenharmony_ci   map2d = get_2d_map(ctx, target);
600bf215546Sopenharmony_ci   assert(map1d || map2d);
601bf215546Sopenharmony_ci
602bf215546Sopenharmony_ci   switch (query) {
603bf215546Sopenharmony_ci      case GL_COEFF:
604bf215546Sopenharmony_ci         if (map1d) {
605bf215546Sopenharmony_ci            data = map1d->Points;
606bf215546Sopenharmony_ci            n = map1d->Order * comps;
607bf215546Sopenharmony_ci         }
608bf215546Sopenharmony_ci         else {
609bf215546Sopenharmony_ci            data = map2d->Points;
610bf215546Sopenharmony_ci            n = map2d->Uorder * map2d->Vorder * comps;
611bf215546Sopenharmony_ci         }
612bf215546Sopenharmony_ci	 if (data) {
613bf215546Sopenharmony_ci            numBytes = n * sizeof *v;
614bf215546Sopenharmony_ci            if (bufSize < numBytes)
615bf215546Sopenharmony_ci               goto overflow;
616bf215546Sopenharmony_ci	    for (i=0;i<n;i++) {
617bf215546Sopenharmony_ci	       v[i] = data[i];
618bf215546Sopenharmony_ci	    }
619bf215546Sopenharmony_ci	 }
620bf215546Sopenharmony_ci         break;
621bf215546Sopenharmony_ci      case GL_ORDER:
622bf215546Sopenharmony_ci         if (map1d) {
623bf215546Sopenharmony_ci            numBytes = 1 * sizeof *v;
624bf215546Sopenharmony_ci            if (bufSize < numBytes)
625bf215546Sopenharmony_ci               goto overflow;
626bf215546Sopenharmony_ci            v[0] = (GLfloat) map1d->Order;
627bf215546Sopenharmony_ci         }
628bf215546Sopenharmony_ci         else {
629bf215546Sopenharmony_ci            numBytes = 2 * sizeof *v;
630bf215546Sopenharmony_ci            if (bufSize < numBytes)
631bf215546Sopenharmony_ci               goto overflow;
632bf215546Sopenharmony_ci            v[0] = (GLfloat) map2d->Uorder;
633bf215546Sopenharmony_ci            v[1] = (GLfloat) map2d->Vorder;
634bf215546Sopenharmony_ci         }
635bf215546Sopenharmony_ci         break;
636bf215546Sopenharmony_ci      case GL_DOMAIN:
637bf215546Sopenharmony_ci         if (map1d) {
638bf215546Sopenharmony_ci            numBytes = 2 * sizeof *v;
639bf215546Sopenharmony_ci            if (bufSize < numBytes)
640bf215546Sopenharmony_ci               goto overflow;
641bf215546Sopenharmony_ci            v[0] = map1d->u1;
642bf215546Sopenharmony_ci            v[1] = map1d->u2;
643bf215546Sopenharmony_ci         }
644bf215546Sopenharmony_ci         else {
645bf215546Sopenharmony_ci            numBytes = 4 * sizeof *v;
646bf215546Sopenharmony_ci            if (bufSize < numBytes)
647bf215546Sopenharmony_ci               goto overflow;
648bf215546Sopenharmony_ci            v[0] = map2d->u1;
649bf215546Sopenharmony_ci            v[1] = map2d->u2;
650bf215546Sopenharmony_ci            v[2] = map2d->v1;
651bf215546Sopenharmony_ci            v[3] = map2d->v2;
652bf215546Sopenharmony_ci         }
653bf215546Sopenharmony_ci         break;
654bf215546Sopenharmony_ci      default:
655bf215546Sopenharmony_ci         _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" );
656bf215546Sopenharmony_ci   }
657bf215546Sopenharmony_ci   return;
658bf215546Sopenharmony_ci
659bf215546Sopenharmony_cioverflow:
660bf215546Sopenharmony_ci   _mesa_error( ctx, GL_INVALID_OPERATION,
661bf215546Sopenharmony_ci               "glGetnMapfvARB(out of bounds: bufSize is %d,"
662bf215546Sopenharmony_ci               " but %d bytes are required)", bufSize, numBytes );
663bf215546Sopenharmony_ci}
664bf215546Sopenharmony_ci
665bf215546Sopenharmony_ci
666bf215546Sopenharmony_civoid GLAPIENTRY
667bf215546Sopenharmony_ci_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
668bf215546Sopenharmony_ci{
669bf215546Sopenharmony_ci   _mesa_GetnMapfvARB(target, query, INT_MAX, v);
670bf215546Sopenharmony_ci}
671bf215546Sopenharmony_ci
672bf215546Sopenharmony_ci
673bf215546Sopenharmony_civoid GLAPIENTRY
674bf215546Sopenharmony_ci_mesa_GetnMapivARB( GLenum target, GLenum query, GLsizei bufSize, GLint *v )
675bf215546Sopenharmony_ci{
676bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
677bf215546Sopenharmony_ci   struct gl_1d_map *map1d;
678bf215546Sopenharmony_ci   struct gl_2d_map *map2d;
679bf215546Sopenharmony_ci   GLuint i, n;
680bf215546Sopenharmony_ci   GLfloat *data;
681bf215546Sopenharmony_ci   GLuint comps;
682bf215546Sopenharmony_ci   GLsizei numBytes;
683bf215546Sopenharmony_ci
684bf215546Sopenharmony_ci   comps = _mesa_evaluator_components(target);
685bf215546Sopenharmony_ci   if (!comps) {
686bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
687bf215546Sopenharmony_ci      return;
688bf215546Sopenharmony_ci   }
689bf215546Sopenharmony_ci
690bf215546Sopenharmony_ci   map1d = get_1d_map(ctx, target);
691bf215546Sopenharmony_ci   map2d = get_2d_map(ctx, target);
692bf215546Sopenharmony_ci   assert(map1d || map2d);
693bf215546Sopenharmony_ci
694bf215546Sopenharmony_ci   switch (query) {
695bf215546Sopenharmony_ci      case GL_COEFF:
696bf215546Sopenharmony_ci         if (map1d) {
697bf215546Sopenharmony_ci            data = map1d->Points;
698bf215546Sopenharmony_ci            n = map1d->Order * comps;
699bf215546Sopenharmony_ci         }
700bf215546Sopenharmony_ci         else {
701bf215546Sopenharmony_ci            data = map2d->Points;
702bf215546Sopenharmony_ci            n = map2d->Uorder * map2d->Vorder * comps;
703bf215546Sopenharmony_ci         }
704bf215546Sopenharmony_ci	 if (data) {
705bf215546Sopenharmony_ci            numBytes = n * sizeof *v;
706bf215546Sopenharmony_ci            if (bufSize < numBytes)
707bf215546Sopenharmony_ci               goto overflow;
708bf215546Sopenharmony_ci	    for (i=0;i<n;i++) {
709bf215546Sopenharmony_ci	       v[i] = lroundf(data[i]);
710bf215546Sopenharmony_ci	    }
711bf215546Sopenharmony_ci	 }
712bf215546Sopenharmony_ci         break;
713bf215546Sopenharmony_ci      case GL_ORDER:
714bf215546Sopenharmony_ci         if (map1d) {
715bf215546Sopenharmony_ci            numBytes = 1 * sizeof *v;
716bf215546Sopenharmony_ci            if (bufSize < numBytes)
717bf215546Sopenharmony_ci               goto overflow;
718bf215546Sopenharmony_ci            v[0] = map1d->Order;
719bf215546Sopenharmony_ci         }
720bf215546Sopenharmony_ci         else {
721bf215546Sopenharmony_ci            numBytes = 2 * sizeof *v;
722bf215546Sopenharmony_ci            if (bufSize < numBytes)
723bf215546Sopenharmony_ci               goto overflow;
724bf215546Sopenharmony_ci            v[0] = map2d->Uorder;
725bf215546Sopenharmony_ci            v[1] = map2d->Vorder;
726bf215546Sopenharmony_ci         }
727bf215546Sopenharmony_ci         break;
728bf215546Sopenharmony_ci      case GL_DOMAIN:
729bf215546Sopenharmony_ci         if (map1d) {
730bf215546Sopenharmony_ci            numBytes = 2 * sizeof *v;
731bf215546Sopenharmony_ci            if (bufSize < numBytes)
732bf215546Sopenharmony_ci               goto overflow;
733bf215546Sopenharmony_ci            v[0] = lroundf(map1d->u1);
734bf215546Sopenharmony_ci            v[1] = lroundf(map1d->u2);
735bf215546Sopenharmony_ci         }
736bf215546Sopenharmony_ci         else {
737bf215546Sopenharmony_ci            numBytes = 4 * sizeof *v;
738bf215546Sopenharmony_ci            if (bufSize < numBytes)
739bf215546Sopenharmony_ci               goto overflow;
740bf215546Sopenharmony_ci            v[0] = lroundf(map2d->u1);
741bf215546Sopenharmony_ci            v[1] = lroundf(map2d->u2);
742bf215546Sopenharmony_ci            v[2] = lroundf(map2d->v1);
743bf215546Sopenharmony_ci            v[3] = lroundf(map2d->v2);
744bf215546Sopenharmony_ci         }
745bf215546Sopenharmony_ci         break;
746bf215546Sopenharmony_ci      default:
747bf215546Sopenharmony_ci         _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" );
748bf215546Sopenharmony_ci   }
749bf215546Sopenharmony_ci   return;
750bf215546Sopenharmony_ci
751bf215546Sopenharmony_cioverflow:
752bf215546Sopenharmony_ci   _mesa_error( ctx, GL_INVALID_OPERATION,
753bf215546Sopenharmony_ci               "glGetnMapivARB(out of bounds: bufSize is %d,"
754bf215546Sopenharmony_ci               " but %d bytes are required)", bufSize, numBytes );
755bf215546Sopenharmony_ci}
756bf215546Sopenharmony_ci
757bf215546Sopenharmony_ci
758bf215546Sopenharmony_civoid GLAPIENTRY
759bf215546Sopenharmony_ci_mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
760bf215546Sopenharmony_ci{
761bf215546Sopenharmony_ci   _mesa_GetnMapivARB(target, query, INT_MAX, v);
762bf215546Sopenharmony_ci}
763bf215546Sopenharmony_ci
764bf215546Sopenharmony_ci
765bf215546Sopenharmony_civoid GLAPIENTRY
766bf215546Sopenharmony_ci_mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 )
767bf215546Sopenharmony_ci{
768bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
769bf215546Sopenharmony_ci
770bf215546Sopenharmony_ci   if (un<1) {
771bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid1f" );
772bf215546Sopenharmony_ci      return;
773bf215546Sopenharmony_ci   }
774bf215546Sopenharmony_ci   FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT);
775bf215546Sopenharmony_ci   vbo_exec_update_eval_maps(ctx);
776bf215546Sopenharmony_ci   ctx->Eval.MapGrid1un = un;
777bf215546Sopenharmony_ci   ctx->Eval.MapGrid1u1 = u1;
778bf215546Sopenharmony_ci   ctx->Eval.MapGrid1u2 = u2;
779bf215546Sopenharmony_ci   ctx->Eval.MapGrid1du = (u2 - u1) / (GLfloat) un;
780bf215546Sopenharmony_ci}
781bf215546Sopenharmony_ci
782bf215546Sopenharmony_ci
783bf215546Sopenharmony_civoid GLAPIENTRY
784bf215546Sopenharmony_ci_mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 )
785bf215546Sopenharmony_ci{
786bf215546Sopenharmony_ci   _mesa_MapGrid1f( un, (GLfloat) u1, (GLfloat) u2 );
787bf215546Sopenharmony_ci}
788bf215546Sopenharmony_ci
789bf215546Sopenharmony_ci
790bf215546Sopenharmony_civoid GLAPIENTRY
791bf215546Sopenharmony_ci_mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2,
792bf215546Sopenharmony_ci                 GLint vn, GLfloat v1, GLfloat v2 )
793bf215546Sopenharmony_ci{
794bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
795bf215546Sopenharmony_ci
796bf215546Sopenharmony_ci   if (un<1) {
797bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" );
798bf215546Sopenharmony_ci      return;
799bf215546Sopenharmony_ci   }
800bf215546Sopenharmony_ci   if (vn<1) {
801bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(vn)" );
802bf215546Sopenharmony_ci      return;
803bf215546Sopenharmony_ci   }
804bf215546Sopenharmony_ci
805bf215546Sopenharmony_ci   FLUSH_VERTICES(ctx, 0, GL_EVAL_BIT);
806bf215546Sopenharmony_ci   vbo_exec_update_eval_maps(ctx);
807bf215546Sopenharmony_ci   ctx->Eval.MapGrid2un = un;
808bf215546Sopenharmony_ci   ctx->Eval.MapGrid2u1 = u1;
809bf215546Sopenharmony_ci   ctx->Eval.MapGrid2u2 = u2;
810bf215546Sopenharmony_ci   ctx->Eval.MapGrid2du = (u2 - u1) / (GLfloat) un;
811bf215546Sopenharmony_ci   ctx->Eval.MapGrid2vn = vn;
812bf215546Sopenharmony_ci   ctx->Eval.MapGrid2v1 = v1;
813bf215546Sopenharmony_ci   ctx->Eval.MapGrid2v2 = v2;
814bf215546Sopenharmony_ci   ctx->Eval.MapGrid2dv = (v2 - v1) / (GLfloat) vn;
815bf215546Sopenharmony_ci}
816bf215546Sopenharmony_ci
817bf215546Sopenharmony_ci
818bf215546Sopenharmony_civoid GLAPIENTRY
819bf215546Sopenharmony_ci_mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2,
820bf215546Sopenharmony_ci                 GLint vn, GLdouble v1, GLdouble v2 )
821bf215546Sopenharmony_ci{
822bf215546Sopenharmony_ci   _mesa_MapGrid2f( un, (GLfloat) u1, (GLfloat) u2,
823bf215546Sopenharmony_ci		    vn, (GLfloat) v1, (GLfloat) v2 );
824bf215546Sopenharmony_ci}
825bf215546Sopenharmony_ci
826bf215546Sopenharmony_ci
827bf215546Sopenharmony_ci/**********************************************************************/
828bf215546Sopenharmony_ci/*****                      Initialization                        *****/
829bf215546Sopenharmony_ci/**********************************************************************/
830bf215546Sopenharmony_ci
831bf215546Sopenharmony_ci/**
832bf215546Sopenharmony_ci * Initialize a 1-D evaluator map.
833bf215546Sopenharmony_ci */
834bf215546Sopenharmony_cistatic void
835bf215546Sopenharmony_ciinit_1d_map( struct gl_1d_map *map, int n, const float *initial )
836bf215546Sopenharmony_ci{
837bf215546Sopenharmony_ci   map->Order = 1;
838bf215546Sopenharmony_ci   map->u1 = 0.0;
839bf215546Sopenharmony_ci   map->u2 = 1.0;
840bf215546Sopenharmony_ci   map->Points = malloc(n * sizeof(GLfloat));
841bf215546Sopenharmony_ci   if (map->Points) {
842bf215546Sopenharmony_ci      GLint i;
843bf215546Sopenharmony_ci      for (i=0;i<n;i++)
844bf215546Sopenharmony_ci         map->Points[i] = initial[i];
845bf215546Sopenharmony_ci   }
846bf215546Sopenharmony_ci}
847bf215546Sopenharmony_ci
848bf215546Sopenharmony_ci
849bf215546Sopenharmony_ci/**
850bf215546Sopenharmony_ci * Initialize a 2-D evaluator map
851bf215546Sopenharmony_ci */
852bf215546Sopenharmony_cistatic void
853bf215546Sopenharmony_ciinit_2d_map( struct gl_2d_map *map, int n, const float *initial )
854bf215546Sopenharmony_ci{
855bf215546Sopenharmony_ci   map->Uorder = 1;
856bf215546Sopenharmony_ci   map->Vorder = 1;
857bf215546Sopenharmony_ci   map->u1 = 0.0;
858bf215546Sopenharmony_ci   map->u2 = 1.0;
859bf215546Sopenharmony_ci   map->v1 = 0.0;
860bf215546Sopenharmony_ci   map->v2 = 1.0;
861bf215546Sopenharmony_ci   map->Points = malloc(n * sizeof(GLfloat));
862bf215546Sopenharmony_ci   if (map->Points) {
863bf215546Sopenharmony_ci      GLint i;
864bf215546Sopenharmony_ci      for (i=0;i<n;i++)
865bf215546Sopenharmony_ci         map->Points[i] = initial[i];
866bf215546Sopenharmony_ci   }
867bf215546Sopenharmony_ci}
868bf215546Sopenharmony_ci
869bf215546Sopenharmony_ci
870bf215546Sopenharmony_civoid _mesa_init_eval( struct gl_context *ctx )
871bf215546Sopenharmony_ci{
872bf215546Sopenharmony_ci   /* Evaluators group */
873bf215546Sopenharmony_ci   ctx->Eval.Map1Color4 = GL_FALSE;
874bf215546Sopenharmony_ci   ctx->Eval.Map1Index = GL_FALSE;
875bf215546Sopenharmony_ci   ctx->Eval.Map1Normal = GL_FALSE;
876bf215546Sopenharmony_ci   ctx->Eval.Map1TextureCoord1 = GL_FALSE;
877bf215546Sopenharmony_ci   ctx->Eval.Map1TextureCoord2 = GL_FALSE;
878bf215546Sopenharmony_ci   ctx->Eval.Map1TextureCoord3 = GL_FALSE;
879bf215546Sopenharmony_ci   ctx->Eval.Map1TextureCoord4 = GL_FALSE;
880bf215546Sopenharmony_ci   ctx->Eval.Map1Vertex3 = GL_FALSE;
881bf215546Sopenharmony_ci   ctx->Eval.Map1Vertex4 = GL_FALSE;
882bf215546Sopenharmony_ci   ctx->Eval.Map2Color4 = GL_FALSE;
883bf215546Sopenharmony_ci   ctx->Eval.Map2Index = GL_FALSE;
884bf215546Sopenharmony_ci   ctx->Eval.Map2Normal = GL_FALSE;
885bf215546Sopenharmony_ci   ctx->Eval.Map2TextureCoord1 = GL_FALSE;
886bf215546Sopenharmony_ci   ctx->Eval.Map2TextureCoord2 = GL_FALSE;
887bf215546Sopenharmony_ci   ctx->Eval.Map2TextureCoord3 = GL_FALSE;
888bf215546Sopenharmony_ci   ctx->Eval.Map2TextureCoord4 = GL_FALSE;
889bf215546Sopenharmony_ci   ctx->Eval.Map2Vertex3 = GL_FALSE;
890bf215546Sopenharmony_ci   ctx->Eval.Map2Vertex4 = GL_FALSE;
891bf215546Sopenharmony_ci   ctx->Eval.AutoNormal = GL_FALSE;
892bf215546Sopenharmony_ci   ctx->Eval.MapGrid1un = 1;
893bf215546Sopenharmony_ci   ctx->Eval.MapGrid1u1 = 0.0;
894bf215546Sopenharmony_ci   ctx->Eval.MapGrid1u2 = 1.0;
895bf215546Sopenharmony_ci   ctx->Eval.MapGrid2un = 1;
896bf215546Sopenharmony_ci   ctx->Eval.MapGrid2vn = 1;
897bf215546Sopenharmony_ci   ctx->Eval.MapGrid2u1 = 0.0;
898bf215546Sopenharmony_ci   ctx->Eval.MapGrid2u2 = 1.0;
899bf215546Sopenharmony_ci   ctx->Eval.MapGrid2v1 = 0.0;
900bf215546Sopenharmony_ci   ctx->Eval.MapGrid2v2 = 1.0;
901bf215546Sopenharmony_ci
902bf215546Sopenharmony_ci   /* Evaluator data */
903bf215546Sopenharmony_ci   {
904bf215546Sopenharmony_ci      static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 };
905bf215546Sopenharmony_ci      static GLfloat normal[3] = { 0.0, 0.0, 1.0 };
906bf215546Sopenharmony_ci      static GLfloat index[1] = { 1.0 };
907bf215546Sopenharmony_ci      static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 };
908bf215546Sopenharmony_ci      static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 };
909bf215546Sopenharmony_ci
910bf215546Sopenharmony_ci      init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex );
911bf215546Sopenharmony_ci      init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex );
912bf215546Sopenharmony_ci      init_1d_map( &ctx->EvalMap.Map1Index, 1, index );
913bf215546Sopenharmony_ci      init_1d_map( &ctx->EvalMap.Map1Color4, 4, color );
914bf215546Sopenharmony_ci      init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal );
915bf215546Sopenharmony_ci      init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord );
916bf215546Sopenharmony_ci      init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord );
917bf215546Sopenharmony_ci      init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord );
918bf215546Sopenharmony_ci      init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord );
919bf215546Sopenharmony_ci
920bf215546Sopenharmony_ci      init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex );
921bf215546Sopenharmony_ci      init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex );
922bf215546Sopenharmony_ci      init_2d_map( &ctx->EvalMap.Map2Index, 1, index );
923bf215546Sopenharmony_ci      init_2d_map( &ctx->EvalMap.Map2Color4, 4, color );
924bf215546Sopenharmony_ci      init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal );
925bf215546Sopenharmony_ci      init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord );
926bf215546Sopenharmony_ci      init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord );
927bf215546Sopenharmony_ci      init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord );
928bf215546Sopenharmony_ci      init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord );
929bf215546Sopenharmony_ci   }
930bf215546Sopenharmony_ci}
931bf215546Sopenharmony_ci
932bf215546Sopenharmony_ci
933bf215546Sopenharmony_civoid _mesa_free_eval_data( struct gl_context *ctx )
934bf215546Sopenharmony_ci{
935bf215546Sopenharmony_ci   /* Free evaluator data */
936bf215546Sopenharmony_ci   free(ctx->EvalMap.Map1Vertex3.Points);
937bf215546Sopenharmony_ci   free(ctx->EvalMap.Map1Vertex4.Points);
938bf215546Sopenharmony_ci   free(ctx->EvalMap.Map1Index.Points);
939bf215546Sopenharmony_ci   free(ctx->EvalMap.Map1Color4.Points);
940bf215546Sopenharmony_ci   free(ctx->EvalMap.Map1Normal.Points);
941bf215546Sopenharmony_ci   free(ctx->EvalMap.Map1Texture1.Points);
942bf215546Sopenharmony_ci   free(ctx->EvalMap.Map1Texture2.Points);
943bf215546Sopenharmony_ci   free(ctx->EvalMap.Map1Texture3.Points);
944bf215546Sopenharmony_ci   free(ctx->EvalMap.Map1Texture4.Points);
945bf215546Sopenharmony_ci
946bf215546Sopenharmony_ci   free(ctx->EvalMap.Map2Vertex3.Points);
947bf215546Sopenharmony_ci   free(ctx->EvalMap.Map2Vertex4.Points);
948bf215546Sopenharmony_ci   free(ctx->EvalMap.Map2Index.Points);
949bf215546Sopenharmony_ci   free(ctx->EvalMap.Map2Color4.Points);
950bf215546Sopenharmony_ci   free(ctx->EvalMap.Map2Normal.Points);
951bf215546Sopenharmony_ci   free(ctx->EvalMap.Map2Texture1.Points);
952bf215546Sopenharmony_ci   free(ctx->EvalMap.Map2Texture2.Points);
953bf215546Sopenharmony_ci   free(ctx->EvalMap.Map2Texture3.Points);
954bf215546Sopenharmony_ci   free(ctx->EvalMap.Map2Texture4.Points);
955bf215546Sopenharmony_ci}
956