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

  1. /* $Id: texture.c,v 1.4.2.3 1999/12/21 17:22:39 keithw 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. #ifdef PC_HEADER
  29. #include "all.h"
  30. #else
  31. #ifndef XFree86Server
  32. #include <math.h>
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #else
  36. #include "GL/xf86glx.h"
  37. #endif
  38. #include "context.h"
  39. #include "macros.h"
  40. #include "mmath.h"
  41. #include "pb.h"
  42. #include "texture.h"
  43. #include "types.h"
  44. #include "xform.h"
  45. #endif
  46.  
  47. /***********************************************************************
  48.  * Automatic texture coordinate generation (texgen) code.
  49.  */
  50.  
  51. static GLuint all_bits[5] = {
  52.    0,
  53.    VEC_SIZE_1,
  54.    VEC_SIZE_2,
  55.    VEC_SIZE_3,
  56.    VEC_SIZE_4,
  57. };
  58.  
  59.  
  60. static texgen_func texgen_generic_tab[4];
  61. static texgen_func texgen_reflection_map_nv_tab[4];
  62. static texgen_func texgen_normal_map_nv_tab[4];
  63. static texgen_func texgen_sphere_map_tab[4];
  64.  
  65.  
  66. typedef void (*build_m_func)(GLfloat f[][3],
  67.                  GLfloat m[],
  68.                  const GLvector3f *normals, 
  69.                  const GLvector4f *coord_vec, 
  70.                  const GLuint flags[],
  71.                  const GLubyte cullmask[] );
  72.  
  73.  
  74. typedef void (*build_f_func)( GLfloat *f, 
  75.                   GLuint fstride,
  76.                   const GLvector3f *normal_vec,
  77.                   const GLvector4f *coord_vec, 
  78.                   const GLuint flags[],
  79.                   const GLubyte cullmask[] );
  80.  
  81.  
  82. /* KW: compacted vs. coindexed normals don't bring any performance
  83.  *     gains to texture generation, but it is still necessary to cope
  84.  *     with the two different formats.
  85.  */
  86. #define TAG(x)           x
  87. #define FIRST_NORMAL     normals->start
  88. #define NEXT_NORMAL      STRIDE_F(normal, normals->stride)
  89. #define LOCAL_VARS
  90. #define CHECK            
  91. #define IDX              0
  92. #include "texgen_tmp.h"
  93.  
  94.  
  95. #define TAG(x)           x##_compacted
  96. #define FIRST_NORMAL     normals->start
  97. #define NEXT_NORMAL      ((flags[i]&VERT_NORM) ? (normal=first_normal[i]) : (normal))
  98. #define CHECK            
  99. #define IDX              2
  100. #define LOCAL_VARS        \
  101.    GLfloat (*first_normal)[3] = (GLfloat (*)[3]) FIRST_NORMAL;
  102.  
  103. #include "texgen_tmp.h"
  104.  
  105. #define TAG(x)           x##_masked
  106. #define FIRST_NORMAL     normals->start
  107. #define NEXT_NORMAL      STRIDE_F(normal, normals->stride)
  108. #define LOCAL_VARS       
  109. #define CHECK            if (cullmask[i])
  110. #define IDX              1
  111. #include "texgen_tmp.h"
  112.  
  113. #define TAG(x)           x##_compacted_masked
  114. #define FIRST_NORMAL     normals->start
  115. #define NEXT_NORMAL      ((flags[i]&VERT_NORM) ? normal=first_normal[i] : 0)
  116. #define CHECK            if (cullmask[i])
  117. #define IDX              3
  118. #define LOCAL_VARS       \
  119.    GLfloat (*first_normal)[3] = (GLfloat (*)[3]) FIRST_NORMAL;
  120.  
  121. #include "texgen_tmp.h"
  122.  
  123.  
  124. /*
  125.  * End texgen code
  126.  ***********************************************************************
  127.  */
  128.  
  129.  
  130.  
  131. /*
  132.  * One time inits for texture mapping.
  133.  * Called by one_time_init() in context.c
  134.  */
  135. void gl_init_texture( void )
  136. {
  137.    init_texgen();
  138.    init_texgen_compacted();
  139.    init_texgen_masked();
  140.    init_texgen_compacted_masked();
  141. }
  142.  
  143.  
  144. /*
  145.  * After state changes to texturing we call this function to update
  146.  * intermediate and derived state.
  147.  * Called by gl_update_state().
  148.  */
  149. void gl_update_texture_unit( GLcontext *ctx, struct gl_texture_unit *texUnit )
  150. {
  151.    (void) ctx;
  152.  
  153.    if ((texUnit->Enabled & TEXTURE0_3D) && texUnit->CurrentD[3]->Complete) {
  154.       texUnit->ReallyEnabled = TEXTURE0_3D;
  155.       texUnit->Current = texUnit->CurrentD[3];
  156.       texUnit->CurrentDimension = 3;
  157.    }
  158.    else if ((texUnit->Enabled & TEXTURE0_2D) && texUnit->CurrentD[2]->Complete) {
  159.       texUnit->ReallyEnabled = TEXTURE0_2D;
  160.       texUnit->Current = texUnit->CurrentD[2];
  161.       texUnit->CurrentDimension = 2;
  162.    }
  163.    else if ((texUnit->Enabled & TEXTURE0_1D) && texUnit->CurrentD[1]->Complete) {
  164.       texUnit->ReallyEnabled = TEXTURE0_1D;
  165.       texUnit->Current = texUnit->CurrentD[1];
  166.       texUnit->CurrentDimension = 1;
  167.    }
  168.    else {
  169.       if (MESA_VERBOSE & VERBOSE_TEXTURE) {
  170.      switch (texUnit->Enabled) {
  171.      case TEXTURE0_3D:
  172.         fprintf(stderr, "Using incomplete 3d texture %u\n",
  173.             texUnit->CurrentD[3]->Name);
  174.         break;
  175.      case TEXTURE0_2D:
  176.         fprintf(stderr, "Using incomplete 2d texture %u\n",
  177.             texUnit->CurrentD[2]->Name);
  178.         break;
  179.      case TEXTURE0_1D:
  180.         fprintf(stderr, "Using incomplete 1d texture %u\n",
  181.             texUnit->CurrentD[1]->Name);
  182.         break;
  183.      default:
  184.         fprintf(stderr, "Bad value for texUnit->Enabled %x\n",
  185.             texUnit->Enabled);
  186.         break;
  187.      }     
  188.       }
  189.  
  190.       texUnit->ReallyEnabled = 0;
  191.       texUnit->Current = NULL;
  192.       texUnit->CurrentDimension = 0;
  193.       return;
  194.    }
  195.  
  196.    texUnit->GenFlags = 0;
  197.  
  198.    if (texUnit->TexGenEnabled) {
  199.       GLuint sz = 0;
  200.  
  201.       if (texUnit->TexGenEnabled & S_BIT) {
  202.          sz = 1;
  203.          texUnit->GenFlags |= texUnit->GenBitS;
  204.       }
  205.       if (texUnit->TexGenEnabled & T_BIT) {
  206.          sz = 2;
  207.          texUnit->GenFlags |= texUnit->GenBitT;
  208.       }
  209.       if (texUnit->TexGenEnabled & Q_BIT) {
  210.          sz = 3;
  211.          texUnit->GenFlags |= texUnit->GenBitQ;
  212.       }
  213.       if (texUnit->TexGenEnabled & R_BIT) {
  214.          sz = 4;
  215.          texUnit->GenFlags |= texUnit->GenBitR;
  216.       }
  217.    
  218.       texUnit->TexgenSize = sz;
  219.       texUnit->Holes = (GLubyte) (all_bits[sz] & ~texUnit->TexGenEnabled);
  220.       texUnit->func = texgen_generic_tab;
  221.  
  222.       if (texUnit->TexGenEnabled == (S_BIT|T_BIT|R_BIT)) {
  223.      if (texUnit->GenFlags == TEXGEN_REFLECTION_MAP_NV) {
  224.         texUnit->func = texgen_reflection_map_nv_tab;
  225.      }
  226.      else if (texUnit->GenFlags == TEXGEN_NORMAL_MAP_NV) {
  227.         texUnit->func = texgen_normal_map_nv_tab;
  228.      }
  229.       }
  230.       else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) && 
  231.            texUnit->GenFlags == TEXGEN_SPHERE_MAP) {
  232.      texUnit->func = texgen_sphere_map_tab;
  233.       }
  234.    }
  235. }
  236.  
  237.  
  238.  
  239. /*
  240.  * Paletted texture sampling.
  241.  * Input:  tObj - the texture object
  242.  *         index - the palette index (8-bit only)
  243.  * Output:  red, green, blue, alpha - the texel color
  244.  */
  245. static void palette_sample(const struct gl_texture_object *tObj,
  246.                            GLubyte index, GLubyte rgba[4] )
  247. {
  248.    GLcontext *ctx = gl_get_current_context();  /* THIS IS A HACK */
  249.    GLint i = index;
  250.    const GLubyte *palette;
  251.  
  252.    if (ctx->Texture.SharedPalette) {
  253.       palette = ctx->Texture.Palette;
  254.    }
  255.    else {
  256.       palette = tObj->Palette;
  257.    }
  258.  
  259.    switch (tObj->PaletteFormat) {
  260.       case GL_ALPHA:
  261.          rgba[ACOMP] = tObj->Palette[index];
  262.          return;
  263.       case GL_LUMINANCE:
  264.       case GL_INTENSITY:
  265.          rgba[RCOMP] = palette[index];
  266.          return;
  267.       case GL_LUMINANCE_ALPHA:
  268.          rgba[RCOMP] = palette[(index << 1) + 0];
  269.          rgba[ACOMP] = palette[(index << 1) + 1];
  270.          return;
  271.       case GL_RGB:
  272.          rgba[RCOMP] = palette[index * 3 + 0];
  273.          rgba[GCOMP] = palette[index * 3 + 1];
  274.          rgba[BCOMP] = palette[index * 3 + 2];
  275.          return;
  276.       case GL_RGBA:
  277.          rgba[RCOMP] = palette[(i << 2) + 0];
  278.          rgba[GCOMP] = palette[(i << 2) + 1];
  279.          rgba[BCOMP] = palette[(i << 2) + 2];
  280.          rgba[ACOMP] = palette[(i << 2) + 3];
  281.          return;
  282.       default:
  283.          gl_problem(NULL, "Bad palette format in palette_sample");
  284.    }
  285. }
  286.  
  287.  
  288.  
  289. /*
  290.  * These values are used in the fixed-point arithmetic used
  291.  * for linear filtering.
  292.  */
  293. #define WEIGHT_SCALE 65536.0F
  294. #define WEIGHT_SHIFT 16
  295.  
  296.  
  297. /*
  298.  * Used to compute texel locations for linear sampling.
  299.  */
  300. #define COMPUTE_LINEAR_TEXEL_LOCATIONS(wrapMode, S, U, SIZE, I0, I1)    \
  301. {                                    \
  302.    if (wrapMode == GL_REPEAT) {                        \
  303.       U = S * SIZE - 0.5F;                        \
  304.       I0 = ((GLint) myFloor(U)) & (SIZE - 1);                \
  305.       I1 = (I0 + 1) & (SIZE - 1);                    \
  306.    }                                    \
  307.    else {                                \
  308.       U = S * SIZE;                            \
  309.       if (U < 0.0F)                            \
  310.          U = 0.0F;                            \
  311.       else if (U >= SIZE)                        \
  312.          U = SIZE;                            \
  313.       U -= 0.5F;                            \
  314.       I0 = (GLint) myFloor(U);                        \
  315.       I1 = I0 + 1;                            \
  316.       if (wrapMode == GL_CLAMP_TO_EDGE) {                \
  317.          if (I0 < 0)                            \
  318.             I0 = 0;                            \
  319.          if (I1 >= SIZE)                        \
  320.             I1 = SIZE - 1;                        \
  321.       }                                    \
  322.    }                                    \
  323. }
  324.  
  325.  
  326. /*
  327.  * Used to compute texel location for nearest sampling.
  328.  */
  329. #define COMPUTE_NEAREST_TEXEL_LOCATION(wrapMode, S, SIZE, I)        \
  330. {                                    \
  331.    if (wrapMode == GL_REPEAT) {                        \
  332.       /* s limited to [0,1) */                        \
  333.       /* i limited to [0,width-1] */                    \
  334.       I = (GLint) (S * SIZE);                        \
  335.       if (S < 0.0F)                            \
  336.          I -= 1;                            \
  337.       I &= (SIZE - 1);                            \
  338.    }                                    \
  339.    else if (wrapMode == GL_CLAMP_TO_EDGE) {                \
  340.       const GLfloat min = 1.0F / (2.0F * SIZE);                \
  341.       const GLfloat max = 1.0F - min;                    \
  342.       if (S < min)                            \
  343.          I = 0;                                \
  344.       else if (S > max)                            \
  345.          I = SIZE - 1;                            \
  346.       else                                \
  347.          I = (GLint) (S * SIZE);                    \
  348.    }                                    \
  349.    else {                                \
  350.       ASSERT(wrapMode == GL_CLAMP);                    \
  351.       /* s limited to [0,1] */                        \
  352.       /* i limited to [0,width-1] */                    \
  353.       if (S <= 0.0F)                            \
  354.          I = 0;                                \
  355.       else if (S >= 1.0F)                        \
  356.          I = SIZE - 1;                            \
  357.       else                                \
  358.          I = (GLint) (S * SIZE);                    \
  359.    }                                    \
  360. }
  361.  
  362.  
  363. /*
  364.  * Bitflags for texture border color sampling.
  365.  */
  366. #define I0BIT   1
  367. #define I1BIT   2
  368. #define J0BIT   4
  369. #define J1BIT   8
  370. #define K0BIT  16
  371. #define K1BIT  32
  372.  
  373.  
  374.  
  375. /**********************************************************************/
  376. /*                    1-D Texture Sampling Functions                  */
  377. /**********************************************************************/
  378.  
  379.  
  380. /*
  381.  * Return floor of x, being careful of negative values.
  382.  */
  383. static GLfloat myFloor(GLfloat x)
  384. {
  385.    if (x < 0.0F)
  386.       return (GLfloat) ((GLint) x - 1);
  387.    else
  388.       return (GLfloat) (GLint) x;
  389. }
  390.  
  391.  
  392. /*
  393.  * Return the fractional part of x.
  394.  */
  395. #define myFrac(x)  ( (x) - myFloor(x) )
  396.  
  397.  
  398.  
  399.  
  400. /*
  401.  * Given 1-D texture image and an (i) texel column coordinate, return the
  402.  * texel color.
  403.  */
  404. static void get_1d_texel( const struct gl_texture_object *tObj,
  405.                           const struct gl_texture_image *img, GLint i,
  406.                           GLubyte rgba[4] )
  407. {
  408.    const GLubyte *texel;
  409.  
  410. #ifdef DEBUG
  411.    GLint width = img->Width;
  412.    assert(i >= 0);
  413.    assert(i < width);
  414. #endif
  415.  
  416.    switch (img->Format) {
  417.       case GL_COLOR_INDEX:
  418.          {
  419.             GLubyte index = img->Data[i];
  420.             palette_sample(tObj, index, rgba);
  421.             return;
  422.          }
  423.       case GL_ALPHA:
  424.          rgba[ACOMP] = img->Data[ i ];
  425.          return;
  426.       case GL_LUMINANCE:
  427.       case GL_INTENSITY:
  428.          rgba[RCOMP] = img->Data[ i ];
  429.          return;
  430.       case GL_LUMINANCE_ALPHA:
  431.          texel = img->Data + i * 2;
  432.          rgba[RCOMP] = texel[0];
  433.          rgba[ACOMP] = texel[1];
  434.          return;
  435.       case GL_RGB:
  436.          texel = img->Data + i * 3;
  437.          rgba[RCOMP] = texel[0];
  438.          rgba[GCOMP] = texel[1];
  439.          rgba[BCOMP] = texel[2];
  440.          return;
  441.       case GL_RGBA:
  442.          texel = img->Data + i * 4;
  443.          rgba[RCOMP] = texel[0];
  444.          rgba[GCOMP] = texel[1];
  445.          rgba[BCOMP] = texel[2];
  446.          rgba[ACOMP] = texel[3];
  447.          return;
  448.       default:
  449.          gl_problem(NULL, "Bad format in get_1d_texel");
  450.          return;
  451.    }
  452. }
  453.  
  454.  
  455.  
  456. /*
  457.  * Return the texture sample for coordinate (s) using GL_NEAREST filter.
  458.  */
  459. static void sample_1d_nearest( const struct gl_texture_object *tObj,
  460.                                const struct gl_texture_image *img,
  461.                                GLfloat s, GLubyte rgba[4] )
  462. {
  463.    const GLint width = img->Width2;  /* without border, power of two */
  464.    const GLubyte *texel;
  465.    GLint i;
  466.  
  467.    COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i);
  468.  
  469.    /* skip over the border, if any */
  470.    i += img->Border;
  471.  
  472.    /* Get the texel */
  473.    switch (img->Format) {
  474.       case GL_COLOR_INDEX:
  475.          {
  476.             GLubyte index = img->Data[i];
  477.             palette_sample(tObj, index, rgba );
  478.             return;
  479.          }
  480.       case GL_ALPHA:
  481.          rgba[ACOMP] = img->Data[i];
  482.          return;
  483.       case GL_LUMINANCE:
  484.       case GL_INTENSITY:
  485.          rgba[RCOMP] = img->Data[i];
  486.          return;
  487.       case GL_LUMINANCE_ALPHA:
  488.          texel = img->Data + i * 2;
  489.          rgba[RCOMP] = texel[0];
  490.          rgba[ACOMP] = texel[1];
  491.          return;
  492.       case GL_RGB:
  493.          texel = img->Data + i * 3;
  494.          rgba[RCOMP] = texel[0];
  495.          rgba[GCOMP] = texel[1];
  496.          rgba[BCOMP] = texel[2];
  497.          return;
  498.       case GL_RGBA:
  499.          texel = img->Data + i * 4;
  500.          rgba[RCOMP] = texel[0];
  501.          rgba[GCOMP] = texel[1];
  502.          rgba[BCOMP] = texel[2];
  503.          rgba[ACOMP] = texel[3];
  504.          return;
  505.       default:
  506.          gl_problem(NULL, "Bad format in sample_1d_nearest");
  507.    }
  508. }
  509.  
  510.  
  511.  
  512. /*
  513.  * Return the texture sample for coordinate (s) using GL_LINEAR filter.
  514.  */
  515. static void sample_1d_linear( const struct gl_texture_object *tObj,
  516.                               const struct gl_texture_image *img,
  517.                               GLfloat s,
  518.                               GLubyte rgba[4] )
  519. {
  520.    const GLint width = img->Width2;
  521.    GLint i0, i1;
  522.    GLfloat u;
  523.    GLuint useBorderColor;
  524.  
  525.    COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width, i0, i1);
  526.  
  527.    useBorderColor = 0;
  528.    if (img->Border) {
  529.       i0 += img->Border;
  530.       i1 += img->Border;
  531.    }
  532.    else {
  533.       if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
  534.       if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
  535.    }
  536.  
  537.    {
  538.       GLfloat a = myFrac(u);
  539.       /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
  540.       GLint w0 = (GLint) ((1.0F-a) * WEIGHT_SCALE + 0.5F);
  541.       GLint w1 = (GLint) (      a  * WEIGHT_SCALE + 0.5F);
  542.  
  543.       GLubyte t0[4], t1[4];  /* texels */
  544.  
  545.       if (useBorderColor & I0BIT) {
  546.          t0[RCOMP] = tObj->BorderColor[0];
  547.          t0[GCOMP] = tObj->BorderColor[1];
  548.          t0[BCOMP] = tObj->BorderColor[2];
  549.          t0[ACOMP] = tObj->BorderColor[3];
  550.       }
  551.       else {
  552.          get_1d_texel( tObj, img, i0, t0 );
  553.       }
  554.       if (useBorderColor & I1BIT) {
  555.          t1[RCOMP] = tObj->BorderColor[0];
  556.          t1[GCOMP] = tObj->BorderColor[1];
  557.          t1[BCOMP] = tObj->BorderColor[2];
  558.          t1[ACOMP] = tObj->BorderColor[3];
  559.       }
  560.       else {
  561.          get_1d_texel( tObj, img, i1, t1 );
  562.       }
  563.  
  564.       rgba[0] = (GLubyte) ((w0 * t0[0] + w1 * t1[0]) >> WEIGHT_SHIFT);
  565.       rgba[1] = (GLubyte) ((w0 * t0[1] + w1 * t1[1]) >> WEIGHT_SHIFT);
  566.       rgba[2] = (GLubyte) ((w0 * t0[2] + w1 * t1[2]) >> WEIGHT_SHIFT);
  567.       rgba[3] = (GLubyte) ((w0 * t0[3] + w1 * t1[3]) >> WEIGHT_SHIFT);
  568.    }
  569. }
  570.  
  571.  
  572. static void
  573. sample_1d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
  574.                                   GLfloat s, GLfloat lambda,
  575.                                   GLubyte rgba[4] )
  576. {
  577.    GLint level;
  578.    if (lambda <= 0.5F)
  579.       lambda = 0.0F;
  580.    else if (lambda > tObj->M + 0.4999F)
  581.       lambda = tObj->M + 0.4999F;
  582.    level = (GLint) (tObj->BaseLevel + lambda + 0.5F);
  583.    if (level > tObj->P)
  584.       level = tObj->P;
  585.  
  586.    sample_1d_nearest( tObj, tObj->Image[level], s, rgba );
  587. }
  588.  
  589.  
  590. static void
  591. sample_1d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
  592.                                  GLfloat s, GLfloat lambda,
  593.                                  GLubyte rgba[4] )
  594. {
  595.    GLint level;
  596.    if (lambda <= 0.5F)
  597.       lambda = 0.0F;
  598.    else if (lambda > tObj->M + 0.4999F)
  599.       lambda = tObj->M + 0.4999F;
  600.    level = (GLint) (tObj->BaseLevel + lambda + 0.5F);
  601.    if (level > tObj->P)
  602.       level = tObj->P;
  603.  
  604.    sample_1d_linear( tObj, tObj->Image[level], s, rgba );
  605. }
  606.  
  607.  
  608.  
  609. static void
  610. sample_1d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
  611.                                  GLfloat s, GLfloat lambda,
  612.                                  GLubyte rgba[4] )
  613. {
  614.    GLint level;
  615.    if (lambda < 0.0F)
  616.       lambda = 0.0F;
  617.    else if (lambda > tObj->M)
  618.       lambda = tObj->M;
  619.    level = (GLint) (tObj->BaseLevel + lambda);
  620.  
  621.    if (level >= tObj->P) {
  622.       sample_1d_nearest( tObj, tObj->Image[tObj->P], s, rgba );
  623.    }
  624.    else {
  625.       GLubyte t0[4], t1[4];
  626.       GLfloat f = myFrac(lambda);
  627.       sample_1d_nearest( tObj, tObj->Image[level  ], s, t0 );
  628.       sample_1d_nearest( tObj, tObj->Image[level+1], s, t1 );
  629.       rgba[RCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  630.       rgba[GCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  631.       rgba[BCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  632.       rgba[ACOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  633.    }
  634. }
  635.  
  636.  
  637.  
  638. static void
  639. sample_1d_linear_mipmap_linear( const struct gl_texture_object *tObj,
  640.                                 GLfloat s, GLfloat lambda,
  641.                                 GLubyte rgba[4] )
  642. {
  643.    GLint level;
  644.    if (lambda < 0.0F)
  645.       lambda = 0.0F;
  646.    else if (lambda > tObj->M)
  647.       lambda = tObj->M;
  648.    level = (GLint) (tObj->BaseLevel + lambda);
  649.  
  650.    if (level >= tObj->P) {
  651.       sample_1d_linear( tObj, tObj->Image[tObj->P], s, rgba );
  652.    }
  653.    else {
  654.       GLubyte t0[4], t1[4];
  655.       GLfloat f = myFrac(lambda);
  656.       sample_1d_linear( tObj, tObj->Image[level  ], s, t0 );
  657.       sample_1d_linear( tObj, tObj->Image[level+1], s, t1 );
  658.       rgba[RCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  659.       rgba[GCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  660.       rgba[BCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  661.       rgba[ACOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  662.    }
  663. }
  664.  
  665.  
  666.  
  667. static void sample_nearest_1d( const struct gl_texture_object *tObj, GLuint n,
  668.                                const GLfloat s[], const GLfloat t[],
  669.                                const GLfloat u[], const GLfloat lambda[],
  670.                                GLubyte rgba[][4] )
  671. {
  672.    GLuint i;
  673.    struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  674.    (void) t;
  675.    (void) u;
  676.    (void) lambda;
  677.    for (i=0;i<n;i++) {
  678.       sample_1d_nearest( tObj, image, s[i], rgba[i] );
  679.    }
  680. }
  681.  
  682.  
  683.  
  684. static void sample_linear_1d( const struct gl_texture_object *tObj, GLuint n,
  685.                               const GLfloat s[], const GLfloat t[],
  686.                               const GLfloat u[], const GLfloat lambda[],
  687.                               GLubyte rgba[][4] )
  688. {
  689.    GLuint i;
  690.    struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  691.    (void) t;
  692.    (void) u;
  693.    (void) lambda;
  694.    for (i=0;i<n;i++) {
  695.       sample_1d_linear( tObj, image, s[i], rgba[i] );
  696.    }
  697. }
  698.  
  699.  
  700. /*
  701.  * Given an (s) texture coordinate and lambda (level of detail) value,
  702.  * return a texture sample.
  703.  *
  704.  */
  705. static void sample_lambda_1d( const struct gl_texture_object *tObj, GLuint n,
  706.                               const GLfloat s[], const GLfloat t[],
  707.                               const GLfloat u[], const GLfloat lambda[],
  708.                               GLubyte rgba[][4] )
  709. {
  710.    GLuint i;
  711.  
  712.    (void) t;
  713.    (void) u;
  714.  
  715.    for (i=0;i<n;i++) {
  716.       if (lambda[i] > tObj->MinMagThresh) {
  717.          /* minification */
  718.          switch (tObj->MinFilter) {
  719.             case GL_NEAREST:
  720.                sample_1d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
  721.                break;
  722.             case GL_LINEAR:
  723.                sample_1d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
  724.                break;
  725.             case GL_NEAREST_MIPMAP_NEAREST:
  726.                sample_1d_nearest_mipmap_nearest( tObj, lambda[i], s[i], rgba[i] );
  727.                break;
  728.             case GL_LINEAR_MIPMAP_NEAREST:
  729.                sample_1d_linear_mipmap_nearest( tObj, s[i], lambda[i], rgba[i] );
  730.                break;
  731.             case GL_NEAREST_MIPMAP_LINEAR:
  732.                sample_1d_nearest_mipmap_linear( tObj, s[i], lambda[i], rgba[i] );
  733.                break;
  734.             case GL_LINEAR_MIPMAP_LINEAR:
  735.                sample_1d_linear_mipmap_linear( tObj, s[i], lambda[i], rgba[i] );
  736.                break;
  737.             default:
  738.                gl_problem(NULL, "Bad min filter in sample_1d_texture");
  739.                return;
  740.          }
  741.       }
  742.       else {
  743.          /* magnification */
  744.          switch (tObj->MagFilter) {
  745.             case GL_NEAREST:
  746.                sample_1d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
  747.                break;
  748.             case GL_LINEAR:
  749.                sample_1d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
  750.                break;
  751.             default:
  752.                gl_problem(NULL, "Bad mag filter in sample_1d_texture");
  753.                return;
  754.          }
  755.       }
  756.    }
  757. }
  758.  
  759.  
  760.  
  761.  
  762. /**********************************************************************/
  763. /*                    2-D Texture Sampling Functions                  */
  764. /**********************************************************************/
  765.  
  766.  
  767. /*
  768.  * Given a texture image and an (i,j) integer texel coordinate, return the
  769.  * texel color.
  770.  */
  771. static void get_2d_texel( const struct gl_texture_object *tObj,
  772.                           const struct gl_texture_image *img, GLint i, GLint j,
  773.                           GLubyte rgba[4] )
  774. {
  775.    const GLint width = img->Width;    /* includes border */
  776.    const GLubyte *texel;
  777.  
  778. #ifdef DEBUG
  779.    const GLint height = img->Height;  /* includes border */
  780.    assert(i >= 0);
  781.    assert(i < width);
  782.    assert(j >= 0);
  783.    assert(j < height);
  784. #endif
  785.  
  786.    switch (img->Format) {
  787.       case GL_COLOR_INDEX:
  788.          {
  789.             GLubyte index = img->Data[ width *j + i ];
  790.             palette_sample(tObj, index, rgba );
  791.             return;
  792.          }
  793.       case GL_ALPHA:
  794.          rgba[ACOMP] = img->Data[ width * j + i ];
  795.          return;
  796.       case GL_LUMINANCE:
  797.       case GL_INTENSITY:
  798.          rgba[RCOMP] = img->Data[ width * j + i ];
  799.          return;
  800.       case GL_LUMINANCE_ALPHA:
  801.          texel = img->Data + (width * j + i) * 2;
  802.          rgba[RCOMP] = texel[0];
  803.          rgba[ACOMP] = texel[1];
  804.          return;
  805.       case GL_RGB:
  806.          texel = img->Data + (width * j + i) * 3;
  807.          rgba[RCOMP] = texel[0];
  808.          rgba[GCOMP] = texel[1];
  809.          rgba[BCOMP] = texel[2];
  810.          return;
  811.       case GL_RGBA:
  812.          texel = img->Data + (width * j + i) * 4;
  813.          rgba[RCOMP] = texel[0];
  814.          rgba[GCOMP] = texel[1];
  815.          rgba[BCOMP] = texel[2];
  816.          rgba[ACOMP] = texel[3];
  817.          return;
  818.       default:
  819.          gl_problem(NULL, "Bad format in get_2d_texel");
  820.    }
  821. }
  822.  
  823.  
  824.  
  825. /*
  826.  * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
  827.  */
  828. static void sample_2d_nearest( const struct gl_texture_object *tObj,
  829.                                const struct gl_texture_image *img,
  830.                                GLfloat s, GLfloat t,
  831.                                GLubyte rgba[] )
  832. {
  833.    const GLint imgWidth = img->Width;  /* includes border */
  834.    const GLint width = img->Width2;    /* without border, power of two */
  835.    const GLint height = img->Height2;  /* without border, power of two */
  836.    const GLubyte *texel;
  837.    GLint i, j;
  838.  
  839.    COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width,  i);
  840.    COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, t, height, j);
  841.  
  842.    /* skip over the border, if any */
  843.    i += img->Border;
  844.    j += img->Border;
  845.  
  846.    switch (img->Format) {
  847.       case GL_COLOR_INDEX:
  848.          {
  849.             GLubyte index = img->Data[ j * imgWidth + i ];
  850.             palette_sample(tObj, index, rgba);
  851.             return;
  852.          }
  853.       case GL_ALPHA:
  854.          rgba[ACOMP] = img->Data[ j * imgWidth + i ];
  855.          return;
  856.       case GL_LUMINANCE:
  857.       case GL_INTENSITY:
  858.          rgba[RCOMP] = img->Data[ j * imgWidth + i ];
  859.          return;
  860.       case GL_LUMINANCE_ALPHA:
  861.          texel = img->Data + ((j * imgWidth + i) << 1);
  862.          rgba[RCOMP] = texel[0];
  863.          rgba[ACOMP] = texel[1];
  864.          return;
  865.       case GL_RGB:
  866.          texel = img->Data + (j * imgWidth + i) * 3;
  867.          rgba[RCOMP] = texel[0];
  868.          rgba[GCOMP] = texel[1];
  869.          rgba[BCOMP] = texel[2];
  870.          return;
  871.       case GL_RGBA:
  872.          texel = img->Data + ((j * imgWidth + i) << 2);
  873.          rgba[RCOMP] = texel[0];
  874.          rgba[GCOMP] = texel[1];
  875.          rgba[BCOMP] = texel[2];
  876.          rgba[ACOMP] = texel[3];
  877.          return;
  878.       default:
  879.          gl_problem(NULL, "Bad format in sample_2d_nearest");
  880.    }
  881. }
  882.  
  883.  
  884.  
  885. /*
  886.  * Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
  887.  * New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
  888.  */
  889. static void sample_2d_linear( const struct gl_texture_object *tObj,
  890.                               const struct gl_texture_image *img,
  891.                               GLfloat s, GLfloat t,
  892.                               GLubyte rgba[] )
  893. {
  894.    const GLint width = img->Width2;
  895.    const GLint height = img->Height2;
  896.    GLint i0, j0, i1, j1;
  897.    GLuint useBorderColor;
  898.    GLfloat u, v;
  899.  
  900.    COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width,  i0, i1);
  901.    COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, t, v, height, j0, j1);
  902.  
  903.    useBorderColor = 0;
  904.    if (img->Border) {
  905.       i0 += img->Border;
  906.       i1 += img->Border;
  907.       j0 += img->Border;
  908.       j1 += img->Border;
  909.    }
  910.    else {
  911.       if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
  912.       if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
  913.       if (j0 < 0 || j0 >= height)  useBorderColor |= J0BIT;
  914.       if (j1 < 0 || j1 >= height)  useBorderColor |= J1BIT;
  915.    }
  916.  
  917.    {
  918.       GLfloat a = myFrac(u);
  919.       GLfloat b = myFrac(v);
  920.       /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
  921.       GLint w00 = (GLint) ((1.0F-a)*(1.0F-b) * WEIGHT_SCALE + 0.5F);
  922.       GLint w10 = (GLint) (      a *(1.0F-b) * WEIGHT_SCALE + 0.5F);
  923.       GLint w01 = (GLint) ((1.0F-a)*      b  * WEIGHT_SCALE + 0.5F);
  924.       GLint w11 = (GLint) (      a *      b  * WEIGHT_SCALE + 0.5F);
  925.       GLubyte t00[4];
  926.       GLubyte t10[4];
  927.       GLubyte t01[4];
  928.       GLubyte t11[4];
  929.  
  930.       if (useBorderColor & (I0BIT | J0BIT)) {
  931.          t00[RCOMP] = tObj->BorderColor[0];
  932.          t00[GCOMP] = tObj->BorderColor[1];
  933.          t00[BCOMP] = tObj->BorderColor[2];
  934.          t00[ACOMP] = tObj->BorderColor[3];
  935.       }
  936.       else {
  937.          get_2d_texel( tObj, img, i0, j0, t00 );
  938.       }
  939.       if (useBorderColor & (I1BIT | J0BIT)) {
  940.          t10[RCOMP] = tObj->BorderColor[0];
  941.          t10[GCOMP] = tObj->BorderColor[1];
  942.          t10[BCOMP] = tObj->BorderColor[2];
  943.          t10[ACOMP] = tObj->BorderColor[3];
  944.       }
  945.       else {
  946.          get_2d_texel( tObj, img, i1, j0, t10 );
  947.       }
  948.       if (useBorderColor & (I0BIT | J1BIT)) {
  949.          t01[RCOMP] = tObj->BorderColor[0];
  950.          t01[GCOMP] = tObj->BorderColor[1];
  951.          t01[BCOMP] = tObj->BorderColor[2];
  952.          t01[ACOMP] = tObj->BorderColor[3];
  953.       }
  954.       else {
  955.          get_2d_texel( tObj, img, i0, j1, t01 );
  956.       }
  957.       if (useBorderColor & (I1BIT | J1BIT)) {
  958.          t11[RCOMP] = tObj->BorderColor[0];
  959.          t11[GCOMP] = tObj->BorderColor[1];
  960.          t11[BCOMP] = tObj->BorderColor[2];
  961.          t11[ACOMP] = tObj->BorderColor[3];
  962.       }
  963.       else {
  964.          get_2d_texel( tObj, img, i1, j1, t11 );
  965.       }
  966.  
  967.       rgba[0] = (GLubyte) ((w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0]) >> WEIGHT_SHIFT);
  968.       rgba[1] = (GLubyte) ((w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1]) >> WEIGHT_SHIFT);
  969.       rgba[2] = (GLubyte) ((w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2]) >> WEIGHT_SHIFT);
  970.       rgba[3] = (GLubyte) ((w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3]) >> WEIGHT_SHIFT);
  971.    }
  972.  
  973. }
  974.  
  975.  
  976.  
  977. static void
  978. sample_2d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
  979.                                   GLfloat s, GLfloat t, GLfloat lambda,
  980.                                   GLubyte rgba[4] )
  981. {
  982.    GLint level;
  983.    if (lambda <= 0.5F)
  984.       lambda = 0.0F;
  985.    else if (lambda > tObj->M + 0.4999F)
  986.       lambda = tObj->M + 0.4999F;
  987.    level = (GLint) (tObj->BaseLevel + lambda + 0.5F);
  988.    if (level > tObj->P)
  989.       level = tObj->P;
  990.  
  991.    sample_2d_nearest( tObj, tObj->Image[level], s, t, rgba );
  992. }
  993.  
  994.  
  995.  
  996. static void
  997. sample_2d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
  998.                                  GLfloat s, GLfloat t, GLfloat lambda,
  999.                                  GLubyte rgba[4] )
  1000. {
  1001.    GLint level;
  1002.    if (lambda <= 0.5F)
  1003.       lambda = 0.0F;
  1004.    else if (lambda > tObj->M + 0.4999F)
  1005.       lambda = tObj->M + 0.4999F;
  1006.    level = (GLint) (tObj->BaseLevel + lambda + 0.5F);
  1007.    if (level > tObj->P)
  1008.       level = tObj->P;
  1009.  
  1010.    sample_2d_linear( tObj, tObj->Image[level], s, t, rgba );
  1011. }
  1012.  
  1013.  
  1014.  
  1015. static void
  1016. sample_2d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
  1017.                                  GLfloat s, GLfloat t, GLfloat lambda,
  1018.                                  GLubyte rgba[4] )
  1019. {
  1020.    GLint level;
  1021.    if (lambda < 0.0F)
  1022.       lambda = 0.0F;
  1023.    else if (lambda > tObj->M)
  1024.       lambda = tObj->M;
  1025.    level = (GLint) (tObj->BaseLevel + lambda);
  1026.  
  1027.    if (level >= tObj->P) {
  1028.       sample_2d_nearest( tObj, tObj->Image[tObj->P], s, t, rgba );
  1029.    }
  1030.    else {
  1031.       GLubyte t0[4], t1[4];  /* texels */
  1032.       GLfloat f = myFrac(lambda);
  1033.       sample_2d_nearest( tObj, tObj->Image[level  ], s, t, t0 );
  1034.       sample_2d_nearest( tObj, tObj->Image[level+1], s, t, t1 );
  1035.       rgba[RCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  1036.       rgba[GCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  1037.       rgba[BCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  1038.       rgba[ACOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  1039.    }
  1040. }
  1041.  
  1042.  
  1043.  
  1044. static void
  1045. sample_2d_linear_mipmap_linear( const struct gl_texture_object *tObj,
  1046.                                 GLfloat s, GLfloat t, GLfloat lambda,
  1047.                                 GLubyte rgba[4] )
  1048. {
  1049.    GLint level;
  1050.    if (lambda < 0.0F)
  1051.       lambda = 0.0F;
  1052.    else if (lambda > tObj->M)
  1053.       lambda = tObj->M;
  1054.    level = (GLint) (tObj->BaseLevel + lambda);
  1055.  
  1056.    if (level >= tObj->P) {
  1057.       sample_2d_linear( tObj, tObj->Image[tObj->P], s, t, rgba );
  1058.    }
  1059.    else {
  1060.       GLubyte t0[4], t1[4];  /* texels */
  1061.       GLfloat f = myFrac(lambda);
  1062.       sample_2d_linear( tObj, tObj->Image[level  ], s, t, t0 );
  1063.       sample_2d_linear( tObj, tObj->Image[level+1], s, t, t1 );
  1064.       rgba[RCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  1065.       rgba[GCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  1066.       rgba[BCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  1067.       rgba[ACOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  1068.    }
  1069. }
  1070.  
  1071.  
  1072.  
  1073. static void sample_nearest_2d( const struct gl_texture_object *tObj, GLuint n,
  1074.                                const GLfloat s[], const GLfloat t[],
  1075.                                const GLfloat u[], const GLfloat lambda[],
  1076.                                GLubyte rgba[][4] )
  1077. {
  1078.    GLuint i;
  1079.    struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  1080.    (void) u;
  1081.    (void) lambda;
  1082.    for (i=0;i<n;i++) {
  1083.       sample_2d_nearest( tObj, image, s[i], t[i], rgba[i] );
  1084.    }
  1085. }
  1086.  
  1087.  
  1088.  
  1089. static void sample_linear_2d( const struct gl_texture_object *tObj, GLuint n,
  1090.                               const GLfloat s[], const GLfloat t[],
  1091.                               const GLfloat u[], const GLfloat lambda[],
  1092.                               GLubyte rgba[][4] )
  1093. {
  1094.    GLuint i;
  1095.    struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  1096.    (void) u;
  1097.    (void) lambda;
  1098.    for (i=0;i<n;i++) {
  1099.       sample_2d_linear( tObj, image, s[i], t[i], rgba[i] );
  1100.    }
  1101. }
  1102.  
  1103.  
  1104. /*
  1105.  * Given an (s,t) texture coordinate and lambda (level of detail) value,
  1106.  * return a texture sample.
  1107.  */
  1108. static void sample_lambda_2d( const struct gl_texture_object *tObj,
  1109.                               GLuint n,
  1110.                               const GLfloat s[], const GLfloat t[],
  1111.                               const GLfloat u[], const GLfloat lambda[],
  1112.                               GLubyte rgba[][4] )
  1113. {
  1114.    GLuint i;
  1115.    (void) u;
  1116.    for (i=0;i<n;i++) {
  1117.       if (lambda[i] > tObj->MinMagThresh) {
  1118.          /* minification */
  1119.          switch (tObj->MinFilter) {
  1120.             case GL_NEAREST:
  1121.                sample_2d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
  1122.                break;
  1123.             case GL_LINEAR:
  1124.                sample_2d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
  1125.                break;
  1126.             case GL_NEAREST_MIPMAP_NEAREST:
  1127.                sample_2d_nearest_mipmap_nearest( tObj, s[i], t[i], lambda[i], rgba[i] );
  1128.                break;
  1129.             case GL_LINEAR_MIPMAP_NEAREST:
  1130.                sample_2d_linear_mipmap_nearest( tObj, s[i], t[i], lambda[i], rgba[i] );
  1131.                break;
  1132.             case GL_NEAREST_MIPMAP_LINEAR:
  1133.                sample_2d_nearest_mipmap_linear( tObj, s[i], t[i], lambda[i], rgba[i] );
  1134.                break;
  1135.             case GL_LINEAR_MIPMAP_LINEAR:
  1136.                sample_2d_linear_mipmap_linear( tObj, s[i], t[i], lambda[i], rgba[i] );
  1137.                break;
  1138.             default:
  1139.                gl_problem(NULL, "Bad min filter in sample_2d_texture");
  1140.                return;
  1141.          }
  1142.       }
  1143.       else {
  1144.          /* magnification */
  1145.          switch (tObj->MagFilter) {
  1146.             case GL_NEAREST:
  1147.                sample_2d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
  1148.                break;
  1149.             case GL_LINEAR:
  1150.                sample_2d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
  1151.                break;
  1152.             default:
  1153.                gl_problem(NULL, "Bad mag filter in sample_2d_texture");
  1154.          }
  1155.       }
  1156.    }
  1157. }
  1158.  
  1159.  
  1160. /*
  1161.  * Optimized 2-D texture sampling:
  1162.  *    S and T wrap mode == GL_REPEAT
  1163.  *    GL_NEAREST min/mag filter
  1164.  *    No border
  1165.  *    Format = GL_RGB
  1166.  */
  1167. static void opt_sample_rgb_2d( const struct gl_texture_object *tObj,
  1168.                                GLuint n, const GLfloat s[], const GLfloat t[],
  1169.                                const GLfloat u[], const GLfloat lambda[],
  1170.                                GLubyte rgba[][4] )
  1171. {
  1172.    const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel];
  1173.    const GLfloat width = (GLfloat) img->Width;
  1174.    const GLfloat height = (GLfloat) img->Height;
  1175.    const GLint colMask = img->Width - 1;
  1176.    const GLint rowMask = img->Height - 1;
  1177.    const GLint shift = img->WidthLog2;
  1178.    GLuint k;
  1179.    (void) u;
  1180.    (void) lambda;
  1181.    ASSERT(tObj->WrapS==GL_REPEAT);
  1182.    ASSERT(tObj->WrapT==GL_REPEAT);
  1183.    ASSERT(tObj->MinFilter==GL_NEAREST);
  1184.    ASSERT(tObj->MagFilter==GL_NEAREST);
  1185.    ASSERT(img->Border==0);
  1186.    ASSERT(img->Format==GL_RGB);
  1187.  
  1188.    /* NOTE: negative float->int doesn't floor, add 10000 as to work-around */
  1189.    for (k=0;k<n;k++) {
  1190.       GLint i = (GLint) ((s[k] + 10000.0) * width) & colMask;
  1191.       GLint j = (GLint) ((t[k] + 10000.0) * height) & rowMask;
  1192.       GLint pos = (j << shift) | i;
  1193.       GLubyte *texel = img->Data + pos + pos + pos;  /* pos*3 */
  1194.       rgba[k][RCOMP] = texel[0];
  1195.       rgba[k][GCOMP] = texel[1];
  1196.       rgba[k][BCOMP] = texel[2];
  1197.    }
  1198. }
  1199.  
  1200.  
  1201. /*
  1202.  * Optimized 2-D texture sampling:
  1203.  *    S and T wrap mode == GL_REPEAT
  1204.  *    GL_NEAREST min/mag filter
  1205.  *    No border
  1206.  *    Format = GL_RGBA
  1207.  */
  1208. static void opt_sample_rgba_2d( const struct gl_texture_object *tObj,
  1209.                                 GLuint n, const GLfloat s[], const GLfloat t[],
  1210.                                 const GLfloat u[], const GLfloat lambda[],
  1211.                                 GLubyte rgba[][4] )
  1212. {
  1213.    const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel];
  1214.    const GLfloat width = (GLfloat) img->Width;
  1215.    const GLfloat height = (GLfloat) img->Height;
  1216.    const GLint colMask = img->Width - 1;
  1217.    const GLint rowMask = img->Height - 1;
  1218.    const GLint shift = img->WidthLog2;
  1219.    GLuint k;
  1220.    (void) u;
  1221.    (void) lambda;
  1222.    ASSERT(tObj->WrapS==GL_REPEAT);
  1223.    ASSERT(tObj->WrapT==GL_REPEAT);
  1224.    ASSERT(tObj->MinFilter==GL_NEAREST);
  1225.    ASSERT(tObj->MagFilter==GL_NEAREST);
  1226.    ASSERT(img->Border==0);
  1227.    ASSERT(img->Format==GL_RGBA);
  1228.  
  1229.    /* NOTE: negative float->int doesn't floor, add 10000 as to work-around */
  1230.    for (k=0;k<n;k++) {
  1231.       GLint i = (GLint) ((s[k] + 10000.0) * width) & colMask;
  1232.       GLint j = (GLint) ((t[k] + 10000.0) * height) & rowMask;
  1233.       GLint pos = (j << shift) | i;
  1234.       GLubyte *texel = img->Data + (pos << 2);    /* pos*4 */
  1235.       rgba[k][RCOMP] = texel[0];
  1236.       rgba[k][GCOMP] = texel[1];
  1237.       rgba[k][BCOMP] = texel[2];
  1238.       rgba[k][ACOMP] = texel[3];
  1239.    }
  1240. }
  1241.  
  1242.  
  1243.  
  1244. /**********************************************************************/
  1245. /*                    3-D Texture Sampling Functions                  */
  1246. /**********************************************************************/
  1247.  
  1248. /*
  1249.  * Given a texture image and an (i,j,k) integer texel coordinate, return the
  1250.  * texel color.
  1251.  */
  1252. static void get_3d_texel( const struct gl_texture_object *tObj,
  1253.                           const struct gl_texture_image *img,
  1254.                           GLint i, GLint j, GLint k,
  1255.                           GLubyte rgba[4] )
  1256. {
  1257.    const GLint width = img->Width;    /* includes border */
  1258.    const GLint height = img->Height;  /* includes border */
  1259.    const GLint rectarea = width * height;
  1260.    const GLubyte *texel;
  1261.  
  1262. #ifdef DEBUG
  1263.    const GLint depth = img->Depth;    /* includes border */
  1264.    assert(i >= 0);
  1265.    assert(i < width);
  1266.    assert(j >= 0);
  1267.    assert(j < height);
  1268.    assert(k >= 0);
  1269.    assert(k < depth);
  1270. #endif
  1271.  
  1272.    switch (img->Format) {
  1273.       case GL_COLOR_INDEX:
  1274.          {
  1275.             GLubyte index = img->Data[ rectarea * k +  width * j + i ];
  1276.             palette_sample(tObj, index, rgba );
  1277.             return;
  1278.          }
  1279.       case GL_ALPHA:
  1280.          rgba[ACOMP] = img->Data[ rectarea * k +  width * j + i ];
  1281.          return;
  1282.       case GL_LUMINANCE:
  1283.       case GL_INTENSITY:
  1284.          rgba[RCOMP] = img->Data[ rectarea * k +  width * j + i ];
  1285.          return;
  1286.       case GL_LUMINANCE_ALPHA:
  1287.          texel = img->Data + ( rectarea * k + width * j + i) * 2;
  1288.          rgba[RCOMP] = texel[0];
  1289.          rgba[ACOMP] = texel[1];
  1290.          return;
  1291.       case GL_RGB:
  1292.          texel = img->Data + (rectarea * k + width * j + i) * 3;
  1293.          rgba[RCOMP] = texel[0];
  1294.          rgba[GCOMP] = texel[1];
  1295.          rgba[BCOMP] = texel[2];
  1296.          return;
  1297.       case GL_RGBA:
  1298.          texel = img->Data + (rectarea * k + width * j + i) * 4;
  1299.          rgba[RCOMP] = texel[0];
  1300.          rgba[GCOMP] = texel[1];
  1301.          rgba[BCOMP] = texel[2];
  1302.          rgba[ACOMP] = texel[3];
  1303.          return;
  1304.       default:
  1305.          gl_problem(NULL, "Bad format in get_3d_texel");
  1306.    }
  1307. }
  1308.  
  1309.  
  1310. /*
  1311.  * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
  1312.  */
  1313. static void sample_3d_nearest( const struct gl_texture_object *tObj,
  1314.                                const struct gl_texture_image *img,
  1315.                                GLfloat s, GLfloat t, GLfloat r,
  1316.                                GLubyte rgba[4] )
  1317. {
  1318.    const GLint imgWidth = img->Width;   /* includes border, if any */
  1319.    const GLint imgHeight = img->Height; /* includes border, if any */
  1320.    const GLint width = img->Width2;     /* without border, power of two */
  1321.    const GLint height = img->Height2;   /* without border, power of two */
  1322.    const GLint depth = img->Depth2;     /* without border, power of two */
  1323.    const GLint rectarea = imgWidth * imgHeight;
  1324.    const GLubyte *texel;
  1325.    GLint i, j, k;
  1326.  
  1327.    COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width,  i);
  1328.    COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, t, height, j);
  1329.    COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapR, r, depth,  k);
  1330.  
  1331.    switch (tObj->Image[0]->Format) {
  1332.       case GL_COLOR_INDEX:
  1333.          {
  1334.             GLubyte index = img->Data[ rectarea * k + j * imgWidth + i ];
  1335.             palette_sample(tObj, index, rgba );
  1336.             return;
  1337.          }
  1338.       case GL_ALPHA:
  1339.          rgba[ACOMP] = img->Data[ rectarea * k + j * imgWidth + i ];
  1340.          return;
  1341.       case GL_LUMINANCE:
  1342.       case GL_INTENSITY:
  1343.          rgba[RCOMP] = img->Data[ rectarea * k + j * imgWidth + i ];
  1344.          return;
  1345.       case GL_LUMINANCE_ALPHA:
  1346.          texel = img->Data + ((rectarea * k + j * imgWidth + i) << 1);
  1347.          rgba[RCOMP] = texel[0];
  1348.          rgba[ACOMP] = texel[1];
  1349.          return;
  1350.       case GL_RGB:
  1351.          texel = img->Data + ( rectarea * k + j * imgWidth + i) * 3;
  1352.          rgba[RCOMP] = texel[0];
  1353.          rgba[GCOMP] = texel[1];
  1354.          rgba[BCOMP] = texel[2];
  1355.          return;
  1356.       case GL_RGBA:
  1357.          texel = img->Data + ((rectarea * k + j * imgWidth + i) << 2);
  1358.          rgba[RCOMP] = texel[0];
  1359.          rgba[GCOMP] = texel[1];
  1360.          rgba[BCOMP] = texel[2];
  1361.          rgba[ACOMP] = texel[3];
  1362.          return;
  1363.       default:
  1364.          gl_problem(NULL, "Bad format in sample_3d_nearest");
  1365.    }
  1366. }
  1367.  
  1368.  
  1369.  
  1370. /*
  1371.  * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
  1372.  */
  1373. static void sample_3d_linear( const struct gl_texture_object *tObj,
  1374.                               const struct gl_texture_image *img,
  1375.                               GLfloat s, GLfloat t, GLfloat r,
  1376.                               GLubyte rgba[4] )
  1377. {
  1378.    const GLint width = img->Width2;
  1379.    const GLint height = img->Height2;
  1380.    const GLint depth = img->Depth2;
  1381.    GLint i0, j0, k0, i1, j1, k1;
  1382.    GLuint useBorderColor;
  1383.    GLfloat u, v, w;
  1384.  
  1385.    COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width,  i0, i1);
  1386.    COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, t, v, height, j0, j1);
  1387.    COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapR, r, w, depth,  k0, k1);
  1388.  
  1389.    useBorderColor = 0;
  1390.    if (img->Border) {
  1391.       i0 += img->Border;
  1392.       i1 += img->Border;
  1393.       j0 += img->Border;
  1394.       j1 += img->Border;
  1395.       k0 += img->Border;
  1396.       k1 += img->Border;
  1397.    }
  1398.    else {
  1399.       /* check if sampling texture border color */
  1400.       if (i0 < 0 || i0 >= width)   useBorderColor |= I0BIT;
  1401.       if (i1 < 0 || i1 >= width)   useBorderColor |= I1BIT;
  1402.       if (j0 < 0 || j0 >= height)  useBorderColor |= J0BIT;
  1403.       if (j1 < 0 || j1 >= height)  useBorderColor |= J1BIT;
  1404.       if (k0 < 0 || k0 >= depth)   useBorderColor |= K0BIT;
  1405.       if (k1 < 0 || k1 >= depth)   useBorderColor |= K1BIT;
  1406.    }
  1407.  
  1408.    {
  1409.       GLfloat a = myFrac(u);
  1410.       GLfloat b = myFrac(v);
  1411.       GLfloat c = myFrac(w);
  1412.       /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
  1413.       GLint w000 = (GLint) ((1.0F-a)*(1.0F-b)*(1.0F-c) * WEIGHT_SCALE + 0.5F);
  1414.       GLint w100 = (GLint) (      a *(1.0F-b)*(1.0F-c) * WEIGHT_SCALE + 0.5F);
  1415.       GLint w010 = (GLint) ((1.0F-a)*      b *(1.0F-c) * WEIGHT_SCALE + 0.5F);
  1416.       GLint w110 = (GLint) (      a *      b *(1.0F-c) * WEIGHT_SCALE + 0.5F);
  1417.       GLint w001 = (GLint) ((1.0F-a)*(1.0F-b)*      c  * WEIGHT_SCALE + 0.5F);
  1418.       GLint w101 = (GLint) (      a *(1.0F-b)*      c  * WEIGHT_SCALE + 0.5F);
  1419.       GLint w011 = (GLint) ((1.0F-a)*      b *      c  * WEIGHT_SCALE + 0.5F);
  1420.       GLint w111 = (GLint) (      a *      b *      c  * WEIGHT_SCALE + 0.5F);
  1421.  
  1422.       GLubyte t000[4], t010[4], t001[4], t011[4];
  1423.       GLubyte t100[4], t110[4], t101[4], t111[4];
  1424.  
  1425.       if (useBorderColor & (I0BIT | J0BIT | K0BIT)) {
  1426.          t000[RCOMP] = tObj->BorderColor[0];
  1427.          t000[GCOMP] = tObj->BorderColor[1];
  1428.          t000[BCOMP] = tObj->BorderColor[2];
  1429.          t000[ACOMP] = tObj->BorderColor[3];
  1430.       }
  1431.       else {
  1432.          get_3d_texel( tObj, img, i0, j0, k0, t000 );
  1433.       }
  1434.       if (useBorderColor & (I1BIT | J0BIT | K0BIT)) {
  1435.          t100[RCOMP] = tObj->BorderColor[0];
  1436.          t100[GCOMP] = tObj->BorderColor[1];
  1437.          t100[BCOMP] = tObj->BorderColor[2];
  1438.          t100[ACOMP] = tObj->BorderColor[3];
  1439.       }
  1440.       else {
  1441.          get_3d_texel( tObj, img, i1, j0, k0, t100 );
  1442.       }
  1443.       if (useBorderColor & (I0BIT | J1BIT | K0BIT)) {
  1444.          t010[RCOMP] = tObj->BorderColor[0];
  1445.          t010[GCOMP] = tObj->BorderColor[1];
  1446.          t010[BCOMP] = tObj->BorderColor[2];
  1447.          t010[ACOMP] = tObj->BorderColor[3];
  1448.       }
  1449.       else {
  1450.          get_3d_texel( tObj, img, i0, j1, k0, t010 );
  1451.       }
  1452.       if (useBorderColor & (I1BIT | J1BIT | K0BIT)) {
  1453.          t110[RCOMP] = tObj->BorderColor[0];
  1454.          t110[GCOMP] = tObj->BorderColor[1];
  1455.          t110[BCOMP] = tObj->BorderColor[2];
  1456.          t110[ACOMP] = tObj->BorderColor[3];
  1457.       }
  1458.       else {
  1459.          get_3d_texel( tObj, img, i1, j1, k0, t110 );
  1460.       }
  1461.  
  1462.       if (useBorderColor & (I0BIT | J0BIT | K1BIT)) {
  1463.          t001[RCOMP] = tObj->BorderColor[0];
  1464.          t001[GCOMP] = tObj->BorderColor[1];
  1465.          t001[BCOMP] = tObj->BorderColor[2];
  1466.          t001[ACOMP] = tObj->BorderColor[3];
  1467.       }
  1468.       else {
  1469.          get_3d_texel( tObj, img, i0, j0, k1, t001 );
  1470.       }
  1471.       if (useBorderColor & (I1BIT | J0BIT | K1BIT)) {
  1472.          t101[RCOMP] = tObj->BorderColor[0];
  1473.          t101[GCOMP] = tObj->BorderColor[1];
  1474.          t101[BCOMP] = tObj->BorderColor[2];
  1475.          t101[ACOMP] = tObj->BorderColor[3];
  1476.       }
  1477.       else {
  1478.          get_3d_texel( tObj, img, i1, j0, k1, t101 );
  1479.       }
  1480.       if (useBorderColor & (I0BIT | J1BIT | K1BIT)) {
  1481.          t011[RCOMP] = tObj->BorderColor[0];
  1482.          t011[GCOMP] = tObj->BorderColor[1];
  1483.          t011[BCOMP] = tObj->BorderColor[2];
  1484.          t011[ACOMP] = tObj->BorderColor[3];
  1485.       }
  1486.       else {
  1487.          get_3d_texel( tObj, img, i0, j1, k1, t011 );
  1488.       }
  1489.       if (useBorderColor & (I1BIT | J1BIT | K1BIT)) {
  1490.          t111[RCOMP] = tObj->BorderColor[0];
  1491.          t111[GCOMP] = tObj->BorderColor[1];
  1492.          t111[BCOMP] = tObj->BorderColor[2];
  1493.          t111[ACOMP] = tObj->BorderColor[3];
  1494.       }
  1495.       else {
  1496.          get_3d_texel( tObj, img, i1, j1, k1, t111 );
  1497.       }
  1498.  
  1499.       rgba[0] = (GLubyte) (
  1500.                  (w000*t000[0] + w010*t010[0] + w001*t001[0] + w011*t011[0] +
  1501.                   w100*t100[0] + w110*t110[0] + w101*t101[0] + w111*t111[0]  )
  1502.                  >> WEIGHT_SHIFT);
  1503.       rgba[1] = (GLubyte) (
  1504.                  (w000*t000[1] + w010*t010[1] + w001*t001[1] + w011*t011[1] +
  1505.                   w100*t100[1] + w110*t110[1] + w101*t101[1] + w111*t111[1] )
  1506.                  >> WEIGHT_SHIFT);
  1507.       rgba[2] = (GLubyte) (
  1508.                  (w000*t000[2] + w010*t010[2] + w001*t001[2] + w011*t011[2] +
  1509.                   w100*t100[2] + w110*t110[2] + w101*t101[2] + w111*t111[2] )
  1510.                  >> WEIGHT_SHIFT);
  1511.       rgba[3] = (GLubyte) (
  1512.                  (w000*t000[3] + w010*t010[3] + w001*t001[3] + w011*t011[3] +
  1513.                   w100*t100[3] + w110*t110[3] + w101*t101[3] + w111*t111[3] )
  1514.                  >> WEIGHT_SHIFT);
  1515.    }
  1516. }
  1517.  
  1518.  
  1519.  
  1520. static void
  1521. sample_3d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
  1522.                                   GLfloat s, GLfloat t, GLfloat r,
  1523.                                   GLfloat lambda, GLubyte rgba[4] )
  1524. {
  1525.    GLint level;
  1526.    if (lambda <= 0.5F)
  1527.       lambda = 0.0F;
  1528.    else if (lambda > tObj->M + 0.4999F)
  1529.       lambda = tObj->M + 0.4999F;
  1530.    level = (GLint) (tObj->BaseLevel + lambda + 0.5F);
  1531.    if (level > tObj->P)
  1532.       level = tObj->P;
  1533.  
  1534.    sample_3d_nearest( tObj, tObj->Image[level], s, t, r, rgba );
  1535. }
  1536.  
  1537.  
  1538. static void
  1539. sample_3d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
  1540.                                  GLfloat s, GLfloat t, GLfloat r,
  1541.                                  GLfloat lambda, GLubyte rgba[4] )
  1542. {
  1543.    GLint level;
  1544.    if (lambda <= 0.5F)
  1545.       lambda = 0.0F;
  1546.    else if (lambda > tObj->M + 0.4999F)
  1547.       lambda = tObj->M + 0.4999F;
  1548.    level = (GLint) (tObj->BaseLevel + lambda + 0.5F);
  1549.    if (level > tObj->P)
  1550.       level = tObj->P;
  1551.  
  1552.    sample_3d_linear( tObj, tObj->Image[level], s, t, r, rgba );
  1553. }
  1554.  
  1555.  
  1556. static void
  1557. sample_3d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
  1558.                                  GLfloat s, GLfloat t, GLfloat r,
  1559.                                  GLfloat lambda, GLubyte rgba[4] )
  1560. {
  1561.    GLint level;
  1562.    if (lambda < 0.0F)
  1563.       lambda = 0.0F;
  1564.    else if (lambda > tObj->M)
  1565.       lambda = tObj->M;
  1566.    level = (GLint) (tObj->BaseLevel + lambda);
  1567.  
  1568.    if (level >= tObj->P) {
  1569.       sample_3d_nearest( tObj, tObj->Image[tObj->P], s, t, r, rgba );
  1570.    }
  1571.    else {
  1572.       GLubyte t0[4], t1[4];  /* texels */
  1573.       GLfloat f = myFrac(lambda);
  1574.       sample_3d_nearest( tObj, tObj->Image[level  ], s, t, r, t0 );
  1575.       sample_3d_nearest( tObj, tObj->Image[level+1], s, t, r, t1 );
  1576.       rgba[RCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  1577.       rgba[GCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  1578.       rgba[BCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  1579.       rgba[ACOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  1580.    }
  1581. }
  1582.  
  1583.  
  1584. static void
  1585. sample_3d_linear_mipmap_linear( const struct gl_texture_object *tObj,
  1586.                                 GLfloat s, GLfloat t, GLfloat r,
  1587.                                 GLfloat lambda, GLubyte rgba[4] )
  1588. {
  1589.    GLint level;
  1590.    if (lambda < 0.0F)
  1591.       lambda = 0.0F;
  1592.    else if (lambda > tObj->M)
  1593.       lambda = tObj->M;
  1594.    level = (GLint) (tObj->BaseLevel + lambda);
  1595.  
  1596.    if (level >= tObj->P) {
  1597.       sample_3d_linear( tObj, tObj->Image[tObj->P], s, t, r, rgba );
  1598.    }
  1599.    else {
  1600.       GLubyte t0[4], t1[4];  /* texels */
  1601.       GLfloat f = myFrac(lambda);
  1602.       sample_3d_linear( tObj, tObj->Image[level  ], s, t, r, t0 );
  1603.       sample_3d_linear( tObj, tObj->Image[level+1], s, t, r, t1 );
  1604.       rgba[RCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  1605.       rgba[GCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  1606.       rgba[BCOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  1607.       rgba[ACOMP] = (GLubyte) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  1608.    }
  1609. }
  1610.  
  1611.  
  1612. static void sample_nearest_3d( const struct gl_texture_object *tObj, GLuint n,
  1613.                                const GLfloat s[], const GLfloat t[],
  1614.                                const GLfloat u[], const GLfloat lambda[],
  1615.                                GLubyte rgba[][4] )
  1616. {
  1617.    GLuint i;
  1618.    struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  1619.    (void) lambda;
  1620.    for (i=0;i<n;i++) {
  1621.       sample_3d_nearest( tObj, image, s[i], t[i], u[i], rgba[i] );
  1622.    }
  1623. }
  1624.  
  1625.  
  1626.  
  1627. static void sample_linear_3d( const struct gl_texture_object *tObj, GLuint n,
  1628.                               const GLfloat s[], const GLfloat t[],
  1629.                               const GLfloat u[], const GLfloat lambda[],
  1630.                               GLubyte rgba[][4] )
  1631. {
  1632.    GLuint i;
  1633.    struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  1634.    (void) lambda;
  1635.    for (i=0;i<n;i++) {
  1636.       sample_3d_linear( tObj, image, s[i], t[i], u[i], rgba[i] );
  1637.    }
  1638. }
  1639.  
  1640.  
  1641. /*
  1642.  * Given an (s,t,r) texture coordinate and lambda (level of detail) value,
  1643.  * return a texture sample.
  1644.  */
  1645. static void sample_lambda_3d( const struct gl_texture_object *tObj, GLuint n,
  1646.                               const GLfloat s[], const GLfloat t[],
  1647.                               const GLfloat u[], const GLfloat lambda[],
  1648.                               GLubyte rgba[][4] )
  1649. {
  1650.    GLuint i;
  1651.  
  1652.    for (i=0;i<n;i++) {
  1653.  
  1654.       if (lambda[i] > tObj->MinMagThresh) {
  1655.          /* minification */
  1656.          switch (tObj->MinFilter) {
  1657.             case GL_NEAREST:
  1658.                sample_3d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
  1659.                break;
  1660.             case GL_LINEAR:
  1661.                sample_3d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
  1662.                break;
  1663.             case GL_NEAREST_MIPMAP_NEAREST:
  1664.                sample_3d_nearest_mipmap_nearest( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
  1665.                break;
  1666.             case GL_LINEAR_MIPMAP_NEAREST:
  1667.                sample_3d_linear_mipmap_nearest( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
  1668.                break;
  1669.             case GL_NEAREST_MIPMAP_LINEAR:
  1670.                sample_3d_nearest_mipmap_linear( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
  1671.                break;
  1672.             case GL_LINEAR_MIPMAP_LINEAR:
  1673.                sample_3d_linear_mipmap_linear( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
  1674.                break;
  1675.             default:
  1676.                gl_problem(NULL, "Bad min filterin sample_3d_texture");
  1677.          }
  1678.       }
  1679.       else {
  1680.          /* magnification */
  1681.          switch (tObj->MagFilter) {
  1682.             case GL_NEAREST:
  1683.                sample_3d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
  1684.                break;
  1685.             case GL_LINEAR:
  1686.                sample_3d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
  1687.                break;
  1688.             default:
  1689.                gl_problem(NULL, "Bad mag filter in sample_3d_texture");
  1690.          }
  1691.       }
  1692.    }
  1693. }
  1694.  
  1695.  
  1696.  
  1697. /**********************************************************************/
  1698. /*                       Texture Sampling Setup                       */
  1699. /**********************************************************************/
  1700.  
  1701.  
  1702. /*
  1703.  * Setup the texture sampling function for this texture object.
  1704.  */
  1705. void gl_set_texture_sampler( struct gl_texture_object *t )
  1706. {
  1707.    if (!t->Complete) {
  1708.       t->SampleFunc = NULL;
  1709.    }
  1710.    else {
  1711.       GLboolean needLambda = (GLboolean) (t->MinFilter != t->MagFilter);
  1712.  
  1713.       if (needLambda) {
  1714.          /* Compute min/mag filter threshold */
  1715.          if (t->MagFilter==GL_LINEAR
  1716.              && (t->MinFilter==GL_NEAREST_MIPMAP_NEAREST ||
  1717.                  t->MinFilter==GL_LINEAR_MIPMAP_NEAREST)) {
  1718.             t->MinMagThresh = 0.5F;
  1719.          }
  1720.          else {
  1721.             t->MinMagThresh = 0.0F;
  1722.          }
  1723.       }
  1724.  
  1725.       switch (t->Dimensions) {
  1726.          case 1:
  1727.             if (needLambda) {
  1728.                t->SampleFunc = sample_lambda_1d;
  1729.             }
  1730.             else if (t->MinFilter==GL_LINEAR) {
  1731.                t->SampleFunc = sample_linear_1d;
  1732.             }
  1733.             else {
  1734.                ASSERT(t->MinFilter==GL_NEAREST);
  1735.                t->SampleFunc = sample_nearest_1d;
  1736.             }
  1737.             break;
  1738.          case 2:
  1739.             if (needLambda) {
  1740.                t->SampleFunc = sample_lambda_2d;
  1741.             }
  1742.             else if (t->MinFilter==GL_LINEAR) {
  1743.                t->SampleFunc = sample_linear_2d;
  1744.             }
  1745.             else {
  1746.                ASSERT(t->MinFilter==GL_NEAREST);
  1747.                if (t->WrapS==GL_REPEAT && t->WrapT==GL_REPEAT
  1748.                    && t->Image[0]->Border==0 && t->Image[0]->Format==GL_RGB) {
  1749.                   t->SampleFunc = opt_sample_rgb_2d;
  1750.                }
  1751.                else if (t->WrapS==GL_REPEAT && t->WrapT==GL_REPEAT
  1752.                    && t->Image[0]->Border==0 && t->Image[0]->Format==GL_RGBA) {
  1753.                   t->SampleFunc = opt_sample_rgba_2d;
  1754.                }
  1755.                else
  1756.                   t->SampleFunc = sample_nearest_2d;
  1757.             }
  1758.             break;
  1759.          case 3:
  1760.             if (needLambda) {
  1761.                t->SampleFunc = sample_lambda_3d;
  1762.             }
  1763.             else if (t->MinFilter==GL_LINEAR) {
  1764.                t->SampleFunc = sample_linear_3d;
  1765.             }
  1766.             else {
  1767.                ASSERT(t->MinFilter==GL_NEAREST);
  1768.                t->SampleFunc = sample_nearest_3d;
  1769.             }
  1770.             break;
  1771.          default:
  1772.             gl_problem(NULL, "invalid dimensions in gl_set_texture_sampler");
  1773.       }
  1774.    }
  1775. }
  1776.  
  1777.  
  1778.  
  1779. /**********************************************************************/
  1780. /*                      Texture Application                           */
  1781. /**********************************************************************/
  1782.  
  1783.  
  1784. /*
  1785.  * Combine incoming fragment color with texel color to produce output color.
  1786.  * Input:  textureUnit - pointer to texture unit to apply
  1787.  *         format - base internal texture format
  1788.  *         n - number of fragments
  1789.  *         texels - array of texel colors
  1790.  * InOut:  rgba - incoming fragment colors modified by texel colors
  1791.  *                according to the texture environment mode.
  1792.  */
  1793. static void apply_texture( const GLcontext *ctx,
  1794.                            const struct gl_texture_unit *texUnit,
  1795.                            GLuint n,
  1796.                            GLubyte rgba[][4], CONST GLubyte texel[][4] )
  1797. {
  1798.    GLuint i;
  1799.    GLint Rc, Gc, Bc, Ac;
  1800.    GLenum format;
  1801.  
  1802.    ASSERT(texUnit);
  1803.    ASSERT(texUnit->Current);
  1804.    ASSERT(texUnit->Current->Image[0]);
  1805.  
  1806.    format = texUnit->Current->Image[0]->Format;
  1807.  
  1808. /*
  1809.  * Use (A*(B+1)) >> 8 as a fast approximation of (A*B)/255 for A
  1810.  * and B in [0,255]
  1811.  */
  1812. #define PROD(A,B)   ( (GLubyte) (((GLint)(A) * ((GLint)(B)+1)) >> 8) )
  1813.  
  1814.    if (format==GL_COLOR_INDEX) {
  1815.       format = GL_RGBA;  /* XXXX a hack! */
  1816.    }
  1817.  
  1818.    switch (texUnit->EnvMode) {
  1819.       case GL_REPLACE:
  1820.      switch (format) {
  1821.         case GL_ALPHA:
  1822.            for (i=0;i<n;i++) {
  1823.           /* Cv = Cf */
  1824.                   /* Av = At */
  1825.                   rgba[i][ACOMP] = texel[i][ACOMP];
  1826.            }
  1827.            break;
  1828.         case GL_LUMINANCE:
  1829.            for (i=0;i<n;i++) {
  1830.           /* Cv = Lt */
  1831.                   GLubyte Lt = texel[i][RCOMP];
  1832.                   rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
  1833.                   /* Av = Af */
  1834.            }
  1835.            break;
  1836.         case GL_LUMINANCE_ALPHA:
  1837.            for (i=0;i<n;i++) {
  1838.                   GLubyte Lt = texel[i][RCOMP];
  1839.           /* Cv = Lt */
  1840.           rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
  1841.           /* Av = At */
  1842.           rgba[i][ACOMP] = texel[i][ACOMP];
  1843.            }
  1844.            break;
  1845.         case GL_INTENSITY:
  1846.            for (i=0;i<n;i++) {
  1847.           /* Cv = It */
  1848.                   GLubyte It = texel[i][RCOMP];
  1849.                   rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = It;
  1850.                   /* Av = It */
  1851.                   rgba[i][ACOMP] = It;
  1852.            }
  1853.            break;
  1854.         case GL_RGB:
  1855.            for (i=0;i<n;i++) {
  1856.           /* Cv = Ct */
  1857.           rgba[i][RCOMP] = texel[i][RCOMP];
  1858.           rgba[i][GCOMP] = texel[i][GCOMP];
  1859.           rgba[i][BCOMP] = texel[i][BCOMP];
  1860.           /* Av = Af */
  1861.            }
  1862.            break;
  1863.         case GL_RGBA:
  1864.            for (i=0;i<n;i++) {
  1865.           /* Cv = Ct */
  1866.           rgba[i][RCOMP] = texel[i][RCOMP];
  1867.           rgba[i][GCOMP] = texel[i][GCOMP];
  1868.           rgba[i][BCOMP] = texel[i][BCOMP];
  1869.           /* Av = At */
  1870.           rgba[i][ACOMP] = texel[i][ACOMP];
  1871.            }
  1872.            break;
  1873.             default:
  1874.                gl_problem(ctx, "Bad format in apply_texture");
  1875.                return;
  1876.      }
  1877.      break;
  1878.  
  1879.       case GL_MODULATE:
  1880.          switch (format) {
  1881.         case GL_ALPHA:
  1882.            for (i=0;i<n;i++) {
  1883.           /* Cv = Cf */
  1884.           /* Av = AfAt */
  1885.           rgba[i][ACOMP] = PROD( rgba[i][ACOMP], texel[i][ACOMP] );
  1886.            }
  1887.            break;
  1888.         case GL_LUMINANCE:
  1889.            for (i=0;i<n;i++) {
  1890.           /* Cv = LtCf */
  1891.                   GLubyte Lt = texel[i][RCOMP];
  1892.           rgba[i][RCOMP] = PROD( rgba[i][RCOMP], Lt );
  1893.           rgba[i][GCOMP] = PROD( rgba[i][GCOMP], Lt );
  1894.           rgba[i][BCOMP] = PROD( rgba[i][BCOMP], Lt );
  1895.           /* Av = Af */
  1896.            }
  1897.            break;
  1898.         case GL_LUMINANCE_ALPHA:
  1899.            for (i=0;i<n;i++) {
  1900.           /* Cv = CfLt */
  1901.                   GLubyte Lt = texel[i][RCOMP];
  1902.           rgba[i][RCOMP] = PROD( rgba[i][RCOMP], Lt );
  1903.           rgba[i][GCOMP] = PROD( rgba[i][GCOMP], Lt );
  1904.           rgba[i][BCOMP] = PROD( rgba[i][BCOMP], Lt );
  1905.           /* Av = AfAt */
  1906.           rgba[i][ACOMP] = PROD( rgba[i][ACOMP], texel[i][ACOMP] );
  1907.            }
  1908.            break;
  1909.         case GL_INTENSITY:
  1910.            for (i=0;i<n;i++) {
  1911.           /* Cv = CfIt */
  1912.                   GLubyte It = texel[i][RCOMP];
  1913.           rgba[i][RCOMP] = PROD( rgba[i][RCOMP], It );
  1914.           rgba[i][GCOMP] = PROD( rgba[i][GCOMP], It );
  1915.           rgba[i][BCOMP] = PROD( rgba[i][BCOMP], It );
  1916.           /* Av = AfIt */
  1917.           rgba[i][ACOMP] = PROD( rgba[i][ACOMP], It );
  1918.            }
  1919.            break;
  1920.         case GL_RGB:
  1921.            for (i=0;i<n;i++) {
  1922.           /* Cv = CfCt */
  1923.           rgba[i][RCOMP] = PROD( rgba[i][RCOMP], texel[i][RCOMP] );
  1924.           rgba[i][GCOMP] = PROD( rgba[i][GCOMP], texel[i][GCOMP] );
  1925.           rgba[i][BCOMP] = PROD( rgba[i][BCOMP], texel[i][BCOMP] );
  1926.           /* Av = Af */
  1927.            }
  1928.            break;
  1929.         case GL_RGBA:
  1930.            for (i=0;i<n;i++) {
  1931.           /* Cv = CfCt */
  1932.           rgba[i][RCOMP] = PROD( rgba[i][RCOMP], texel[i][RCOMP] );
  1933.           rgba[i][GCOMP] = PROD( rgba[i][GCOMP], texel[i][GCOMP] );
  1934.           rgba[i][BCOMP] = PROD( rgba[i][BCOMP], texel[i][BCOMP] );
  1935.           /* Av = AfAt */
  1936.           rgba[i][ACOMP] = PROD( rgba[i][ACOMP], texel[i][ACOMP] );
  1937.            }
  1938.            break;
  1939.             default:
  1940.                gl_problem(ctx, "Bad format (2) in apply_texture");
  1941.                return;
  1942.      }
  1943.      break;
  1944.  
  1945.       case GL_DECAL:
  1946.          switch (format) {
  1947.             case GL_ALPHA:
  1948.             case GL_LUMINANCE:
  1949.             case GL_LUMINANCE_ALPHA:
  1950.             case GL_INTENSITY:
  1951.                /* undefined */
  1952.                break;
  1953.         case GL_RGB:
  1954.            for (i=0;i<n;i++) {
  1955.           /* Cv = Ct */
  1956.           rgba[i][RCOMP] = texel[i][RCOMP];
  1957.           rgba[i][GCOMP] = texel[i][GCOMP];
  1958.           rgba[i][BCOMP] = texel[i][BCOMP];
  1959.           /* Av = Af */
  1960.            }
  1961.            break;
  1962.         case GL_RGBA:
  1963.            for (i=0;i<n;i++) {
  1964.           /* Cv = Cf(1-At) + CtAt */
  1965.           GLint t = texel[i][ACOMP], s = 255 - t;
  1966.           rgba[i][RCOMP] = PROD(rgba[i][RCOMP], s) + PROD(texel[i][RCOMP],t);
  1967.           rgba[i][GCOMP] = PROD(rgba[i][GCOMP], s) + PROD(texel[i][GCOMP],t);
  1968.           rgba[i][BCOMP] = PROD(rgba[i][BCOMP], s) + PROD(texel[i][BCOMP],t);
  1969.           /* Av = Af */
  1970.            }
  1971.            break;
  1972.             default:
  1973.                gl_problem(ctx, "Bad format (3) in apply_texture");
  1974.                return;
  1975.      }
  1976.      break;
  1977.  
  1978.       case GL_BLEND:
  1979.          Rc = (GLint) (texUnit->EnvColor[0] * 255.0F);
  1980.          Gc = (GLint) (texUnit->EnvColor[1] * 255.0F);
  1981.          Bc = (GLint) (texUnit->EnvColor[2] * 255.0F);
  1982.          Ac = (GLint) (texUnit->EnvColor[3] * 255.0F);
  1983.      switch (format) {
  1984.         case GL_ALPHA:
  1985.            for (i=0;i<n;i++) {
  1986.           /* Cv = Cf */
  1987.           /* Av = AfAt */
  1988.                   rgba[i][ACOMP] = PROD(rgba[i][ACOMP], texel[i][ACOMP]);
  1989.            }
  1990.            break;
  1991.             case GL_LUMINANCE:
  1992.            for (i=0;i<n;i++) {
  1993.           /* Cv = Cf(1-Lt) + CcLt */
  1994.           GLubyte Lt = texel[i][RCOMP], s = 255 - Lt;
  1995.           rgba[i][RCOMP] = PROD(rgba[i][RCOMP], s) + PROD(Rc, Lt);
  1996.           rgba[i][GCOMP] = PROD(rgba[i][GCOMP], s) + PROD(Gc, Lt);
  1997.           rgba[i][BCOMP] = PROD(rgba[i][BCOMP], s) + PROD(Bc, Lt);
  1998.           /* Av = Af */
  1999.            }
  2000.            break;
  2001.         case GL_LUMINANCE_ALPHA:
  2002.            for (i=0;i<n;i++) {
  2003.           /* Cv = Cf(1-Lt) + CcLt */
  2004.           GLubyte Lt = texel[i][RCOMP], s = 255 - Lt;
  2005.           rgba[i][RCOMP] = PROD(rgba[i][RCOMP], s) + PROD(Rc, Lt);
  2006.           rgba[i][GCOMP] = PROD(rgba[i][GCOMP], s) + PROD(Gc, Lt);
  2007.           rgba[i][BCOMP] = PROD(rgba[i][BCOMP], s) + PROD(Bc, Lt);
  2008.           /* Av = AfAt */
  2009.           rgba[i][ACOMP] = PROD(rgba[i][ACOMP],texel[i][ACOMP]);
  2010.            }
  2011.            break;
  2012.             case GL_INTENSITY:
  2013.            for (i=0;i<n;i++) {
  2014.           /* Cv = Cf(1-It) + CcLt */
  2015.           GLubyte It = texel[i][RCOMP], s = 255 - It;
  2016.           rgba[i][RCOMP] = PROD(rgba[i][RCOMP], s) + PROD(Rc, It);
  2017.           rgba[i][GCOMP] = PROD(rgba[i][GCOMP], s) + PROD(Gc, It);
  2018.           rgba[i][BCOMP] = PROD(rgba[i][BCOMP], s) + PROD(Bc, It);
  2019.                   /* Av = Af(1-It) + Ac*It */
  2020.                   rgba[i][ACOMP] = PROD(rgba[i][ACOMP], s) + PROD(Ac, It);
  2021.                }
  2022.                break;
  2023.         case GL_RGB:
  2024.            for (i=0;i<n;i++) {
  2025.           /* Cv = Cf(1-Ct) + CcCt */
  2026.           rgba[i][RCOMP] = PROD(rgba[i][RCOMP], (255-texel[i][RCOMP])) + PROD(Rc,texel[i][RCOMP]);
  2027.           rgba[i][GCOMP] = PROD(rgba[i][GCOMP], (255-texel[i][GCOMP])) + PROD(Gc,texel[i][GCOMP]);
  2028.           rgba[i][BCOMP] = PROD(rgba[i][BCOMP], (255-texel[i][BCOMP])) + PROD(Bc,texel[i][BCOMP]);
  2029.           /* Av = Af */
  2030.            }
  2031.            break;
  2032.         case GL_RGBA:
  2033.            for (i=0;i<n;i++) {
  2034.           /* Cv = Cf(1-Ct) + CcCt */
  2035.           rgba[i][RCOMP] = PROD(rgba[i][RCOMP], (255-texel[i][RCOMP])) + PROD(Rc,texel[i][RCOMP]);
  2036.           rgba[i][GCOMP] = PROD(rgba[i][GCOMP], (255-texel[i][GCOMP])) + PROD(Gc,texel[i][GCOMP]);
  2037.           rgba[i][BCOMP] = PROD(rgba[i][BCOMP], (255-texel[i][BCOMP])) + PROD(Bc,texel[i][BCOMP]);
  2038.           /* Av = AfAt */
  2039.           rgba[i][ACOMP] = PROD(rgba[i][ACOMP],texel[i][ACOMP]);
  2040.            }
  2041.            break;
  2042.             default:
  2043.                gl_problem(ctx, "Bad format (4) in apply_texture");
  2044.                return;
  2045.      }
  2046.      break;
  2047.  
  2048.       case GL_ADD:  /* GL_EXT_texture_add_env */
  2049.          switch (format) {
  2050.             case GL_ALPHA:
  2051.                for (i=0;i<n;i++) {
  2052.                   /* Rv = Rf */
  2053.                   /* Gv = Gf */
  2054.                   /* Bv = Bf */
  2055.                   rgba[i][ACOMP] = PROD(rgba[i][ACOMP], texel[i][ACOMP]);
  2056.                }
  2057.                break;
  2058.             case GL_LUMINANCE:
  2059.                for (i=0;i<n;i++) {
  2060.                   GLuint Lt = texel[i][RCOMP];
  2061.                   GLuint r = rgba[i][RCOMP] + Lt;
  2062.                   GLuint g = rgba[i][GCOMP] + Lt;
  2063.                   GLuint b = rgba[i][BCOMP] + Lt;
  2064.                   rgba[i][RCOMP] = r < 256 ? (GLubyte) r : 255;
  2065.                   rgba[i][GCOMP] = g < 256 ? (GLubyte) g : 255;
  2066.                   rgba[i][BCOMP] = b < 256 ? (GLubyte) b : 255;
  2067.                   /* Av = Af */
  2068.                }
  2069.                break;
  2070.             case GL_LUMINANCE_ALPHA:
  2071.                for (i=0;i<n;i++) {
  2072.                   GLuint Lt = texel[i][RCOMP];
  2073.                   GLuint r = rgba[i][RCOMP] + Lt;
  2074.                   GLuint g = rgba[i][GCOMP] + Lt;
  2075.                   GLuint b = rgba[i][BCOMP] + Lt;
  2076.                   rgba[i][RCOMP] = r < 256 ? (GLubyte) r : 255;
  2077.                   rgba[i][GCOMP] = g < 256 ? (GLubyte) g : 255;
  2078.                   rgba[i][BCOMP] = b < 256 ? (GLubyte) b : 255;
  2079.                   rgba[i][ACOMP] = PROD(rgba[i][ACOMP], texel[i][ACOMP]);
  2080.                }
  2081.                break;
  2082.             case GL_INTENSITY:
  2083.                for (i=0;i<n;i++) {
  2084.                   GLubyte It = texel[i][RCOMP];
  2085.                   GLuint r = rgba[i][RCOMP] + It;
  2086.                   GLuint g = rgba[i][GCOMP] + It;
  2087.                   GLuint b = rgba[i][BCOMP] + It;
  2088.                   GLuint a = rgba[i][ACOMP] + It;
  2089.                   rgba[i][RCOMP] = r < 256 ? (GLubyte) r : 255;
  2090.                   rgba[i][GCOMP] = g < 256 ? (GLubyte) g : 255;
  2091.                   rgba[i][BCOMP] = b < 256 ? (GLubyte) b : 255;
  2092.                   rgba[i][ACOMP] = a < 256 ? (GLubyte) a : 255;
  2093.                }
  2094.                break;
  2095.         case GL_RGB:
  2096.            for (i=0;i<n;i++) {
  2097.                   GLuint r = rgba[i][RCOMP] + texel[i][RCOMP];
  2098.                   GLuint g = rgba[i][GCOMP] + texel[i][GCOMP];
  2099.                   GLuint b = rgba[i][BCOMP] + texel[i][BCOMP];
  2100.           rgba[i][RCOMP] = r < 256 ? (GLubyte) r : 255;
  2101.           rgba[i][GCOMP] = g < 256 ? (GLubyte) g : 255;
  2102.           rgba[i][BCOMP] = b < 256 ? (GLubyte) b : 255;
  2103.           /* Av = Af */
  2104.            }
  2105.            break;
  2106.         case GL_RGBA:
  2107.            for (i=0;i<n;i++) {
  2108.                   GLuint r = rgba[i][RCOMP] + texel[i][RCOMP];
  2109.                   GLuint g = rgba[i][GCOMP] + texel[i][GCOMP];
  2110.                   GLuint b = rgba[i][BCOMP] + texel[i][BCOMP];
  2111.           rgba[i][RCOMP] = r < 256 ? (GLubyte) r : 255;
  2112.           rgba[i][GCOMP] = g < 256 ? (GLubyte) g : 255;
  2113.           rgba[i][BCOMP] = b < 256 ? (GLubyte) b : 255;
  2114.                   rgba[i][ACOMP] = PROD(rgba[i][ACOMP], texel[i][ACOMP]);
  2115.                }
  2116.                break;
  2117.             default:
  2118.                gl_problem(ctx, "Bad format (GL_ADD) in apply_texture");
  2119.                return;
  2120.      }
  2121.      break;
  2122.  
  2123.       default:
  2124.          gl_problem(ctx, "Bad env mode in apply_texture");
  2125.          return;
  2126.    }
  2127.  
  2128. #undef PROD
  2129. }
  2130.  
  2131.  
  2132.  
  2133. /*
  2134.  * Apply a unit of texture mapping to the incoming fragments.
  2135.  */
  2136. void gl_texture_pixels( GLcontext *ctx, GLuint texUnit, GLuint n,
  2137.                         const GLfloat s[], const GLfloat t[],
  2138.                         const GLfloat r[], GLfloat lambda[],
  2139.                         GLubyte rgba[][4] )
  2140. {
  2141.    GLuint mask = (TEXTURE0_1D | TEXTURE0_2D | TEXTURE0_3D) << (texUnit * 4);
  2142.    if (ctx->Texture.Enabled & mask) {
  2143.       const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit];
  2144.       if (textureUnit->Current && textureUnit->Current->SampleFunc) {
  2145.  
  2146.          GLubyte texel[PB_SIZE][4];
  2147.  
  2148.          if (textureUnit->Current->MinLod != -1000.0
  2149.              || textureUnit->Current->MaxLod != 1000.0) {
  2150.             /* apply LOD clamping to lambda */
  2151.             GLfloat min = textureUnit->Current->MinLod;
  2152.             GLfloat max = textureUnit->Current->MaxLod;
  2153.             GLuint i;
  2154.             for (i=0;i<n;i++) {
  2155.                GLfloat l = lambda[i];
  2156.                lambda[i] = CLAMP(l, min, max);
  2157.             }
  2158.          }
  2159.  
  2160.          /* Sample the texture. */
  2161.          (*textureUnit->Current->SampleFunc)( textureUnit->Current, n,
  2162.                                              s, t, r, lambda, texel );
  2163.  
  2164.          apply_texture( ctx, textureUnit, n, 
  2165.             rgba, (const GLubyte (*)[4])texel );
  2166.       }
  2167.    }
  2168. }
  2169.