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

  1. /* $Id: varray.c,v 1.47 2002/10/24 23:57:21 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27. #include "glheader.h"
  28. #include "context.h"
  29. #include "enable.h"
  30. #include "enums.h"
  31. #include "dlist.h"
  32. #include "light.h"
  33. #include "macros.h"
  34. #include "mmath.h"
  35. #include "state.h"
  36. #include "texstate.h"
  37. #include "mtypes.h"
  38. #include "varray.h"
  39. #include "math/m_translate.h"
  40.  
  41.  
  42.  
  43. void
  44. _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
  45. {
  46.    GET_CURRENT_CONTEXT(ctx);
  47.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  48.  
  49.    if (size < 2 || size > 4) {
  50.       _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
  51.       return;
  52.    }
  53.    if (stride < 0) {
  54.       _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
  55.       return;
  56.    }
  57.  
  58.    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
  59.       _mesa_debug(ctx, "glVertexPointer( sz %d type %s stride %d )\n", size,
  60.                   _mesa_lookup_enum_by_nr( type ), stride);
  61.  
  62.    /* always need to check that <type> is legal */
  63.    switch (type) {
  64.       case GL_SHORT:
  65.          ctx->Array.Vertex.StrideB = size * sizeof(GLshort);
  66.          break;
  67.       case GL_INT:
  68.          ctx->Array.Vertex.StrideB = size * sizeof(GLint);
  69.          break;
  70.       case GL_FLOAT:
  71.          ctx->Array.Vertex.StrideB = size * sizeof(GLfloat);
  72.          break;
  73.       case GL_DOUBLE:
  74.          ctx->Array.Vertex.StrideB = size * sizeof(GLdouble);
  75.          break;
  76.       default:
  77.          _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
  78.          return;
  79.    }
  80.  
  81.    if (stride)
  82.       ctx->Array.Vertex.StrideB = stride;
  83.  
  84.    ctx->Array.Vertex.Size = size;
  85.    ctx->Array.Vertex.Type = type;
  86.    ctx->Array.Vertex.Stride = stride;
  87.    ctx->Array.Vertex.Ptr = (void *) ptr;
  88.    ctx->NewState |= _NEW_ARRAY;
  89.    ctx->Array.NewState |= _NEW_ARRAY_VERTEX;
  90.  
  91.    if (ctx->Driver.VertexPointer)
  92.       ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );
  93. }
  94.  
  95.  
  96.  
  97.  
  98. void
  99. _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
  100. {
  101.    GET_CURRENT_CONTEXT(ctx);
  102.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  103.  
  104.    if (stride < 0) {
  105.       _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
  106.       return;
  107.    }
  108.  
  109.    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
  110.       _mesa_debug(ctx, "glNormalPointer( type %s stride %d )\n",
  111.                   _mesa_lookup_enum_by_nr( type ), stride);
  112.  
  113.    switch (type) {
  114.       case GL_BYTE:
  115.          ctx->Array.Normal.StrideB = 3 * sizeof(GLbyte);
  116.          break;
  117.       case GL_SHORT:
  118.          ctx->Array.Normal.StrideB = 3 * sizeof(GLshort);
  119.          break;
  120.       case GL_INT:
  121.          ctx->Array.Normal.StrideB = 3 * sizeof(GLint);
  122.          break;
  123.       case GL_FLOAT:
  124.          ctx->Array.Normal.StrideB = 3 * sizeof(GLfloat);
  125.          break;
  126.       case GL_DOUBLE:
  127.          ctx->Array.Normal.StrideB = 3 * sizeof(GLdouble);
  128.          break;
  129.       default:
  130.          _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
  131.          return;
  132.    }
  133.    if (stride)
  134.       ctx->Array.Normal.StrideB = stride;
  135.  
  136.    ctx->Array.Normal.Size = 3;
  137.    ctx->Array.Normal.Type = type;
  138.    ctx->Array.Normal.Stride = stride;
  139.    ctx->Array.Normal.Ptr = (void *) ptr;
  140.    ctx->NewState |= _NEW_ARRAY;
  141.    ctx->Array.NewState |= _NEW_ARRAY_NORMAL;
  142.  
  143.    if (ctx->Driver.NormalPointer)
  144.       ctx->Driver.NormalPointer( ctx, type, stride, ptr );
  145. }
  146.  
  147.  
  148.  
  149. void
  150. _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
  151. {
  152.    GET_CURRENT_CONTEXT(ctx);
  153.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  154.  
  155.    if (size < 3 || size > 4) {
  156.       _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
  157.       return;
  158.    }
  159.    if (stride<0) {
  160.       _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
  161.       return;
  162.    }
  163.  
  164.    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
  165.       _mesa_debug(ctx, "glColorPointer( sz %d type %s stride %d )\n", size,
  166.                   _mesa_lookup_enum_by_nr( type ), stride);
  167.  
  168.    switch (type) {
  169.       case GL_BYTE:
  170.          ctx->Array.Color.StrideB = size * sizeof(GLbyte);
  171.          break;
  172.       case GL_UNSIGNED_BYTE:
  173.          ctx->Array.Color.StrideB = size * sizeof(GLubyte);
  174.          break;
  175.       case GL_SHORT:
  176.          ctx->Array.Color.StrideB = size * sizeof(GLshort);
  177.          break;
  178.       case GL_UNSIGNED_SHORT:
  179.          ctx->Array.Color.StrideB = size * sizeof(GLushort);
  180.          break;
  181.       case GL_INT:
  182.          ctx->Array.Color.StrideB = size * sizeof(GLint);
  183.          break;
  184.       case GL_UNSIGNED_INT:
  185.          ctx->Array.Color.StrideB = size * sizeof(GLuint);
  186.          break;
  187.       case GL_FLOAT:
  188.          ctx->Array.Color.StrideB = size * sizeof(GLfloat);
  189.          break;
  190.       case GL_DOUBLE:
  191.          ctx->Array.Color.StrideB = size * sizeof(GLdouble);
  192.          break;
  193.       default:
  194.          _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
  195.          return;
  196.    }
  197.  
  198.    if (stride)
  199.       ctx->Array.Color.StrideB = stride;
  200.  
  201.    ctx->Array.Color.Size = size;
  202.    ctx->Array.Color.Type = type;
  203.    ctx->Array.Color.Stride = stride;
  204.    ctx->Array.Color.Ptr = (void *) ptr;
  205.    ctx->NewState |= _NEW_ARRAY;
  206.    ctx->Array.NewState |= _NEW_ARRAY_COLOR0;
  207.  
  208.    if (ctx->Driver.ColorPointer)
  209.       ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
  210. }
  211.  
  212.  
  213.  
  214. void
  215. _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
  216. {
  217.    GET_CURRENT_CONTEXT(ctx);
  218.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  219.  
  220.    if (stride < 0) {
  221.       _mesa_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" );
  222.       return;
  223.    }
  224.  
  225.    switch (type) {
  226.       case GL_FLOAT:
  227.          ctx->Array.FogCoord.StrideB =  sizeof(GLfloat);
  228.          break;
  229.       case GL_DOUBLE:
  230.          ctx->Array.FogCoord.StrideB =  sizeof(GLdouble);
  231.          break;
  232.       default:
  233.          _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" );
  234.          return;
  235.    }
  236.  
  237.    if (stride)
  238.       ctx->Array.FogCoord.StrideB = stride;
  239.  
  240.    ctx->Array.FogCoord.Size = 1;
  241.    ctx->Array.FogCoord.Type = type;
  242.    ctx->Array.FogCoord.Stride = stride;
  243.    ctx->Array.FogCoord.Ptr = (void *) ptr;
  244.    ctx->NewState |= _NEW_ARRAY;
  245.    ctx->Array.NewState |= _NEW_ARRAY_FOGCOORD;
  246.  
  247.    if (ctx->Driver.FogCoordPointer)
  248.       ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );
  249. }
  250.  
  251.  
  252. void
  253. _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
  254. {
  255.    GET_CURRENT_CONTEXT(ctx);
  256.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  257.  
  258.    if (stride < 0) {
  259.       _mesa_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
  260.       return;
  261.    }
  262.  
  263.    switch (type) {
  264.       case GL_UNSIGNED_BYTE:
  265.          ctx->Array.Index.StrideB =  sizeof(GLubyte);
  266.          break;
  267.       case GL_SHORT:
  268.          ctx->Array.Index.StrideB =  sizeof(GLshort);
  269.          break;
  270.       case GL_INT:
  271.          ctx->Array.Index.StrideB =  sizeof(GLint);
  272.          break;
  273.       case GL_FLOAT:
  274.          ctx->Array.Index.StrideB =  sizeof(GLfloat);
  275.          break;
  276.       case GL_DOUBLE:
  277.          ctx->Array.Index.StrideB =  sizeof(GLdouble);
  278.          break;
  279.       default:
  280.          _mesa_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
  281.          return;
  282.    }
  283.  
  284.    if (stride)
  285.       ctx->Array.Index.StrideB = stride;
  286.  
  287.    ctx->Array.Index.Size = 1;
  288.    ctx->Array.Index.Type = type;
  289.    ctx->Array.Index.Stride = stride;
  290.    ctx->Array.Index.Ptr = (void *) ptr;
  291.    ctx->NewState |= _NEW_ARRAY;
  292.    ctx->Array.NewState |= _NEW_ARRAY_INDEX;
  293.  
  294.    if (ctx->Driver.IndexPointer)
  295.       ctx->Driver.IndexPointer( ctx, type, stride, ptr );
  296. }
  297.  
  298.  
  299. void
  300. _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
  301.                    GLsizei stride, const GLvoid *ptr)
  302. {
  303.    GET_CURRENT_CONTEXT(ctx);
  304.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  305.  
  306.    if (size != 3 && size != 4) {
  307.       _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(size)" );
  308.       return;
  309.    }
  310.    if (stride < 0) {
  311.       _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(stride)" );
  312.       return;
  313.    }
  314.  
  315.    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
  316.       _mesa_debug(ctx, "glSecondaryColorPointer( sz %d type %s stride %d )\n",
  317.                   size, _mesa_lookup_enum_by_nr( type ), stride);
  318.  
  319.    switch (type) {
  320.       case GL_BYTE:
  321.          ctx->Array.SecondaryColor.StrideB = size * sizeof(GLbyte);
  322.          break;
  323.       case GL_UNSIGNED_BYTE:
  324.          ctx->Array.SecondaryColor.StrideB = size * sizeof(GLubyte);
  325.          break;
  326.       case GL_SHORT:
  327.          ctx->Array.SecondaryColor.StrideB = size * sizeof(GLshort);
  328.          break;
  329.       case GL_UNSIGNED_SHORT:
  330.          ctx->Array.SecondaryColor.StrideB = size * sizeof(GLushort);
  331.          break;
  332.       case GL_INT:
  333.          ctx->Array.SecondaryColor.StrideB = size * sizeof(GLint);
  334.          break;
  335.       case GL_UNSIGNED_INT:
  336.          ctx->Array.SecondaryColor.StrideB = size * sizeof(GLuint);
  337.          break;
  338.       case GL_FLOAT:
  339.          ctx->Array.SecondaryColor.StrideB = size * sizeof(GLfloat);
  340.          break;
  341.       case GL_DOUBLE:
  342.          ctx->Array.SecondaryColor.StrideB = size * sizeof(GLdouble);
  343.          break;
  344.       default:
  345.          _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
  346.          return;
  347.    }
  348.  
  349.    if (stride)
  350.       ctx->Array.SecondaryColor.StrideB = stride;
  351.  
  352.    ctx->Array.SecondaryColor.Size = 3; /* hardwire */
  353.    ctx->Array.SecondaryColor.Type = type;
  354.    ctx->Array.SecondaryColor.Stride = stride;
  355.    ctx->Array.SecondaryColor.Ptr = (void *) ptr;
  356.    ctx->NewState |= _NEW_ARRAY;
  357.    ctx->Array.NewState |= _NEW_ARRAY_COLOR1;
  358.  
  359.    if (ctx->Driver.SecondaryColorPointer)
  360.       ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
  361. }
  362.  
  363.  
  364.  
  365. void
  366. _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
  367.                       const GLvoid *ptr)
  368. {
  369.    GET_CURRENT_CONTEXT(ctx);
  370.    GLuint texUnit = ctx->Array.ActiveTexture;
  371.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  372.  
  373.    if (size < 1 || size > 4) {
  374.       _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
  375.       return;
  376.    }
  377.    if (stride < 0) {
  378.       _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
  379.       return;
  380.    }
  381.  
  382.    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
  383.       _mesa_debug(ctx, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n",
  384.                   texUnit, size, _mesa_lookup_enum_by_nr( type ), stride);
  385.  
  386.    /* always need to check that <type> is legal */
  387.    switch (type) {
  388.       case GL_SHORT:
  389.          ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLshort);
  390.          break;
  391.       case GL_INT:
  392.          ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLint);
  393.          break;
  394.       case GL_FLOAT:
  395.          ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLfloat);
  396.          break;
  397.       case GL_DOUBLE:
  398.          ctx->Array.TexCoord[texUnit].StrideB = size * sizeof(GLdouble);
  399.          break;
  400.       default:
  401.          _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
  402.          return;
  403.    }
  404.  
  405.    if (stride)
  406.       ctx->Array.TexCoord[texUnit].StrideB = stride;
  407.  
  408.    ctx->Array.TexCoord[texUnit].Size = size;
  409.    ctx->Array.TexCoord[texUnit].Type = type;
  410.    ctx->Array.TexCoord[texUnit].Stride = stride;
  411.    ctx->Array.TexCoord[texUnit].Ptr = (void *) ptr;
  412.    ctx->NewState |= _NEW_ARRAY;
  413.    ctx->Array.NewState |= _NEW_ARRAY_TEXCOORD(texUnit);
  414.  
  415.    if (ctx->Driver.TexCoordPointer)
  416.       ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
  417. }
  418.  
  419.  
  420. void
  421. _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *vptr)
  422. {
  423.    GET_CURRENT_CONTEXT(ctx);
  424.    const GLboolean *ptr = (GLboolean *)vptr;
  425.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  426.  
  427.    if (stride<0) {
  428.       _mesa_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
  429.       return;
  430.    }
  431.    ctx->Array.EdgeFlag.Stride = stride;
  432.    ctx->Array.EdgeFlag.StrideB = stride ? stride : sizeof(GLboolean);
  433.    ctx->Array.EdgeFlag.Ptr = (GLboolean *) ptr;
  434.    ctx->NewState |= _NEW_ARRAY;
  435.    ctx->Array.NewState |= _NEW_ARRAY_EDGEFLAG;
  436.  
  437.    if (ctx->Driver.EdgeFlagPointer)
  438.       ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
  439. }
  440.  
  441.  
  442. void _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
  443.                                  GLsizei stride, const GLvoid *ptr)
  444. {
  445.    GET_CURRENT_CONTEXT(ctx);
  446.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  447.  
  448.    if (index >= VERT_ATTRIB_MAX) {
  449.       _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
  450.       return;
  451.    }
  452.  
  453.    if (size < 1 || size > 4) {
  454.       _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size)");
  455.       return;
  456.    }
  457.  
  458.    if (stride < 0) {
  459.       _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(stride)");
  460.       return;
  461.    }
  462.  
  463.    if (type == GL_UNSIGNED_BYTE && size != 4) {
  464.       _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)");
  465.       return;
  466.    }
  467.  
  468.    /* check for valid 'type' and compute StrideB right away */
  469.    switch (type) {
  470.       case GL_UNSIGNED_BYTE:
  471.          ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLubyte);
  472.          break;
  473.       case GL_SHORT:
  474.          ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLshort);
  475.          break;
  476.       case GL_FLOAT:
  477.          ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLfloat);
  478.          break;
  479.       case GL_DOUBLE:
  480.          ctx->Array.VertexAttrib[index].StrideB = size * sizeof(GLdouble);
  481.          break;
  482.       default:
  483.          _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" );
  484.          return;
  485.    }
  486.  
  487.    if (stride)
  488.       ctx->Array.VertexAttrib[index].StrideB = stride;
  489.  
  490.    ctx->Array.VertexAttrib[index].Stride = stride;
  491.    ctx->Array.VertexAttrib[index].Size = size;
  492.    ctx->Array.VertexAttrib[index].Type = type;
  493.    ctx->Array.VertexAttrib[index].Ptr = (void *) ptr;
  494.  
  495.    ctx->NewState |= _NEW_ARRAY;
  496.    ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
  497.  
  498.    if (ctx->Driver.VertexAttribPointer)
  499.       ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
  500. }
  501.  
  502.  
  503. void
  504. _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
  505.                        GLsizei count, const GLvoid *ptr)
  506. {
  507.    (void) count;
  508.    _mesa_VertexPointer(size, type, stride, ptr);
  509. }
  510.  
  511.  
  512. void
  513. _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
  514.                        const GLvoid *ptr)
  515. {
  516.    (void) count;
  517.    _mesa_NormalPointer(type, stride, ptr);
  518. }
  519.  
  520.  
  521. void
  522. _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
  523.                       const GLvoid *ptr)
  524. {
  525.    (void) count;
  526.    _mesa_ColorPointer(size, type, stride, ptr);
  527. }
  528.  
  529.  
  530. void
  531. _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
  532.                       const GLvoid *ptr)
  533. {
  534.    (void) count;
  535.    _mesa_IndexPointer(type, stride, ptr);
  536. }
  537.  
  538.  
  539. void
  540. _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
  541.                          GLsizei count, const GLvoid *ptr)
  542. {
  543.    (void) count;
  544.    _mesa_TexCoordPointer(size, type, stride, ptr);
  545. }
  546.  
  547.  
  548. void
  549. _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
  550. {
  551.    (void) count;
  552.    _mesa_EdgeFlagPointer(stride, ptr);
  553. }
  554.  
  555.  
  556.  
  557.  
  558. void
  559. _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
  560. {
  561.    GET_CURRENT_CONTEXT(ctx);
  562.    GLboolean tflag, cflag, nflag;  /* enable/disable flags */
  563.    GLint tcomps, ccomps, vcomps;   /* components per texcoord, color, vertex */
  564.  
  565.    GLenum ctype = 0;               /* color type */
  566.    GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
  567.    GLint defstride;                /* default stride */
  568.    GLint c, f;
  569.    GLint coordUnitSave;
  570.  
  571.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  572.  
  573.    f = sizeof(GLfloat);
  574.    c = f * ((4*sizeof(GLubyte) + (f-1)) / f);
  575.  
  576.    if (stride<0) {
  577.       _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
  578.       return;
  579.    }
  580.  
  581.    switch (format) {
  582.       case GL_V2F:
  583.          tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  584.          tcomps = 0;  ccomps = 0;  vcomps = 2;
  585.          voffset = 0;
  586.          defstride = 2*f;
  587.          break;
  588.       case GL_V3F:
  589.          tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  590.          tcomps = 0;  ccomps = 0;  vcomps = 3;
  591.          voffset = 0;
  592.          defstride = 3*f;
  593.          break;
  594.       case GL_C4UB_V2F:
  595.          tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  596.          tcomps = 0;  ccomps = 4;  vcomps = 2;
  597.          ctype = GL_UNSIGNED_BYTE;
  598.          coffset = 0;
  599.          voffset = c;
  600.          defstride = c + 2*f;
  601.          break;
  602.       case GL_C4UB_V3F:
  603.          tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  604.          tcomps = 0;  ccomps = 4;  vcomps = 3;
  605.          ctype = GL_UNSIGNED_BYTE;
  606.          coffset = 0;
  607.          voffset = c;
  608.          defstride = c + 3*f;
  609.          break;
  610.       case GL_C3F_V3F:
  611.          tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  612.          tcomps = 0;  ccomps = 3;  vcomps = 3;
  613.          ctype = GL_FLOAT;
  614.          coffset = 0;
  615.          voffset = 3*f;
  616.          defstride = 6*f;
  617.          break;
  618.       case GL_N3F_V3F:
  619.          tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_TRUE;
  620.          tcomps = 0;  ccomps = 0;  vcomps = 3;
  621.          noffset = 0;
  622.          voffset = 3*f;
  623.          defstride = 6*f;
  624.          break;
  625.       case GL_C4F_N3F_V3F:
  626.          tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_TRUE;
  627.          tcomps = 0;  ccomps = 4;  vcomps = 3;
  628.          ctype = GL_FLOAT;
  629.          coffset = 0;
  630.          noffset = 4*f;
  631.          voffset = 7*f;
  632.          defstride = 10*f;
  633.          break;
  634.       case GL_T2F_V3F:
  635.          tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  636.          tcomps = 2;  ccomps = 0;  vcomps = 3;
  637.          voffset = 2*f;
  638.          defstride = 5*f;
  639.          break;
  640.       case GL_T4F_V4F:
  641.          tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  642.          tcomps = 4;  ccomps = 0;  vcomps = 4;
  643.          voffset = 4*f;
  644.          defstride = 8*f;
  645.          break;
  646.       case GL_T2F_C4UB_V3F:
  647.          tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  648.          tcomps = 2;  ccomps = 4;  vcomps = 3;
  649.          ctype = GL_UNSIGNED_BYTE;
  650.          coffset = 2*f;
  651.          voffset = c+2*f;
  652.          defstride = c+5*f;
  653.          break;
  654.       case GL_T2F_C3F_V3F:
  655.          tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  656.          tcomps = 2;  ccomps = 3;  vcomps = 3;
  657.          ctype = GL_FLOAT;
  658.          coffset = 2*f;
  659.          voffset = 5*f;
  660.          defstride = 8*f;
  661.          break;
  662.       case GL_T2F_N3F_V3F:
  663.          tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_TRUE;
  664.          tcomps = 2;  ccomps = 0;  vcomps = 3;
  665.          noffset = 2*f;
  666.          voffset = 5*f;
  667.          defstride = 8*f;
  668.          break;
  669.       case GL_T2F_C4F_N3F_V3F:
  670.          tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
  671.          tcomps = 2;  ccomps = 4;  vcomps = 3;
  672.          ctype = GL_FLOAT;
  673.          coffset = 2*f;
  674.          noffset = 6*f;
  675.          voffset = 9*f;
  676.          defstride = 12*f;
  677.          break;
  678.       case GL_T4F_C4F_N3F_V4F:
  679.          tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
  680.          tcomps = 4;  ccomps = 4;  vcomps = 4;
  681.          ctype = GL_FLOAT;
  682.          coffset = 4*f;
  683.          noffset = 8*f;
  684.          voffset = 11*f;
  685.          defstride = 15*f;
  686.          break;
  687.       default:
  688.          _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
  689.          return;
  690.    }
  691.  
  692.    if (stride==0) {
  693.       stride = defstride;
  694.    }
  695.  
  696.    _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
  697.    _mesa_DisableClientState( GL_INDEX_ARRAY );
  698.  
  699.    /* Texcoords */
  700.    coordUnitSave = ctx->Array.ActiveTexture;
  701.    if (tflag) {
  702.       GLint i;
  703.       GLint factor = ctx->Array.TexCoordInterleaveFactor;
  704.       for (i = 0; i < factor; i++) {
  705.          _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
  706.          _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
  707.          _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
  708.                 (GLubyte *) pointer + i * coffset );
  709.       }
  710.       for (i = factor; i < (GLint) ctx->Const.MaxTextureUnits; i++) {
  711.          _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
  712.          _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
  713.       }
  714.    }
  715.    else {
  716.       GLint i;
  717.       for (i = 0; i < (GLint) ctx->Const.MaxTextureUnits; i++) {
  718.          _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) );
  719.          _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
  720.       }
  721.    }
  722.    /* Restore texture coordinate unit index */
  723.    _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + coordUnitSave) );
  724.  
  725.  
  726.    /* Color */
  727.    if (cflag) {
  728.       _mesa_EnableClientState( GL_COLOR_ARRAY );
  729.       _mesa_ColorPointer( ccomps, ctype, stride,
  730.               (GLubyte*) pointer + coffset );
  731.    }
  732.    else {
  733.       _mesa_DisableClientState( GL_COLOR_ARRAY );
  734.    }
  735.  
  736.  
  737.    /* Normals */
  738.    if (nflag) {
  739.       _mesa_EnableClientState( GL_NORMAL_ARRAY );
  740.       _mesa_NormalPointer( GL_FLOAT, stride,
  741.                (GLubyte*) pointer + noffset );
  742.    }
  743.    else {
  744.       _mesa_DisableClientState( GL_NORMAL_ARRAY );
  745.    }
  746.  
  747.    _mesa_EnableClientState( GL_VERTEX_ARRAY );
  748.    _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
  749.             (GLubyte *) pointer + voffset );
  750. }
  751.  
  752.  
  753.  
  754. void
  755. _mesa_LockArraysEXT(GLint first, GLsizei count)
  756. {
  757.    GET_CURRENT_CONTEXT(ctx);
  758.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  759.  
  760.    if (MESA_VERBOSE & VERBOSE_API)
  761.       _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
  762.  
  763.    if (first == 0 && count > 0 &&
  764.        count <= (GLint) ctx->Const.MaxArrayLockSize) {
  765.       ctx->Array.LockFirst = first;
  766.       ctx->Array.LockCount = count;
  767.    }
  768.    else {
  769.       ctx->Array.LockFirst = 0;
  770.       ctx->Array.LockCount = 0;
  771.    }
  772.  
  773.    ctx->NewState |= _NEW_ARRAY;
  774.    ctx->Array.NewState |= _NEW_ARRAY_ALL;
  775.  
  776.    if (ctx->Driver.LockArraysEXT)
  777.       ctx->Driver.LockArraysEXT( ctx, first, count );
  778. }
  779.  
  780.  
  781. void
  782. _mesa_UnlockArraysEXT( void )
  783. {
  784.    GET_CURRENT_CONTEXT(ctx);
  785.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  786.  
  787.    if (MESA_VERBOSE & VERBOSE_API)
  788.       _mesa_debug(ctx, "glUnlockArrays\n");
  789.  
  790.    ctx->Array.LockFirst = 0;
  791.    ctx->Array.LockCount = 0;
  792.    ctx->NewState |= _NEW_ARRAY;
  793.    ctx->Array.NewState |= _NEW_ARRAY_ALL;
  794.  
  795.    if (ctx->Driver.UnlockArraysEXT)
  796.       ctx->Driver.UnlockArraysEXT( ctx );
  797. }
  798.  
  799.  
  800.  
  801. /* GL_EXT_multi_draw_arrays */
  802. /* Somebody forgot to spec the first and count parameters as const! <sigh> */
  803. void
  804. _mesa_MultiDrawArraysEXT( GLenum mode, GLint *first,
  805.                           GLsizei *count, GLsizei primcount )
  806. {
  807.    GET_CURRENT_CONTEXT(ctx);
  808.    GLint i;
  809.  
  810.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  811.  
  812.    for (i = 0; i < primcount; i++) {
  813.       if (count[i] > 0) {
  814.          (ctx->Exec->DrawArrays)(mode, first[i], count[i]);
  815.       }
  816.    }
  817. }
  818.  
  819.  
  820. /* GL_EXT_multi_draw_arrays */
  821. void
  822. _mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
  823.                             const GLvoid **indices, GLsizei primcount )
  824. {
  825.    GET_CURRENT_CONTEXT(ctx);
  826.    GLint i;
  827.  
  828.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  829.  
  830.    for (i = 0; i < primcount; i++) {
  831.       if (count[i] > 0) {
  832.          (ctx->Exec->DrawElements)(mode, count[i], type, indices[i]);
  833.       }
  834.    }
  835. }
  836.