eval.c revision 3464ebd5
17117f1b4Smrg 27117f1b4Smrg/* 37117f1b4Smrg * Mesa 3-D graphics library 47117f1b4Smrg * Version: 5.1 57117f1b4Smrg * 67117f1b4Smrg * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. 77117f1b4Smrg * 87117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a 97117f1b4Smrg * copy of this software and associated documentation files (the "Software"), 107117f1b4Smrg * to deal in the Software without restriction, including without limitation 117117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 127117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the 137117f1b4Smrg * Software is furnished to do so, subject to the following conditions: 147117f1b4Smrg * 157117f1b4Smrg * The above copyright notice and this permission notice shall be included 167117f1b4Smrg * in all copies or substantial portions of the Software. 177117f1b4Smrg * 187117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 197117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 207117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 217117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 227117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 237117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 247117f1b4Smrg */ 257117f1b4Smrg 267117f1b4Smrg 277117f1b4Smrg/* 287117f1b4Smrg * eval.c was written by 297117f1b4Smrg * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and 307117f1b4Smrg * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de). 317117f1b4Smrg * 327117f1b4Smrg * My original implementation of evaluators was simplistic and didn't 337117f1b4Smrg * compute surface normal vectors properly. Bernd and Volker applied 347117f1b4Smrg * used more sophisticated methods to get better results. 357117f1b4Smrg * 367117f1b4Smrg * Thanks guys! 377117f1b4Smrg */ 387117f1b4Smrg 397117f1b4Smrg 407117f1b4Smrg#include "glheader.h" 417117f1b4Smrg#include "imports.h" 427117f1b4Smrg#include "colormac.h" 437117f1b4Smrg#include "context.h" 447117f1b4Smrg#include "eval.h" 457117f1b4Smrg#include "macros.h" 463464ebd5Sriastradh#include "mfeatures.h" 477117f1b4Smrg#include "mtypes.h" 48cdc920a0Smrg#include "main/dispatch.h" 494a49301eSmrg 504a49301eSmrg 514a49301eSmrg#if FEATURE_evaluators 527117f1b4Smrg 537117f1b4Smrg 547117f1b4Smrg/* 557117f1b4Smrg * Return the number of components per control point for any type of 567117f1b4Smrg * evaluator. Return 0 if bad target. 577117f1b4Smrg * See table 5.1 in the OpenGL 1.2 spec. 587117f1b4Smrg */ 597117f1b4SmrgGLuint _mesa_evaluator_components( GLenum target ) 607117f1b4Smrg{ 617117f1b4Smrg switch (target) { 627117f1b4Smrg case GL_MAP1_VERTEX_3: return 3; 637117f1b4Smrg case GL_MAP1_VERTEX_4: return 4; 647117f1b4Smrg case GL_MAP1_INDEX: return 1; 657117f1b4Smrg case GL_MAP1_COLOR_4: return 4; 667117f1b4Smrg case GL_MAP1_NORMAL: return 3; 677117f1b4Smrg case GL_MAP1_TEXTURE_COORD_1: return 1; 687117f1b4Smrg case GL_MAP1_TEXTURE_COORD_2: return 2; 697117f1b4Smrg case GL_MAP1_TEXTURE_COORD_3: return 3; 707117f1b4Smrg case GL_MAP1_TEXTURE_COORD_4: return 4; 717117f1b4Smrg case GL_MAP2_VERTEX_3: return 3; 727117f1b4Smrg case GL_MAP2_VERTEX_4: return 4; 737117f1b4Smrg case GL_MAP2_INDEX: return 1; 747117f1b4Smrg case GL_MAP2_COLOR_4: return 4; 757117f1b4Smrg case GL_MAP2_NORMAL: return 3; 767117f1b4Smrg case GL_MAP2_TEXTURE_COORD_1: return 1; 777117f1b4Smrg case GL_MAP2_TEXTURE_COORD_2: return 2; 787117f1b4Smrg case GL_MAP2_TEXTURE_COORD_3: return 3; 797117f1b4Smrg case GL_MAP2_TEXTURE_COORD_4: return 4; 807117f1b4Smrg default: break; 817117f1b4Smrg } 827117f1b4Smrg 837117f1b4Smrg /* XXX need to check for the vertex program extension 847117f1b4Smrg if (!ctx->Extensions.NV_vertex_program) 857117f1b4Smrg return 0; 867117f1b4Smrg */ 877117f1b4Smrg 887117f1b4Smrg if (target >= GL_MAP1_VERTEX_ATTRIB0_4_NV && 897117f1b4Smrg target <= GL_MAP1_VERTEX_ATTRIB15_4_NV) 907117f1b4Smrg return 4; 917117f1b4Smrg 927117f1b4Smrg if (target >= GL_MAP2_VERTEX_ATTRIB0_4_NV && 937117f1b4Smrg target <= GL_MAP2_VERTEX_ATTRIB15_4_NV) 947117f1b4Smrg return 4; 957117f1b4Smrg 967117f1b4Smrg return 0; 977117f1b4Smrg} 987117f1b4Smrg 997117f1b4Smrg 1007117f1b4Smrg/* 1017117f1b4Smrg * Return pointer to the gl_1d_map struct for the named target. 1027117f1b4Smrg */ 1037117f1b4Smrgstatic struct gl_1d_map * 1043464ebd5Sriastradhget_1d_map( struct gl_context *ctx, GLenum target ) 1057117f1b4Smrg{ 1067117f1b4Smrg switch (target) { 1077117f1b4Smrg case GL_MAP1_VERTEX_3: 1087117f1b4Smrg return &ctx->EvalMap.Map1Vertex3; 1097117f1b4Smrg case GL_MAP1_VERTEX_4: 1107117f1b4Smrg return &ctx->EvalMap.Map1Vertex4; 1117117f1b4Smrg case GL_MAP1_INDEX: 1127117f1b4Smrg return &ctx->EvalMap.Map1Index; 1137117f1b4Smrg case GL_MAP1_COLOR_4: 1147117f1b4Smrg return &ctx->EvalMap.Map1Color4; 1157117f1b4Smrg case GL_MAP1_NORMAL: 1167117f1b4Smrg return &ctx->EvalMap.Map1Normal; 1177117f1b4Smrg case GL_MAP1_TEXTURE_COORD_1: 1187117f1b4Smrg return &ctx->EvalMap.Map1Texture1; 1197117f1b4Smrg case GL_MAP1_TEXTURE_COORD_2: 1207117f1b4Smrg return &ctx->EvalMap.Map1Texture2; 1217117f1b4Smrg case GL_MAP1_TEXTURE_COORD_3: 1227117f1b4Smrg return &ctx->EvalMap.Map1Texture3; 1237117f1b4Smrg case GL_MAP1_TEXTURE_COORD_4: 1247117f1b4Smrg return &ctx->EvalMap.Map1Texture4; 1257117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB0_4_NV: 1267117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB1_4_NV: 1277117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB2_4_NV: 1287117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB3_4_NV: 1297117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB4_4_NV: 1307117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB5_4_NV: 1317117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB6_4_NV: 1327117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB7_4_NV: 1337117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB8_4_NV: 1347117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB9_4_NV: 1357117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB10_4_NV: 1367117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB11_4_NV: 1377117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB12_4_NV: 1387117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB13_4_NV: 1397117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB14_4_NV: 1407117f1b4Smrg case GL_MAP1_VERTEX_ATTRIB15_4_NV: 1417117f1b4Smrg if (!ctx->Extensions.NV_vertex_program) 1427117f1b4Smrg return NULL; 1437117f1b4Smrg return &ctx->EvalMap.Map1Attrib[target - GL_MAP1_VERTEX_ATTRIB0_4_NV]; 1447117f1b4Smrg default: 1457117f1b4Smrg return NULL; 1467117f1b4Smrg } 1477117f1b4Smrg} 1487117f1b4Smrg 1497117f1b4Smrg 1507117f1b4Smrg/* 1517117f1b4Smrg * Return pointer to the gl_2d_map struct for the named target. 1527117f1b4Smrg */ 1537117f1b4Smrgstatic struct gl_2d_map * 1543464ebd5Sriastradhget_2d_map( struct gl_context *ctx, GLenum target ) 1557117f1b4Smrg{ 1567117f1b4Smrg switch (target) { 1577117f1b4Smrg case GL_MAP2_VERTEX_3: 1587117f1b4Smrg return &ctx->EvalMap.Map2Vertex3; 1597117f1b4Smrg case GL_MAP2_VERTEX_4: 1607117f1b4Smrg return &ctx->EvalMap.Map2Vertex4; 1617117f1b4Smrg case GL_MAP2_INDEX: 1627117f1b4Smrg return &ctx->EvalMap.Map2Index; 1637117f1b4Smrg case GL_MAP2_COLOR_4: 1647117f1b4Smrg return &ctx->EvalMap.Map2Color4; 1657117f1b4Smrg case GL_MAP2_NORMAL: 1667117f1b4Smrg return &ctx->EvalMap.Map2Normal; 1677117f1b4Smrg case GL_MAP2_TEXTURE_COORD_1: 1687117f1b4Smrg return &ctx->EvalMap.Map2Texture1; 1697117f1b4Smrg case GL_MAP2_TEXTURE_COORD_2: 1707117f1b4Smrg return &ctx->EvalMap.Map2Texture2; 1717117f1b4Smrg case GL_MAP2_TEXTURE_COORD_3: 1727117f1b4Smrg return &ctx->EvalMap.Map2Texture3; 1737117f1b4Smrg case GL_MAP2_TEXTURE_COORD_4: 1747117f1b4Smrg return &ctx->EvalMap.Map2Texture4; 1757117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB0_4_NV: 1767117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB1_4_NV: 1777117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB2_4_NV: 1787117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB3_4_NV: 1797117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB4_4_NV: 1807117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB5_4_NV: 1817117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB6_4_NV: 1827117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB7_4_NV: 1837117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB8_4_NV: 1847117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB9_4_NV: 1857117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB10_4_NV: 1867117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB11_4_NV: 1877117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB12_4_NV: 1887117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB13_4_NV: 1897117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB14_4_NV: 1907117f1b4Smrg case GL_MAP2_VERTEX_ATTRIB15_4_NV: 1917117f1b4Smrg if (!ctx->Extensions.NV_vertex_program) 1927117f1b4Smrg return NULL; 1937117f1b4Smrg return &ctx->EvalMap.Map2Attrib[target - GL_MAP2_VERTEX_ATTRIB0_4_NV]; 1947117f1b4Smrg default: 1957117f1b4Smrg return NULL; 1967117f1b4Smrg } 1977117f1b4Smrg} 1987117f1b4Smrg 1997117f1b4Smrg 2007117f1b4Smrg/**********************************************************************/ 2017117f1b4Smrg/*** Copy and deallocate control points ***/ 2027117f1b4Smrg/**********************************************************************/ 2037117f1b4Smrg 2047117f1b4Smrg 2057117f1b4Smrg/* 2067117f1b4Smrg * Copy 1-parametric evaluator control points from user-specified 2077117f1b4Smrg * memory space to a buffer of contiguous control points. 2087117f1b4Smrg * \param see glMap1f for details 2097117f1b4Smrg * \return pointer to buffer of contiguous control points or NULL if out 2107117f1b4Smrg * of memory. 2117117f1b4Smrg */ 2127117f1b4SmrgGLfloat *_mesa_copy_map_points1f( GLenum target, GLint ustride, GLint uorder, 2137117f1b4Smrg const GLfloat *points ) 2147117f1b4Smrg{ 2157117f1b4Smrg GLfloat *buffer, *p; 2167117f1b4Smrg GLint i, k, size = _mesa_evaluator_components(target); 2177117f1b4Smrg 2187117f1b4Smrg if (!points || !size) 2197117f1b4Smrg return NULL; 2207117f1b4Smrg 2217117f1b4Smrg buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat)); 2227117f1b4Smrg 2237117f1b4Smrg if (buffer) 2247117f1b4Smrg for (i = 0, p = buffer; i < uorder; i++, points += ustride) 2257117f1b4Smrg for (k = 0; k < size; k++) 2267117f1b4Smrg *p++ = points[k]; 2277117f1b4Smrg 2287117f1b4Smrg return buffer; 2297117f1b4Smrg} 2307117f1b4Smrg 2317117f1b4Smrg 2327117f1b4Smrg 2337117f1b4Smrg/* 2347117f1b4Smrg * Same as above but convert doubles to floats. 2357117f1b4Smrg */ 2367117f1b4SmrgGLfloat *_mesa_copy_map_points1d( GLenum target, GLint ustride, GLint uorder, 2377117f1b4Smrg const GLdouble *points ) 2387117f1b4Smrg{ 2397117f1b4Smrg GLfloat *buffer, *p; 2407117f1b4Smrg GLint i, k, size = _mesa_evaluator_components(target); 2417117f1b4Smrg 2427117f1b4Smrg if (!points || !size) 2437117f1b4Smrg return NULL; 2447117f1b4Smrg 2457117f1b4Smrg buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat)); 2467117f1b4Smrg 2477117f1b4Smrg if (buffer) 2487117f1b4Smrg for (i = 0, p = buffer; i < uorder; i++, points += ustride) 2497117f1b4Smrg for (k = 0; k < size; k++) 2507117f1b4Smrg *p++ = (GLfloat) points[k]; 2517117f1b4Smrg 2527117f1b4Smrg return buffer; 2537117f1b4Smrg} 2547117f1b4Smrg 2557117f1b4Smrg 2567117f1b4Smrg 2577117f1b4Smrg/* 2587117f1b4Smrg * Copy 2-parametric evaluator control points from user-specified 2597117f1b4Smrg * memory space to a buffer of contiguous control points. 2607117f1b4Smrg * Additional memory is allocated to be used by the horner and 2617117f1b4Smrg * de Casteljau evaluation schemes. 2627117f1b4Smrg * 2637117f1b4Smrg * \param see glMap2f for details 2647117f1b4Smrg * \return pointer to buffer of contiguous control points or NULL if out 2657117f1b4Smrg * of memory. 2667117f1b4Smrg */ 2677117f1b4SmrgGLfloat *_mesa_copy_map_points2f( GLenum target, 2687117f1b4Smrg GLint ustride, GLint uorder, 2697117f1b4Smrg GLint vstride, GLint vorder, 2707117f1b4Smrg const GLfloat *points ) 2717117f1b4Smrg{ 2727117f1b4Smrg GLfloat *buffer, *p; 2737117f1b4Smrg GLint i, j, k, size, dsize, hsize; 2747117f1b4Smrg GLint uinc; 2757117f1b4Smrg 2767117f1b4Smrg size = _mesa_evaluator_components(target); 2777117f1b4Smrg 2787117f1b4Smrg if (!points || size==0) { 2797117f1b4Smrg return NULL; 2807117f1b4Smrg } 2817117f1b4Smrg 2827117f1b4Smrg /* max(uorder, vorder) additional points are used in */ 2837117f1b4Smrg /* horner evaluation and uorder*vorder additional */ 2847117f1b4Smrg /* values are needed for de Casteljau */ 2857117f1b4Smrg dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder; 2867117f1b4Smrg hsize = (uorder > vorder ? uorder : vorder)*size; 2877117f1b4Smrg 2887117f1b4Smrg if(hsize>dsize) 2897117f1b4Smrg buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat)); 2907117f1b4Smrg else 2917117f1b4Smrg buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat)); 2927117f1b4Smrg 2937117f1b4Smrg /* compute the increment value for the u-loop */ 2947117f1b4Smrg uinc = ustride - vorder*vstride; 2957117f1b4Smrg 2967117f1b4Smrg if (buffer) 2977117f1b4Smrg for (i=0, p=buffer; i<uorder; i++, points += uinc) 2987117f1b4Smrg for (j=0; j<vorder; j++, points += vstride) 2997117f1b4Smrg for (k=0; k<size; k++) 3007117f1b4Smrg *p++ = points[k]; 3017117f1b4Smrg 3027117f1b4Smrg return buffer; 3037117f1b4Smrg} 3047117f1b4Smrg 3057117f1b4Smrg 3067117f1b4Smrg 3077117f1b4Smrg/* 3087117f1b4Smrg * Same as above but convert doubles to floats. 3097117f1b4Smrg */ 3107117f1b4SmrgGLfloat *_mesa_copy_map_points2d(GLenum target, 3117117f1b4Smrg GLint ustride, GLint uorder, 3127117f1b4Smrg GLint vstride, GLint vorder, 3137117f1b4Smrg const GLdouble *points ) 3147117f1b4Smrg{ 3157117f1b4Smrg GLfloat *buffer, *p; 3167117f1b4Smrg GLint i, j, k, size, hsize, dsize; 3177117f1b4Smrg GLint uinc; 3187117f1b4Smrg 3197117f1b4Smrg size = _mesa_evaluator_components(target); 3207117f1b4Smrg 3217117f1b4Smrg if (!points || size==0) { 3227117f1b4Smrg return NULL; 3237117f1b4Smrg } 3247117f1b4Smrg 3257117f1b4Smrg /* max(uorder, vorder) additional points are used in */ 3267117f1b4Smrg /* horner evaluation and uorder*vorder additional */ 3277117f1b4Smrg /* values are needed for de Casteljau */ 3287117f1b4Smrg dsize = (uorder == 2 && vorder == 2)? 0 : uorder*vorder; 3297117f1b4Smrg hsize = (uorder > vorder ? uorder : vorder)*size; 3307117f1b4Smrg 3317117f1b4Smrg if(hsize>dsize) 3327117f1b4Smrg buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat)); 3337117f1b4Smrg else 3347117f1b4Smrg buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat)); 3357117f1b4Smrg 3367117f1b4Smrg /* compute the increment value for the u-loop */ 3377117f1b4Smrg uinc = ustride - vorder*vstride; 3387117f1b4Smrg 3397117f1b4Smrg if (buffer) 3407117f1b4Smrg for (i=0, p=buffer; i<uorder; i++, points += uinc) 3417117f1b4Smrg for (j=0; j<vorder; j++, points += vstride) 3427117f1b4Smrg for (k=0; k<size; k++) 3437117f1b4Smrg *p++ = (GLfloat) points[k]; 3447117f1b4Smrg 3457117f1b4Smrg return buffer; 3467117f1b4Smrg} 3477117f1b4Smrg 3487117f1b4Smrg 3497117f1b4Smrg 3507117f1b4Smrg 3517117f1b4Smrg/**********************************************************************/ 3527117f1b4Smrg/*** API entry points ***/ 3537117f1b4Smrg/**********************************************************************/ 3547117f1b4Smrg 3557117f1b4Smrg 3567117f1b4Smrg/* 3577117f1b4Smrg * This does the work of glMap1[fd]. 3587117f1b4Smrg */ 3597117f1b4Smrgstatic void 3607117f1b4Smrgmap1(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, 3617117f1b4Smrg GLint uorder, const GLvoid *points, GLenum type ) 3627117f1b4Smrg{ 3637117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 3647117f1b4Smrg GLint k; 3657117f1b4Smrg GLfloat *pnts; 3667117f1b4Smrg struct gl_1d_map *map = NULL; 3677117f1b4Smrg 3687117f1b4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 3697117f1b4Smrg ASSERT(type == GL_FLOAT || type == GL_DOUBLE); 3707117f1b4Smrg 3717117f1b4Smrg if (u1 == u2) { 3727117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(u1,u2)" ); 3737117f1b4Smrg return; 3747117f1b4Smrg } 3757117f1b4Smrg if (uorder < 1 || uorder > MAX_EVAL_ORDER) { 3767117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(order)" ); 3777117f1b4Smrg return; 3787117f1b4Smrg } 3797117f1b4Smrg if (!points) { 3807117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(points)" ); 3817117f1b4Smrg return; 3827117f1b4Smrg } 3837117f1b4Smrg 3847117f1b4Smrg k = _mesa_evaluator_components( target ); 3857117f1b4Smrg if (k == 0) { 3867117f1b4Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" ); 3877117f1b4Smrg } 3887117f1b4Smrg 3897117f1b4Smrg if (ustride < k) { 3907117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" ); 3917117f1b4Smrg return; 3927117f1b4Smrg } 3937117f1b4Smrg 3947117f1b4Smrg if (ctx->Texture.CurrentUnit != 0) { 3957117f1b4Smrg /* See OpenGL 1.2.1 spec, section F.2.13 */ 3967117f1b4Smrg _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" ); 3977117f1b4Smrg return; 3987117f1b4Smrg } 3997117f1b4Smrg 4007117f1b4Smrg map = get_1d_map(ctx, target); 4017117f1b4Smrg if (!map) { 4027117f1b4Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" ); 4037117f1b4Smrg return; 4047117f1b4Smrg } 4057117f1b4Smrg 4067117f1b4Smrg /* make copy of the control points */ 4077117f1b4Smrg if (type == GL_FLOAT) 4087117f1b4Smrg pnts = _mesa_copy_map_points1f(target, ustride, uorder, (GLfloat*) points); 4097117f1b4Smrg else 4107117f1b4Smrg pnts = _mesa_copy_map_points1d(target, ustride, uorder, (GLdouble*) points); 4117117f1b4Smrg 4127117f1b4Smrg 4137117f1b4Smrg FLUSH_VERTICES(ctx, _NEW_EVAL); 4147117f1b4Smrg map->Order = uorder; 4157117f1b4Smrg map->u1 = u1; 4167117f1b4Smrg map->u2 = u2; 4177117f1b4Smrg map->du = 1.0F / (u2 - u1); 4187117f1b4Smrg if (map->Points) 4197117f1b4Smrg FREE( map->Points ); 4207117f1b4Smrg map->Points = pnts; 4217117f1b4Smrg} 4227117f1b4Smrg 4237117f1b4Smrg 4247117f1b4Smrg 4254a49301eSmrgstatic void GLAPIENTRY 4267117f1b4Smrg_mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride, 4277117f1b4Smrg GLint order, const GLfloat *points ) 4287117f1b4Smrg{ 4297117f1b4Smrg map1(target, u1, u2, stride, order, points, GL_FLOAT); 4307117f1b4Smrg} 4317117f1b4Smrg 4327117f1b4Smrg 4334a49301eSmrgstatic void GLAPIENTRY 4347117f1b4Smrg_mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride, 4357117f1b4Smrg GLint order, const GLdouble *points ) 4367117f1b4Smrg{ 4377117f1b4Smrg map1(target, (GLfloat) u1, (GLfloat) u2, stride, order, points, GL_DOUBLE); 4387117f1b4Smrg} 4397117f1b4Smrg 4407117f1b4Smrg 4417117f1b4Smrgstatic void 4427117f1b4Smrgmap2( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, 4437117f1b4Smrg GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, 4447117f1b4Smrg const GLvoid *points, GLenum type ) 4457117f1b4Smrg{ 4467117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 4477117f1b4Smrg GLint k; 4487117f1b4Smrg GLfloat *pnts; 4497117f1b4Smrg struct gl_2d_map *map = NULL; 4507117f1b4Smrg 4517117f1b4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 4527117f1b4Smrg ASSERT(type == GL_FLOAT || type == GL_DOUBLE); 4537117f1b4Smrg 4547117f1b4Smrg if (u1==u2) { 4557117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(u1,u2)" ); 4567117f1b4Smrg return; 4577117f1b4Smrg } 4587117f1b4Smrg 4597117f1b4Smrg if (v1==v2) { 4607117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(v1,v2)" ); 4617117f1b4Smrg return; 4627117f1b4Smrg } 4637117f1b4Smrg 4647117f1b4Smrg if (uorder<1 || uorder>MAX_EVAL_ORDER) { 4657117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(uorder)" ); 4667117f1b4Smrg return; 4677117f1b4Smrg } 4687117f1b4Smrg 4697117f1b4Smrg if (vorder<1 || vorder>MAX_EVAL_ORDER) { 4707117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vorder)" ); 4717117f1b4Smrg return; 4727117f1b4Smrg } 4737117f1b4Smrg 4747117f1b4Smrg k = _mesa_evaluator_components( target ); 4757117f1b4Smrg if (k==0) { 4767117f1b4Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" ); 4777117f1b4Smrg } 4787117f1b4Smrg 4797117f1b4Smrg if (ustride < k) { 4807117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(ustride)" ); 4817117f1b4Smrg return; 4827117f1b4Smrg } 4837117f1b4Smrg if (vstride < k) { 4847117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vstride)" ); 4857117f1b4Smrg return; 4867117f1b4Smrg } 4877117f1b4Smrg 4887117f1b4Smrg if (ctx->Texture.CurrentUnit != 0) { 4897117f1b4Smrg /* See OpenGL 1.2.1 spec, section F.2.13 */ 4907117f1b4Smrg _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" ); 4917117f1b4Smrg return; 4927117f1b4Smrg } 4937117f1b4Smrg 4947117f1b4Smrg map = get_2d_map(ctx, target); 4957117f1b4Smrg if (!map) { 4967117f1b4Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" ); 4977117f1b4Smrg return; 4987117f1b4Smrg } 4997117f1b4Smrg 5007117f1b4Smrg /* make copy of the control points */ 5017117f1b4Smrg if (type == GL_FLOAT) 5027117f1b4Smrg pnts = _mesa_copy_map_points2f(target, ustride, uorder, 5037117f1b4Smrg vstride, vorder, (GLfloat*) points); 5047117f1b4Smrg else 5057117f1b4Smrg pnts = _mesa_copy_map_points2d(target, ustride, uorder, 5067117f1b4Smrg vstride, vorder, (GLdouble*) points); 5077117f1b4Smrg 5087117f1b4Smrg 5097117f1b4Smrg FLUSH_VERTICES(ctx, _NEW_EVAL); 5107117f1b4Smrg map->Uorder = uorder; 5117117f1b4Smrg map->u1 = u1; 5127117f1b4Smrg map->u2 = u2; 5137117f1b4Smrg map->du = 1.0F / (u2 - u1); 5147117f1b4Smrg map->Vorder = vorder; 5157117f1b4Smrg map->v1 = v1; 5167117f1b4Smrg map->v2 = v2; 5177117f1b4Smrg map->dv = 1.0F / (v2 - v1); 5187117f1b4Smrg if (map->Points) 5197117f1b4Smrg FREE( map->Points ); 5207117f1b4Smrg map->Points = pnts; 5217117f1b4Smrg} 5227117f1b4Smrg 5237117f1b4Smrg 5244a49301eSmrgstatic void GLAPIENTRY 5257117f1b4Smrg_mesa_Map2f( GLenum target, 5267117f1b4Smrg GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, 5277117f1b4Smrg GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, 5287117f1b4Smrg const GLfloat *points) 5297117f1b4Smrg{ 5307117f1b4Smrg map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, 5317117f1b4Smrg points, GL_FLOAT); 5327117f1b4Smrg} 5337117f1b4Smrg 5347117f1b4Smrg 5354a49301eSmrgstatic void GLAPIENTRY 5367117f1b4Smrg_mesa_Map2d( GLenum target, 5377117f1b4Smrg GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, 5387117f1b4Smrg GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, 5397117f1b4Smrg const GLdouble *points ) 5407117f1b4Smrg{ 5417117f1b4Smrg map2(target, (GLfloat) u1, (GLfloat) u2, ustride, uorder, 5427117f1b4Smrg (GLfloat) v1, (GLfloat) v2, vstride, vorder, points, GL_DOUBLE); 5437117f1b4Smrg} 5447117f1b4Smrg 5457117f1b4Smrg 5467117f1b4Smrg 5474a49301eSmrgstatic void GLAPIENTRY 5483464ebd5Sriastradh_mesa_GetnMapdvARB( GLenum target, GLenum query, GLsizei bufSize, GLdouble *v ) 5497117f1b4Smrg{ 5507117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 5517117f1b4Smrg struct gl_1d_map *map1d; 5527117f1b4Smrg struct gl_2d_map *map2d; 5537117f1b4Smrg GLint i, n; 5547117f1b4Smrg GLfloat *data; 5557117f1b4Smrg GLuint comps; 5563464ebd5Sriastradh GLsizei numBytes; 5577117f1b4Smrg 5587117f1b4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 5597117f1b4Smrg 5607117f1b4Smrg comps = _mesa_evaluator_components(target); 5617117f1b4Smrg if (!comps) { 5627117f1b4Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" ); 5637117f1b4Smrg return; 5647117f1b4Smrg } 5657117f1b4Smrg 5667117f1b4Smrg map1d = get_1d_map(ctx, target); 5677117f1b4Smrg map2d = get_2d_map(ctx, target); 5687117f1b4Smrg ASSERT(map1d || map2d); 5697117f1b4Smrg 5707117f1b4Smrg switch (query) { 5717117f1b4Smrg case GL_COEFF: 5727117f1b4Smrg if (map1d) { 5737117f1b4Smrg data = map1d->Points; 5747117f1b4Smrg n = map1d->Order * comps; 5757117f1b4Smrg } 5767117f1b4Smrg else { 5777117f1b4Smrg data = map2d->Points; 5787117f1b4Smrg n = map2d->Uorder * map2d->Vorder * comps; 5797117f1b4Smrg } 5807117f1b4Smrg if (data) { 5813464ebd5Sriastradh numBytes = n * sizeof *v; 5823464ebd5Sriastradh if (bufSize < numBytes) 5833464ebd5Sriastradh goto overflow; 5847117f1b4Smrg for (i=0;i<n;i++) { 5857117f1b4Smrg v[i] = data[i]; 5867117f1b4Smrg } 5877117f1b4Smrg } 5887117f1b4Smrg break; 5897117f1b4Smrg case GL_ORDER: 5907117f1b4Smrg if (map1d) { 5913464ebd5Sriastradh numBytes = 1 * sizeof *v; 5923464ebd5Sriastradh if (bufSize < numBytes) 5933464ebd5Sriastradh goto overflow; 5947117f1b4Smrg v[0] = (GLdouble) map1d->Order; 5957117f1b4Smrg } 5967117f1b4Smrg else { 5973464ebd5Sriastradh numBytes = 2 * sizeof *v; 5983464ebd5Sriastradh if (bufSize < numBytes) 5993464ebd5Sriastradh goto overflow; 6007117f1b4Smrg v[0] = (GLdouble) map2d->Uorder; 6017117f1b4Smrg v[1] = (GLdouble) map2d->Vorder; 6027117f1b4Smrg } 6037117f1b4Smrg break; 6047117f1b4Smrg case GL_DOMAIN: 6057117f1b4Smrg if (map1d) { 6063464ebd5Sriastradh numBytes = 2 * sizeof *v; 6073464ebd5Sriastradh if (bufSize < numBytes) 6083464ebd5Sriastradh goto overflow; 6097117f1b4Smrg v[0] = (GLdouble) map1d->u1; 6107117f1b4Smrg v[1] = (GLdouble) map1d->u2; 6117117f1b4Smrg } 6127117f1b4Smrg else { 6133464ebd5Sriastradh numBytes = 4 * sizeof *v; 6143464ebd5Sriastradh if (bufSize < numBytes) 6153464ebd5Sriastradh goto overflow; 6167117f1b4Smrg v[0] = (GLdouble) map2d->u1; 6177117f1b4Smrg v[1] = (GLdouble) map2d->u2; 6187117f1b4Smrg v[2] = (GLdouble) map2d->v1; 6197117f1b4Smrg v[3] = (GLdouble) map2d->v2; 6207117f1b4Smrg } 6217117f1b4Smrg break; 6227117f1b4Smrg default: 6237117f1b4Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" ); 6247117f1b4Smrg } 6253464ebd5Sriastradh return; 6263464ebd5Sriastradh 6273464ebd5Sriastradhoverflow: 6283464ebd5Sriastradh _mesa_error( ctx, GL_INVALID_OPERATION, 6293464ebd5Sriastradh "glGetnMapdvARB(out of bounds: bufSize is %d," 6303464ebd5Sriastradh " but %d bytes are required)", bufSize, numBytes ); 6317117f1b4Smrg} 6327117f1b4Smrg 6333464ebd5Sriastradhstatic void GLAPIENTRY 6343464ebd5Sriastradh_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v ) 6353464ebd5Sriastradh{ 6363464ebd5Sriastradh _mesa_GetnMapdvARB(target, query, INT_MAX, v); 6373464ebd5Sriastradh} 6387117f1b4Smrg 6394a49301eSmrgstatic void GLAPIENTRY 6403464ebd5Sriastradh_mesa_GetnMapfvARB( GLenum target, GLenum query, GLsizei bufSize, GLfloat *v ) 6417117f1b4Smrg{ 6427117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 6437117f1b4Smrg struct gl_1d_map *map1d; 6447117f1b4Smrg struct gl_2d_map *map2d; 6457117f1b4Smrg GLint i, n; 6467117f1b4Smrg GLfloat *data; 6477117f1b4Smrg GLuint comps; 6483464ebd5Sriastradh GLsizei numBytes; 6497117f1b4Smrg 6507117f1b4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 6517117f1b4Smrg 6527117f1b4Smrg comps = _mesa_evaluator_components(target); 6537117f1b4Smrg if (!comps) { 6547117f1b4Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" ); 6557117f1b4Smrg return; 6567117f1b4Smrg } 6577117f1b4Smrg 6587117f1b4Smrg map1d = get_1d_map(ctx, target); 6597117f1b4Smrg map2d = get_2d_map(ctx, target); 6607117f1b4Smrg ASSERT(map1d || map2d); 6617117f1b4Smrg 6627117f1b4Smrg switch (query) { 6637117f1b4Smrg case GL_COEFF: 6647117f1b4Smrg if (map1d) { 6657117f1b4Smrg data = map1d->Points; 6667117f1b4Smrg n = map1d->Order * comps; 6677117f1b4Smrg } 6687117f1b4Smrg else { 6697117f1b4Smrg data = map2d->Points; 6707117f1b4Smrg n = map2d->Uorder * map2d->Vorder * comps; 6717117f1b4Smrg } 6727117f1b4Smrg if (data) { 6733464ebd5Sriastradh numBytes = n * sizeof *v; 6743464ebd5Sriastradh if (bufSize < numBytes) 6753464ebd5Sriastradh goto overflow; 6767117f1b4Smrg for (i=0;i<n;i++) { 6777117f1b4Smrg v[i] = data[i]; 6787117f1b4Smrg } 6797117f1b4Smrg } 6807117f1b4Smrg break; 6817117f1b4Smrg case GL_ORDER: 6827117f1b4Smrg if (map1d) { 6833464ebd5Sriastradh numBytes = 1 * sizeof *v; 6843464ebd5Sriastradh if (bufSize < numBytes) 6853464ebd5Sriastradh goto overflow; 6867117f1b4Smrg v[0] = (GLfloat) map1d->Order; 6877117f1b4Smrg } 6887117f1b4Smrg else { 6893464ebd5Sriastradh numBytes = 2 * sizeof *v; 6903464ebd5Sriastradh if (bufSize < numBytes) 6913464ebd5Sriastradh goto overflow; 6927117f1b4Smrg v[0] = (GLfloat) map2d->Uorder; 6937117f1b4Smrg v[1] = (GLfloat) map2d->Vorder; 6947117f1b4Smrg } 6957117f1b4Smrg break; 6967117f1b4Smrg case GL_DOMAIN: 6977117f1b4Smrg if (map1d) { 6983464ebd5Sriastradh numBytes = 2 * sizeof *v; 6993464ebd5Sriastradh if (bufSize < numBytes) 7003464ebd5Sriastradh goto overflow; 7017117f1b4Smrg v[0] = map1d->u1; 7027117f1b4Smrg v[1] = map1d->u2; 7037117f1b4Smrg } 7047117f1b4Smrg else { 7053464ebd5Sriastradh numBytes = 4 * sizeof *v; 7063464ebd5Sriastradh if (bufSize < numBytes) 7073464ebd5Sriastradh goto overflow; 7087117f1b4Smrg v[0] = map2d->u1; 7097117f1b4Smrg v[1] = map2d->u2; 7107117f1b4Smrg v[2] = map2d->v1; 7117117f1b4Smrg v[3] = map2d->v2; 7127117f1b4Smrg } 7137117f1b4Smrg break; 7147117f1b4Smrg default: 7157117f1b4Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" ); 7167117f1b4Smrg } 7173464ebd5Sriastradh return; 7183464ebd5Sriastradh 7193464ebd5Sriastradhoverflow: 7203464ebd5Sriastradh _mesa_error( ctx, GL_INVALID_OPERATION, 7213464ebd5Sriastradh "glGetnMapfvARB(out of bounds: bufSize is %d," 7223464ebd5Sriastradh " but %d bytes are required)", bufSize, numBytes ); 7237117f1b4Smrg} 7247117f1b4Smrg 7257117f1b4Smrg 7264a49301eSmrgstatic void GLAPIENTRY 7273464ebd5Sriastradh_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ) 7283464ebd5Sriastradh{ 7293464ebd5Sriastradh _mesa_GetnMapfvARB(target, query, INT_MAX, v); 7303464ebd5Sriastradh} 7313464ebd5Sriastradh 7323464ebd5Sriastradh 7333464ebd5Sriastradhstatic void GLAPIENTRY 7343464ebd5Sriastradh_mesa_GetnMapivARB( GLenum target, GLenum query, GLsizei bufSize, GLint *v ) 7357117f1b4Smrg{ 7367117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 7377117f1b4Smrg struct gl_1d_map *map1d; 7387117f1b4Smrg struct gl_2d_map *map2d; 7397117f1b4Smrg GLuint i, n; 7407117f1b4Smrg GLfloat *data; 7417117f1b4Smrg GLuint comps; 7423464ebd5Sriastradh GLsizei numBytes; 7437117f1b4Smrg 7447117f1b4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 7457117f1b4Smrg 7467117f1b4Smrg comps = _mesa_evaluator_components(target); 7477117f1b4Smrg if (!comps) { 7487117f1b4Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" ); 7497117f1b4Smrg return; 7507117f1b4Smrg } 7517117f1b4Smrg 7527117f1b4Smrg map1d = get_1d_map(ctx, target); 7537117f1b4Smrg map2d = get_2d_map(ctx, target); 7547117f1b4Smrg ASSERT(map1d || map2d); 7557117f1b4Smrg 7567117f1b4Smrg switch (query) { 7577117f1b4Smrg case GL_COEFF: 7587117f1b4Smrg if (map1d) { 7597117f1b4Smrg data = map1d->Points; 7607117f1b4Smrg n = map1d->Order * comps; 7617117f1b4Smrg } 7627117f1b4Smrg else { 7637117f1b4Smrg data = map2d->Points; 7647117f1b4Smrg n = map2d->Uorder * map2d->Vorder * comps; 7657117f1b4Smrg } 7667117f1b4Smrg if (data) { 7673464ebd5Sriastradh numBytes = n * sizeof *v; 7683464ebd5Sriastradh if (bufSize < numBytes) 7693464ebd5Sriastradh goto overflow; 7707117f1b4Smrg for (i=0;i<n;i++) { 7717117f1b4Smrg v[i] = IROUND(data[i]); 7727117f1b4Smrg } 7737117f1b4Smrg } 7747117f1b4Smrg break; 7757117f1b4Smrg case GL_ORDER: 7767117f1b4Smrg if (map1d) { 7773464ebd5Sriastradh numBytes = 1 * sizeof *v; 7783464ebd5Sriastradh if (bufSize < numBytes) 7793464ebd5Sriastradh goto overflow; 7807117f1b4Smrg v[0] = map1d->Order; 7817117f1b4Smrg } 7827117f1b4Smrg else { 7833464ebd5Sriastradh numBytes = 2 * sizeof *v; 7843464ebd5Sriastradh if (bufSize < numBytes) 7853464ebd5Sriastradh goto overflow; 7867117f1b4Smrg v[0] = map2d->Uorder; 7877117f1b4Smrg v[1] = map2d->Vorder; 7887117f1b4Smrg } 7897117f1b4Smrg break; 7907117f1b4Smrg case GL_DOMAIN: 7917117f1b4Smrg if (map1d) { 7923464ebd5Sriastradh numBytes = 2 * sizeof *v; 7933464ebd5Sriastradh if (bufSize < numBytes) 7943464ebd5Sriastradh goto overflow; 7957117f1b4Smrg v[0] = IROUND(map1d->u1); 7967117f1b4Smrg v[1] = IROUND(map1d->u2); 7977117f1b4Smrg } 7987117f1b4Smrg else { 7993464ebd5Sriastradh numBytes = 4 * sizeof *v; 8003464ebd5Sriastradh if (bufSize < numBytes) 8013464ebd5Sriastradh goto overflow; 8027117f1b4Smrg v[0] = IROUND(map2d->u1); 8037117f1b4Smrg v[1] = IROUND(map2d->u2); 8047117f1b4Smrg v[2] = IROUND(map2d->v1); 8057117f1b4Smrg v[3] = IROUND(map2d->v2); 8067117f1b4Smrg } 8077117f1b4Smrg break; 8087117f1b4Smrg default: 8097117f1b4Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" ); 8107117f1b4Smrg } 8113464ebd5Sriastradh return; 8123464ebd5Sriastradh 8133464ebd5Sriastradhoverflow: 8143464ebd5Sriastradh _mesa_error( ctx, GL_INVALID_OPERATION, 8153464ebd5Sriastradh "glGetnMapivARB(out of bounds: bufSize is %d," 8163464ebd5Sriastradh " but %d bytes are required)", bufSize, numBytes ); 8177117f1b4Smrg} 8187117f1b4Smrg 8197117f1b4Smrg 8203464ebd5Sriastradhstatic void GLAPIENTRY 8213464ebd5Sriastradh_mesa_GetMapiv( GLenum target, GLenum query, GLint *v ) 8223464ebd5Sriastradh{ 8233464ebd5Sriastradh _mesa_GetnMapivARB(target, query, INT_MAX, v); 8243464ebd5Sriastradh} 8253464ebd5Sriastradh 8267117f1b4Smrg 8274a49301eSmrgstatic void GLAPIENTRY 8287117f1b4Smrg_mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 ) 8297117f1b4Smrg{ 8307117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 8317117f1b4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 8327117f1b4Smrg 8337117f1b4Smrg if (un<1) { 8347117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid1f" ); 8357117f1b4Smrg return; 8367117f1b4Smrg } 8377117f1b4Smrg FLUSH_VERTICES(ctx, _NEW_EVAL); 8387117f1b4Smrg ctx->Eval.MapGrid1un = un; 8397117f1b4Smrg ctx->Eval.MapGrid1u1 = u1; 8407117f1b4Smrg ctx->Eval.MapGrid1u2 = u2; 8417117f1b4Smrg ctx->Eval.MapGrid1du = (u2 - u1) / (GLfloat) un; 8427117f1b4Smrg} 8437117f1b4Smrg 8447117f1b4Smrg 8454a49301eSmrgstatic void GLAPIENTRY 8467117f1b4Smrg_mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 ) 8477117f1b4Smrg{ 8487117f1b4Smrg _mesa_MapGrid1f( un, (GLfloat) u1, (GLfloat) u2 ); 8497117f1b4Smrg} 8507117f1b4Smrg 8517117f1b4Smrg 8524a49301eSmrgstatic void GLAPIENTRY 8537117f1b4Smrg_mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2, 8547117f1b4Smrg GLint vn, GLfloat v1, GLfloat v2 ) 8557117f1b4Smrg{ 8567117f1b4Smrg GET_CURRENT_CONTEXT(ctx); 8577117f1b4Smrg ASSERT_OUTSIDE_BEGIN_END(ctx); 8587117f1b4Smrg 8597117f1b4Smrg if (un<1) { 8607117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" ); 8617117f1b4Smrg return; 8627117f1b4Smrg } 8637117f1b4Smrg if (vn<1) { 8647117f1b4Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(vn)" ); 8657117f1b4Smrg return; 8667117f1b4Smrg } 8677117f1b4Smrg 8687117f1b4Smrg FLUSH_VERTICES(ctx, _NEW_EVAL); 8697117f1b4Smrg ctx->Eval.MapGrid2un = un; 8707117f1b4Smrg ctx->Eval.MapGrid2u1 = u1; 8717117f1b4Smrg ctx->Eval.MapGrid2u2 = u2; 8727117f1b4Smrg ctx->Eval.MapGrid2du = (u2 - u1) / (GLfloat) un; 8737117f1b4Smrg ctx->Eval.MapGrid2vn = vn; 8747117f1b4Smrg ctx->Eval.MapGrid2v1 = v1; 8757117f1b4Smrg ctx->Eval.MapGrid2v2 = v2; 8767117f1b4Smrg ctx->Eval.MapGrid2dv = (v2 - v1) / (GLfloat) vn; 8777117f1b4Smrg} 8787117f1b4Smrg 8797117f1b4Smrg 8804a49301eSmrgstatic void GLAPIENTRY 8817117f1b4Smrg_mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2, 8827117f1b4Smrg GLint vn, GLdouble v1, GLdouble v2 ) 8837117f1b4Smrg{ 8847117f1b4Smrg _mesa_MapGrid2f( un, (GLfloat) u1, (GLfloat) u2, 8857117f1b4Smrg vn, (GLfloat) v1, (GLfloat) v2 ); 8867117f1b4Smrg} 8877117f1b4Smrg 8887117f1b4Smrg 8894a49301eSmrgvoid 8904a49301eSmrg_mesa_install_eval_vtxfmt(struct _glapi_table *disp, 8914a49301eSmrg const GLvertexformat *vfmt) 8924a49301eSmrg{ 8934a49301eSmrg SET_EvalCoord1f(disp, vfmt->EvalCoord1f); 8944a49301eSmrg SET_EvalCoord1fv(disp, vfmt->EvalCoord1fv); 8954a49301eSmrg SET_EvalCoord2f(disp, vfmt->EvalCoord2f); 8964a49301eSmrg SET_EvalCoord2fv(disp, vfmt->EvalCoord2fv); 8974a49301eSmrg SET_EvalPoint1(disp, vfmt->EvalPoint1); 8984a49301eSmrg SET_EvalPoint2(disp, vfmt->EvalPoint2); 8994a49301eSmrg 9004a49301eSmrg SET_EvalMesh1(disp, vfmt->EvalMesh1); 9014a49301eSmrg SET_EvalMesh2(disp, vfmt->EvalMesh2); 9024a49301eSmrg} 9034a49301eSmrg 9044a49301eSmrg 9054a49301eSmrgvoid 9064a49301eSmrg_mesa_init_eval_dispatch(struct _glapi_table *disp) 9074a49301eSmrg{ 9084a49301eSmrg SET_GetMapdv(disp, _mesa_GetMapdv); 9094a49301eSmrg SET_GetMapfv(disp, _mesa_GetMapfv); 9104a49301eSmrg SET_GetMapiv(disp, _mesa_GetMapiv); 9114a49301eSmrg SET_Map1d(disp, _mesa_Map1d); 9124a49301eSmrg SET_Map1f(disp, _mesa_Map1f); 9134a49301eSmrg SET_Map2d(disp, _mesa_Map2d); 9144a49301eSmrg SET_Map2f(disp, _mesa_Map2f); 9154a49301eSmrg SET_MapGrid1d(disp, _mesa_MapGrid1d); 9164a49301eSmrg SET_MapGrid1f(disp, _mesa_MapGrid1f); 9174a49301eSmrg SET_MapGrid2d(disp, _mesa_MapGrid2d); 9184a49301eSmrg SET_MapGrid2f(disp, _mesa_MapGrid2f); 9193464ebd5Sriastradh 9203464ebd5Sriastradh /* GL_ARB_robustness */ 9213464ebd5Sriastradh SET_GetnMapdvARB(disp, _mesa_GetnMapdvARB); 9223464ebd5Sriastradh SET_GetnMapfvARB(disp, _mesa_GetnMapfvARB); 9233464ebd5Sriastradh SET_GetnMapivARB(disp, _mesa_GetnMapivARB); 9244a49301eSmrg} 9254a49301eSmrg 9264a49301eSmrg 9274a49301eSmrg#endif /* FEATURE_evaluators */ 9284a49301eSmrg 9297117f1b4Smrg 9307117f1b4Smrg/**********************************************************************/ 9317117f1b4Smrg/***** Initialization *****/ 9327117f1b4Smrg/**********************************************************************/ 9337117f1b4Smrg 9347117f1b4Smrg/** 9357117f1b4Smrg * Initialize a 1-D evaluator map. 9367117f1b4Smrg */ 9377117f1b4Smrgstatic void 9387117f1b4Smrginit_1d_map( struct gl_1d_map *map, int n, const float *initial ) 9397117f1b4Smrg{ 9407117f1b4Smrg map->Order = 1; 9417117f1b4Smrg map->u1 = 0.0; 9427117f1b4Smrg map->u2 = 1.0; 9437117f1b4Smrg map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat)); 9447117f1b4Smrg if (map->Points) { 9457117f1b4Smrg GLint i; 9467117f1b4Smrg for (i=0;i<n;i++) 9477117f1b4Smrg map->Points[i] = initial[i]; 9487117f1b4Smrg } 9497117f1b4Smrg} 9507117f1b4Smrg 9517117f1b4Smrg 9527117f1b4Smrg/** 9537117f1b4Smrg * Initialize a 2-D evaluator map 9547117f1b4Smrg */ 9557117f1b4Smrgstatic void 9567117f1b4Smrginit_2d_map( struct gl_2d_map *map, int n, const float *initial ) 9577117f1b4Smrg{ 9587117f1b4Smrg map->Uorder = 1; 9597117f1b4Smrg map->Vorder = 1; 9607117f1b4Smrg map->u1 = 0.0; 9617117f1b4Smrg map->u2 = 1.0; 9627117f1b4Smrg map->v1 = 0.0; 9637117f1b4Smrg map->v2 = 1.0; 9647117f1b4Smrg map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat)); 9657117f1b4Smrg if (map->Points) { 9667117f1b4Smrg GLint i; 9677117f1b4Smrg for (i=0;i<n;i++) 9687117f1b4Smrg map->Points[i] = initial[i]; 9697117f1b4Smrg } 9707117f1b4Smrg} 9717117f1b4Smrg 9727117f1b4Smrg 9733464ebd5Sriastradhvoid _mesa_init_eval( struct gl_context *ctx ) 9747117f1b4Smrg{ 9757117f1b4Smrg int i; 9767117f1b4Smrg 9777117f1b4Smrg /* Evaluators group */ 9787117f1b4Smrg ctx->Eval.Map1Color4 = GL_FALSE; 9797117f1b4Smrg ctx->Eval.Map1Index = GL_FALSE; 9807117f1b4Smrg ctx->Eval.Map1Normal = GL_FALSE; 9817117f1b4Smrg ctx->Eval.Map1TextureCoord1 = GL_FALSE; 9827117f1b4Smrg ctx->Eval.Map1TextureCoord2 = GL_FALSE; 9837117f1b4Smrg ctx->Eval.Map1TextureCoord3 = GL_FALSE; 9847117f1b4Smrg ctx->Eval.Map1TextureCoord4 = GL_FALSE; 9857117f1b4Smrg ctx->Eval.Map1Vertex3 = GL_FALSE; 9867117f1b4Smrg ctx->Eval.Map1Vertex4 = GL_FALSE; 987cdc920a0Smrg memset(ctx->Eval.Map1Attrib, 0, sizeof(ctx->Eval.Map1Attrib)); 9887117f1b4Smrg ctx->Eval.Map2Color4 = GL_FALSE; 9897117f1b4Smrg ctx->Eval.Map2Index = GL_FALSE; 9907117f1b4Smrg ctx->Eval.Map2Normal = GL_FALSE; 9917117f1b4Smrg ctx->Eval.Map2TextureCoord1 = GL_FALSE; 9927117f1b4Smrg ctx->Eval.Map2TextureCoord2 = GL_FALSE; 9937117f1b4Smrg ctx->Eval.Map2TextureCoord3 = GL_FALSE; 9947117f1b4Smrg ctx->Eval.Map2TextureCoord4 = GL_FALSE; 9957117f1b4Smrg ctx->Eval.Map2Vertex3 = GL_FALSE; 9967117f1b4Smrg ctx->Eval.Map2Vertex4 = GL_FALSE; 997cdc920a0Smrg memset(ctx->Eval.Map2Attrib, 0, sizeof(ctx->Eval.Map2Attrib)); 9987117f1b4Smrg ctx->Eval.AutoNormal = GL_FALSE; 9997117f1b4Smrg ctx->Eval.MapGrid1un = 1; 10007117f1b4Smrg ctx->Eval.MapGrid1u1 = 0.0; 10017117f1b4Smrg ctx->Eval.MapGrid1u2 = 1.0; 10027117f1b4Smrg ctx->Eval.MapGrid2un = 1; 10037117f1b4Smrg ctx->Eval.MapGrid2vn = 1; 10047117f1b4Smrg ctx->Eval.MapGrid2u1 = 0.0; 10057117f1b4Smrg ctx->Eval.MapGrid2u2 = 1.0; 10067117f1b4Smrg ctx->Eval.MapGrid2v1 = 0.0; 10077117f1b4Smrg ctx->Eval.MapGrid2v2 = 1.0; 10087117f1b4Smrg 10097117f1b4Smrg /* Evaluator data */ 10107117f1b4Smrg { 10117117f1b4Smrg static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 }; 10127117f1b4Smrg static GLfloat normal[3] = { 0.0, 0.0, 1.0 }; 10137117f1b4Smrg static GLfloat index[1] = { 1.0 }; 10147117f1b4Smrg static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 }; 10157117f1b4Smrg static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 }; 10167117f1b4Smrg static GLfloat attrib[4] = { 0.0, 0.0, 0.0, 1.0 }; 10177117f1b4Smrg 10187117f1b4Smrg init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex ); 10197117f1b4Smrg init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex ); 10207117f1b4Smrg init_1d_map( &ctx->EvalMap.Map1Index, 1, index ); 10217117f1b4Smrg init_1d_map( &ctx->EvalMap.Map1Color4, 4, color ); 10227117f1b4Smrg init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal ); 10237117f1b4Smrg init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord ); 10247117f1b4Smrg init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord ); 10257117f1b4Smrg init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord ); 10267117f1b4Smrg init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord ); 10277117f1b4Smrg for (i = 0; i < 16; i++) 10287117f1b4Smrg init_1d_map( ctx->EvalMap.Map1Attrib + i, 4, attrib ); 10297117f1b4Smrg 10307117f1b4Smrg init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex ); 10317117f1b4Smrg init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex ); 10327117f1b4Smrg init_2d_map( &ctx->EvalMap.Map2Index, 1, index ); 10337117f1b4Smrg init_2d_map( &ctx->EvalMap.Map2Color4, 4, color ); 10347117f1b4Smrg init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal ); 10357117f1b4Smrg init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord ); 10367117f1b4Smrg init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord ); 10377117f1b4Smrg init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord ); 10387117f1b4Smrg init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord ); 10397117f1b4Smrg for (i = 0; i < 16; i++) 10407117f1b4Smrg init_2d_map( ctx->EvalMap.Map2Attrib + i, 4, attrib ); 10417117f1b4Smrg } 10427117f1b4Smrg} 10437117f1b4Smrg 10447117f1b4Smrg 10453464ebd5Sriastradhvoid _mesa_free_eval_data( struct gl_context *ctx ) 10467117f1b4Smrg{ 10477117f1b4Smrg int i; 10487117f1b4Smrg 10497117f1b4Smrg /* Free evaluator data */ 10507117f1b4Smrg if (ctx->EvalMap.Map1Vertex3.Points) 10517117f1b4Smrg FREE( ctx->EvalMap.Map1Vertex3.Points ); 10527117f1b4Smrg if (ctx->EvalMap.Map1Vertex4.Points) 10537117f1b4Smrg FREE( ctx->EvalMap.Map1Vertex4.Points ); 10547117f1b4Smrg if (ctx->EvalMap.Map1Index.Points) 10557117f1b4Smrg FREE( ctx->EvalMap.Map1Index.Points ); 10567117f1b4Smrg if (ctx->EvalMap.Map1Color4.Points) 10577117f1b4Smrg FREE( ctx->EvalMap.Map1Color4.Points ); 10587117f1b4Smrg if (ctx->EvalMap.Map1Normal.Points) 10597117f1b4Smrg FREE( ctx->EvalMap.Map1Normal.Points ); 10607117f1b4Smrg if (ctx->EvalMap.Map1Texture1.Points) 10617117f1b4Smrg FREE( ctx->EvalMap.Map1Texture1.Points ); 10627117f1b4Smrg if (ctx->EvalMap.Map1Texture2.Points) 10637117f1b4Smrg FREE( ctx->EvalMap.Map1Texture2.Points ); 10647117f1b4Smrg if (ctx->EvalMap.Map1Texture3.Points) 10657117f1b4Smrg FREE( ctx->EvalMap.Map1Texture3.Points ); 10667117f1b4Smrg if (ctx->EvalMap.Map1Texture4.Points) 10677117f1b4Smrg FREE( ctx->EvalMap.Map1Texture4.Points ); 10687117f1b4Smrg for (i = 0; i < 16; i++) 10697117f1b4Smrg FREE((ctx->EvalMap.Map1Attrib[i].Points)); 10707117f1b4Smrg 10717117f1b4Smrg if (ctx->EvalMap.Map2Vertex3.Points) 10727117f1b4Smrg FREE( ctx->EvalMap.Map2Vertex3.Points ); 10737117f1b4Smrg if (ctx->EvalMap.Map2Vertex4.Points) 10747117f1b4Smrg FREE( ctx->EvalMap.Map2Vertex4.Points ); 10757117f1b4Smrg if (ctx->EvalMap.Map2Index.Points) 10767117f1b4Smrg FREE( ctx->EvalMap.Map2Index.Points ); 10777117f1b4Smrg if (ctx->EvalMap.Map2Color4.Points) 10787117f1b4Smrg FREE( ctx->EvalMap.Map2Color4.Points ); 10797117f1b4Smrg if (ctx->EvalMap.Map2Normal.Points) 10807117f1b4Smrg FREE( ctx->EvalMap.Map2Normal.Points ); 10817117f1b4Smrg if (ctx->EvalMap.Map2Texture1.Points) 10827117f1b4Smrg FREE( ctx->EvalMap.Map2Texture1.Points ); 10837117f1b4Smrg if (ctx->EvalMap.Map2Texture2.Points) 10847117f1b4Smrg FREE( ctx->EvalMap.Map2Texture2.Points ); 10857117f1b4Smrg if (ctx->EvalMap.Map2Texture3.Points) 10867117f1b4Smrg FREE( ctx->EvalMap.Map2Texture3.Points ); 10877117f1b4Smrg if (ctx->EvalMap.Map2Texture4.Points) 10887117f1b4Smrg FREE( ctx->EvalMap.Map2Texture4.Points ); 10897117f1b4Smrg for (i = 0; i < 16; i++) 10907117f1b4Smrg FREE((ctx->EvalMap.Map2Attrib[i].Points)); 10917117f1b4Smrg} 1092