home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / src / vbxform.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  36.9 KB  |  1,237 lines

  1. /* $Id: vbxform.c,v 1.20 1997/11/20 00:09:38 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.5
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: vbxform.c,v $
  26.  * Revision 1.20  1997/11/20 00:09:38  brianp
  27.  * transform_points4() wasn't calling asm routines
  28.  *
  29.  * Revision 1.19  1997/10/30 06:00:06  brianp
  30.  * added Intel X86 assembly optimzations (Josh Vanderhoof)
  31.  *
  32.  * Revision 1.18  1997/10/15 00:36:36  brianp
  33.  * renamed the FAST/REGULAR_MATH macros
  34.  *
  35.  * Revision 1.17  1997/10/04 00:30:52  brianp
  36.  * vertices specified with glVertex4 weren't always projected correctly
  37.  *
  38.  * Revision 1.16  1997/09/29 22:24:22  brianp
  39.  * added REGULAR/FAST_MATH macros
  40.  *
  41.  * Revision 1.15  1997/09/18 01:32:47  brianp
  42.  * fixed divide by zero problem for "weird" projection matrices
  43.  *
  44.  * Revision 1.14  1997/09/10 00:28:11  brianp
  45.  * fixed an optimization bug in viewport_map_vertices()
  46.  *
  47.  * Revision 1.13  1997/07/24 01:25:27  brianp
  48.  * changed precompiled header symbol from PCH to PC_HEADER
  49.  *
  50.  * Revision 1.12  1997/06/20 02:57:59  brianp
  51.  * changed color components from GLfixed to GLubyte
  52.  *
  53.  * Revision 1.11  1997/05/28 03:26:49  brianp
  54.  * added precompiled header (PCH) support
  55.  *
  56.  * Revision 1.10  1997/05/23 03:01:45  brianp
  57.  * commented out a few const keywords because IRIX cc chokes on them
  58.  *
  59.  * Revision 1.9  1997/04/29 01:31:07  brianp
  60.  * added RasterSetup() function to device driver
  61.  *
  62.  * Revision 1.8  1997/04/21 01:21:52  brianp
  63.  * added MATRIX_2D_NO_ROT
  64.  *
  65.  * Revision 1.7  1997/04/20 19:47:27  brianp
  66.  * added RenderVB to device driver
  67.  *
  68.  * Revision 1.6  1997/04/20 15:59:30  brianp
  69.  * removed VERTEX2_BIT stuff
  70.  *
  71.  * Revision 1.5  1997/04/14 02:12:53  brianp
  72.  * small optimization in transform_texcoords()
  73.  *
  74.  * Revision 1.4  1997/04/12 16:22:22  brianp
  75.  * removed gl_init_vb()
  76.  *
  77.  * Revision 1.3  1997/04/12 12:28:39  brianp
  78.  * fixed <= material_update bug, removed some unused vars
  79.  *
  80.  * Revision 1.2  1997/04/07 03:01:11  brianp
  81.  * optimized vertex[234] code
  82.  *
  83.  * Revision 1.1  1997/04/02 03:14:29  brianp
  84.  * Initial revision
  85.  *
  86.  */
  87.  
  88.  
  89. /*
  90.  * This file implements transformation, clip testing, and lighting of
  91.  * vertices in the vertex buffer.
  92.  *
  93.  * The entry points to this file are the functions:
  94.  *    gl_init_vb() - initialize the vertex buffer
  95.  *    gl_transform_vb_part1() - first stage of vertex transformation
  96.  *    gl_transform_vb_part2() - second stage of vertex transformation
  97.  */
  98.  
  99.  
  100. #ifdef PC_HEADER
  101. #include "all.h"
  102. #else
  103. #include <stdio.h>
  104. #include <stdlib.h>
  105. #include "context.h"
  106. #include "fog.h"
  107. #include "light.h"
  108. #include "macros.h"
  109. #include "matrix.h"
  110. #include "mmath.h"
  111. #include "shade.h"
  112. #include "texture.h"
  113. #include "types.h"
  114. #include "vb.h"
  115. #include "vbrender.h"
  116. #include "vbxform.h"
  117. #include "xform.h"
  118. #endif
  119.  
  120.  
  121. #if 0
  122. /*
  123.  * Use the current modelview matrix to transform XY vertices from object
  124.  * to eye coordinates.
  125.  * Input:  ctx - the context
  126.  *         n - number of vertices to transform
  127.  *         vObj - array [n][4] of object coordinates
  128.  * In/Out;  vEye - array [n][4] of eye coordinates
  129.  */
  130. static void transform_points2( GLcontext *ctx, GLuint n,
  131.                    const GLfloat vObj[][4], GLfloat vEye[][4] )
  132. {
  133.    switch (ctx->ModelViewMatrixType) {
  134.       case MATRIX_GENERAL:
  135.      {
  136.         const GLfloat *m = ctx->ModelViewMatrix;
  137.         GLfloat m0 = m[0],  m4 = m[4],  m12 = m[12];
  138.         GLfloat m1 = m[1],  m5 = m[5],  m13 = m[13];
  139.         GLfloat m2 = m[2],  m6 = m[6],  m14 = m[14];
  140.         GLfloat m3 = m[3],  m7 = m[7],  m15 = m[15];
  141.         GLuint i;
  142.         for (i=0;i<n;i++) {
  143.            GLfloat ox = vObj[i][0], oy = vObj[i][1];
  144.            vEye[i][0] = m0 * ox + m4 * oy + m12;
  145.            vEye[i][1] = m1 * ox + m5 * oy + m13;
  146.            vEye[i][2] = m2 * ox + m6 * oy + m14;
  147.            vEye[i][3] = m3 * ox + m7 * oy + m15;
  148.         }
  149.      }
  150.      break;
  151.       case MATRIX_IDENTITY:
  152.      {
  153.         GLuint i;
  154.         for (i=0;i<n;i++) {
  155.            vEye[i][0] = vObj[i][0];
  156.            vEye[i][1] = vObj[i][1];
  157.            vEye[i][2] = 0.0F;
  158.            vEye[i][3] = 1.0F;
  159.         }
  160.      }
  161.      break;
  162.       case MATRIX_2D:
  163.      {
  164.         const GLfloat *m = ctx->ModelViewMatrix;
  165.         GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
  166.         GLfloat m12 = m[12], m13 = m[13];
  167.         GLuint i;
  168.         for (i=0;i<n;i++) {
  169.            GLfloat ox = vObj[i][0], oy = vObj[i][1];
  170.            vEye[i][0] = m0 * ox + m4 * oy + m12;
  171.            vEye[i][1] = m1 * ox + m5 * oy + m13;
  172.            vEye[i][2] = 0.0F;
  173.            vEye[i][3] = 1.0F;
  174.         }
  175.      }
  176.      break;
  177.       case MATRIX_2D_NO_ROT:
  178.      {
  179.         const GLfloat *m = ctx->ModelViewMatrix;
  180.         GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
  181.         GLuint i;
  182.         for (i=0;i<n;i++) {
  183.            GLfloat ox = vObj[i][0], oy = vObj[i][1];
  184.            vEye[i][0] = m0 * ox           + m12;
  185.            vEye[i][1] =           m5 * oy + m13;
  186.            vEye[i][2] = 0.0F;
  187.            vEye[i][3] = 1.0F;
  188.         }
  189.      }
  190.      break;
  191.       case MATRIX_3D:
  192.      {
  193.         const GLfloat *m = ctx->ModelViewMatrix;
  194.         GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
  195.         GLfloat m6 = m[6], m12 = m[12], m13 = m[13], m14 = m[14];
  196.         GLuint i;
  197.         for (i=0;i<n;i++) {
  198.            GLfloat ox = vObj[i][0], oy = vObj[i][1];
  199.            vEye[i][0] = m0 * ox + m4 * oy + m12;
  200.            vEye[i][1] = m1 * ox + m5 * oy + m13;
  201.            vEye[i][2] = m2 * ox + m6 * oy + m14;
  202.            vEye[i][3] = 1.0F;
  203.         }
  204.      }
  205.      break;
  206.       default:
  207.      /* should never get here */
  208.      gl_problem( NULL, "invalid matrix type in transform_points3()" );
  209.      return;
  210.    }
  211. }
  212. #endif
  213.  
  214.  
  215. /*
  216.  * Use the current modelview matrix to transform XYZ vertices from object
  217.  * to eye coordinates.
  218.  * Input:  ctx - the context
  219.  *         n - number of vertices to transform
  220.  *         vObj - array [n][4] of object coordinates
  221.  * In/Out;  vEye - array [n][4] of eye coordinates
  222.  */
  223. static void transform_points3( GLcontext *ctx, GLuint n,
  224.                    /*const*/ GLfloat vObj[][4], GLfloat vEye[][4] )
  225. {
  226. #ifndef USE_ASM
  227.    START_FAST_MATH;
  228.    switch (ctx->ModelViewMatrixType) {
  229.       case MATRIX_GENERAL:
  230.      {
  231.         const GLfloat *m = ctx->ModelViewMatrix;
  232.         GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
  233.         GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
  234.         GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
  235.         GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
  236.         GLuint i;
  237.         for (i=0;i<n;i++) {
  238.            GLfloat ox = vObj[i][0], oy = vObj[i][1], oz = vObj[i][2];
  239.            vEye[i][0] = m0 * ox + m4 * oy + m8  * oz + m12;
  240.            vEye[i][1] = m1 * ox + m5 * oy + m9  * oz + m13;
  241.            vEye[i][2] = m2 * ox + m6 * oy + m10 * oz + m14;
  242.            vEye[i][3] = m3 * ox + m7 * oy + m11 * oz + m15;
  243.         }
  244.      }
  245.      break;
  246.       case MATRIX_IDENTITY:
  247.      {
  248.         GLuint i;
  249.         for (i=0;i<n;i++) {
  250.            vEye[i][0] = vObj[i][0];
  251.            vEye[i][1] = vObj[i][1];
  252.            vEye[i][2] = vObj[i][2];
  253.            vEye[i][3] = 1.0F;
  254.         }
  255.      }
  256.      break;
  257.       case MATRIX_2D:
  258.      {
  259.         const GLfloat *m = ctx->ModelViewMatrix;
  260.         GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
  261.         GLfloat m12 = m[12], m13 = m[13];
  262.         GLuint i;
  263.         for (i=0;i<n;i++) {
  264.            GLfloat ox = vObj[i][0], oy = vObj[i][1], oz = vObj[i][2];
  265.            vEye[i][0] = m0 * ox + m4 * oy            + m12       ;
  266.            vEye[i][1] = m1 * ox + m5 * oy            + m13       ;
  267.            vEye[i][2] =                   +       oz             ;
  268.            vEye[i][3] =                                      1.0F;
  269.         }
  270.      }
  271.      break;
  272.       case MATRIX_2D_NO_ROT:
  273.      {
  274.         const GLfloat *m = ctx->ModelViewMatrix;
  275.         GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
  276.         GLuint i;
  277.         for (i=0;i<n;i++) {
  278.            GLfloat ox = vObj[i][0], oy = vObj[i][1], oz = vObj[i][2];
  279.            vEye[i][0] = m0 * ox                      + m12       ;
  280.            vEye[i][1] =           m5 * oy            + m13       ;
  281.            vEye[i][2] =                   +       oz             ;
  282.            vEye[i][3] =                                      1.0F;
  283.         }
  284.      }
  285.      break;
  286.       case MATRIX_3D:
  287.      {
  288.         const GLfloat *m = ctx->ModelViewMatrix;
  289.         GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
  290.         GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
  291.         GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
  292.         GLuint i;
  293.         for (i=0;i<n;i++) {
  294.            GLfloat ox = vObj[i][0], oy = vObj[i][1], oz = vObj[i][2];
  295.            vEye[i][0] = m0 * ox + m4 * oy +  m8 * oz + m12       ;
  296.            vEye[i][1] = m1 * ox + m5 * oy +  m9 * oz + m13       ;
  297.            vEye[i][2] = m2 * ox + m6 * oy + m10 * oz + m14       ;
  298.            vEye[i][3] =                                      1.0F;
  299.         }
  300.      }
  301.      break;
  302.       default:
  303.      /* should never get here */
  304.      gl_problem( NULL, "invalid matrix type in transform_points3()" );
  305.    }
  306.    END_FAST_MATH;
  307. #else
  308.    switch (ctx->ModelViewMatrixType) {
  309.       case MATRIX_GENERAL:
  310.      asm_transform_points3_general( n, vEye, ctx->ModelViewMatrix, vObj );
  311.      break;
  312.       case MATRIX_IDENTITY:
  313.      asm_transform_points3_identity( n, vEye, vObj );
  314.      break;
  315.       case MATRIX_2D:
  316.      asm_transform_points3_2d( n, vEye, ctx->ModelViewMatrix, vObj );
  317.      break;
  318.       case MATRIX_2D_NO_ROT:
  319.      asm_transform_points3_2d_no_rot( n, vEye, ctx->ModelViewMatrix,
  320.                       vObj );
  321.      break;
  322.       case MATRIX_3D:
  323.      asm_transform_points3_3d( n, vEye, ctx->ModelViewMatrix, vObj );
  324.      break;
  325.       default:
  326.      /* should never get here */
  327.      gl_problem( NULL, "invalid matrix type in transform_points3()" );
  328.      return;
  329.    }
  330. #endif
  331. }
  332.  
  333.  
  334.  
  335. /*
  336.  * Use the current modelview matrix to transform XYZW vertices from object
  337.  * to eye coordinates.
  338.  * Input:  ctx - the context
  339.  *         n - number of vertices to transform
  340.  *         vObj - array [n][4] of object coordinates
  341.  * In/Out;  vEye - array [n][4] of eye coordinates
  342.  */
  343. static void transform_points4( GLcontext *ctx, GLuint n,
  344.                    /*const*/ GLfloat vObj[][4], GLfloat vEye[][4] )
  345. {
  346. #ifndef USE_ASM
  347.    START_FAST_MATH;
  348.    switch (ctx->ModelViewMatrixType) {
  349.       case MATRIX_GENERAL:
  350.      {
  351.         const GLfloat *m = ctx->ModelViewMatrix;
  352.         GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
  353.         GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
  354.         GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
  355.         GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
  356.         GLuint i;
  357.         for (i=0;i<n;i++) {
  358.            GLfloat ox = vObj[i][0], oy = vObj[i][1];
  359.            GLfloat oz = vObj[i][2], ow = vObj[i][3];
  360.            vEye[i][0] = m0 * ox + m4 * oy + m8  * oz + m12 * ow;
  361.            vEye[i][1] = m1 * ox + m5 * oy + m9  * oz + m13 * ow;
  362.            vEye[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow;
  363.            vEye[i][3] = m3 * ox + m7 * oy + m11 * oz + m15 * ow;
  364.         }
  365.      }
  366.      break;
  367.       case MATRIX_IDENTITY:
  368.      {
  369.         GLuint i;
  370.         for (i=0;i<n;i++) {
  371.            vEye[i][0] = vObj[i][0];
  372.            vEye[i][1] = vObj[i][1];
  373.            vEye[i][2] = vObj[i][2];
  374.            vEye[i][3] = vObj[i][3];
  375.         }
  376.      }
  377.      break;
  378.       case MATRIX_2D:
  379.      {
  380.         const GLfloat *m = ctx->ModelViewMatrix;
  381.         GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
  382.         GLfloat m12 = m[12], m13 = m[13];
  383.         GLuint i;
  384.         for (i=0;i<n;i++) {
  385.            GLfloat ox = vObj[i][0], oy = vObj[i][1];
  386.            GLfloat oz = vObj[i][2], ow = vObj[i][3];
  387.            vEye[i][0] = m0 * ox + m4 * oy            + m12 * ow;
  388.            vEye[i][1] = m1 * ox + m5 * oy            + m13 * ow;
  389.            vEye[i][2] =                   +       oz           ;
  390.            vEye[i][3] =                                      ow;
  391.         }
  392.      }
  393.      break;
  394.       case MATRIX_2D_NO_ROT:
  395.      {
  396.         const GLfloat *m = ctx->ModelViewMatrix;
  397.         GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13];
  398.         GLuint i;
  399.         for (i=0;i<n;i++) {
  400.            GLfloat ox = vObj[i][0], oy = vObj[i][1];
  401.            GLfloat oz = vObj[i][2], ow = vObj[i][3];
  402.            vEye[i][0] = m0 * ox                      + m12 * ow;
  403.            vEye[i][1] =           m5 * oy            + m13 * ow;
  404.            vEye[i][2] =                   +       oz           ;
  405.            vEye[i][3] =                                      ow;
  406.         }
  407.      }
  408.      break;
  409.       case MATRIX_3D:
  410.      {
  411.         const GLfloat *m = ctx->ModelViewMatrix;
  412.         GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
  413.         GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
  414.         GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
  415.         GLuint i;
  416.         for (i=0;i<n;i++) {
  417.            GLfloat ox = vObj[i][0], oy = vObj[i][1];
  418.            GLfloat oz = vObj[i][2], ow = vObj[i][3];
  419.            vEye[i][0] = m0 * ox + m4 * oy +  m8 * oz + m12 * ow;
  420.            vEye[i][1] = m1 * ox + m5 * oy +  m9 * oz + m13 * ow;
  421.            vEye[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow;
  422.            vEye[i][3] =                                      ow;
  423.         }
  424.      }
  425.      break;
  426.       default:
  427.      /* should never get here */
  428.      gl_problem( NULL, "invalid matrix type in transform_points4()" );
  429.    }
  430.    END_FAST_MATH;
  431. #else
  432.    switch (ctx->ModelViewMatrixType) {
  433.       case MATRIX_GENERAL:
  434.      asm_transform_points4_general( n, vEye, ctx->ModelViewMatrix, vObj );
  435.      break;
  436.       case MATRIX_IDENTITY:
  437.      asm_transform_points4_identity( n, vEye, vObj );
  438.      break;
  439.       case MATRIX_2D:
  440.      asm_transform_points4_2d( n, vEye, ctx->ModelViewMatrix, vObj );
  441.      break;
  442.       case MATRIX_2D_NO_ROT:
  443.      asm_transform_points4_2d_no_rot( n, vEye, ctx->ModelViewMatrix,
  444.                       vObj );
  445.      break;
  446.       case MATRIX_3D:
  447.      asm_transform_points4_3d( n, vEye, ctx->ModelViewMatrix, vObj );
  448.      break;
  449.       default:
  450.      /* should never get here */
  451.      gl_problem( NULL, "invalid matrix type in transform_points4()" );
  452.      return;
  453.    }
  454. #endif
  455. }
  456.  
  457.  
  458.  
  459. /*
  460.  * Transform an array of texture coordinates by the current texture matrix.
  461.  * Input:  ctx - the context
  462.  *         n - number of texture coordinates in array
  463.  * In/Out:  t - array [n][4] of texture coordinates to transform
  464.  */
  465. static void transform_texcoords( GLcontext *ctx, GLuint n, GLfloat t[][4] )
  466. {
  467. #ifndef USE_ASM
  468.    START_FAST_MATH;
  469.    switch (ctx->TextureMatrixType) {
  470.       case MATRIX_GENERAL:
  471.      {
  472.         const GLfloat *m = ctx->TextureMatrix;
  473.         GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
  474.         GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
  475.         GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
  476.         GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
  477.         GLuint i;
  478.         for (i=0;i<n;i++) {
  479.            GLfloat t0 = t[i][0], t1 = t[i][1], t2 = t[i][2], t3 = t[i][3];
  480.            t[i][0] = m0 * t0 + m4 * t1 + m8  * t2 + m12 * t3;
  481.            t[i][1] = m1 * t0 + m5 * t1 + m9  * t2 + m13 * t3;
  482.            t[i][2] = m2 * t0 + m6 * t1 + m10 * t2 + m14 * t3;
  483.            t[i][3] = m3 * t0 + m7 * t1 + m11 * t2 + m15 * t3;
  484.         }
  485.      }
  486.      break;
  487.       case MATRIX_IDENTITY:
  488.      /* Do nothing */
  489.      break;
  490.       case MATRIX_2D:
  491.      {
  492.         const GLfloat *m = ctx->TextureMatrix;
  493.         GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5];
  494.         GLfloat m12 = m[12], m13 = m[13];
  495.         GLuint i;
  496.         for (i=0;i<n;i++) {
  497.            GLfloat t0 = t[i][0], t1 = t[i][1], t2 = t[i][2], t3 = t[i][3];
  498.            t[i][0] = m0 * t0 + m4 * t1            + m12 * t3;
  499.            t[i][1] = m1 * t0 + m5 * t1            + m13 * t3;
  500.            t[i][2] =                   +       t2           ;
  501.            /*t[i][3] unchanged*/
  502.         }
  503.      }
  504.      break;
  505.       case MATRIX_3D:
  506.      {
  507.         const GLfloat *m = ctx->TextureMatrix;
  508.         GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5];
  509.         GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10];
  510.         GLfloat m12 = m[12], m13 = m[13], m14 = m[14];
  511.         GLuint i;
  512.         for (i=0;i<n;i++) {
  513.            GLfloat t0 = t[i][0], t1 = t[i][1], t2 = t[i][2], t3 = t[i][3];
  514.            t[i][0] = m0 * t0 + m4 * t1 +  m8 * t2 + m12 * t3;
  515.            t[i][1] = m1 * t0 + m5 * t1 +  m9 * t2 + m13 * t3;
  516.            t[i][2] = m2 * t0 + m6 * t1 + m10 * t2 + m14 * t3;
  517.            /*t[i][3] unchanged*/
  518.         }
  519.      }
  520.      break;
  521.       default:
  522.      /* should never get here */
  523.      gl_problem( NULL, "invalid matrix type in transform_texcoords()" );
  524.    }
  525.    END_FAST_MATH;
  526. #else
  527.    switch (ctx->TextureMatrixType) {
  528.       case MATRIX_GENERAL:
  529.      asm_transform_points4_general( n, t, ctx->TextureMatrix, t );
  530.      break;
  531.       case MATRIX_IDENTITY:
  532.      /* Do nothing */
  533.      break;
  534.       case MATRIX_2D:
  535.      asm_transform_points4_2d( n, t, ctx->TextureMatrix, t );
  536.      break;
  537.       case MATRIX_3D:
  538.      asm_transform_points4_3d( n, t, ctx->TextureMatrix, t );
  539.      break;
  540.       default:
  541.      /* should never get here */
  542.      gl_problem( NULL, "invalid matrix type in transform_texcoords()" );
  543.      return;
  544.    }
  545. #endif
  546. }
  547.  
  548.  
  549.  
  550. /*
  551.  * Apply the projection matrix to an array of vertices in Eye coordinates
  552.  * resulting in Clip coordinates.  Also, compute the ClipMask bitfield for
  553.  * each vertex.
  554.  * Input:  ctx - the context
  555.  *         n - number of vertices
  556.  *         vEye - array [n][4] of Eye coordinates
  557.  * Output:  vClip - array [n][4] of Clip coordinates
  558.  *          clipMask - array [n] of clip masks
  559.  */
  560. static void project_and_cliptest( GLcontext *ctx,
  561.                   GLuint n, /*const*/ GLfloat vEye[][4],
  562.                   GLfloat vClip[][4], GLubyte clipMask[],
  563.                   GLubyte *orMask, GLubyte *andMask )
  564.  
  565. {
  566. #ifndef USE_ASM
  567.    GLubyte tmpOrMask = *orMask;
  568.    GLubyte tmpAndMask = *andMask;
  569.  
  570.    START_FAST_MATH;
  571.    switch (ctx->ProjectionMatrixType) {
  572.       case MATRIX_GENERAL:
  573.      {
  574.         const GLfloat *m = ctx->ProjectionMatrix;
  575.         GLfloat m0 = m[0],  m4 = m[4],  m8 = m[8],  m12 = m[12];
  576.         GLfloat m1 = m[1],  m5 = m[5],  m9 = m[9],  m13 = m[13];
  577.         GLfloat m2 = m[2],  m6 = m[6],  m10 = m[10],  m14 = m[14];
  578.         GLfloat m3 = m[3],  m7 = m[7],  m11 = m[11],  m15 = m[15];
  579.         GLuint i;
  580.         for (i=0;i<n;i++) {
  581.            GLfloat ex = vEye[i][0], ey = vEye[i][1];
  582.            GLfloat ez = vEye[i][2], ew = vEye[i][3];
  583.            GLfloat cx = m0 * ex + m4 * ey + m8  * ez + m12 * ew;
  584.            GLfloat cy = m1 * ex + m5 * ey + m9  * ez + m13 * ew;
  585.            GLfloat cz = m2 * ex + m6 * ey + m10 * ez + m14 * ew;
  586.            GLfloat cw = m3 * ex + m7 * ey + m11 * ez + m15 * ew;
  587.            GLubyte mask = 0;
  588.            vClip[i][0] = cx;
  589.            vClip[i][1] = cy;
  590.            vClip[i][2] = cz;
  591.            vClip[i][3] = cw;
  592.            if (cx >  cw)       mask |= CLIP_RIGHT_BIT;
  593.            else if (cx < -cw)  mask |= CLIP_LEFT_BIT;
  594.            if (cy >  cw)       mask |= CLIP_TOP_BIT;
  595.            else if (cy < -cw)  mask |= CLIP_BOTTOM_BIT;
  596.            if (cz >  cw)       mask |= CLIP_FAR_BIT;
  597.            else if (cz < -cw)  mask |= CLIP_NEAR_BIT;
  598.            if (mask) {
  599.           clipMask[i] |= mask;
  600.           tmpOrMask |= mask;
  601.            }
  602.            tmpAndMask &= mask;
  603.         }
  604.      }
  605.      break;
  606.       case MATRIX_IDENTITY:
  607.      {
  608.         GLuint i;
  609.         for (i=0;i<n;i++) {
  610.            GLfloat cx = vClip[i][0] = vEye[i][0];
  611.            GLfloat cy = vClip[i][1] = vEye[i][1];
  612.            GLfloat cz = vClip[i][2] = vEye[i][2];
  613.            GLfloat cw = vClip[i][3] = vEye[i][3];
  614.            GLubyte mask = 0;
  615.            if (cx >  cw)       mask |= CLIP_RIGHT_BIT;
  616.            else if (cx < -cw)  mask |= CLIP_LEFT_BIT;
  617.            if (cy >  cw)       mask |= CLIP_TOP_BIT;
  618.            else if (cy < -cw)  mask |= CLIP_BOTTOM_BIT;
  619.            if (cz >  cw)       mask |= CLIP_FAR_BIT;
  620.            else if (cz < -cw)  mask |= CLIP_NEAR_BIT;
  621.            if (mask) {
  622.           clipMask[i] |= mask;
  623.           tmpOrMask |= mask;
  624.            }
  625.            tmpAndMask &= mask;
  626.         }
  627.      }
  628.      break;
  629.       case MATRIX_ORTHO:
  630.      {
  631.         const GLfloat *m = ctx->ProjectionMatrix;
  632.         GLfloat m0 = m[0], m5 = m[5], m10 = m[10], m12 = m[12];
  633.         GLfloat m13 = m[13], m14 = m[14];
  634.         GLuint i;
  635.         for (i=0;i<n;i++) {
  636.            GLfloat ex = vEye[i][0], ey = vEye[i][1];
  637.            GLfloat ez = vEye[i][2], ew = vEye[i][3];
  638.            GLfloat cx = m0 * ex                      + m12 * ew;
  639.            GLfloat cy =           m5 * ey            + m13 * ew;
  640.            GLfloat cz =                     m10 * ez + m14 * ew;
  641.            GLfloat cw =                                      ew;
  642.            GLubyte mask = 0;
  643.            vClip[i][0] = cx;
  644.            vClip[i][1] = cy;
  645.            vClip[i][2] = cz;
  646.            vClip[i][3] = cw;
  647.            if (cx >  cw)       mask |= CLIP_RIGHT_BIT;
  648.            else if (cx < -cw)  mask |= CLIP_LEFT_BIT;
  649.            if (cy >  cw)       mask |= CLIP_TOP_BIT;
  650.            else if (cy < -cw)  mask |= CLIP_BOTTOM_BIT;
  651.            if (cz >  cw)       mask |= CLIP_FAR_BIT;
  652.            else if (cz < -cw)  mask |= CLIP_NEAR_BIT;
  653.            if (mask) {
  654.           clipMask[i] |= mask;
  655.           tmpOrMask |= mask;
  656.            }
  657.            tmpAndMask &= mask;
  658.         }
  659.      }
  660.      break;
  661.       case MATRIX_PERSPECTIVE:
  662.      {
  663.         const GLfloat *m = ctx->ProjectionMatrix;
  664.         GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9];
  665.         GLfloat m10 = m[10], m14 = m[14];
  666.         GLuint i;
  667.         for (i=0;i<n;i++) {
  668.            GLfloat ex = vEye[i][0], ey = vEye[i][1];
  669.            GLfloat ez = vEye[i][2], ew = vEye[i][3];
  670.            GLfloat cx = m0 * ex           + m8  * ez           ;
  671.            GLfloat cy =           m5 * ey + m9  * ez           ;
  672.            GLfloat cz =                     m10 * ez + m14 * ew;
  673.            GLfloat cw =                          -ez           ;
  674.            GLubyte mask = 0;
  675.            vClip[i][0] = cx;
  676.            vClip[i][1] = cy;
  677.            vClip[i][2] = cz;
  678.            vClip[i][3] = cw;
  679.            if (cx >  cw)       mask |= CLIP_RIGHT_BIT;
  680.            else if (cx < -cw)  mask |= CLIP_LEFT_BIT;
  681.            if (cy >  cw)       mask |= CLIP_TOP_BIT;
  682.            else if (cy < -cw)  mask |= CLIP_BOTTOM_BIT;
  683.            if (cz >  cw)       mask |= CLIP_FAR_BIT;
  684.            else if (cz < -cw)  mask |= CLIP_NEAR_BIT;
  685.            if (mask) {
  686.           clipMask[i] |= mask;
  687.           tmpOrMask |= mask;
  688.            }
  689.            tmpAndMask &= mask;
  690.         }
  691.      }
  692.      break;
  693.       default:
  694.      /* should never get here */
  695.      gl_problem( NULL, "invalid matrix type in project_and_cliptest()" );
  696.    }
  697.  
  698.    *orMask = tmpOrMask;
  699.    *andMask = tmpAndMask;
  700.    END_FAST_MATH;
  701. #else
  702.    switch (ctx->ProjectionMatrixType) {
  703.       case MATRIX_GENERAL:
  704.      asm_project_and_cliptest_general( n, vClip, ctx->ProjectionMatrix, vEye, 
  705.                        clipMask, orMask, andMask );
  706.      break;
  707.       case MATRIX_IDENTITY:
  708.      asm_project_and_cliptest_identity( n, vClip, vEye, clipMask, orMask, andMask );
  709.      break;
  710.       case MATRIX_ORTHO:
  711.      asm_project_and_cliptest_ortho( n, vClip, ctx->ProjectionMatrix, vEye, 
  712.                      clipMask, orMask, andMask );
  713.      break;
  714.       case MATRIX_PERSPECTIVE:
  715.      asm_project_and_cliptest_perspective( n, vClip, ctx->ProjectionMatrix,
  716.                            vEye, clipMask, orMask, andMask );
  717.      break;
  718.       default:
  719.      /* should never get here */
  720.      gl_problem( NULL, "invalid matrix type in project_and_cliptest()" );
  721.      return;
  722.    }
  723. #endif
  724. }
  725.  
  726.  
  727.  
  728. /*
  729.  * Test an array of vertices against the user-defined clipping planes.
  730.  * Input:  ctx - the context
  731.  *         n - number of vertices
  732.  *         vEye - array [n] of vertices, in eye coordinate system
  733.  * Output:  clipMask - array [n] of clip values: 0=not clipped, !0=clipped
  734.  * Return:  CLIP_ALL - if all vertices are clipped by one of the planes
  735.  *          CLIP_NONE - if no vertices were clipped
  736.  *          CLIP_SOME - if some vertices were clipped
  737.  */
  738. static GLuint userclip_vertices( GLcontext *ctx, GLuint n,
  739.                  /*const*/ GLfloat vEye[][4],
  740.                  GLubyte clipMask[] )
  741. {
  742.    GLboolean anyClipped = GL_FALSE;
  743.    GLuint p;
  744.  
  745.    ASSERT(ctx->Transform.AnyClip);
  746.  
  747.    START_FAST_MATH;
  748.  
  749.    for (p=0;p<MAX_CLIP_PLANES;p++) {
  750.       if (ctx->Transform.ClipEnabled[p]) {
  751.      GLfloat a = ctx->Transform.ClipEquation[p][0];
  752.      GLfloat b = ctx->Transform.ClipEquation[p][1];
  753.      GLfloat c = ctx->Transform.ClipEquation[p][2];
  754.      GLfloat d = ctx->Transform.ClipEquation[p][3];
  755.      GLboolean allClipped = GL_TRUE;
  756.      GLuint i;
  757.      for (i=0;i<n;i++) {
  758.         GLfloat dot = vEye[i][0] * a + vEye[i][1] * b
  759.             + vEye[i][2] * c + vEye[i][3] * d;
  760.         if (dot < 0.0F) {
  761.            /* this vertex is clipped */
  762.            clipMask[i] = CLIP_USER_BIT;
  763.            anyClipped = GL_TRUE;
  764.         }
  765.         else {
  766.            /* vertex not clipped */
  767.            allClipped = GL_FALSE;
  768.         }
  769.      }
  770.      if (allClipped) {
  771.         return CLIP_ALL;
  772.      }
  773.       }
  774.    }
  775.  
  776.    END_FAST_MATH;
  777.  
  778.    return anyClipped ? CLIP_SOME : CLIP_NONE;
  779. }
  780.  
  781.  
  782.  
  783. /*
  784.  * Transform an array of vertices from clip coordinate space to window
  785.  * coordinates.
  786.  * Input:  ctx - the context
  787.  *         n - number of vertices to transform
  788.  *         vClip - array [n] of input vertices
  789.  *         clipMask - array [n] of vertex clip masks.  NULL = no clipped verts
  790.  * Output:  vWin - array [n] of vertices in window coordinate system
  791.  */
  792. static void viewport_map_vertices( GLcontext *ctx,
  793.                    GLuint n, /*const*/ GLfloat vClip[][4],
  794.                    const GLubyte clipMask[], GLfloat vWin[][3])
  795. {
  796.    GLfloat sx = ctx->Viewport.Sx;
  797.    GLfloat tx = ctx->Viewport.Tx;
  798.    GLfloat sy = ctx->Viewport.Sy;
  799.    GLfloat ty = ctx->Viewport.Ty;
  800.    GLfloat sz = ctx->Viewport.Sz;
  801.    GLfloat tz = ctx->Viewport.Tz;
  802.  
  803.    START_FAST_MATH;
  804.    if ((ctx->ProjectionMatrixType==MATRIX_ORTHO || 
  805.     ctx->ProjectionMatrixType==MATRIX_IDENTITY)
  806.        && ctx->ModelViewMatrixType!=MATRIX_GENERAL
  807.        && (ctx->VB->VertexSizeMask & VERTEX4_BIT)==0) {
  808.       /* don't need to divide by W */
  809.       if (clipMask) {
  810.      /* one or more vertices are clipped */
  811.      GLuint i;
  812.      for (i=0;i<n;i++) {
  813.         if (clipMask[i]==0) {
  814.            vWin[i][0] = vClip[i][0] * sx + tx;
  815.            vWin[i][1] = vClip[i][1] * sy + ty;
  816.            vWin[i][2] = vClip[i][2] * sz + tz;
  817.         }
  818.      }
  819.       }
  820.       else {
  821.      /* no vertices are clipped */
  822.      GLuint i;
  823.      for (i=0;i<n;i++) {
  824.         vWin[i][0] = vClip[i][0] * sx + tx;
  825.         vWin[i][1] = vClip[i][1] * sy + ty;
  826.         vWin[i][2] = vClip[i][2] * sz + tz;
  827.      }
  828.       }
  829.    }
  830.    else {
  831.       /* need to divide by W */
  832.       if (clipMask) {
  833.      /* one or more vertices are clipped */
  834.      GLuint i;
  835.      for (i=0;i<n;i++) {
  836.         if (clipMask[i] == 0) {
  837.            if (vClip[i][3] != 0.0F) {
  838.           GLfloat wInv = 1.0F / vClip[i][3];
  839.           vWin[i][0] = vClip[i][0] * wInv * sx + tx;
  840.           vWin[i][1] = vClip[i][1] * wInv * sy + ty;
  841.           vWin[i][2] = vClip[i][2] * wInv * sz + tz;
  842.            }
  843.            else {
  844.           /* Div by zero!  Can't set window coords to infinity, so...*/
  845.           vWin[i][0] = 0.0F;
  846.           vWin[i][1] = 0.0F;
  847.           vWin[i][2] = 0.0F;
  848.            }
  849.         }
  850.      }
  851.       }
  852.       else {
  853.      /* no vertices are clipped */
  854.      GLuint i;
  855.      for (i=0;i<n;i++) {
  856.         if (vClip[i][3] != 0.0F) {
  857.            GLfloat wInv = 1.0F / vClip[i][3];
  858.            vWin[i][0] = vClip[i][0] * wInv * sx + tx;
  859.            vWin[i][1] = vClip[i][1] * wInv * sy + ty;
  860.            vWin[i][2] = vClip[i][2] * wInv * sz + tz;
  861.         }
  862.         else {
  863.            /* Divide by zero!  Can't set window coords to infinity, so...*/
  864.            vWin[i][0] = 0.0F;
  865.            vWin[i][1] = 0.0F;
  866.            vWin[i][2] = 0.0F;
  867.         }
  868.      }
  869.       }
  870.    }
  871.  
  872.    END_FAST_MATH;
  873. }
  874.  
  875.  
  876.  
  877. /*
  878.  * Check if the global material has to be updated with info that was
  879.  * associated with a vertex via glMaterial.
  880.  * This function is used when any material values get changed between
  881.  * glBegin/glEnd either by calling glMaterial() or by calling glColor()
  882.  * when GL_COLOR_MATERIAL is enabled.
  883.  */
  884. static void update_material( GLcontext *ctx, GLuint i )
  885. {
  886.    struct vertex_buffer *VB = ctx->VB;
  887.  
  888.    if (VB->MaterialMask[i]) {
  889.       if (VB->MaterialMask[i] & FRONT_AMBIENT_BIT) {
  890.      COPY_4V( ctx->Light.Material[0].Ambient, VB->Material[i][0].Ambient );
  891.       }
  892.       if (VB->MaterialMask[i] & BACK_AMBIENT_BIT) {
  893.      COPY_4V( ctx->Light.Material[1].Ambient, VB->Material[i][1].Ambient );
  894.       }
  895.       if (VB->MaterialMask[i] & FRONT_DIFFUSE_BIT) {
  896.      COPY_4V( ctx->Light.Material[0].Diffuse, VB->Material[i][0].Diffuse );
  897.       }
  898.       if (VB->MaterialMask[i] & BACK_DIFFUSE_BIT) {
  899.      COPY_4V( ctx->Light.Material[1].Diffuse, VB->Material[i][1].Diffuse );
  900.       }
  901.       if (VB->MaterialMask[i] & FRONT_SPECULAR_BIT) {
  902.      COPY_4V( ctx->Light.Material[0].Specular, VB->Material[i][0].Specular );
  903.       }
  904.       if (VB->MaterialMask[i] & BACK_SPECULAR_BIT) {
  905.      COPY_4V( ctx->Light.Material[1].Specular, VB->Material[i][1].Specular );
  906.       }
  907.       if (VB->MaterialMask[i] & FRONT_EMISSION_BIT) {
  908.      COPY_4V( ctx->Light.Material[0].Emission, VB->Material[i][0].Emission );
  909.       }
  910.       if (VB->MaterialMask[i] & BACK_EMISSION_BIT) {
  911.      COPY_4V( ctx->Light.Material[1].Emission, VB->Material[i][1].Emission );
  912.       }
  913.       if (VB->MaterialMask[i] & FRONT_SHININESS_BIT) {
  914.      ctx->Light.Material[0].Shininess = VB->Material[i][0].Shininess;
  915.      gl_compute_material_shine_table( &ctx->Light.Material[0] );
  916.       }
  917.       if (VB->MaterialMask[i] & BACK_SHININESS_BIT) {
  918.      ctx->Light.Material[1].Shininess = VB->Material[i][1].Shininess;
  919.      gl_compute_material_shine_table( &ctx->Light.Material[1] );
  920.       }
  921.       if (VB->MaterialMask[i] & FRONT_INDEXES_BIT) {
  922.      ctx->Light.Material[0].AmbientIndex = VB->Material[i][0].AmbientIndex;
  923.      ctx->Light.Material[0].DiffuseIndex = VB->Material[i][0].DiffuseIndex;
  924.      ctx->Light.Material[0].SpecularIndex = VB->Material[i][0].SpecularIndex;
  925.       }
  926.       if (VB->MaterialMask[i] & BACK_INDEXES_BIT) {
  927.      ctx->Light.Material[1].AmbientIndex = VB->Material[i][1].AmbientIndex;
  928.      ctx->Light.Material[1].DiffuseIndex = VB->Material[i][1].DiffuseIndex;
  929.      ctx->Light.Material[1].SpecularIndex = VB->Material[i][1].SpecularIndex;
  930.       }
  931.       VB->MaterialMask[i] = 0;  /* reset now */
  932.    }
  933. }
  934.  
  935.  
  936. /*
  937.  * Compute the shading (lighting) for the vertices in the vertex buffer.
  938.  */
  939. static void shade_vertices( GLcontext *ctx )
  940. {
  941.    struct vertex_buffer *VB = ctx->VB;
  942.  
  943.    if (ctx->Visual->RGBAflag) {
  944.       if (!VB->MonoMaterial) {
  945.      /* Material may change with each vertex */
  946.      GLuint i;
  947.      for (i=VB->Start; i<VB->Count; i++) {
  948.         update_material( ctx, i );
  949.         gl_color_shade_vertices( ctx, 0, 1, &VB->Eye[i],
  950.                      &VB->Normal[i], &VB->Fcolor[i]);
  951.         if (ctx->Light.Model.TwoSide) {
  952.            gl_color_shade_vertices( ctx, 1, 1, &VB->Eye[i],
  953.                     &VB->Normal[i], &VB->Bcolor[i]);
  954.         }
  955.      }
  956.      /* Need this in case a glColor/glMaterial is called after the
  957.       * last vertex between glBegin/glEnd.
  958.       */
  959.      update_material( ctx, VB->Count );
  960.       }
  961.       else {
  962.      if (ctx->Light.Fast) {
  963.         if (VB->MonoNormal) {
  964.            /* call optimized shader */
  965.            GLubyte color[1][4];
  966.            GLuint i;
  967.            gl_color_shade_vertices_fast( ctx, 0,  /* front side */
  968.                          1,
  969.                          VB->Normal + VB->Start,
  970.                          color );
  971.            for (i=VB->Start; i<VB->Count; i++) {
  972.           COPY_4V( VB->Fcolor[i], color[0] );
  973.            }
  974.            if (ctx->Light.Model.TwoSide) {
  975.           gl_color_shade_vertices_fast( ctx, 1,  /* back side */
  976.                         1,
  977.                         VB->Normal + VB->Start,
  978.                         color );
  979.           for (i=VB->Start; i<VB->Count; i++) {
  980.              COPY_4V( VB->Bcolor[i], color[0] );
  981.           }
  982.            }
  983.  
  984.         }
  985.         else {
  986.            /* call optimized shader */
  987.            gl_color_shade_vertices_fast( ctx, 0,  /* front side */
  988.                          VB->Count - VB->Start,
  989.                          VB->Normal + VB->Start,
  990.                          VB->Fcolor + VB->Start );
  991.            if (ctx->Light.Model.TwoSide) {
  992.           gl_color_shade_vertices_fast( ctx, 1,  /* back side */
  993.                         VB->Count - VB->Start,
  994.                         VB->Normal + VB->Start,
  995.                         VB->Bcolor + VB->Start );
  996.            }
  997.         }
  998.      }
  999.      else {
  1000.         /* call slower, full-featured shader */
  1001.         gl_color_shade_vertices( ctx, 0,
  1002.                      VB->Count - VB->Start,
  1003.                      VB->Eye + VB->Start,
  1004.                      VB->Normal + VB->Start,
  1005.                      VB->Fcolor + VB->Start );
  1006.         if (ctx->Light.Model.TwoSide) {
  1007.            gl_color_shade_vertices( ctx, 1,
  1008.                     VB->Count - VB->Start,
  1009.                     VB->Eye + VB->Start,
  1010.                     VB->Normal + VB->Start,
  1011.                     VB->Bcolor + VB->Start );
  1012.         }
  1013.      }
  1014.       }
  1015.    }
  1016.    else {
  1017.       /* Color index mode */
  1018.       if (!VB->MonoMaterial) {
  1019.      /* Material may change with each vertex */
  1020.      GLuint i;
  1021.      /* NOTE the <= here.  This is needed in case glColor/glMaterial
  1022.       * is called after the last glVertex inside a glBegin/glEnd pair.
  1023.       */
  1024.      for (i=VB->Start; i<VB->Count; i++) {
  1025.         update_material( ctx, i );
  1026.         gl_index_shade_vertices( ctx, 0, 1, &VB->Eye[i],
  1027.                      &VB->Normal[i], &VB->Findex[i] );
  1028.         if (ctx->Light.Model.TwoSide) {
  1029.            gl_index_shade_vertices( ctx, 1, 1, &VB->Eye[i],
  1030.                     &VB->Normal[i], &VB->Bindex[i] );
  1031.         }
  1032.      }
  1033.      /* Need this in case a glColor/glMaterial is called after the
  1034.       * last vertex between glBegin/glEnd.
  1035.       */
  1036.      update_material( ctx, VB->Count );
  1037.       }
  1038.       else {
  1039.      gl_index_shade_vertices( ctx, 0,
  1040.                   VB->Count - VB->Start,
  1041.                   VB->Eye + VB->Start,
  1042.                   VB->Normal + VB->Start,
  1043.                   VB->Findex + VB->Start );
  1044.      if (ctx->Light.Model.TwoSide) {
  1045.         gl_index_shade_vertices( ctx, 1,
  1046.                      VB->Count - VB->Start,
  1047.                      VB->Eye + VB->Start,
  1048.                      VB->Normal + VB->Start,
  1049.                      VB->Bindex + VB->Start );
  1050.      }
  1051.       }
  1052.    }
  1053. }
  1054.  
  1055.  
  1056.  
  1057. /*
  1058.  * Compute fog for the vertices in the vertex buffer.
  1059.  */
  1060. static void fog_vertices( GLcontext *ctx )
  1061. {
  1062.    struct vertex_buffer *VB = ctx->VB;
  1063.  
  1064.    if (ctx->Visual->RGBAflag) {
  1065.       /* Fog RGB colors */
  1066.       gl_fog_color_vertices( ctx, VB->Count - VB->Start,
  1067.                  VB->Eye + VB->Start,
  1068.                  VB->Fcolor + VB->Start );
  1069.       if (ctx->LightTwoSide) {
  1070.      gl_fog_color_vertices( ctx, VB->Count - VB->Start,
  1071.                 VB->Eye + VB->Start,
  1072.                 VB->Bcolor + VB->Start );
  1073.       }
  1074.    }
  1075.    else {
  1076.       /* Fog color indexes */
  1077.       gl_fog_index_vertices( ctx, VB->Count - VB->Start,
  1078.                  VB->Eye + VB->Start,
  1079.                  VB->Findex + VB->Start );
  1080.       if (ctx->LightTwoSide) {
  1081.      gl_fog_index_vertices( ctx, VB->Count - VB->Start,
  1082.                 VB->Eye + VB->Start,
  1083.                 VB->Bindex + VB->Start );
  1084.       }
  1085.    }
  1086. }
  1087.  
  1088.  
  1089.  
  1090. /*
  1091.  * When the Vertex Buffer is full, this function applies the modelview
  1092.  * matrix to transform vertices and normals from object coordinates to
  1093.  * eye coordinates.  Next, we'll call gl_transform_vb_part2()...
  1094.  * This function might not be called when using vertex arrays.
  1095.  */
  1096. void gl_transform_vb_part1( GLcontext *ctx, GLboolean allDone )
  1097. {
  1098.    struct vertex_buffer *VB = ctx->VB;
  1099. #ifdef PROFILE
  1100.    GLdouble t0 = gl_time();
  1101. #endif
  1102.  
  1103.    ASSERT( VB->Count>0 );
  1104.  
  1105.    /* Apply the modelview matrix to transform vertexes from Object
  1106.     * to Eye coords.
  1107.     */
  1108.    if (VB->VertexSizeMask==VERTEX4_BIT) {
  1109.       transform_points4( ctx, VB->Count - VB->Start,
  1110.              VB->Obj + VB->Start, VB->Eye + VB->Start );
  1111.    }
  1112.    else {
  1113.       transform_points3( ctx, VB->Count - VB->Start,
  1114.              VB->Obj + VB->Start, VB->Eye + VB->Start );
  1115.    }
  1116.  
  1117.    /* Now transform the normal vectors */
  1118.    if (ctx->NeedNormals) {
  1119.       gl_xform_normals_3fv( VB->Count - VB->Start,
  1120.                 VB->Normal + VB->Start, ctx->ModelViewInv,
  1121.                 VB->Normal + VB->Start, ctx->Transform.Normalize );
  1122.    }
  1123.  
  1124. #ifdef PROFILE
  1125.    ctx->VertexTime += gl_time() - t0;
  1126. #endif
  1127.  
  1128.    /* lighting, project, etc */
  1129.    gl_transform_vb_part2( ctx, allDone );
  1130. }
  1131.  
  1132.  
  1133.  
  1134. /*
  1135.  * Part 2 of Vertex Buffer transformation:  compute lighting, clipflags,
  1136.  * fog, texture coords, etc.
  1137.  * Before this function is called the VB->Eye coordinates must have
  1138.  * already been computed.
  1139.  * Callers:  gl_transform_vb_part1(), glDrawArraysEXT()
  1140.  */
  1141. void gl_transform_vb_part2( GLcontext *ctx, GLboolean allDone )
  1142. {
  1143.    struct vertex_buffer *VB = ctx->VB;
  1144. #ifdef PROFILE
  1145.    GLdouble t0 = gl_time();
  1146. #endif
  1147.  
  1148.    ASSERT( VB->Count>0 );
  1149.  
  1150.    /* Test vertices in eye coordinate space against user clipping planes */
  1151.    if (ctx->Transform.AnyClip) {
  1152.       GLuint result = userclip_vertices( ctx, VB->Count - VB->Start,
  1153.                      VB->Eye + VB->Start,
  1154.                      VB->ClipMask + VB->Start );
  1155.       if (result==CLIP_ALL) {
  1156.      /* All vertices were outside one of the clip planes! */
  1157.      gl_reset_vb( ctx, allDone );
  1158.      return;
  1159.       }
  1160.       else if (result==CLIP_SOME) {
  1161.      VB->ClipOrMask = CLIP_USER_BIT;
  1162.       }
  1163.       else {
  1164.      VB->ClipAndMask = 0;
  1165.       }
  1166.    }
  1167.  
  1168.    /* Apply the projection matrix to the Eye coordinates, resulting in
  1169.     * Clip coordinates.  Also, compute the ClipMask for each vertex.
  1170.     */
  1171.    project_and_cliptest( ctx, VB->Count - VB->Start, VB->Eye + VB->Start,
  1172.              VB->Clip + VB->Start, VB->ClipMask + VB->Start,
  1173.              &VB->ClipOrMask, &VB->ClipAndMask );
  1174.  
  1175.    if (VB->ClipAndMask) {
  1176.       /* All vertices clipped by one plane, all done! */
  1177.       gl_reset_vb( ctx, allDone );
  1178.       return;
  1179.    }
  1180.  
  1181.    /* Lighting */
  1182.    if (ctx->Light.Enabled) {
  1183.       shade_vertices(ctx);
  1184.    }
  1185.  
  1186.    /* Per-vertex fog */
  1187.    if (ctx->Fog.Enabled && ctx->Hint.Fog!=GL_NICEST) {
  1188.       fog_vertices(ctx);
  1189.    }
  1190.  
  1191.    /* Generate/transform texture coords */
  1192.    if (ctx->Texture.Enabled || ctx->RenderMode==GL_FEEDBACK) {
  1193.       if (ctx->Texture.TexGenEnabled) {
  1194.      gl_texgen( ctx, VB->Count - VB->Start,
  1195.             VB->Obj + VB->Start,
  1196.             VB->Eye + VB->Start,
  1197.             VB->Normal + VB->Start,
  1198.             VB->TexCoord + VB->Start );
  1199.       }
  1200.       if (ctx->NewTextureMatrix) {
  1201.      gl_analyze_texture_matrix(ctx);
  1202.       }
  1203.       if (ctx->TextureMatrixType!=MATRIX_IDENTITY) {
  1204.      transform_texcoords( ctx, VB->Count - VB->Start,
  1205.                   VB->TexCoord + VB->Start );
  1206.       }
  1207.    }
  1208.  
  1209.    /* Use the viewport parameters to transform vertices from Clip
  1210.     * coordinates to Window coordinates.
  1211.     */
  1212.    viewport_map_vertices( ctx, VB->Count - VB->Start, VB->Clip + VB->Start,
  1213.               VB->ClipOrMask ? VB->ClipMask + VB->Start : NULL,
  1214.               VB->Win + VB->Start );
  1215.  
  1216.    /* Device driver rasterization setup.  3Dfx driver, for example. */
  1217.    if (ctx->Driver.RasterSetup) {
  1218.       (*ctx->Driver.RasterSetup)( ctx, 0, VB->Count );
  1219.    }
  1220.  
  1221.  
  1222. #ifdef PROFILE
  1223.    ctx->VertexTime += gl_time() - t0;
  1224.    ctx->VertexCount += VB->Count - VB->Start;
  1225. #endif
  1226.  
  1227.    /*
  1228.     * Now we're ready to rasterize the Vertex Buffer!!!
  1229.     *
  1230.     * If the device driver can't rasterize the vertex buffer then we'll
  1231.     * do it ourselves.
  1232.     */
  1233.    if (!ctx->Driver.RenderVB || !(*ctx->Driver.RenderVB)(ctx,allDone)) {
  1234.       gl_render_vb( ctx, allDone );
  1235.    }
  1236. }
  1237.