Subversion Repositories Kolibri OS

Rev

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

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