home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / triangle.c < prev    next >
C/C++ Source or Header  |  2000-01-07  |  62KB  |  1,611 lines

  1. /* $Id: triangle.c,v 1.4.2.1 1999/11/22 13:43:15 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.1
  6.  * 
  7.  * Copyright (C) 1999  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.  
  28.  
  29.  
  30. /*
  31.  * Triangle rasterizers
  32.  * When the device driver doesn't implement triangle rasterization Mesa
  33.  * will use these functions to draw triangles.
  34.  */
  35.  
  36.  
  37. #ifdef PC_HEADER
  38. #include "all.h"
  39. #else
  40. #ifndef XFree86Server
  41. #include <assert.h>
  42. #include <math.h>
  43. #include <stdio.h>
  44. #else
  45. #include "GL/xf86glx.h"
  46. #endif
  47. #include "context.h"
  48. #include "depth.h"
  49. #include "feedback.h"
  50. #include "macros.h"
  51. #include "mmath.h"
  52. #include "span.h"
  53. #include "texstate.h"
  54. #include "triangle.h"
  55. #include "types.h"
  56. #include "vb.h"
  57. #endif
  58.  
  59.  
  60. GLboolean gl_cull_triangle( GLcontext *ctx,
  61.                                GLuint v0, GLuint v1, GLuint v2, GLuint pv )
  62. {
  63.    struct vertex_buffer *VB = ctx->VB;
  64.    GLfloat (*win)[4] = VB->Win.data;
  65.    GLfloat ex = win[v1][0] - win[v0][0];
  66.    GLfloat ey = win[v1][1] - win[v0][1];
  67.    GLfloat fx = win[v2][0] - win[v0][0];
  68.    GLfloat fy = win[v2][1] - win[v0][1];
  69.    GLfloat c = ex*fy-ey*fx;
  70.  
  71.    if (c * ctx->backface_sign > 0)
  72.       return 0;
  73.  
  74.    return 1;
  75. }
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82. /*
  83.  * Render a flat-shaded color index triangle.
  84.  */
  85. static void flat_ci_triangle( GLcontext *ctx,
  86.                               GLuint v0, GLuint v1, GLuint v2, GLuint pv )
  87. {
  88. #define INTERP_Z 1
  89.  
  90. #define SETUP_CODE                \
  91.    GLuint index = VB->IndexPtr->data[pv];    \
  92.    if (1) {                    \
  93.       /* set the color index */            \
  94.       (*ctx->Driver.Index)( ctx, index );    \
  95.    }
  96.  
  97. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  98.     {                            \
  99.        GLint i, n = RIGHT-LEFT;                \
  100.        GLdepth zspan[MAX_WIDTH];                \
  101.        if (n>0) {                        \
  102.           for (i=0;i<n;i++) {                \
  103.          zspan[i] = FixedToDepth(ffz);            \
  104.          ffz += fdzdx;                    \
  105.           }                            \
  106.           gl_write_monoindex_span( ctx, n, LEFT, Y,        \
  107.                                 zspan, index, GL_POLYGON );    \
  108.        }                            \
  109.     }
  110.  
  111. #include "tritemp.h"          
  112. }
  113.  
  114.  
  115.  
  116. /*
  117.  * Render a smooth-shaded color index triangle.
  118.  */
  119. static void smooth_ci_triangle( GLcontext *ctx,
  120.                                 GLuint v0, GLuint v1, GLuint v2, GLuint pv )
  121. {
  122.    (void) pv;
  123. #define INTERP_Z 1
  124. #define INTERP_INDEX 1
  125.  
  126. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  127.     {                            \
  128.        GLint i, n = RIGHT-LEFT;                \
  129.        GLdepth zspan[MAX_WIDTH];                \
  130.            GLuint index[MAX_WIDTH];                \
  131.        if (n>0) {                        \
  132.           for (i=0;i<n;i++) {                \
  133.          zspan[i] = FixedToDepth(ffz);            \
  134.                  index[i] = FixedToInt(ffi);            \
  135.          ffz += fdzdx;                    \
  136.          ffi += fdidx;                    \
  137.           }                            \
  138.           gl_write_index_span( ctx, n, LEFT, Y, zspan,    \
  139.                                index, GL_POLYGON );        \
  140.        }                            \
  141.     }
  142.  
  143. #include "tritemp.h"
  144. }
  145.  
  146.  
  147.  
  148. /*
  149.  * Render a flat-shaded RGBA triangle.
  150.  */
  151. static void flat_rgba_triangle( GLcontext *ctx,
  152.                                 GLuint v0, GLuint v1, GLuint v2, GLuint pv )
  153. {
  154. #define INTERP_Z 1
  155.  
  156. #define SETUP_CODE                \
  157.    if (1) {                    \
  158.       /* set the color */            \
  159.       GLubyte r = VB->ColorPtr->data[pv][0];    \
  160.       GLubyte g = VB->ColorPtr->data[pv][1];    \
  161.       GLubyte b = VB->ColorPtr->data[pv][2];    \
  162.       GLubyte a = VB->ColorPtr->data[pv][3];    \
  163.       (*ctx->Driver.Color)( ctx, r, g, b, a );    \
  164.    }
  165.  
  166. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  167.     {                            \
  168.        GLint i, n = RIGHT-LEFT;                \
  169.        GLdepth zspan[MAX_WIDTH];                \
  170.        if (n>0) {                        \
  171.           for (i=0;i<n;i++) {                \
  172.          zspan[i] = FixedToDepth(ffz);            \
  173.          ffz += fdzdx;                    \
  174.           }                            \
  175.               gl_write_monocolor_span( ctx, n, LEFT, Y, zspan,    \
  176.                                     VB->ColorPtr->data[pv],    \
  177.                         GL_POLYGON );        \
  178.        }                            \
  179.     }
  180.  
  181. #include "tritemp.h"
  182.  
  183.    ASSERT(!ctx->Texture.ReallyEnabled);  /* texturing must be off */
  184.    ASSERT(ctx->Light.ShadeModel==GL_FLAT);
  185. }
  186.  
  187.  
  188.  
  189. /*
  190.  * Render a smooth-shaded RGBA triangle.
  191.  */
  192. static void smooth_rgba_triangle( GLcontext *ctx,
  193.                                   GLuint v0, GLuint v1, GLuint v2, GLuint pv )
  194. {
  195.    (void) pv;
  196. #define INTERP_Z 1
  197. #define INTERP_RGB 1
  198. #define INTERP_ALPHA 1
  199.  
  200. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  201.     {                            \
  202.        GLint i, n = RIGHT-LEFT;                \
  203.        GLdepth zspan[MAX_WIDTH];                \
  204.        GLubyte rgba[MAX_WIDTH][4];                \
  205.        if (n>0) {                        \
  206.           for (i=0;i<n;i++) {                \
  207.          zspan[i] = FixedToDepth(ffz);            \
  208.          rgba[i][RCOMP] = FixedToInt(ffr);        \
  209.          rgba[i][GCOMP] = FixedToInt(ffg);        \
  210.          rgba[i][BCOMP] = FixedToInt(ffb);        \
  211.          rgba[i][ACOMP] = FixedToInt(ffa);        \
  212.          ffz += fdzdx;                    \
  213.          ffr += fdrdx;                    \
  214.          ffg += fdgdx;                    \
  215.          ffb += fdbdx;                    \
  216.          ffa += fdadx;                    \
  217.           }                            \
  218.           gl_write_rgba_span( ctx, n, LEFT, Y,        \
  219.                                   (const GLdepth *) zspan,    \
  220.                               rgba, GL_POLYGON );        \
  221.        }                            \
  222.     }
  223.  
  224. #include "tritemp.h"
  225.  
  226.    ASSERT(!ctx->Texture.ReallyEnabled);  /* texturing must be off */
  227.    ASSERT(ctx->Light.ShadeModel==GL_SMOOTH);
  228. }
  229.  
  230.  
  231. /*
  232.  * Render an RGB, GL_DECAL, textured triangle.
  233.  * Interpolate S,T only w/out mipmapping or perspective correction.
  234.  */
  235. static void simple_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  236.                                       GLuint v2, GLuint pv )
  237. {
  238. #define INTERP_INT_ST 1
  239. #define S_SCALE twidth
  240. #define T_SCALE theight
  241. #define SETUP_CODE                            \
  242.    struct gl_texture_object *obj = ctx->Texture.Unit[0].CurrentD[2];    \
  243.    GLint b = obj->BaseLevel;                        \
  244.    GLfloat twidth = (GLfloat) obj->Image[b]->Width;            \
  245.    GLfloat theight = (GLfloat) obj->Image[b]->Height;            \
  246.    GLint twidth_log2 = obj->Image[b]->WidthLog2;            \
  247.    GLubyte *texture = obj->Image[b]->Data;                \
  248.    GLint smask = obj->Image[b]->Width - 1;                \
  249.    GLint tmask = obj->Image[b]->Height - 1;
  250.    (void) pv;
  251.  
  252. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  253.     {                            \
  254.        GLint i, n = RIGHT-LEFT;                \
  255.        GLubyte rgb[MAX_WIDTH][3];                \
  256.        if (n>0) {                        \
  257.               ffs -= FIXED_HALF; /* off-by-one error? */        \
  258.               fft -= FIXED_HALF;                                \
  259.           for (i=0;i<n;i++) {                \
  260.                  GLint s = FixedToInt(ffs) & smask;        \
  261.                  GLint t = FixedToInt(fft) & tmask;        \
  262.                  GLint pos = (t << twidth_log2) + s;        \
  263.                  pos = pos + pos + pos;  /* multiply by 3 */    \
  264.                  rgb[i][RCOMP] = texture[pos];            \
  265.                  rgb[i][GCOMP] = texture[pos+1];        \
  266.                  rgb[i][BCOMP] = texture[pos+2];        \
  267.          ffs += fdsdx;                    \
  268.          fft += fdtdx;                    \
  269.           }                            \
  270.               (*ctx->Driver.WriteRGBSpan)( ctx, n, LEFT, Y,    \
  271.                            (const GLubyte (*)[3]) rgb, NULL );    \
  272.        }                            \
  273.     }
  274.  
  275. #include "tritemp.h"
  276. }
  277.  
  278.  
  279. /*
  280.  * Render an RGB, GL_DECAL, textured triangle.
  281.  * Interpolate S,T, GL_LESS depth test, w/out mipmapping or
  282.  * perspective correction.
  283.  */
  284. static void simple_z_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  285.                                         GLuint v2, GLuint pv )
  286. {
  287. #define INTERP_Z 1
  288. #define INTERP_INT_ST 1
  289. #define S_SCALE twidth
  290. #define T_SCALE theight
  291. #define SETUP_CODE                            \
  292.    struct gl_texture_object *obj = ctx->Texture.Unit[0].CurrentD[2];    \
  293.    GLint b = obj->BaseLevel;                        \
  294.    GLfloat twidth = (GLfloat) obj->Image[b]->Width;            \
  295.    GLfloat theight = (GLfloat) obj->Image[b]->Height;            \
  296.    GLint twidth_log2 = obj->Image[b]->WidthLog2;            \
  297.    GLubyte *texture = obj->Image[b]->Data;                \
  298.    GLint smask = obj->Image[b]->Width - 1;                \
  299.    GLint tmask = obj->Image[b]->Height - 1;
  300.    (void) pv;
  301.  
  302. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  303.     {                            \
  304.        GLint i, n = RIGHT-LEFT;                \
  305.        GLubyte rgb[MAX_WIDTH][3];                \
  306.            GLubyte mask[MAX_WIDTH];                \
  307.        if (n>0) {                        \
  308.               ffs -= FIXED_HALF; /* off-by-one error? */        \
  309.               fft -= FIXED_HALF;                                \
  310.           for (i=0;i<n;i++) {                \
  311.                  GLdepth z = FixedToDepth(ffz);            \
  312.                  if (z < zRow[i]) {                \
  313.                     GLint s = FixedToInt(ffs) & smask;        \
  314.                     GLint t = FixedToInt(fft) & tmask;        \
  315.                     GLint pos = (t << twidth_log2) + s;        \
  316.                     pos = pos + pos + pos;  /* multiply by 3 */    \
  317.                     rgb[i][RCOMP] = texture[pos];        \
  318.                     rgb[i][GCOMP] = texture[pos+1];        \
  319.                     rgb[i][BCOMP] = texture[pos+2];        \
  320.             zRow[i] = z;                \
  321.                     mask[i] = 1;                \
  322.                  }                        \
  323.                  else {                        \
  324.                     mask[i] = 0;                \
  325.                  }                        \
  326.          ffz += fdzdx;                    \
  327.          ffs += fdsdx;                    \
  328.          fft += fdtdx;                    \
  329.           }                            \
  330.               (*ctx->Driver.WriteRGBSpan)( ctx, n, LEFT, Y,    \
  331.                            (const GLubyte (*)[3]) rgb, mask );    \
  332.        }                            \
  333.     }
  334.  
  335. #include "tritemp.h"
  336. }
  337.  
  338.  
  339.  
  340. /*
  341.  * Render an RGB/RGBA textured triangle without perspective correction.
  342.  */
  343. static void affine_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  344.                       GLuint v2, GLuint pv )
  345. {
  346. #define INTERP_Z 1
  347. #define INTERP_RGB 1
  348. #define INTERP_ALPHA 1
  349. #define INTERP_INT_ST 1
  350. #define S_SCALE twidth
  351. #define T_SCALE theight
  352. #define SETUP_CODE                            \
  353.    struct gl_texture_unit *unit = ctx->Texture.Unit+0;            \
  354.    struct gl_texture_object *obj = unit->CurrentD[2];            \
  355.    GLint b = obj->BaseLevel;                        \
  356.    GLfloat twidth = (GLfloat) obj->Image[b]->Width;            \
  357.    GLfloat theight = (GLfloat) obj->Image[b]->Height;            \
  358.    GLint twidth_log2 = obj->Image[b]->WidthLog2;            \
  359.    GLubyte *texture = obj->Image[b]->Data;                \
  360.    GLint smask = obj->Image[b]->Width - 1;                \
  361.    GLint tmask = obj->Image[b]->Height - 1;                             \
  362.    GLint format = obj->Image[b]->Format;                                \
  363.    GLint filter = obj->MinFilter;                                       \
  364.    GLint envmode = unit->EnvMode;                                       \
  365.    GLint comp, tbytesline, tsize;                                       \
  366.    GLfixed er, eg, eb, ea;                                              \
  367.    GLint tr, tg, tb, ta;                                                \
  368.    if (envmode == GL_BLEND || envmode == GL_ADD) {                      \
  369.       /* potential off-by-one error here? (1.0f -> 2048 -> 0) */        \
  370.       er = FloatToFixed(unit->EnvColor[0]);                             \
  371.       eg = FloatToFixed(unit->EnvColor[1]);                             \
  372.       eb = FloatToFixed(unit->EnvColor[2]);                             \
  373.       ea = FloatToFixed(unit->EnvColor[3]);                             \
  374.    }                                                                    \
  375.    switch (format) {                                                    \
  376.    case GL_ALPHA:                                                       \
  377.    case GL_LUMINANCE:                                                   \
  378.    case GL_INTENSITY:                                                   \
  379.       comp = 1;                                                         \
  380.       break;                                                            \
  381.    case GL_LUMINANCE_ALPHA:                                             \
  382.       comp = 2;                                                         \
  383.       break;                                                            \
  384.    case GL_RGB:                                                         \
  385.       comp = 3;                                                         \
  386.       break;                                                            \
  387.    case GL_RGBA:                                                        \
  388.       comp = 4;                                                         \
  389.       break;                                                            \
  390.    default:                                                             \
  391.       gl_problem(NULL, "Bad texture format in affine_texture_triangle");\
  392.       return;                                                           \
  393.    }                                                                    \
  394.    tbytesline = obj->Image[b]->Width * comp;                            \
  395.    tsize = theight * tbytesline;
  396.    (void) pv;
  397.  
  398.   /* Instead of defining a function for each mode, a test is done 
  399.    * between the outer and inner loops. This is to reduce code size
  400.    * and complexity. Observe that an optimizing compiler kills 
  401.    * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
  402.    */ 
  403.  
  404. #define NEAREST_RGB    \
  405.         tr = tex00[0]; \
  406.         tg = tex00[1]; \
  407.         tb = tex00[2]; \
  408.         ta = 0xff
  409.  
  410. #define LINEAR_RGB                                                      \
  411.     tr = (ti * (si * tex00[0] + sf * tex01[0]) +                    \
  412.               tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT; \
  413.     tg = (ti * (si * tex00[1] + sf * tex01[1]) +                    \
  414.               tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT; \
  415.     tb = (ti * (si * tex00[2] + sf * tex01[2]) +                    \
  416.               tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT; \
  417.     ta = 0xff
  418.  
  419. #define NEAREST_RGBA   \
  420.         tr = tex00[0]; \
  421.         tg = tex00[1]; \
  422.         tb = tex00[2]; \
  423.         ta = tex00[3]
  424.  
  425. #define LINEAR_RGBA                                                     \
  426.     tr = (ti * (si * tex00[0] + sf * tex01[0]) +                    \
  427.               tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT; \
  428.     tg = (ti * (si * tex00[1] + sf * tex01[1]) +                    \
  429.               tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT; \
  430.     tb = (ti * (si * tex00[2] + sf * tex01[2]) +                    \
  431.               tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT; \
  432.     ta = (ti * (si * tex00[3] + sf * tex01[3]) +                    \
  433.               tf * (si * tex10[3] + sf * tex11[3])) >> 2 * FIXED_SHIFT
  434.  
  435. #define MODULATE                                       \
  436.         dest[0] = ffr * (tr + 1) >> (FIXED_SHIFT + 8); \
  437.         dest[1] = ffg * (tg + 1) >> (FIXED_SHIFT + 8); \
  438.         dest[2] = ffb * (tb + 1) >> (FIXED_SHIFT + 8); \
  439.         dest[3] = ffa * (ta + 1) >> (FIXED_SHIFT + 8)
  440.  
  441. #define DECAL                                                                \
  442.     dest[0] = ((0xff - ta) * ffr + ((ta + 1) * tr << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \
  443.     dest[1] = ((0xff - ta) * ffg + ((ta + 1) * tg << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \
  444.     dest[2] = ((0xff - ta) * ffb + ((ta + 1) * tb << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \
  445.     dest[3] = FixedToInt(ffa)
  446.  
  447. #define BLEND                                                               \
  448.         dest[0] = ((0xff - tr) * ffr + (tr + 1) * er) >> (FIXED_SHIFT + 8); \
  449.         dest[1] = ((0xff - tg) * ffg + (tg + 1) * eg) >> (FIXED_SHIFT + 8); \
  450.         dest[2] = ((0xff - tb) * ffb + (tb + 1) * eb) >> (FIXED_SHIFT + 8); \
  451.     dest[3] = ffa * (ta + 1) >> (FIXED_SHIFT + 8)
  452.  
  453. #define REPLACE       \
  454.         dest[0] = tr; \
  455.         dest[1] = tg; \
  456.         dest[2] = tb; \
  457.         dest[3] = ta
  458.  
  459. #define ADD                                                          \
  460.         dest[0] = ((ffr << 8) + (tr + 1) * er) >> (FIXED_SHIFT + 8); \
  461.         dest[1] = ((ffg << 8) + (tg + 1) * eg) >> (FIXED_SHIFT + 8); \
  462.         dest[2] = ((ffb << 8) + (tb + 1) * eb) >> (FIXED_SHIFT + 8); \
  463.     dest[3] = ffa * (ta + 1) >> (FIXED_SHIFT + 8)
  464.  
  465. /* shortcuts */
  466.  
  467. #define NEAREST_RGB_REPLACE  NEAREST_RGB;REPLACE
  468.  
  469. #define NEAREST_RGBA_REPLACE  *(GLint *)dest = *(GLint *)tex00
  470.  
  471. #define SPAN1(DO_TEX,COMP)                                 \
  472.     for (i=0;i<n;i++) {                                \
  473.            GLint s = FixedToInt(ffs) & smask;              \
  474.            GLint t = FixedToInt(fft) & tmask;              \
  475.            GLint pos = (t << twidth_log2) + s;             \
  476.            GLubyte *tex00 = texture + COMP * pos;          \
  477.        zspan[i] = FixedToDepth(ffz);                   \
  478.            DO_TEX;                                         \
  479.        ffz += fdzdx;                                   \
  480.            ffr += fdrdx;                                   \
  481.        ffg += fdgdx;                                   \
  482.            ffb += fdbdx;                                   \
  483.        ffa += fdadx;                                   \
  484.        ffs += fdsdx;                                   \
  485.        fft += fdtdx;                                   \
  486.            dest += 4;                                      \
  487.     }
  488.  
  489. #define SPAN2(DO_TEX,COMP)                                 \
  490.     for (i=0;i<n;i++) {                                \
  491.            GLint s = FixedToInt(ffs) & smask;              \
  492.            GLint t = FixedToInt(fft) & tmask;              \
  493.            GLint sf = ffs & FIXED_FRAC_MASK;               \
  494.            GLint tf = fft & FIXED_FRAC_MASK;               \
  495.            GLint si = FIXED_FRAC_MASK - sf;                \
  496.            GLint ti = FIXED_FRAC_MASK - tf;                \
  497.            GLint pos = (t << twidth_log2) + s;             \
  498.            GLubyte *tex00 = texture + COMP * pos;          \
  499.            GLubyte *tex10 = tex00 + tbytesline;            \
  500.            GLubyte *tex01 = tex00 + COMP;                  \
  501.            GLubyte *tex11 = tex10 + COMP;                  \
  502.            if (t == tmask) {                               \
  503.               tex10 -= tsize;                              \
  504.               tex11 -= tsize;                              \
  505.            }                                               \
  506.            if (s == smask) {                               \
  507.               tex01 -= tbytesline;                         \
  508.               tex11 -= tbytesline;                         \
  509.            }                                               \
  510.        zspan[i] = FixedToDepth(ffz);                   \
  511.            DO_TEX;                                         \
  512.        ffz += fdzdx;                                   \
  513.            ffr += fdrdx;                                   \
  514.        ffg += fdgdx;                                   \
  515.            ffb += fdbdx;                                   \
  516.        ffa += fdadx;                                   \
  517.        ffs += fdsdx;                                   \
  518.        fft += fdtdx;                                   \
  519.            dest += 4;                                      \
  520.     }
  521.  
  522. /* here comes the heavy part.. (something for the compiler to chew on) */
  523. #define INNER_LOOP( LEFT, RIGHT, Y )                       \
  524.     {                                   \
  525.        GLint i, n = RIGHT-LEFT;                       \
  526.        GLdepth zspan[MAX_WIDTH];                       \
  527.        GLubyte rgba[MAX_WIDTH][4];                     \
  528.        if (n>0) {                                      \
  529.               GLubyte *dest = rgba[0];                     \
  530.               ffs -= FIXED_HALF; /* off-by-one error? */   \
  531.               fft -= FIXED_HALF;                           \
  532.               switch (filter) {                            \
  533.              case GL_NEAREST:                             \
  534.          switch (format) {                         \
  535.                  case GL_RGB:                              \
  536.                 switch (envmode) {                     \
  537.                 case GL_MODULATE:                      \
  538.                        SPAN1(NEAREST_RGB;MODULATE,3);      \
  539.                        break;                              \
  540.                 case GL_DECAL:                         \
  541.                     case GL_REPLACE:                       \
  542.                        SPAN1(NEAREST_RGB_REPLACE,3);       \
  543.                        break;                              \
  544.                     case GL_BLEND:                         \
  545.                        SPAN1(NEAREST_RGB;BLEND,3);         \
  546.                        break;                              \
  547.                     case GL_ADD:                           \
  548.                        SPAN1(NEAREST_RGB;ADD,3);           \
  549.                        break;                              \
  550.                 }                                      \
  551.                     break;                                 \
  552.          case GL_RGBA:                             \
  553.             switch(envmode) {                      \
  554.             case GL_MODULATE:                      \
  555.                        SPAN1(NEAREST_RGBA;MODULATE,4);     \
  556.                        break;                              \
  557.             case GL_DECAL:                         \
  558.                        SPAN1(NEAREST_RGBA;DECAL,4);        \
  559.                        break;                              \
  560.             case GL_BLEND:                         \
  561.                        SPAN1(NEAREST_RGBA;BLEND,4);        \
  562.                        break;                              \
  563.             case GL_REPLACE:                       \
  564.                        SPAN1(NEAREST_RGBA_REPLACE,4);      \
  565.                        break;                              \
  566.             case GL_ADD:                           \
  567.                        SPAN1(NEAREST_RGBA;ADD,4);          \
  568.                        break;                              \
  569.             }                                      \
  570.                     break;                                 \
  571.              }                                         \
  572.                  break;                                    \
  573.           case GL_LINEAR:                              \
  574.                  ffs -= FIXED_HALF;                        \
  575.                  fft -= FIXED_HALF;                        \
  576.          switch (format) {                         \
  577.          case GL_RGB:                              \
  578.             switch (envmode) {                     \
  579.             case GL_MODULATE:                      \
  580.                SPAN2(LINEAR_RGB;MODULATE,3);       \
  581.                        break;                              \
  582.             case GL_DECAL:                         \
  583.             case GL_REPLACE:                       \
  584.                        SPAN2(LINEAR_RGB;REPLACE,3);        \
  585.                        break;                              \
  586.             case GL_BLEND:                         \
  587.                SPAN2(LINEAR_RGB;BLEND,3);          \
  588.                break;                              \
  589.             case GL_ADD:                           \
  590.                SPAN2(LINEAR_RGB;ADD,3);            \
  591.                break;                              \
  592.             }                                      \
  593.             break;                                 \
  594.          case GL_RGBA:                             \
  595.             switch (envmode) {                     \
  596.             case GL_MODULATE:                      \
  597.                SPAN2(LINEAR_RGBA;MODULATE,4);      \
  598.                break;                              \
  599.             case GL_DECAL:                         \
  600.                SPAN2(LINEAR_RGBA;DECAL,4);         \
  601.                break;                              \
  602.             case GL_BLEND:                         \
  603.                SPAN2(LINEAR_RGBA;BLEND,4);         \
  604.                break;                              \
  605.             case GL_REPLACE:                       \
  606.                SPAN2(LINEAR_RGBA;REPLACE,4);       \
  607.                break;                              \
  608.             case GL_ADD:                           \
  609.                SPAN2(LINEAR_RGBA;ADD,4);           \
  610.                break;                              \
  611.             }                                      \
  612.             break;                                 \
  613.              }                                         \
  614.                  break;                                    \
  615.           }                                            \
  616.               gl_write_rgba_span(ctx, n, LEFT, Y, zspan,   \
  617.                                  rgba, GL_POLYGON);        \
  618.               /* explicit kill of variables: */            \
  619.               ffr = ffg = ffb = ffa = 0;                   \
  620.            }                                               \
  621.     }
  622.  
  623. #include "tritemp.h"
  624. #undef SPAN1
  625. #undef SPAN2
  626. }
  627.  
  628.  
  629. /*
  630.  * Render an perspective corrected RGB/RGBA textured triangle.
  631.  * The Q (aka V in Mesa) coordinate must be zero such that the divide
  632.  * by interpolated Q/W comes out right.
  633.  *
  634.  * XXX (May 15, 1999) this function not used for now because repeating
  635.  * of negative texture coords not handled correctly!!!
  636.  */
  637. #if 000
  638. static void persp_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  639.                      GLuint v2, GLuint pv )
  640. {
  641.  
  642. #define INTERP_Z 1
  643. #define INTERP_RGB 1
  644. #define INTERP_ALPHA 1
  645. #define INTERP_STUV 1
  646. #define SETUP_CODE                            \
  647.    struct gl_texture_unit *unit = ctx->Texture.Unit+0;            \
  648.    struct gl_texture_object *obj = unit->CurrentD[2];            \
  649.    GLint b = obj->BaseLevel;                        \
  650.    GLfloat twidth = (GLfloat) obj->Image[b]->Width;            \
  651.    GLfloat theight = (GLfloat) obj->Image[b]->Height;            \
  652.    GLint twidth_log2 = obj->Image[b]->WidthLog2;            \
  653.    GLubyte *texture = obj->Image[b]->Data;                \
  654.    GLint smask = (obj->Image[b]->Width - 1);                            \
  655.    GLint tmask = (obj->Image[b]->Height - 1);                           \
  656.    GLint format = obj->Image[b]->Format;                                \
  657.    GLint filter = obj->MinFilter;                                       \
  658.    GLint envmode = unit->EnvMode;                                       \
  659.    GLfloat sscale, tscale;                                              \
  660.    GLint comp, tbytesline, tsize;                                       \
  661.    GLfixed er, eg, eb, ea;                                              \
  662.    GLint tr, tg, tb, ta;                                                \
  663.    if (envmode == GL_BLEND || envmode == GL_ADD) {                      \
  664.       er = FloatToFixed(unit->EnvColor[0]);                             \
  665.       eg = FloatToFixed(unit->EnvColor[1]);                             \
  666.       eb = FloatToFixed(unit->EnvColor[2]);                             \
  667.       ea = FloatToFixed(unit->EnvColor[3]);                             \
  668.    }                                                                    \
  669.    switch (format) {                                                    \
  670.    case GL_ALPHA:                                                       \
  671.    case GL_LUMINANCE:                                                   \
  672.    case GL_INTENSITY:                                                   \
  673.       comp = 1;                                                         \
  674.       break;                                                            \
  675.    case GL_LUMINANCE_ALPHA:                                             \
  676.       comp = 2;                                                         \
  677.       break;                                                            \
  678.    case GL_RGB:                                                         \
  679.       comp = 3;                                                         \
  680.       break;                                                            \
  681.    case GL_RGBA:                                                        \
  682.       comp = 4;                                                         \
  683.       break;                                                            \
  684.    default:                                                             \
  685.       gl_problem(NULL, "Bad texture format in persp_texture_triangle"); \
  686.       return;                                                           \
  687.    }                                                                    \
  688.    if (filter == GL_NEAREST) {                                          \
  689.       sscale = twidth;                                                  \
  690.       tscale = theight;                                                 \
  691.    }                                                                    \
  692.    else {                                                               \
  693.       sscale = FIXED_SCALE * twidth;                                    \
  694.       tscale = FIXED_SCALE * theight;                                   \
  695.    }                                                                    \
  696.    tbytesline = obj->Image[b]->Width * comp;                            \
  697.    tsize = theight * tbytesline;
  698.    (void) pv;
  699.  
  700. #define SPAN1(DO_TEX,COMP)                                 \
  701.         for (i=0;i<n;i++) {                                \
  702.            GLfloat invQ = 1.0f / vv;                       \
  703.            GLint s = (int)(SS * invQ) & smask;             \
  704.            GLint t = (int)(TT * invQ) & tmask;             \
  705.            GLint pos = COMP * ((t << twidth_log2) + s);    \
  706.            GLubyte *tex00 = texture + pos;                 \
  707.        zspan[i] = FixedToDepth(ffz);                   \
  708.            DO_TEX;                                         \
  709.        ffz += fdzdx;                                   \
  710.            ffr += fdrdx;                                   \
  711.        ffg += fdgdx;                                   \
  712.            ffb += fdbdx;                                   \
  713.        ffa += fdadx;                                   \
  714.            SS += dSdx;                                     \
  715.            TT += dTdx;                                     \
  716.        vv += dvdx;                                     \
  717.            dest += 4;                                      \
  718.     }
  719.  
  720. #define SPAN2(DO_TEX,COMP)                                 \
  721.         for (i=0;i<n;i++) {                                \
  722.            GLfloat invQ = 1.0f / vv;                       \
  723.            GLfixed ffs = (int)(SS * invQ);                 \
  724.            GLfixed fft = (int)(TT * invQ);                 \
  725.        GLint s = FixedToInt(ffs) & smask;              \
  726.        GLint t = FixedToInt(fft) & tmask;              \
  727.            GLint sf = ffs & FIXED_FRAC_MASK;               \
  728.            GLint tf = fft & FIXED_FRAC_MASK;               \
  729.            GLint si = FIXED_FRAC_MASK - sf;                \
  730.            GLint ti = FIXED_FRAC_MASK - tf;                \
  731.            GLint pos = COMP * ((t << twidth_log2) + s);    \
  732.            GLubyte *tex00 = texture + pos;                 \
  733.            GLubyte *tex10 = tex00 + tbytesline;            \
  734.            GLubyte *tex01 = tex00 + COMP;                  \
  735.            GLubyte *tex11 = tex10 + COMP;                  \
  736.            if (t == tmask) {                               \
  737.               tex10 -= tsize;                              \
  738.               tex11 -= tsize;                              \
  739.            }                                               \
  740.            if (s == smask) {                               \
  741.               tex01 -= tbytesline;                         \
  742.               tex11 -= tbytesline;                         \
  743.            }                                               \
  744.        zspan[i] = FixedToDepth(ffz);                   \
  745.            DO_TEX;                                         \
  746.        ffz += fdzdx;                                   \
  747.            ffr += fdrdx;                                   \
  748.        ffg += fdgdx;                                   \
  749.            ffb += fdbdx;                                   \
  750.        ffa += fdadx;                                   \
  751.            SS += dSdx;                                     \
  752.            TT += dTdx;                                     \
  753.        vv += dvdx;                                     \
  754.            dest += 4;                                      \
  755.     }
  756.  
  757. #define INNER_LOOP( LEFT, RIGHT, Y )                       \
  758.     {                                   \
  759.        GLint i, n = RIGHT-LEFT;                       \
  760.        GLdepth zspan[MAX_WIDTH];                       \
  761.        GLubyte rgba[MAX_WIDTH][4];                       \
  762.            (void)uu; /* please GCC */                      \
  763.        if (n>0) {                                      \
  764.               GLfloat SS = ss * sscale;                    \
  765.               GLfloat TT = tt * tscale;                    \
  766.               GLfloat dSdx = dsdx * sscale;                \
  767.               GLfloat dTdx = dtdx * tscale;                \
  768.               GLubyte *dest = rgba[0];                     \
  769.               switch (filter) {                            \
  770.              case GL_NEAREST:                             \
  771.          switch (format) {                         \
  772.                  case GL_RGB:                              \
  773.                 switch (envmode) {                     \
  774.                 case GL_MODULATE:                      \
  775.                        SPAN1(NEAREST_RGB;MODULATE,3);      \
  776.                        break;                              \
  777.                 case GL_DECAL:                         \
  778.                     case GL_REPLACE:                       \
  779.                        SPAN1(NEAREST_RGB_REPLACE,3);       \
  780.                        break;                              \
  781.                     case GL_BLEND:                         \
  782.                        SPAN1(NEAREST_RGB;BLEND,3);         \
  783.                        break;                              \
  784.                     case GL_ADD:                           \
  785.                        SPAN1(NEAREST_RGB;ADD,3);           \
  786.                        break;                              \
  787.                 }                                      \
  788.                     break;                                 \
  789.          case GL_RGBA:                             \
  790.             switch(envmode) {                      \
  791.             case GL_MODULATE:                      \
  792.                        SPAN1(NEAREST_RGBA;MODULATE,4);     \
  793.                        break;                              \
  794.             case GL_DECAL:                         \
  795.                        SPAN1(NEAREST_RGBA;DECAL,4);        \
  796.                        break;                              \
  797.             case GL_BLEND:                         \
  798.                        SPAN1(NEAREST_RGBA;BLEND,4);        \
  799.                        break;                              \
  800.             case GL_REPLACE:                       \
  801.                        SPAN1(NEAREST_RGBA_REPLACE,4);      \
  802.                        break;                              \
  803.             case GL_ADD:                           \
  804.                        SPAN1(NEAREST_RGBA;ADD,4);          \
  805.                        break;                              \
  806.             }                                      \
  807.                     break;                                 \
  808.              }                                         \
  809.                  break;                                    \
  810.           case GL_LINEAR:                              \
  811.              SS -= 0.5f * FIXED_SCALE * vv;            \
  812.          TT -= 0.5f * FIXED_SCALE * vv;            \
  813.          switch (format) {                         \
  814.          case GL_RGB:                              \
  815.             switch (envmode) {                     \
  816.             case GL_MODULATE:                      \
  817.                SPAN2(LINEAR_RGB;MODULATE,3);       \
  818.                        break;                              \
  819.             case GL_DECAL:                         \
  820.             case GL_REPLACE:                       \
  821.                        SPAN2(LINEAR_RGB;REPLACE,3);        \
  822.                        break;                              \
  823.             case GL_BLEND:                         \
  824.                SPAN2(LINEAR_RGB;BLEND,3);          \
  825.                break;                              \
  826.             case GL_ADD:                           \
  827.                SPAN2(LINEAR_RGB;ADD,3);            \
  828.                break;                              \
  829.             }                                      \
  830.             break;                                 \
  831.          case GL_RGBA:                             \
  832.             switch (envmode) {                     \
  833.             case GL_MODULATE:                      \
  834.                SPAN2(LINEAR_RGBA;MODULATE,4);      \
  835.                break;                              \
  836.             case GL_DECAL:                         \
  837.                SPAN2(LINEAR_RGBA;DECAL,4);         \
  838.                break;                              \
  839.             case GL_BLEND:                         \
  840.                SPAN2(LINEAR_RGBA;BLEND,4);         \
  841.                break;                              \
  842.             case GL_REPLACE:                       \
  843.                SPAN2(LINEAR_RGBA;REPLACE,4);       \
  844.                break;                              \
  845.             case GL_ADD:                           \
  846.                SPAN2(LINEAR_RGBA;ADD,4);           \
  847.                break;                              \
  848.             }                                      \
  849.             break;                                 \
  850.              }                                         \
  851.                  break;                                    \
  852.           }                                            \
  853.           gl_write_rgba_span( ctx, n, LEFT, Y, zspan,  \
  854.                   rgba, GL_POLYGON );      \
  855.               ffr = ffg = ffb = ffa = 0;                   \
  856.        }                                               \
  857.     }
  858.  
  859.  
  860. #include "tritemp.h"
  861. #undef SPAN1
  862. #undef SPAN2
  863. }
  864. #endif
  865.  
  866.  
  867.  
  868. /*
  869.  * Render a smooth-shaded, textured, RGBA triangle.
  870.  * Interpolate S,T,U with perspective correction, w/out mipmapping.
  871.  * Note: we use texture coordinates S,T,U,V instead of S,T,R,Q because
  872.  * R is already used for red.
  873.  */
  874. static void general_textured_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  875.                                        GLuint v2, GLuint pv )
  876. {
  877. #define INTERP_Z 1
  878. #define INTERP_RGB 1
  879. #define INTERP_ALPHA 1
  880. #define INTERP_STUV 1
  881. #define SETUP_CODE                        \
  882.    GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);    \
  883.    GLint r, g, b, a;                        \
  884.    if (flat_shade) {                        \
  885.       r = VB->ColorPtr->data[pv][0];                \
  886.       g = VB->ColorPtr->data[pv][1];                \
  887.       b = VB->ColorPtr->data[pv][2];                \
  888.       a = VB->ColorPtr->data[pv][3];                \
  889.    }
  890. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  891.     {                            \
  892.        GLint i, n = RIGHT-LEFT;                \
  893.        GLdepth zspan[MAX_WIDTH];                \
  894.        GLubyte rgba[MAX_WIDTH][4];                \
  895.            GLfloat s[MAX_WIDTH], t[MAX_WIDTH], u[MAX_WIDTH];    \
  896.        if (n>0) {                        \
  897.               if (flat_shade) {                    \
  898.                  for (i=0;i<n;i++) {                \
  899.             GLdouble invQ = 1.0 / vv;            \
  900.             zspan[i] = FixedToDepth(ffz);        \
  901.             rgba[i][RCOMP] = r;                \
  902.             rgba[i][GCOMP] = g;                \
  903.             rgba[i][BCOMP] = b;                \
  904.             rgba[i][ACOMP] = a;                \
  905.             s[i] = ss*invQ;                \
  906.             t[i] = tt*invQ;                \
  907.             u[i] = uu*invQ;                \
  908.             ffz += fdzdx;                \
  909.             ss += dsdx;                    \
  910.             tt += dtdx;                    \
  911.             uu += dudx;                    \
  912.             vv += dvdx;                    \
  913.          }                        \
  914.               }                            \
  915.               else {                        \
  916.                  for (i=0;i<n;i++) {                \
  917.             GLdouble invQ = 1.0 / vv;            \
  918.             zspan[i] = FixedToDepth(ffz);        \
  919.             rgba[i][RCOMP] = FixedToInt(ffr);        \
  920.             rgba[i][GCOMP] = FixedToInt(ffg);        \
  921.             rgba[i][BCOMP] = FixedToInt(ffb);        \
  922.             rgba[i][ACOMP] = FixedToInt(ffa);        \
  923.             s[i] = ss*invQ;                \
  924.             t[i] = tt*invQ;                \
  925.             u[i] = uu*invQ;                \
  926.             ffz += fdzdx;                \
  927.             ffr += fdrdx;                \
  928.             ffg += fdgdx;                \
  929.             ffb += fdbdx;                \
  930.             ffa += fdadx;                \
  931.             ss += dsdx;                    \
  932.             tt += dtdx;                    \
  933.             uu += dudx;                    \
  934.             vv += dvdx;                    \
  935.          }                        \
  936.               }                            \
  937.           gl_write_texture_span( ctx, n, LEFT, Y, zspan,    \
  938.                                      s, t, u, NULL,         \
  939.                                  rgba, \
  940.                                      NULL, GL_POLYGON );    \
  941.        }                            \
  942.     }
  943.  
  944. #include "tritemp.h"
  945. }
  946.  
  947.  
  948. /*
  949.  * Render a smooth-shaded, textured, RGBA triangle with separate specular
  950.  * color interpolation.
  951.  * Interpolate S,T,U with perspective correction, w/out mipmapping.
  952.  * Note: we use texture coordinates S,T,U,V instead of S,T,R,Q because
  953.  * R is already used for red.
  954.  */
  955. static void general_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
  956.                                              GLuint v1, GLuint v2, GLuint pv,
  957.                                              GLdepth zspan[MAX_WIDTH],
  958.                                              GLubyte rgba[MAX_WIDTH][4],
  959.                                              GLubyte spec[MAX_WIDTH][4] )
  960. {
  961. #define INTERP_Z 1
  962. #define INTERP_RGB 1
  963. #define INTERP_SPEC 1
  964. #define INTERP_ALPHA 1
  965. #define INTERP_STUV 1
  966. #define SETUP_CODE                        \
  967.    GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);    \
  968.    GLint r, g, b, a, sr, sg, sb;                \
  969.    if (flat_shade) {                        \
  970.       r = VB->ColorPtr->data[pv][0];                \
  971.       g = VB->ColorPtr->data[pv][1];                \
  972.       b = VB->ColorPtr->data[pv][2];                \
  973.       a = VB->ColorPtr->data[pv][3];                \
  974.       sr = VB->Specular[pv][0];                 \
  975.       sg = VB->Specular[pv][1];                 \
  976.       sb = VB->Specular[pv][2];                 \
  977.    }
  978. #define INNER_LOOP( LEFT, RIGHT, Y )                \
  979.     {                            \
  980.        GLint i, n = RIGHT-LEFT;                \
  981.            GLfloat s[MAX_WIDTH], t[MAX_WIDTH], u[MAX_WIDTH];    \
  982.        if (n>0) {                        \
  983.               if (flat_shade) {                    \
  984.                  for (i=0;i<n;i++) {                \
  985.             GLdouble invQ = 1.0 / vv;            \
  986.             zspan[i] = FixedToDepth(ffz);        \
  987.             rgba[i][RCOMP] = r;                \
  988.             rgba[i][GCOMP] = g;                \
  989.             rgba[i][BCOMP] = b;                \
  990.             rgba[i][ACOMP] = a;                \
  991.             spec[i][RCOMP] = sr;            \
  992.             spec[i][GCOMP] = sg;            \
  993.             spec[i][BCOMP] = sb;            \
  994.             s[i] = ss*invQ;                \
  995.             t[i] = tt*invQ;                \
  996.             u[i] = uu*invQ;                \
  997.             ffz += fdzdx;                \
  998.             ss += dsdx;                    \
  999.             tt += dtdx;                    \
  1000.             uu += dudx;                    \
  1001.             vv += dvdx;                    \
  1002.          }                        \
  1003.               }                            \
  1004.               else {                        \
  1005.                  for (i=0;i<n;i++) {                \
  1006.             GLdouble invQ = 1.0 / vv;            \
  1007.             zspan[i] = FixedToDepth(ffz);        \
  1008.             rgba[i][RCOMP] = FixedToInt(ffr);        \
  1009.             rgba[i][GCOMP] = FixedToInt(ffg);        \
  1010.             rgba[i][BCOMP] = FixedToInt(ffb);        \
  1011.             rgba[i][ACOMP] = FixedToInt(ffa);        \
  1012.             spec[i][RCOMP] = FixedToInt(ffsr);        \
  1013.             spec[i][GCOMP] = FixedToInt(ffsg);        \
  1014.             spec[i][BCOMP] = FixedToInt(ffsb);        \
  1015.             s[i] = ss*invQ;                \
  1016.             t[i] = tt*invQ;                \
  1017.             u[i] = uu*invQ;                \
  1018.             ffz += fdzdx;                \
  1019.             ffr += fdrdx;                \
  1020.             ffg += fdgdx;                \
  1021.             ffb += fdbdx;                \
  1022.             ffa += fdadx;                \
  1023.             ffsr += fdsrdx;                \
  1024.             ffsg += fdsgdx;                \
  1025.             ffsb += fdsbdx;                \
  1026.             ss += dsdx;                    \
  1027.             tt += dtdx;                    \
  1028.             uu += dudx;                    \
  1029.             vv += dvdx;                    \
  1030.          }                        \
  1031.               }                            \
  1032.           gl_write_texture_span( ctx, n, LEFT, Y, zspan,    \
  1033.                                    s, t, u, NULL, rgba,        \
  1034.                                    (const GLubyte (*)[4]) spec,    \
  1035.                                GL_POLYGON );        \
  1036.        }                            \
  1037.     }
  1038.  
  1039. #include "tritemp.h"
  1040. }
  1041.  
  1042.  
  1043.  
  1044. /*
  1045.  * Compute the lambda value (texture level value) for a fragment.
  1046.  */
  1047. static GLfloat compute_lambda( GLfloat s, GLfloat dsdx, GLfloat dsdy,
  1048.                                GLfloat t, GLfloat dtdx, GLfloat dtdy,
  1049.                                GLfloat invQ, GLfloat dqdx, GLfloat dqdy,
  1050.                                GLfloat width, GLfloat height ) 
  1051. {
  1052.    GLfloat dudx, dudy, dvdx, dvdy;
  1053.    GLfloat r1, r2, rho2;
  1054.    GLfloat invQ_width = invQ * width;
  1055.    GLfloat invQ_height = invQ * height;
  1056.  
  1057.    dudx = (dsdx - s*dqdx) * invQ_width;
  1058.    dudy = (dsdy - s*dqdy) * invQ_width;
  1059.    dvdx = (dtdx - t*dqdx) * invQ_height;
  1060.    dvdy = (dtdy - t*dqdy) * invQ_height;
  1061.  
  1062.    r1 = dudx * dudx + dudy * dudy;
  1063.    r2 = dvdx * dvdx + dvdy * dvdy;
  1064.  
  1065.    rho2 = r1 + r2;     /* used to be:  rho2 = MAX2(r1,r2); */
  1066.    ASSERT( rho2 >= 0.0 );
  1067.  
  1068.    /* return log base 2 of rho */
  1069.    return log(rho2) * 1.442695 * 0.5;       /* 1.442695 = 1/log(2) */
  1070. }
  1071.  
  1072.  
  1073. /*
  1074.  * Render a smooth-shaded, textured, RGBA triangle.
  1075.  * Interpolate S,T,U with perspective correction and compute lambda for
  1076.  * each fragment.  Lambda is used to determine whether to use the
  1077.  * minification or magnification filter.  If minification and using
  1078.  * mipmaps, lambda is also used to select the texture level of detail.
  1079.  */
  1080. static void lambda_textured_triangle1( GLcontext *ctx, GLuint v0, GLuint v1,
  1081.                                        GLuint v2, GLuint pv,
  1082.                                        GLfloat s[MAX_WIDTH],
  1083.                                        GLfloat t[MAX_WIDTH],
  1084.                                        GLfloat u[MAX_WIDTH] )
  1085. {
  1086. #define INTERP_Z 1
  1087. #define INTERP_RGB 1
  1088. #define INTERP_ALPHA 1
  1089. #define INTERP_STUV 1
  1090.  
  1091. #define SETUP_CODE                            \
  1092.    const struct gl_texture_object *obj = ctx->Texture.Unit[0].Current;    \
  1093.    const GLint baseLevel = obj->BaseLevel;                \
  1094.    const struct gl_texture_image *texImage = obj->Image[baseLevel];    \
  1095.    const GLfloat twidth = (GLfloat) texImage->Width;            \
  1096.    const GLfloat theight = (GLfloat) texImage->Height;            \
  1097.    const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);    \
  1098.    GLint r, g, b, a;                            \
  1099.    if (flat_shade) {                            \
  1100.       r = VB->ColorPtr->data[pv][0];                    \
  1101.       g = VB->ColorPtr->data[pv][1];                    \
  1102.       b = VB->ColorPtr->data[pv][2];                    \
  1103.       a = VB->ColorPtr->data[pv][3];                    \
  1104.    }
  1105.  
  1106. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1107.     {                                \
  1108.        GLint i, n = RIGHT-LEFT;                    \
  1109.        GLdepth zspan[MAX_WIDTH];                    \
  1110.        GLubyte rgba[MAX_WIDTH][4];                    \
  1111.        GLfloat lambda[MAX_WIDTH];                    \
  1112.        if (n>0) {                            \
  1113.           if (flat_shade) {                        \
  1114.          for (i=0;i<n;i++) {                    \
  1115.             GLdouble invQ = 1.0 / vv;                \
  1116.             zspan[i] = FixedToDepth(ffz);            \
  1117.             rgba[i][RCOMP] = r;                    \
  1118.             rgba[i][GCOMP] = g;                    \
  1119.             rgba[i][BCOMP] = b;                    \
  1120.             rgba[i][ACOMP] = a;                    \
  1121.             s[i] = ss*invQ;                    \
  1122.             t[i] = tt*invQ;                    \
  1123.             u[i] = uu*invQ;                    \
  1124.             lambda[i] = compute_lambda( s[i], dsdx, dsdy,    \
  1125.                         t[i], dtdx, dtdy,    \
  1126.                         invQ, dvdx, dvdy,    \
  1127.                         twidth, theight );    \
  1128.             ffz += fdzdx;                    \
  1129.             ss += dsdx;                        \
  1130.             tt += dtdx;                        \
  1131.             uu += dudx;                        \
  1132.             vv += dvdx;                        \
  1133.          }                            \
  1134.               }                                \
  1135.               else {                            \
  1136.          for (i=0;i<n;i++) {                    \
  1137.             GLdouble invQ = 1.0 / vv;                \
  1138.             zspan[i] = FixedToDepth(ffz);            \
  1139.             rgba[i][RCOMP] = FixedToInt(ffr);            \
  1140.             rgba[i][GCOMP] = FixedToInt(ffg);            \
  1141.             rgba[i][BCOMP] = FixedToInt(ffb);            \
  1142.             rgba[i][ACOMP] = FixedToInt(ffa);            \
  1143.             s[i] = ss*invQ;                    \
  1144.             t[i] = tt*invQ;                    \
  1145.             u[i] = uu*invQ;                    \
  1146.             lambda[i] = compute_lambda( s[i], dsdx, dsdy,    \
  1147.                         t[i], dtdx, dtdy,    \
  1148.                         invQ, dvdx, dvdy,    \
  1149.                         twidth, theight );    \
  1150.             ffz += fdzdx;                    \
  1151.             ffr += fdrdx;                    \
  1152.             ffg += fdgdx;                    \
  1153.             ffb += fdbdx;                    \
  1154.             ffa += fdadx;                    \
  1155.             ss += dsdx;                        \
  1156.             tt += dtdx;                        \
  1157.             uu += dudx;                        \
  1158.             vv += dvdx;                        \
  1159.          }                            \
  1160.               }                                \
  1161.           gl_write_texture_span( ctx, n, LEFT, Y, zspan,        \
  1162.                                      s, t, u, lambda,             \
  1163.                                  rgba, NULL, GL_POLYGON );        \
  1164.        }                                \
  1165.     }
  1166.  
  1167. #include "tritemp.h"
  1168. }
  1169.  
  1170.  
  1171. /*
  1172.  * Render a smooth-shaded, textured, RGBA triangle with separate specular
  1173.  * interpolation.
  1174.  * Interpolate S,T,U with perspective correction and compute lambda for
  1175.  * each fragment.  Lambda is used to determine whether to use the
  1176.  * minification or magnification filter.  If minification and using
  1177.  * mipmaps, lambda is also used to select the texture level of detail.
  1178.  */
  1179. static void lambda_textured_spec_triangle1( GLcontext *ctx, GLuint v0,
  1180.                                             GLuint v1, GLuint v2, GLuint pv,
  1181.                                             GLfloat s[MAX_WIDTH],
  1182.                                             GLfloat t[MAX_WIDTH],
  1183.                                             GLfloat u[MAX_WIDTH] )
  1184. {
  1185. #define INTERP_Z 1
  1186. #define INTERP_RGB 1
  1187. #define INTERP_SPEC 1
  1188. #define INTERP_ALPHA 1
  1189. #define INTERP_STUV 1
  1190.  
  1191. #define SETUP_CODE                            \
  1192.    const struct gl_texture_object *obj = ctx->Texture.Unit[0].Current;    \
  1193.    const GLint baseLevel = obj->BaseLevel;                \
  1194.    const struct gl_texture_image *texImage = obj->Image[baseLevel];    \
  1195.    const GLfloat twidth = (GLfloat) texImage->Width;            \
  1196.    const GLfloat theight = (GLfloat) texImage->Height;            \
  1197.    const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);    \
  1198.    GLint r, g, b, a, sr, sg, sb;                    \
  1199.    if (flat_shade) {                            \
  1200.       r = VB->ColorPtr->data[pv][0];                    \
  1201.       g = VB->ColorPtr->data[pv][1];                    \
  1202.       b = VB->ColorPtr->data[pv][2];                    \
  1203.       a = VB->ColorPtr->data[pv][3];                    \
  1204.       sr = VB->Specular[pv][0];                        \
  1205.       sg = VB->Specular[pv][1];                        \
  1206.       sb = VB->Specular[pv][2];                        \
  1207.    }
  1208.  
  1209. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1210.     {                                \
  1211.        GLint i, n = RIGHT-LEFT;                    \
  1212.        GLdepth zspan[MAX_WIDTH];                    \
  1213.        GLubyte spec[MAX_WIDTH][4];                    \
  1214.            GLubyte rgba[MAX_WIDTH][4];                    \
  1215.        GLfloat lambda[MAX_WIDTH];                    \
  1216.        if (n>0) {                            \
  1217.           if (flat_shade) {                        \
  1218.          for (i=0;i<n;i++) {                    \
  1219.             GLdouble invQ = 1.0 / vv;                \
  1220.             zspan[i] = FixedToDepth(ffz);            \
  1221.             rgba[i][RCOMP] = r;                    \
  1222.             rgba[i][GCOMP] = g;                    \
  1223.             rgba[i][BCOMP] = b;                    \
  1224.             rgba[i][ACOMP] = a;                    \
  1225.             spec[i][RCOMP] = sr;                \
  1226.             spec[i][GCOMP] = sg;                \
  1227.             spec[i][BCOMP] = sb;                \
  1228.             s[i] = ss*invQ;                    \
  1229.             t[i] = tt*invQ;                    \
  1230.             u[i] = uu*invQ;                    \
  1231.             lambda[i] = compute_lambda( s[i], dsdx, dsdy,    \
  1232.                         t[i], dtdx, dtdy,    \
  1233.                         invQ, dvdx, dvdy,    \
  1234.                         twidth, theight );    \
  1235.             ffz += fdzdx;                    \
  1236.             ss += dsdx;                        \
  1237.             tt += dtdx;                        \
  1238.             uu += dudx;                        \
  1239.             vv += dvdx;                        \
  1240.          }                            \
  1241.               }                                \
  1242.               else {                            \
  1243.          for (i=0;i<n;i++) {                    \
  1244.             GLdouble invQ = 1.0 / vv;                \
  1245.             zspan[i] = FixedToDepth(ffz);            \
  1246.             rgba[i][RCOMP] = FixedToInt(ffr);            \
  1247.             rgba[i][GCOMP] = FixedToInt(ffg);            \
  1248.             rgba[i][BCOMP] = FixedToInt(ffb);            \
  1249.             rgba[i][ACOMP] = FixedToInt(ffa);            \
  1250.             spec[i][RCOMP] = FixedToInt(ffsr);            \
  1251.             spec[i][GCOMP] = FixedToInt(ffsg);            \
  1252.             spec[i][BCOMP] = FixedToInt(ffsb);            \
  1253.             s[i] = ss*invQ;                    \
  1254.             t[i] = tt*invQ;                    \
  1255.             u[i] = uu*invQ;                    \
  1256.             lambda[i] = compute_lambda( s[i], dsdx, dsdy,    \
  1257.                         t[i], dtdx, dtdy,    \
  1258.                         invQ, dvdx, dvdy,    \
  1259.                         twidth, theight );    \
  1260.             ffz += fdzdx;                    \
  1261.             ffr += fdrdx;                    \
  1262.             ffg += fdgdx;                    \
  1263.             ffb += fdbdx;                    \
  1264.             ffa += fdadx;                    \
  1265.             ffsr += fdsrdx;                    \
  1266.             ffsg += fdsgdx;                    \
  1267.             ffsb += fdsbdx;                    \
  1268.             ss += dsdx;                        \
  1269.             tt += dtdx;                        \
  1270.             uu += dudx;                        \
  1271.             vv += dvdx;                        \
  1272.          }                            \
  1273.               }                                \
  1274.           gl_write_texture_span( ctx, n, LEFT, Y, zspan,        \
  1275.                                      s, t, u, lambda,             \
  1276.                                  rgba, (const GLubyte (*)[4]) spec, \
  1277.                                      GL_POLYGON );            \
  1278.        }                                \
  1279.     }
  1280.  
  1281. #include "tritemp.h"
  1282. }
  1283.  
  1284.  
  1285. /*
  1286.  * This is the big one!
  1287.  * Interpolate Z, RGB, Alpha, and two sets of texture coordinates.
  1288.  * Yup, it's slow.
  1289.  */
  1290. static void lambda_multitextured_triangle1( GLcontext *ctx, GLuint v0,
  1291.                                       GLuint v1, GLuint v2, GLuint pv,
  1292.                                       GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH],
  1293.                                       GLfloat t[MAX_TEXTURE_UNITS][MAX_WIDTH],
  1294.                                       GLfloat u[MAX_TEXTURE_UNITS][MAX_WIDTH]
  1295.                                       )
  1296. {
  1297.    GLubyte rgba[MAX_WIDTH][4];
  1298. #define INTERP_Z 1
  1299. #define INTERP_RGB 1
  1300. #define INTERP_ALPHA 1
  1301. #define INTERP_STUV 1
  1302. #define INTERP_STUV1 1
  1303.  
  1304. #define SETUP_CODE                            \
  1305.    const struct gl_texture_object *obj0 = ctx->Texture.Unit[0].Current;    \
  1306.    const GLint baseLevel0 = obj0->BaseLevel;                \
  1307.    const struct gl_texture_image *texImage0 = obj0->Image[baseLevel0];    \
  1308.    const GLfloat twidth0 = (GLfloat) texImage0->Width;            \
  1309.    const GLfloat theight0 = (GLfloat) texImage0->Height;        \
  1310.    const struct gl_texture_object *obj1 = ctx->Texture.Unit[1].Current;    \
  1311.    const GLint baseLevel1 = obj1->BaseLevel;                \
  1312.    const struct gl_texture_image *texImage1 = obj1->Image[baseLevel1];    \
  1313.    const GLfloat twidth1 = (GLfloat) texImage1->Width;            \
  1314.    const GLfloat theight1 = (GLfloat) texImage1->Height;        \
  1315.    const GLboolean flat_shade = (ctx->Light.ShadeModel==GL_FLAT);    \
  1316.    GLint r, g, b, a;                            \
  1317.    if (flat_shade) {                            \
  1318.       r = VB->ColorPtr->data[pv][0];                    \
  1319.       g = VB->ColorPtr->data[pv][1];                    \
  1320.       b = VB->ColorPtr->data[pv][2];                    \
  1321.       a = VB->ColorPtr->data[pv][3];                    \
  1322.    }
  1323.  
  1324. #define INNER_LOOP( LEFT, RIGHT, Y )                    \
  1325.     {                                \
  1326.        GLint i, n = RIGHT-LEFT;                    \
  1327.        GLdepth zspan[MAX_WIDTH];                    \
  1328.            GLfloat lambda[MAX_TEXTURE_UNITS][MAX_WIDTH];        \
  1329.        if (n>0) {                            \
  1330.           if (flat_shade) {                        \
  1331.          for (i=0;i<n;i++) {                    \
  1332.             GLdouble invQ = 1.0 / vv;                \
  1333.             GLdouble invQ1 = 1.0 / vv1;                \
  1334.             zspan[i] = FixedToDepth(ffz);            \
  1335.             rgba[i][RCOMP] = r;                    \
  1336.             rgba[i][GCOMP] = g;                    \
  1337.             rgba[i][BCOMP] = b;                    \
  1338.             rgba[i][ACOMP] = a;                    \
  1339.             s[0][i] = ss*invQ;                    \
  1340.             t[0][i] = tt*invQ;                    \
  1341.             u[0][i] = uu*invQ;                    \
  1342.             lambda[0][i] = compute_lambda( s[0][i], dsdx, dsdy,    \
  1343.                            t[0][i], dtdx, dtdy,    \
  1344.                            invQ, dvdx, dvdy,    \
  1345.                            twidth0, theight0 );    \
  1346.             s[1][i] = ss1*invQ1;                \
  1347.             t[1][i] = tt1*invQ1;                \
  1348.             u[1][i] = uu1*invQ1;                \
  1349.             lambda[1][i] = compute_lambda( s[1][i], ds1dx, ds1dy,    \
  1350.                            t[1][i], dt1dx, dt1dy,    \
  1351.                            invQ1, dvdx, dvdy,    \
  1352.                            twidth1, theight1 );    \
  1353.             ffz += fdzdx;                    \
  1354.             ss += dsdx;                        \
  1355.             tt += dtdx;                        \
  1356.             uu += dudx;                        \
  1357.             vv += dvdx;                        \
  1358.             ss1 += ds1dx;                    \
  1359.             tt1 += dt1dx;                    \
  1360.             uu1 += du1dx;                    \
  1361.             vv1 += dv1dx;                    \
  1362.          }                            \
  1363.               }                                \
  1364.               else {                            \
  1365.          for (i=0;i<n;i++) {                    \
  1366.             GLdouble invQ = 1.0 / vv;                \
  1367.             GLdouble invQ1 = 1.0 / vv1;                \
  1368.             zspan[i] = FixedToDepth(ffz);            \
  1369.             rgba[i][RCOMP] = FixedToInt(ffr);            \
  1370.             rgba[i][GCOMP] = FixedToInt(ffg);            \
  1371.             rgba[i][BCOMP] = FixedToInt(ffb);            \
  1372.             rgba[i][ACOMP] = FixedToInt(ffa);            \
  1373.             s[0][i] = ss*invQ;                    \
  1374.             t[0][i] = tt*invQ;                    \
  1375.             u[0][i] = uu*invQ;                    \
  1376.             lambda[0][i] = compute_lambda( s[0][i], dsdx, dsdy,    \
  1377.                            t[0][i], dtdx, dtdy,    \
  1378.                            invQ, dvdx, dvdy,    \
  1379.                            twidth0, theight0 );    \
  1380.             s[1][i] = ss1*invQ1;                \
  1381.             t[1][i] = tt1*invQ1;                \
  1382.             u[1][i] = uu1*invQ1;                \
  1383.             lambda[1][i] = compute_lambda( s[1][i], ds1dx, ds1dy, \
  1384.                            t[1][i], dt1dx, dt1dy, \
  1385.                            invQ1, dvdx, dvdy,    \
  1386.                            twidth1, theight1 );    \
  1387.             ffz += fdzdx;                    \
  1388.             ffr += fdrdx;                    \
  1389.             ffg += fdgdx;                    \
  1390.             ffb += fdbdx;                    \
  1391.             ffa += fdadx;                    \
  1392.             ss += dsdx;                        \
  1393.             tt += dtdx;                        \
  1394.             uu += dudx;                        \
  1395.             vv += dvdx;                        \
  1396.             ss1 += ds1dx;                    \
  1397.             tt1 += dt1dx;                    \
  1398.             uu1 += du1dx;                    \
  1399.             vv1 += dv1dx;                    \
  1400.          }                            \
  1401.               }                                \
  1402.           gl_write_multitexture_span( ctx, 2, n, LEFT, Y, zspan,    \
  1403.                                       (const GLfloat (*)[MAX_WIDTH]) s,    \
  1404.                                       (const GLfloat (*)[MAX_WIDTH]) t,    \
  1405.                                       (const GLfloat (*)[MAX_WIDTH]) u,    \
  1406.                                       (GLfloat (*)[MAX_WIDTH]) lambda,    \
  1407.                                   rgba, NULL, GL_POLYGON );        \
  1408.        }                                \
  1409.     }
  1410.  
  1411. #include "tritemp.h"
  1412. }
  1413.  
  1414.  
  1415. /*
  1416.  * These wrappers are needed to deal with the 32KB / stack frame limit
  1417.  * on Mac / PowerPC systems.
  1418.  */
  1419.  
  1420. static void general_textured_spec_triangle(GLcontext *ctx, GLuint v0,
  1421.                                            GLuint v1, GLuint v2, GLuint pv)
  1422. {
  1423.    GLdepth zspan[MAX_WIDTH];
  1424.    GLubyte rgba[MAX_WIDTH][4], spec[MAX_WIDTH][4];
  1425.    general_textured_spec_triangle1(ctx,v0,v1,v2,pv,zspan,rgba,spec);
  1426. }
  1427.  
  1428. static void lambda_textured_triangle( GLcontext *ctx, GLuint v0,
  1429.                                       GLuint v1, GLuint v2, GLuint pv )
  1430. {
  1431.    GLfloat s[MAX_WIDTH], t[MAX_WIDTH], u[MAX_WIDTH];
  1432.    lambda_textured_triangle1(ctx,v0,v1,v2,pv,s,t,u);
  1433. }
  1434.  
  1435. static void lambda_textured_spec_triangle( GLcontext *ctx, GLuint v0,
  1436.                                            GLuint v1, GLuint v2, GLuint pv )
  1437. {
  1438.    GLfloat s[MAX_WIDTH];
  1439.    GLfloat t[MAX_WIDTH];
  1440.    GLfloat u[MAX_WIDTH];
  1441.    lambda_textured_spec_triangle1(ctx,v0,v1,v2,pv,s,t,u);
  1442. }
  1443.  
  1444.  
  1445. static void lambda_multitextured_triangle( GLcontext *ctx, GLuint v0,
  1446.                                            GLuint v1, GLuint v2, GLuint pv)
  1447. {
  1448.  
  1449.    GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH];
  1450.    GLfloat t[MAX_TEXTURE_UNITS][MAX_WIDTH];
  1451.    DEFMARRAY(GLfloat,u,MAX_TEXTURE_UNITS,MAX_WIDTH);
  1452.    CHECKARRAY(u,return);
  1453.    
  1454.    lambda_multitextured_triangle1(ctx,v0,v1,v2,pv,s,t,u);
  1455.    
  1456.    UNDEFARRAY(u);
  1457. }
  1458.  
  1459.  
  1460. /*
  1461.  * Null rasterizer for measuring transformation speed.
  1462.  */
  1463. static void null_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  1464.                            GLuint v2, GLuint pv )
  1465. {
  1466.    (void) ctx;
  1467.    (void) v0;
  1468.    (void) v1;
  1469.    (void) v2;
  1470.    (void) pv;
  1471. }
  1472.  
  1473.  
  1474. #if 0
  1475. # define dputs(s) puts(s)
  1476. #else
  1477. # define dputs(s)
  1478. #endif
  1479.  
  1480. /*
  1481.  * Determine which triangle rendering function to use given the current
  1482.  * rendering context.
  1483.  */
  1484. void gl_set_triangle_function( GLcontext *ctx )
  1485. {
  1486.    GLboolean rgbmode = ctx->Visual->RGBAflag;
  1487.  
  1488.    if (ctx->RenderMode==GL_RENDER) {
  1489.       if (ctx->NoRaster) {
  1490.          ctx->Driver.TriangleFunc = null_triangle;
  1491.          return;
  1492.       }
  1493.       if (ctx->Driver.TriangleFunc) {
  1494.          /* Device driver will draw triangles. */
  1495.      return;
  1496.       }
  1497.  
  1498.       if (ctx->Texture.ReallyEnabled) {
  1499.          /* Ugh, we do a _lot_ of tests to pick the best textured tri func */
  1500.      int format, filter;
  1501.      const struct gl_texture_object *current2Dtex = ctx->Texture.Unit[0].CurrentD[2];
  1502.          const struct gl_texture_image *image;
  1503.          /* First see if we can used an optimized 2-D texture function */
  1504.          if (ctx->Texture.ReallyEnabled==TEXTURE0_2D
  1505.              && current2Dtex->WrapS==GL_REPEAT
  1506.          && current2Dtex->WrapT==GL_REPEAT
  1507.              && ((image = current2Dtex->Image[current2Dtex->BaseLevel]) != 0)  /* correct! */
  1508.              && image->Border==0
  1509.              && ((format = image->Format)==GL_RGB || format==GL_RGBA)
  1510.          && (filter = current2Dtex->MinFilter)==current2Dtex->MagFilter
  1511.          && ctx->Light.Model.ColorControl==GL_SINGLE_COLOR) {
  1512.  
  1513.         if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) {
  1514.          
  1515.            if (filter==GL_NEAREST
  1516.            && format==GL_RGB
  1517.            && (ctx->Texture.Unit[0].EnvMode==GL_REPLACE
  1518.                || ctx->Texture.Unit[0].EnvMode==GL_DECAL)
  1519.            && ((ctx->RasterMask==DEPTH_BIT
  1520.             && ctx->Depth.Func==GL_LESS
  1521.             && ctx->Depth.Mask==GL_TRUE)
  1522.                || ctx->RasterMask==0)
  1523.            && ctx->Polygon.StippleFlag==GL_FALSE) {
  1524.  
  1525.           if (ctx->RasterMask==DEPTH_BIT) {
  1526.              ctx->Driver.TriangleFunc = simple_z_textured_triangle;
  1527.              dputs("simple_z_textured_triangle");
  1528.           }
  1529.           else {
  1530.              ctx->Driver.TriangleFunc = simple_textured_triangle;
  1531.              dputs("simple_textured_triangle");
  1532.           }
  1533.            }
  1534.            else {
  1535.           ctx->Driver.TriangleFunc = affine_textured_triangle;
  1536.           dputs("affine_textured_triangle");
  1537.            }
  1538.         }
  1539.         else {
  1540.            /*ctx->Driver.TriangleFunc = persp_textured_triangle;*/
  1541.                ctx->Driver.TriangleFunc = general_textured_triangle;
  1542.            dputs("persp_textured_triangle");
  1543.         }
  1544.      }
  1545.          else {
  1546.             /* More complicated textures (mipmap, multi-tex, sep specular) */
  1547.             GLboolean needLambda;
  1548.             /* if mag filter != min filter we need to compute lambda */
  1549.             const struct gl_texture_object *obj0 = ctx->Texture.Unit[0].Current;
  1550.             const struct gl_texture_object *obj1 = ctx->Texture.Unit[1].Current;
  1551.             if (obj0 && obj0->MinFilter != obj0->MagFilter)
  1552.                needLambda = GL_TRUE;
  1553.             else if (obj1 && obj1->MinFilter != obj1->MagFilter)
  1554.                needLambda = GL_TRUE;
  1555.             else
  1556.                needLambda = GL_FALSE;
  1557.             if (ctx->Texture.ReallyEnabled >= TEXTURE1_1D) {
  1558.                /* multi-texture! */
  1559.                ctx->Driver.TriangleFunc = lambda_multitextured_triangle;
  1560.            dputs("lambda_multitextured_triangle");
  1561.             }
  1562.             else if (ctx->Light.Enabled &&
  1563.                ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) {
  1564.                /* separate specular color interpolation */
  1565.                if (needLambda) {
  1566.                   ctx->Driver.TriangleFunc = lambda_textured_spec_triangle;
  1567.           dputs("lambda_textured_spec_triangle");
  1568.            }
  1569.                else {
  1570.                   ctx->Driver.TriangleFunc = general_textured_spec_triangle;
  1571.           dputs("general_textured_spec_triangle");
  1572.            }
  1573.             }
  1574.             else {
  1575.                if (needLambda) {
  1576.                   ctx->Driver.TriangleFunc = lambda_textured_triangle;
  1577.           dputs("lambda_textured_triangle");
  1578.            }
  1579.                else {
  1580.                   ctx->Driver.TriangleFunc = general_textured_triangle;
  1581.           dputs("general_textured_triangle");
  1582.            }
  1583.             }
  1584.          }
  1585.       }
  1586.       else {
  1587.      if (ctx->Light.ShadeModel==GL_SMOOTH) {
  1588.         /* smooth shaded, no texturing, stippled or some raster ops */
  1589.             if (rgbmode)
  1590.                ctx->Driver.TriangleFunc = smooth_rgba_triangle;
  1591.             else
  1592.                ctx->Driver.TriangleFunc = smooth_ci_triangle;
  1593.      }
  1594.      else {
  1595.         /* flat shaded, no texturing, stippled or some raster ops */
  1596.             if (rgbmode)
  1597.                ctx->Driver.TriangleFunc = flat_rgba_triangle;
  1598.             else
  1599.                ctx->Driver.TriangleFunc = flat_ci_triangle;
  1600.      }
  1601.       }
  1602.    }
  1603.    else if (ctx->RenderMode==GL_FEEDBACK) {
  1604.       ctx->Driver.TriangleFunc = gl_feedback_triangle;
  1605.    }
  1606.    else {
  1607.       /* GL_SELECT mode */
  1608.       ctx->Driver.TriangleFunc = gl_select_triangle;
  1609.    }
  1610. }
  1611.