Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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