home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / MesaDLL / eval.cpp < prev    next >
C/C++ Source or Header  |  2002-10-24  |  22KB  |  800 lines

  1. /* $Id: eval.c,v 1.24 2002/10/24 23:57:20 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28. /*
  29.  * eval.c was written by
  30.  * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and
  31.  * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de).
  32.  *
  33.  * My original implementation of evaluators was simplistic and didn't
  34.  * compute surface normal vectors properly.  Bernd and Volker applied
  35.  * used more sophisticated methods to get better results.
  36.  *
  37.  * Thanks guys!
  38.  */
  39.  
  40.  
  41. #include "glheader.h"
  42. #include "imports.h"
  43. #include "colormac.h"
  44. #include "context.h"
  45. #include "eval.h"
  46. #include "macros.h"
  47. #include "mmath.h"
  48. #include "mtypes.h"
  49.  
  50.  
  51. /*
  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.
  55.  */
  56. GLuint _mesa_evaluator_components( GLenum target )
  57. {
  58.    switch (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;
  77.       default:                break;
  78.    }
  79.  
  80.    /* XXX need to check for the vertex program extension
  81.    if (!ctx->Extensions.NV_vertex_program)
  82.       return 0;
  83.    */
  84.  
  85.    if (target >= GL_MAP1_VERTEX_ATTRIB0_4_NV &&
  86.        target <= GL_MAP1_VERTEX_ATTRIB15_4_NV)
  87.       return 4;
  88.  
  89.    if (target >= GL_MAP2_VERTEX_ATTRIB0_4_NV &&
  90.        target <= GL_MAP2_VERTEX_ATTRIB15_4_NV)
  91.       return 4;
  92.  
  93.    return 0;
  94. }
  95.  
  96.  
  97. /*
  98.  * Return pointer to the gl_1d_map struct for the named target.
  99.  */
  100. static struct gl_1d_map *
  101. get_1d_map( GLcontext *ctx, GLenum target )
  102. {
  103.    switch (target) {
  104.       case GL_MAP1_VERTEX_3:
  105.          return &ctx->EvalMap.Map1Vertex3;
  106.       case GL_MAP1_VERTEX_4:
  107.          return &ctx->EvalMap.Map1Vertex4;
  108.       case GL_MAP1_INDEX:
  109.          return &ctx->EvalMap.Map1Index;
  110.       case GL_MAP1_COLOR_4:
  111.          return &ctx->EvalMap.Map1Color4;
  112.       case GL_MAP1_NORMAL:
  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)
  139.             return NULL;
  140.          return &ctx->EvalMap.Map1Attrib[target - GL_MAP1_VERTEX_ATTRIB0_4_NV];
  141.       default:
  142.          return NULL;
  143.    }
  144. }
  145.  
  146.  
  147. /*
  148.  * Return pointer to the gl_2d_map struct for the named target.
  149.  */
  150. static struct gl_2d_map *
  151. get_2d_map( GLcontext *ctx, GLenum target )
  152. {
  153.    switch (target) {
  154.       case GL_MAP2_VERTEX_3:
  155.          return &ctx->EvalMap.Map2Vertex3;
  156.       case GL_MAP2_VERTEX_4:
  157.          return &ctx->EvalMap.Map2Vertex4;
  158.       case GL_MAP2_INDEX:
  159.          return &ctx->EvalMap.Map2Index;
  160.       case GL_MAP2_COLOR_4:
  161.          return &ctx->EvalMap.Map2Color4;
  162.       case GL_MAP2_NORMAL:
  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)
  189.             return NULL;
  190.          return &ctx->EvalMap.Map2Attrib[target - GL_MAP2_VERTEX_ATTRIB0_4_NV];
  191.       default:
  192.          return NULL;
  193.    }
  194. }
  195.  
  196.  
  197. /**********************************************************************/
  198. /***            Copy and deallocate control points                  ***/
  199. /**********************************************************************/
  200.  
  201.  
  202. /*
  203.  * Copy 1-parametric evaluator control points from user-specified
  204.  * memory space to a buffer of contiguous control points.
  205.  * Input:  see glMap1f for details
  206.  * Return:  pointer to buffer of contiguous control points or NULL if out
  207.  *          of memory.
  208.  */
  209. GLfloat *_mesa_copy_map_points1f( GLenum target, GLint ustride, GLint uorder,
  210.                                   const GLfloat *points )
  211. {
  212.    GLfloat *buffer, *p;
  213.    GLint i, k, size = _mesa_evaluator_components(target);
  214.  
  215.    if (!points || !size)
  216.       return NULL;
  217.  
  218.    buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat));
  219.  
  220.    if (buffer)
  221.       for (i = 0, p = buffer; i < uorder; i++, points += ustride)
  222.     for (k = 0; k < size; k++)
  223.       *p++ = points[k];
  224.  
  225.    return buffer;
  226. }
  227.  
  228.  
  229.  
  230. /*
  231.  * Same as above but convert doubles to floats.
  232.  */
  233. GLfloat *_mesa_copy_map_points1d( GLenum target, GLint ustride, GLint uorder,
  234.                                   const GLdouble *points )
  235. {
  236.    GLfloat *buffer, *p;
  237.    GLint i, k, size = _mesa_evaluator_components(target);
  238.  
  239.    if (!points || !size)
  240.       return NULL;
  241.  
  242.    buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat));
  243.  
  244.    if (buffer)
  245.       for (i = 0, p = buffer; i < uorder; i++, points += ustride)
  246.     for (k = 0; k < size; k++)
  247.       *p++ = (GLfloat) points[k];
  248.  
  249.    return buffer;
  250. }
  251.  
  252.  
  253.  
  254. /*
  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.
  259.  *
  260.  * Input:  see glMap2f for details
  261.  * Return:  pointer to buffer of contiguous control points or NULL if out
  262.  *          of memory.
  263.  */
  264. GLfloat *_mesa_copy_map_points2f( GLenum target,
  265.                                   GLint ustride, GLint uorder,
  266.                                   GLint vstride, GLint vorder,
  267.                                   const GLfloat *points )
  268. {
  269.    GLfloat *buffer, *p;
  270.    GLint i, j, k, size, dsize, hsize;
  271.    GLint uinc;
  272.  
  273.    size = _mesa_evaluator_components(target);
  274.  
  275.    if (!points || size==0) {
  276.       return NULL;
  277.    }
  278.  
  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;
  284.  
  285.    if(hsize>dsize)
  286.      buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat));
  287.    else
  288.      buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat));
  289.  
  290.    /* compute the increment value for the u-loop */
  291.    uinc = ustride - vorder*vstride;
  292.  
  293.    if (buffer)
  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++)
  297.            *p++ = points[k];
  298.  
  299.    return buffer;
  300. }
  301.  
  302.  
  303.  
  304. /*
  305.  * Same as above but convert doubles to floats.
  306.  */
  307. GLfloat *_mesa_copy_map_points2d(GLenum target,
  308.                                  GLint ustride, GLint uorder,
  309.                                  GLint vstride, GLint vorder,
  310.                                  const GLdouble *points )
  311. {
  312.    GLfloat *buffer, *p;
  313.    GLint i, j, k, size, hsize, dsize;
  314.    GLint uinc;
  315.  
  316.    size = _mesa_evaluator_components(target);
  317.  
  318.    if (!points || size==0) {
  319.       return NULL;
  320.    }
  321.  
  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;
  327.  
  328.    if(hsize>dsize)
  329.      buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat));
  330.    else
  331.      buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat));
  332.  
  333.    /* compute the increment value for the u-loop */
  334.    uinc = ustride - vorder*vstride;
  335.  
  336.    if (buffer)
  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];
  341.  
  342.    return buffer;
  343. }
  344.  
  345.  
  346.  
  347.  
  348. /**********************************************************************/
  349. /***                      API entry points                          ***/
  350. /**********************************************************************/
  351.  
  352.  
  353. /*
  354.  * This does the work of glMap1[fd].
  355.  */
  356. static void
  357. map1(GLenum target, GLfloat u1, GLfloat u2, GLint ustride,
  358.      GLint uorder, const GLvoid *points, GLenum type )
  359. {
  360.    GET_CURRENT_CONTEXT(ctx);
  361.    GLint k;
  362.    GLfloat *pnts;
  363.    struct gl_1d_map *map = NULL;
  364.  
  365.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  366.    ASSERT(type == GL_FLOAT || type == GL_DOUBLE);
  367.  
  368.    if (u1 == u2) {
  369.       _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(u1,u2)" );
  370.       return;
  371.    }
  372.    if (uorder < 1 || uorder > MAX_EVAL_ORDER) {
  373.       _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(order)" );
  374.       return;
  375.    }
  376.    if (!points) {
  377.       _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(points)" );
  378.       return;
  379.    }
  380.  
  381.    k = _mesa_evaluator_components( target );
  382.    if (k == 0) {
  383.       _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
  384.    }
  385.  
  386.    if (ustride < k) {
  387.       _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" );
  388.       return;
  389.    }
  390.  
  391.    if (ctx->Texture.CurrentUnit != 0) {
  392.       /* See OpenGL 1.2.1 spec, section F.2.13 */
  393.       _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" );
  394.       return;
  395.    }
  396.  
  397.    map = get_1d_map(ctx, target);
  398.    if (!map) {
  399.       _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" );
  400.       return;
  401.    }
  402.  
  403.    /* make copy of the control points */
  404.    if (type == GL_FLOAT)
  405.       pnts = _mesa_copy_map_points1f(target, ustride, uorder, (GLfloat*) points);
  406.    else
  407.       pnts = _mesa_copy_map_points1d(target, ustride, uorder, (GLdouble*) points);
  408.  
  409.  
  410.    FLUSH_VERTICES(ctx, _NEW_EVAL);
  411.    map->Order = uorder;
  412.    map->u1 = u1;
  413.    map->u2 = u2;
  414.    map->du = 1.0F / (u2 - u1);
  415.    if (map->Points)
  416.       FREE( map->Points );
  417.    map->Points = pnts;
  418. }
  419.  
  420.  
  421.  
  422. void
  423. _mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride,
  424.              GLint order, const GLfloat *points )
  425. {
  426.    map1(target, u1, u2, stride, order, points, GL_FLOAT);
  427. }
  428.  
  429.  
  430. void
  431. _mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride,
  432.              GLint order, const GLdouble *points )
  433. {
  434.    map1(target, (GLfloat) u1, (GLfloat) u2, stride, order, points, GL_DOUBLE);
  435. }
  436.  
  437.  
  438. static void
  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 )
  442. {
  443.    GET_CURRENT_CONTEXT(ctx);
  444.    GLint k;
  445.    GLfloat *pnts;
  446.    struct gl_2d_map *map = NULL;
  447.  
  448.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  449.    ASSERT(type == GL_FLOAT || type == GL_DOUBLE);
  450.  
  451.    if (u1==u2) {
  452.       _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(u1,u2)" );
  453.       return;
  454.    }
  455.  
  456.    if (v1==v2) {
  457.       _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(v1,v2)" );
  458.       return;
  459.    }
  460.  
  461.    if (uorder<1 || uorder>MAX_EVAL_ORDER) {
  462.       _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(uorder)" );
  463.       return;
  464.    }
  465.  
  466.    if (vorder<1 || vorder>MAX_EVAL_ORDER) {
  467.       _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vorder)" );
  468.       return;
  469.    }
  470.  
  471.    k = _mesa_evaluator_components( target );
  472.    if (k==0) {
  473.       _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
  474.    }
  475.  
  476.    if (ustride < k) {
  477.       _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(ustride)" );
  478.       return;
  479.    }
  480.    if (vstride < k) {
  481.       _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vstride)" );
  482.       return;
  483.    }
  484.  
  485.    if (ctx->Texture.CurrentUnit != 0) {
  486.       /* See OpenGL 1.2.1 spec, section F.2.13 */
  487.       _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" );
  488.       return;
  489.    }
  490.  
  491.    map = get_2d_map(ctx, target);
  492.    if (!map) {
  493.       _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" );
  494.       return;
  495.    }
  496.  
  497.    /* make copy of the control points */
  498.    if (type == GL_FLOAT)
  499.       pnts = _mesa_copy_map_points2f(target, ustride, uorder,
  500.                                   vstride, vorder, (GLfloat*) points);
  501.    else
  502.       pnts = _mesa_copy_map_points2d(target, ustride, uorder,
  503.                                   vstride, vorder, (GLdouble*) points);
  504.  
  505.  
  506.    FLUSH_VERTICES(ctx, _NEW_EVAL);
  507.    map->Uorder = uorder;
  508.    map->u1 = u1;
  509.    map->u2 = u2;
  510.    map->du = 1.0F / (u2 - u1);
  511.    map->Vorder = vorder;
  512.    map->v1 = v1;
  513.    map->v2 = v2;
  514.    map->dv = 1.0F / (v2 - v1);
  515.    if (map->Points)
  516.       FREE( map->Points );
  517.    map->Points = pnts;
  518. }
  519.  
  520.  
  521. void
  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)
  526. {
  527.    map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder,
  528.         points, GL_FLOAT);
  529. }
  530.  
  531.  
  532. void
  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 )
  537. {
  538.    map2(target, (GLfloat) u1, (GLfloat) u2, ustride, uorder, 
  539.     (GLfloat) v1, (GLfloat) v2, vstride, vorder, points, GL_DOUBLE);
  540. }
  541.  
  542.  
  543.  
  544. void
  545. _mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v )
  546. {
  547.    GET_CURRENT_CONTEXT(ctx);
  548.    struct gl_1d_map *map1d;
  549.    struct gl_2d_map *map2d;
  550.    GLint i, n;
  551.    GLfloat *data;
  552.    GLuint comps;
  553.  
  554.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  555.  
  556.    comps = _mesa_evaluator_components(target);
  557.    if (!comps) {
  558.       _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" );
  559.       return;
  560.    }
  561.  
  562.    map1d = get_1d_map(ctx, target);
  563.    map2d = get_2d_map(ctx, target);
  564.    ASSERT(map1d || map2d);
  565.  
  566.    switch (query) {
  567.       case GL_COEFF:
  568.          if (map1d) {
  569.             data = map1d->Points;
  570.             n = map1d->Order * comps;
  571.          }
  572.          else {
  573.             data = map2d->Points;
  574.             n = map2d->Uorder * map2d->Vorder * comps;
  575.          }
  576.      if (data) {
  577.         for (i=0;i<n;i++) {
  578.            v[i] = data[i];
  579.         }
  580.      }
  581.          break;
  582.       case GL_ORDER:
  583.          if (map1d) {
  584.             v[0] = (GLdouble) map1d->Order;
  585.          }
  586.          else {
  587.             v[0] = (GLdouble) map2d->Uorder;
  588.             v[1] = (GLdouble) map2d->Vorder;
  589.          }
  590.          break;
  591.       case GL_DOMAIN:
  592.          if (map1d) {
  593.             v[0] = (GLdouble) map1d->u1;
  594.             v[1] = (GLdouble) map1d->u2;
  595.          }
  596.          else {
  597.             v[0] = (GLdouble) map2d->u1;
  598.             v[1] = (GLdouble) map2d->u2;
  599.             v[2] = (GLdouble) map2d->v1;
  600.             v[3] = (GLdouble) map2d->v2;
  601.          }
  602.          break;
  603.       default:
  604.          _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" );
  605.    }
  606. }
  607.  
  608.  
  609. void
  610. _mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v )
  611. {
  612.    GET_CURRENT_CONTEXT(ctx);
  613.    struct gl_1d_map *map1d;
  614.    struct gl_2d_map *map2d;
  615.    GLint i, n;
  616.    GLfloat *data;
  617.    GLuint comps;
  618.  
  619.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  620.  
  621.    comps = _mesa_evaluator_components(target);
  622.    if (!comps) {
  623.       _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" );
  624.       return;
  625.    }
  626.  
  627.    map1d = get_1d_map(ctx, target);
  628.    map2d = get_2d_map(ctx, target);
  629.    ASSERT(map1d || map2d);
  630.  
  631.    switch (query) {
  632.       case GL_COEFF:
  633.          if (map1d) {
  634.             data = map1d->Points;
  635.             n = map1d->Order * comps;
  636.          }
  637.          else {
  638.             data = map2d->Points;
  639.             n = map2d->Uorder * map2d->Vorder * comps;
  640.          }
  641.      if (data) {
  642.         for (i=0;i<n;i++) {
  643.            v[i] = data[i];
  644.         }
  645.      }
  646.          break;
  647.       case GL_ORDER:
  648.          if (map1d) {
  649.             v[0] = (GLfloat) map1d->Order;
  650.          }
  651.          else {
  652.             v[0] = (GLfloat) map2d->Uorder;
  653.             v[1] = (GLfloat) map2d->Vorder;
  654.          }
  655.          break;
  656.       case GL_DOMAIN:
  657.          if (map1d) {
  658.             v[0] = map1d->u1;
  659.             v[1] = map1d->u2;
  660.          }
  661.          else {
  662.             v[0] = map2d->u1;
  663.             v[1] = map2d->u2;
  664.             v[2] = map2d->v1;
  665.             v[3] = map2d->v2;
  666.          }
  667.          break;
  668.       default:
  669.          _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" );
  670.    }
  671. }
  672.  
  673.  
  674. void
  675. _mesa_GetMapiv( GLenum target, GLenum query, GLint *v )
  676. {
  677.    GET_CURRENT_CONTEXT(ctx);
  678.    struct gl_1d_map *map1d;
  679.    struct gl_2d_map *map2d;
  680.    GLuint i, n;
  681.    GLfloat *data;
  682.    GLuint comps;
  683.  
  684.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  685.  
  686.    comps = _mesa_evaluator_components(target);
  687.    if (!comps) {
  688.       _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" );
  689.       return;
  690.    }
  691.  
  692.    map1d = get_1d_map(ctx, target);
  693.    map2d = get_2d_map(ctx, target);
  694.    ASSERT(map1d || map2d);
  695.  
  696.    switch (query) {
  697.       case GL_COEFF:
  698.          if (map1d) {
  699.             data = map1d->Points;
  700.             n = map1d->Order * comps;
  701.          }
  702.          else {
  703.             data = map2d->Points;
  704.             n = map2d->Uorder * map2d->Vorder * comps;
  705.          }
  706.      if (data) {
  707.         for (i=0;i<n;i++) {
  708.            v[i] = ROUNDF(data[i]);
  709.         }
  710.      }
  711.          break;
  712.       case GL_ORDER:
  713.          if (map1d) {
  714.             v[0] = map1d->Order;
  715.          }
  716.          else {
  717.             v[0] = map2d->Uorder;
  718.             v[1] = map2d->Vorder;
  719.          }
  720.          break;
  721.       case GL_DOMAIN:
  722.          if (map1d) {
  723.             v[0] = ROUNDF(map1d->u1);
  724.             v[1] = ROUNDF(map1d->u2);
  725.          }
  726.          else {
  727.             v[0] = ROUNDF(map2d->u1);
  728.             v[1] = ROUNDF(map2d->u2);
  729.             v[2] = ROUNDF(map2d->v1);
  730.             v[3] = ROUNDF(map2d->v2);
  731.          }
  732.          break;
  733.       default:
  734.          _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" );
  735.    }
  736. }
  737.  
  738.  
  739.  
  740. void
  741. _mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 )
  742. {
  743.    GET_CURRENT_CONTEXT(ctx);
  744.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  745.  
  746.    if (un<1) {
  747.       _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid1f" );
  748.       return;
  749.    }
  750.    FLUSH_VERTICES(ctx, _NEW_EVAL);
  751.    ctx->Eval.MapGrid1un = un;
  752.    ctx->Eval.MapGrid1u1 = u1;
  753.    ctx->Eval.MapGrid1u2 = u2;
  754.    ctx->Eval.MapGrid1du = (u2 - u1) / (GLfloat) un;
  755. }
  756.  
  757.  
  758. void
  759. _mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 )
  760. {
  761.    _mesa_MapGrid1f( un, (GLfloat) u1, (GLfloat) u2 );
  762. }
  763.  
  764.  
  765. void
  766. _mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2,
  767.                  GLint vn, GLfloat v1, GLfloat v2 )
  768. {
  769.    GET_CURRENT_CONTEXT(ctx);
  770.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  771.  
  772.    if (un<1) {
  773.       _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" );
  774.       return;
  775.    }
  776.    if (vn<1) {
  777.       _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(vn)" );
  778.       return;
  779.    }
  780.  
  781.    FLUSH_VERTICES(ctx, _NEW_EVAL);
  782.    ctx->Eval.MapGrid2un = un;
  783.    ctx->Eval.MapGrid2u1 = u1;
  784.    ctx->Eval.MapGrid2u2 = u2;
  785.    ctx->Eval.MapGrid2du = (u2 - u1) / (GLfloat) un;
  786.    ctx->Eval.MapGrid2vn = vn;
  787.    ctx->Eval.MapGrid2v1 = v1;
  788.    ctx->Eval.MapGrid2v2 = v2;
  789.    ctx->Eval.MapGrid2dv = (v2 - v1) / (GLfloat) vn;
  790. }
  791.  
  792.  
  793. void
  794. _mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2,
  795.                  GLint vn, GLdouble v1, GLdouble v2 )
  796. {
  797.    _mesa_MapGrid2f( un, (GLfloat) u1, (GLfloat) u2, 
  798.             vn, (GLfloat) v1, (GLfloat) v2 );
  799. }
  800.