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:  3.5
  5.  *
  6.  * Copyright (C) 1999-2001  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.  * New (3.1) transformation code written by Keith Whitwell.
  28.  */
  29.  
  30.  
  31. /*----------------------------------------------------------------------
  32.  * Begin Keith's new code
  33.  *
  34.  *----------------------------------------------------------------------
  35.  */
  36.  
  37. /* KW: Fixed stride, now measured in bytes as is the OpenGL array stride.
  38.  */
  39.  
  40. /* KW: These are now parameterized to produce two versions, one
  41.  *     which transforms all incoming points, and a second which
  42.  *     takes notice of a cullmask array, and only transforms
  43.  *     unculled vertices.
  44.  */
  45.  
  46. /* KW: 1-vectors can sneak into the texture pipeline via the array
  47.  *     interface.  These functions are here because I want consistant
  48.  *     treatment of the vertex sizes and a lazy strategy for
  49.  *     cleaning unused parts of the vector, and so as not to exclude
  50.  *     them from the vertex array interface.
  51.  *
  52.  *     Under our current analysis of matrices, there is no way that
  53.  *     the product of a matrix and a 1-vector can remain a 1-vector,
  54.  *     with the exception of the identity transform.
  55.  */
  56.  
  57. /* KW: No longer zero-pad outgoing vectors.  Now that external
  58.  *     vectors can get into the pipeline we cannot ever assume
  59.  *     that there is more to a vector than indicated by its
  60.  *     size.
  61.  */
  62.  
  63. /* KW: Now uses clipmask and a flag to allow us to skip both/either
  64.  *     cliped and/or culled vertices.
  65.  */
  66.  
  67. /* GH: Not any more -- it's easier (and faster) to just process the
  68.  *     entire vector.  Clipping and culling are handled further down
  69.  *     the pipe, most often during or after the conversion to some
  70.  *     driver-specific vertex format.
  71.  */
  72.  
  73. static void _XFORMAPI
  74. TAG(transform_points1_general)( GLvector4f *to_vec,
  75.                                 const GLfloat m[16],
  76.                                 const GLvector4f *from_vec )
  77. {
  78.    const GLuint stride = from_vec->stride;
  79.    GLfloat *from = from_vec->start;
  80.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  81.    GLuint count = from_vec->count;
  82.    const GLfloat m0 = m[0],  m12 = m[12];
  83.    const GLfloat m1 = m[1],  m13 = m[13];
  84.    const GLfloat m2 = m[2],  m14 = m[14];
  85.    const GLfloat m3 = m[3],  m15 = m[15];
  86.    GLuint i;
  87.    STRIDE_LOOP {
  88.       const GLfloat ox = from[0];
  89.       to[i][0] = m0 * ox + m12;
  90.       to[i][1] = m1 * ox + m13;
  91.       to[i][2] = m2 * ox + m14;
  92.       to[i][3] = m3 * ox + m15;
  93.    }
  94.    to_vec->size = 4;
  95.    to_vec->flags |= VEC_SIZE_4;
  96.    to_vec->count = from_vec->count;
  97. }
  98.  
  99. static void _XFORMAPI
  100. TAG(transform_points1_identity)( GLvector4f *to_vec,
  101.                                  const GLfloat m[16],
  102.                                  const GLvector4f *from_vec )
  103. {
  104.    const GLuint stride = from_vec->stride;
  105.    GLfloat *from = from_vec->start;
  106.    GLuint count = from_vec->count;
  107.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  108.    GLuint i;
  109.    (void) m;
  110.    if (to_vec == from_vec) return;
  111.    STRIDE_LOOP {
  112.       to[i][0] = from[0];
  113.    }
  114.    to_vec->size = 1;
  115.    to_vec->flags |= VEC_SIZE_1;
  116.    to_vec->count = from_vec->count;
  117. }
  118.  
  119. static void _XFORMAPI
  120. TAG(transform_points1_2d)( GLvector4f *to_vec,
  121.                            const GLfloat m[16],
  122.                            const GLvector4f *from_vec )
  123. {
  124.    const GLuint stride = from_vec->stride;
  125.    GLfloat *from = from_vec->start;
  126.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  127.    GLuint count = from_vec->count;
  128.    const GLfloat m0 = m[0], m1 = m[1];
  129.    const GLfloat m12 = m[12], m13 = m[13];
  130.    GLuint i;
  131.    STRIDE_LOOP {
  132.       const GLfloat ox = from[0];
  133.       to[i][0] = m0 * ox + m12;
  134.       to[i][1] = m1 * ox + m13;
  135.    }
  136.    to_vec->size = 2;
  137.    to_vec->flags |= VEC_SIZE_2;
  138.    to_vec->count = from_vec->count;
  139. }
  140.  
  141. static void _XFORMAPI
  142. TAG(transform_points1_2d_no_rot)( GLvector4f *to_vec,
  143.                                   const GLfloat m[16],
  144.                                   const GLvector4f *from_vec )
  145. {
  146.    const GLuint stride = from_vec->stride;
  147.    GLfloat *from = from_vec->start;
  148.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  149.    GLuint count = from_vec->count;
  150.    const GLfloat m0 = m[0], m12 = m[12], m13 = m[13];
  151.    GLuint i;
  152.    STRIDE_LOOP {
  153.       const GLfloat ox = from[0];
  154.       to[i][0] = m0 * ox + m12;
  155.       to[i][1] =           m13;
  156.    }
  157.    to_vec->size = 2;
  158.    to_vec->flags |= VEC_SIZE_2;
  159.    to_vec->count = from_vec->count;
  160. }
  161.  
  162. static void _XFORMAPI
  163. TAG(transform_points1_3d)( GLvector4f *to_vec,
  164.                            const GLfloat m[16],
  165.                            const GLvector4f *from_vec )
  166. {
  167.    const GLuint stride = from_vec->stride;
  168.    GLfloat *from = from_vec->start;
  169.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  170.    GLuint count = from_vec->count;
  171.    const GLfloat m0 = m[0], m1 = m[1], m2 = m[2];
  172.    const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
  173.    GLuint i;
  174.    STRIDE_LOOP {
  175.       const GLfloat ox = from[0];
  176.       to[i][0] = m0 * ox + m12;
  177.       to[i][1] = m1 * ox + m13;
  178.       to[i][2] = m2 * ox + m14;
  179.    }
  180.    to_vec->size = 3;
  181.    to_vec->flags |= VEC_SIZE_3;
  182.    to_vec->count = from_vec->count;
  183. }
  184.  
  185.  
  186. static void _XFORMAPI
  187. TAG(transform_points1_3d_no_rot)( GLvector4f *to_vec,
  188.                                   const GLfloat m[16],
  189.                                   const GLvector4f *from_vec )
  190. {
  191.    const GLuint stride = from_vec->stride;
  192.    GLfloat *from = from_vec->start;
  193.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  194.    GLuint count = from_vec->count;
  195.    const GLfloat m0 = m[0];
  196.    const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
  197.    GLuint i;
  198.    STRIDE_LOOP {
  199.       const GLfloat ox = from[0];
  200.       to[i][0] = m0 * ox           + m12;
  201.       to[i][1] =                     m13;
  202.       to[i][2] =                     m14;
  203.    }
  204.    to_vec->size = 3;
  205.    to_vec->flags |= VEC_SIZE_3;
  206.    to_vec->count = from_vec->count;
  207. }
  208.  
  209. static void _XFORMAPI
  210. TAG(transform_points1_perspective)( GLvector4f *to_vec,
  211.                                     const GLfloat m[16],
  212.                                     const GLvector4f *from_vec )
  213. {
  214.    const GLuint stride = from_vec->stride;
  215.    GLfloat *from = from_vec->start;
  216.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  217.    GLuint count = from_vec->count;
  218.    const GLfloat m0 = m[0], m14 = m[14];
  219.    GLuint i;
  220.    STRIDE_LOOP {
  221.       const GLfloat ox = from[0];
  222.       to[i][0] = m0 * ox                ;
  223.       to[i][1] =           0            ;
  224.       to[i][2] =                     m14;
  225.       to[i][3] = 0;
  226.    }
  227.    to_vec->size = 4;
  228.    to_vec->flags |= VEC_SIZE_4;
  229.    to_vec->count = from_vec->count;
  230. }
  231.  
  232.  
  233.  
  234.  
  235. /* 2-vectors, which are a lot more relevant than 1-vectors, are
  236.  * present early in the geometry pipeline and throughout the
  237.  * texture pipeline.
  238.  */
  239. static void _XFORMAPI
  240. TAG(transform_points2_general)( GLvector4f *to_vec,
  241.                                 const GLfloat m[16],
  242.                                 const GLvector4f *from_vec )
  243. {
  244.    const GLuint stride = from_vec->stride;
  245.    GLfloat *from = from_vec->start;
  246.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  247.    GLuint count = from_vec->count;
  248.    const GLfloat m0 = m[0],  m4 = m[4],  m12 = m[12];
  249.    const GLfloat m1 = m[1],  m5 = m[5],  m13 = m[13];
  250.    const GLfloat m2 = m[2],  m6 = m[6],  m14 = m[14];
  251.    const GLfloat m3 = m[3],  m7 = m[7],  m15 = m[15];
  252.    GLuint i;
  253.    STRIDE_LOOP {
  254.       const GLfloat ox = from[0], oy = from[1];
  255.       to[i][0] = m0 * ox + m4 * oy + m12;
  256.       to[i][1] = m1 * ox + m5 * oy + m13;
  257.       to[i][2] = m2 * ox + m6 * oy + m14;
  258.       to[i][3] = m3 * ox + m7 * oy + m15;
  259.    }
  260.    to_vec->size = 4;
  261.    to_vec->flags |= VEC_SIZE_4;
  262.    to_vec->count = from_vec->count;
  263. }
  264.  
  265. static void _XFORMAPI
  266. TAG(transform_points2_identity)( GLvector4f *to_vec,
  267.                                  const GLfloat m[16],
  268.                                  const GLvector4f *from_vec )
  269. {
  270.    const GLuint stride = from_vec->stride;
  271.    GLfloat *from = from_vec->start;
  272.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  273.    GLuint count = from_vec->count;
  274.    GLuint i;
  275.    (void) m;
  276.    if (to_vec == from_vec) return;
  277.    STRIDE_LOOP {
  278.       to[i][0] = from[0];
  279.       to[i][1] = from[1];
  280.    }
  281.    to_vec->size = 2;
  282.    to_vec->flags |= VEC_SIZE_2;
  283.    to_vec->count = from_vec->count;
  284. }
  285.  
  286. static void _XFORMAPI
  287. TAG(transform_points2_2d)( GLvector4f *to_vec,
  288.                            const GLfloat m[16],
  289.                            const GLvector4f *from_vec )
  290. {
  291.    const GLuint stride = from_vec->stride;
  292.    GLfloat *from = from_vec->start;
  293.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  294.    GLuint count = from_vec->count;
  295.    const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
  296.    const GLfloat m12 = m[12], m13 = m[13];
  297.    GLuint i;
  298.    STRIDE_LOOP {
  299.       const GLfloat ox = from[0], oy = from[1];
  300.       to[i][0] = m0 * ox + m4 * oy + m12;
  301.       to[i][1] = m1 * ox + m5 * oy + m13;
  302.    }
  303.    to_vec->size = 2;
  304.    to_vec->flags |= VEC_SIZE_2;
  305.    to_vec->count = from_vec->count;
  306. }
  307.  
  308. static void _XFORMAPI
  309. TAG(transform_points2_2d_no_rot)( GLvector4f *to_vec,
  310.                                   const GLfloat m[16],
  311.                                   const GLvector4f *from_vec )
  312. {
  313.    const GLuint stride = from_vec->stride;
  314.    GLfloat *from = from_vec->start;
  315.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  316.    GLuint count = from_vec->count;
  317.    const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
  318.    GLuint i;
  319.    STRIDE_LOOP {
  320.       const GLfloat ox = from[0], oy = from[1];
  321.       to[i][0] = m0 * ox           + m12;
  322.       to[i][1] =           m5 * oy + m13;
  323.    }
  324.    to_vec->size = 2;
  325.    to_vec->flags |= VEC_SIZE_2;
  326.    to_vec->count = from_vec->count;
  327. }
  328.  
  329. static void _XFORMAPI
  330. TAG(transform_points2_3d)( GLvector4f *to_vec,
  331.                            const GLfloat m[16],
  332.                            const GLvector4f *from_vec )
  333. {
  334.    const GLuint stride = from_vec->stride;
  335.    GLfloat *from = from_vec->start;
  336.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  337.    GLuint count = from_vec->count;
  338.    const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
  339.    const GLfloat m6 = m[6], m12 = m[12], m13 = m[13], m14 = m[14];
  340.    GLuint i;
  341.    STRIDE_LOOP {
  342.       const GLfloat ox = from[0], oy = from[1];
  343.       to[i][0] = m0 * ox + m4 * oy + m12;
  344.       to[i][1] = m1 * ox + m5 * oy + m13;
  345.       to[i][2] = m2 * ox + m6 * oy + m14;
  346.    }
  347.    to_vec->size = 3;
  348.    to_vec->flags |= VEC_SIZE_3;
  349.    to_vec->count = from_vec->count;
  350. }
  351.  
  352.  
  353. /* I would actually say this was a fairly important function, from
  354.  * a texture transformation point of view.
  355.  */
  356. static void _XFORMAPI
  357. TAG(transform_points2_3d_no_rot)( GLvector4f *to_vec,
  358.                                   const GLfloat m[16],
  359.                                   const GLvector4f *from_vec )
  360. {
  361.    const GLuint stride = from_vec->stride;
  362.    GLfloat *from = from_vec->start;
  363.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  364.    GLuint count = from_vec->count;
  365.    const GLfloat m0 = m[0], m5 = m[5];
  366.    const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
  367.    GLuint i;
  368.    STRIDE_LOOP {
  369.       const GLfloat ox = from[0], oy = from[1];
  370.       to[i][0] = m0 * ox           + m12;
  371.       to[i][1] =           m5 * oy + m13;
  372.       to[i][2] =                     m14;
  373.    }
  374.    if (m14 == 0) {
  375.       to_vec->size = 2;
  376.       to_vec->flags |= VEC_SIZE_2;
  377.    } else {
  378.       to_vec->size = 3;
  379.       to_vec->flags |= VEC_SIZE_3;
  380.    }
  381.    to_vec->count = from_vec->count;
  382. }
  383.  
  384.  
  385. static void _XFORMAPI
  386. TAG(transform_points2_perspective)( GLvector4f *to_vec,
  387.                                     const GLfloat m[16],
  388.                                     const GLvector4f *from_vec )
  389. {
  390.    const GLuint stride = from_vec->stride;
  391.    GLfloat *from = from_vec->start;
  392.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  393.    GLuint count = from_vec->count;
  394.    const GLfloat m0 = m[0], m5 = m[5], m14 = m[14];
  395.    GLuint i;
  396.    STRIDE_LOOP {
  397.       const GLfloat ox = from[0], oy = from[1];
  398.       to[i][0] = m0 * ox                ;
  399.       to[i][1] =           m5 * oy      ;
  400.       to[i][2] =                     m14;
  401.       to[i][3] = 0;
  402.    }
  403.    to_vec->size = 4;
  404.    to_vec->flags |= VEC_SIZE_4;
  405.    to_vec->count = from_vec->count;
  406. }
  407.  
  408.  
  409.  
  410. static void _XFORMAPI
  411. TAG(transform_points3_general)( GLvector4f *to_vec,
  412.                                 const GLfloat m[16],
  413.                                 const GLvector4f *from_vec )
  414. {
  415.    const GLuint stride = from_vec->stride;
  416.    GLfloat *from = from_vec->start;
  417.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  418.    GLuint count = from_vec->count;
  419.    const GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
  420.    const GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
  421.    const GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
  422.    const GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
  423.    GLuint i;
  424.    STRIDE_LOOP {
  425.       const GLfloat ox = from[0], oy = from[1], oz = from[2];
  426.       to[i][0] = m0 * ox + m4 * oy + m8  * oz + m12;
  427.       to[i][1] = m1 * ox + m5 * oy + m9  * oz + m13;
  428.       to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14;
  429.       to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15;
  430.    }
  431.    to_vec->size = 4;
  432.    to_vec->flags |= VEC_SIZE_4;
  433.    to_vec->count = from_vec->count;
  434. }
  435.  
  436. static void _XFORMAPI
  437. TAG(transform_points3_identity)( GLvector4f *to_vec,
  438.                                  const GLfloat m[16],
  439.                                  const GLvector4f *from_vec )
  440. {
  441.    const GLuint stride = from_vec->stride;
  442.    GLfloat *from = from_vec->start;
  443.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  444.    GLuint count = from_vec->count;
  445.    GLuint i;
  446.    (void) m;
  447.    if (to_vec == from_vec) return;
  448.    STRIDE_LOOP {
  449.       to[i][0] = from[0];
  450.       to[i][1] = from[1];
  451.       to[i][2] = from[2];
  452.    }
  453.    to_vec->size = 3;
  454.    to_vec->flags |= VEC_SIZE_3;
  455.    to_vec->count = from_vec->count;
  456. }
  457.  
  458. static void _XFORMAPI
  459. TAG(transform_points3_2d)( GLvector4f *to_vec,
  460.                            const GLfloat m[16],
  461.                            const GLvector4f *from_vec )
  462. {
  463.    const GLuint stride = from_vec->stride;
  464.    GLfloat *from = from_vec->start;
  465.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  466.    GLuint count = from_vec->count;
  467.    const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
  468.    const GLfloat m12 = m[12], m13 = m[13];
  469.    GLuint i;
  470.    STRIDE_LOOP {
  471.       const GLfloat ox = from[0], oy = from[1], oz = from[2];
  472.       to[i][0] = m0 * ox + m4 * oy            + m12       ;
  473.       to[i][1] = m1 * ox + m5 * oy            + m13       ;
  474.       to[i][2] =                   +       oz             ;
  475.    }
  476.    to_vec->size = 3;
  477.    to_vec->flags |= VEC_SIZE_3;
  478.    to_vec->count = from_vec->count;
  479. }
  480.  
  481. static void _XFORMAPI
  482. TAG(transform_points3_2d_no_rot)( GLvector4f *to_vec,
  483.                                   const GLfloat m[16],
  484.                                   const GLvector4f *from_vec )
  485. {
  486.    const GLuint stride = from_vec->stride;
  487.    GLfloat *from = from_vec->start;
  488.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  489.    GLuint count = from_vec->count;
  490.    const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
  491.    GLuint i;
  492.    STRIDE_LOOP {
  493.       const GLfloat ox = from[0], oy = from[1], oz = from[2];
  494.       to[i][0] = m0 * ox                      + m12       ;
  495.       to[i][1] =           m5 * oy            + m13       ;
  496.       to[i][2] =                   +       oz             ;
  497.    }
  498.    to_vec->size = 3;
  499.    to_vec->flags |= VEC_SIZE_3;
  500.    to_vec->count = from_vec->count;
  501. }
  502.  
  503. static void _XFORMAPI
  504. TAG(transform_points3_3d)( GLvector4f *to_vec,
  505.                            const GLfloat m[16],
  506.                            const GLvector4f *from_vec )
  507. {
  508.    const GLuint stride = from_vec->stride;
  509.    GLfloat *from = from_vec->start;
  510.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  511.    GLuint count = from_vec->count;
  512.    const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
  513.    const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
  514.    const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
  515.    GLuint i;
  516.    STRIDE_LOOP {
  517.       const GLfloat ox = from[0], oy = from[1], oz = from[2];
  518.       to[i][0] = m0 * ox + m4 * oy +  m8 * oz + m12       ;
  519.       to[i][1] = m1 * ox + m5 * oy +  m9 * oz + m13       ;
  520.       to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14       ;
  521.    }
  522.    to_vec->size = 3;
  523.    to_vec->flags |= VEC_SIZE_3;
  524.    to_vec->count = from_vec->count;
  525. }
  526.  
  527. /* previously known as ortho...
  528.  */
  529. static void _XFORMAPI
  530. TAG(transform_points3_3d_no_rot)( GLvector4f *to_vec,
  531.                                   const GLfloat m[16],
  532.                                   const GLvector4f *from_vec )
  533. {
  534.    const GLuint stride = from_vec->stride;
  535.    GLfloat *from = from_vec->start;
  536.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  537.    GLuint count = from_vec->count;
  538.    const GLfloat m0 = m[0], m5 = m[5];
  539.    const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14];
  540.    GLuint i;
  541.    STRIDE_LOOP {
  542.       const GLfloat ox = from[0], oy = from[1], oz = from[2];
  543.       to[i][0] = m0 * ox                      + m12       ;
  544.       to[i][1] =           m5 * oy            + m13       ;
  545.       to[i][2] =                     m10 * oz + m14       ;
  546.    }
  547.    to_vec->size = 3;
  548.    to_vec->flags |= VEC_SIZE_3;
  549.    to_vec->count = from_vec->count;
  550. }
  551.  
  552. static void _XFORMAPI
  553. TAG(transform_points3_perspective)( GLvector4f *to_vec,
  554.                                     const GLfloat m[16],
  555.                                     const GLvector4f *from_vec )
  556. {
  557.    const GLuint stride = from_vec->stride;
  558.    GLfloat *from = from_vec->start;
  559.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  560.    GLuint count = from_vec->count;
  561.    const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9];
  562.    const GLfloat m10 = m[10], m14 = m[14];
  563.    GLuint i;
  564.    STRIDE_LOOP {
  565.       const GLfloat ox = from[0], oy = from[1], oz = from[2];
  566.       to[i][0] = m0 * ox           + m8  * oz       ;
  567.       to[i][1] =           m5 * oy + m9  * oz       ;
  568.       to[i][2] =                     m10 * oz + m14 ;
  569.       to[i][3] =                          -oz       ;
  570.    }
  571.    to_vec->size = 4;
  572.    to_vec->flags |= VEC_SIZE_4;
  573.    to_vec->count = from_vec->count;
  574. }
  575.  
  576.  
  577.  
  578. static void _XFORMAPI
  579. TAG(transform_points4_general)( GLvector4f *to_vec,
  580.                                 const GLfloat m[16],
  581.                                 const GLvector4f *from_vec )
  582. {
  583.    const GLuint stride = from_vec->stride;
  584.    GLfloat *from = from_vec->start;
  585.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  586.    GLuint count = from_vec->count;
  587.    const GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
  588.    const GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
  589.    const GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
  590.    const GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
  591.    GLuint i;
  592.    STRIDE_LOOP {
  593.       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
  594.       to[i][0] = m0 * ox + m4 * oy + m8  * oz + m12 * ow;
  595.       to[i][1] = m1 * ox + m5 * oy + m9  * oz + m13 * ow;
  596.       to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow;
  597.       to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15 * ow;
  598.    }
  599.    to_vec->size = 4;
  600.    to_vec->flags |= VEC_SIZE_4;
  601.    to_vec->count = from_vec->count;
  602. }
  603.  
  604. static void _XFORMAPI
  605. TAG(transform_points4_identity)( GLvector4f *to_vec,
  606.                                  const GLfloat m[16],
  607.                                  const GLvector4f *from_vec )
  608. {
  609.    const GLuint stride = from_vec->stride;
  610.    GLfloat *from = from_vec->start;
  611.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  612.    GLuint count = from_vec->count;
  613.    GLuint i;
  614.    (void) m;
  615.    if (to_vec == from_vec) return;
  616.    STRIDE_LOOP {
  617.       to[i][0] = from[0];
  618.       to[i][1] = from[1];
  619.       to[i][2] = from[2];
  620.       to[i][3] = from[3];
  621.    }
  622.    to_vec->size = 4;
  623.    to_vec->flags |= VEC_SIZE_4;
  624.    to_vec->count = from_vec->count;
  625. }
  626.  
  627. static void _XFORMAPI
  628. TAG(transform_points4_2d)( GLvector4f *to_vec,
  629.                            const GLfloat m[16],
  630.                            const GLvector4f *from_vec )
  631. {
  632.    const GLuint stride = from_vec->stride;
  633.    GLfloat *from = from_vec->start;
  634.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  635.    GLuint count = from_vec->count;
  636.    const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
  637.    const GLfloat m12 = m[12], m13 = m[13];
  638.    GLuint i;
  639.    STRIDE_LOOP {
  640.       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
  641.       to[i][0] = m0 * ox + m4 * oy            + m12 * ow;
  642.       to[i][1] = m1 * ox + m5 * oy            + m13 * ow;
  643.       to[i][2] =                   +       oz           ;
  644.       to[i][3] =                                      ow;
  645.    }
  646.    to_vec->size = 4;
  647.    to_vec->flags |= VEC_SIZE_4;
  648.    to_vec->count = from_vec->count;
  649. }
  650.  
  651. static void _XFORMAPI
  652. TAG(transform_points4_2d_no_rot)( GLvector4f *to_vec,
  653.                                   const GLfloat m[16],
  654.                                   const GLvector4f *from_vec )
  655. {
  656.    const GLuint stride = from_vec->stride;
  657.    GLfloat *from = from_vec->start;
  658.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  659.    GLuint count = from_vec->count;
  660.    const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
  661.    GLuint i;
  662.    STRIDE_LOOP {
  663.       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
  664.       to[i][0] = m0 * ox                      + m12 * ow;
  665.       to[i][1] =           m5 * oy            + m13 * ow;
  666.       to[i][2] =                   +       oz           ;
  667.       to[i][3] =                                      ow;
  668.    }
  669.    to_vec->size = 4;
  670.    to_vec->flags |= VEC_SIZE_4;
  671.    to_vec->count = from_vec->count;
  672. }
  673.  
  674. static void _XFORMAPI
  675. TAG(transform_points4_3d)( GLvector4f *to_vec,
  676.                            const GLfloat m[16],
  677.                            const GLvector4f *from_vec )
  678. {
  679.    const GLuint stride = from_vec->stride;
  680.    GLfloat *from = from_vec->start;
  681.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  682.    GLuint count = from_vec->count;
  683.    const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
  684.    const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
  685.    const GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
  686.    GLuint i;
  687.    STRIDE_LOOP {
  688.       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
  689.       to[i][0] = m0 * ox + m4 * oy +  m8 * oz + m12 * ow;
  690.       to[i][1] = m1 * ox + m5 * oy +  m9 * oz + m13 * ow;
  691.       to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow;
  692.       to[i][3] =                                      ow;
  693.    }
  694.    to_vec->size = 4;
  695.    to_vec->flags |= VEC_SIZE_4;
  696.    to_vec->count = from_vec->count;
  697. }
  698.  
  699. static void _XFORMAPI
  700. TAG(transform_points4_3d_no_rot)( GLvector4f *to_vec,
  701.                                   const GLfloat m[16],
  702.                                   const GLvector4f *from_vec )
  703. {
  704.    const GLuint stride = from_vec->stride;
  705.    GLfloat *from = from_vec->start;
  706.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  707.    GLuint count = from_vec->count;
  708.    const GLfloat m0 = m[0], m5 = m[5];
  709.    const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14];
  710.    GLuint i;
  711.    STRIDE_LOOP {
  712.       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
  713.       to[i][0] = m0 * ox                      + m12 * ow;
  714.       to[i][1] =           m5 * oy            + m13 * ow;
  715.       to[i][2] =                     m10 * oz + m14 * ow;
  716.       to[i][3] =                                      ow;
  717.    }
  718.    to_vec->size = 4;
  719.    to_vec->flags |= VEC_SIZE_4;
  720.    to_vec->count = from_vec->count;
  721. }
  722.  
  723. static void _XFORMAPI
  724. TAG(transform_points4_perspective)( GLvector4f *to_vec,
  725.                                     const GLfloat m[16],
  726.                                     const GLvector4f *from_vec )
  727. {
  728.    const GLuint stride = from_vec->stride;
  729.    GLfloat *from = from_vec->start;
  730.    GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start;
  731.    GLuint count = from_vec->count;
  732.    const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9];
  733.    const GLfloat m10 = m[10], m14 = m[14];
  734.    GLuint i;
  735.    STRIDE_LOOP {
  736.       const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3];
  737.       to[i][0] = m0 * ox           + m8  * oz            ;
  738.       to[i][1] =           m5 * oy + m9  * oz            ;
  739.       to[i][2] =                     m10 * oz + m14 * ow ;
  740.       to[i][3] =                          -oz            ;
  741.    }
  742.    to_vec->size = 4;
  743.    to_vec->flags |= VEC_SIZE_4;
  744.    to_vec->count = from_vec->count;
  745. }
  746.  
  747. static transform_func TAG(transform_tab_1)[7];
  748. static transform_func TAG(transform_tab_2)[7];
  749. static transform_func TAG(transform_tab_3)[7];
  750. static transform_func TAG(transform_tab_4)[7];
  751.  
  752. /* Similar functions could be called several times, with more highly
  753.  * optimized routines overwriting the arrays.  This only occurs during
  754.  * startup.
  755.  */
  756. static void _XFORMAPI TAG(init_c_transformations)( void )
  757. {
  758. #define TAG_TAB   _mesa_transform_tab
  759. #define TAG_TAB_1 TAG(transform_tab_1)
  760. #define TAG_TAB_2 TAG(transform_tab_2)
  761. #define TAG_TAB_3 TAG(transform_tab_3)
  762. #define TAG_TAB_4 TAG(transform_tab_4)
  763.  
  764.    TAG_TAB[1] = TAG_TAB_1;
  765.    TAG_TAB[2] = TAG_TAB_2;
  766.    TAG_TAB[3] = TAG_TAB_3;
  767.    TAG_TAB[4] = TAG_TAB_4;
  768.  
  769.    /* 1-D points (ie texcoords) */
  770.    TAG_TAB_1[MATRIX_GENERAL]     = TAG(transform_points1_general);
  771.    TAG_TAB_1[MATRIX_IDENTITY]    = TAG(transform_points1_identity);
  772.    TAG_TAB_1[MATRIX_3D_NO_ROT]   = TAG(transform_points1_3d_no_rot);
  773.    TAG_TAB_1[MATRIX_PERSPECTIVE] = TAG(transform_points1_perspective);
  774.    TAG_TAB_1[MATRIX_2D]          = TAG(transform_points1_2d);
  775.    TAG_TAB_1[MATRIX_2D_NO_ROT]   = TAG(transform_points1_2d_no_rot);
  776.    TAG_TAB_1[MATRIX_3D]          = TAG(transform_points1_3d);
  777.  
  778.    /* 2-D points */
  779.    TAG_TAB_2[MATRIX_GENERAL]     = TAG(transform_points2_general);
  780.    TAG_TAB_2[MATRIX_IDENTITY]    = TAG(transform_points2_identity);
  781.    TAG_TAB_2[MATRIX_3D_NO_ROT]   = TAG(transform_points2_3d_no_rot);
  782.    TAG_TAB_2[MATRIX_PERSPECTIVE] = TAG(transform_points2_perspective);
  783.    TAG_TAB_2[MATRIX_2D]          = TAG(transform_points2_2d);
  784.    TAG_TAB_2[MATRIX_2D_NO_ROT]   = TAG(transform_points2_2d_no_rot);
  785.    TAG_TAB_2[MATRIX_3D]          = TAG(transform_points2_3d);
  786.  
  787.    /* 3-D points */
  788.    TAG_TAB_3[MATRIX_GENERAL]     = TAG(transform_points3_general);
  789.    TAG_TAB_3[MATRIX_IDENTITY]    = TAG(transform_points3_identity);
  790.    TAG_TAB_3[MATRIX_3D_NO_ROT]   = TAG(transform_points3_3d_no_rot);
  791.    TAG_TAB_3[MATRIX_PERSPECTIVE] = TAG(transform_points3_perspective);
  792.    TAG_TAB_3[MATRIX_2D]          = TAG(transform_points3_2d);
  793.    TAG_TAB_3[MATRIX_2D_NO_ROT]   = TAG(transform_points3_2d_no_rot);
  794.    TAG_TAB_3[MATRIX_3D]          = TAG(transform_points3_3d);
  795.  
  796.    /* 4-D points */
  797.    TAG_TAB_4[MATRIX_GENERAL]     = TAG(transform_points4_general);
  798.    TAG_TAB_4[MATRIX_IDENTITY]    = TAG(transform_points4_identity);
  799.    TAG_TAB_4[MATRIX_3D_NO_ROT]   = TAG(transform_points4_3d_no_rot);
  800.    TAG_TAB_4[MATRIX_PERSPECTIVE] = TAG(transform_points4_perspective);
  801.    TAG_TAB_4[MATRIX_2D]          = TAG(transform_points4_2d);
  802.    TAG_TAB_4[MATRIX_2D_NO_ROT]   = TAG(transform_points4_2d_no_rot);
  803.    TAG_TAB_4[MATRIX_3D]          = TAG(transform_points4_3d);
  804.  
  805. #undef TAG_TAB
  806. #undef TAG_TAB_1
  807. #undef TAG_TAB_2
  808. #undef TAG_TAB_3
  809. #undef TAG_TAB_4
  810. }
  811.