home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / fog_tmp.h < prev    next >
Text File  |  2000-01-07  |  12KB  |  436 lines

  1. /* $Id: fog_tmp.h,v 1.2.2.1 1999/11/25 16:51:24 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. /* For 3.2: Add a helper function for drivers to do fog coordinate
  28.  * calculation.  Not called from standard pipelines.  
  29.  */
  30. static void TAG(make_fog_coord)( struct vertex_buffer *VB,
  31.                  const GLvector4f *eye,
  32.                  GLubyte flag)
  33. {
  34.    const GLcontext *ctx = VB->ctx;
  35.    GLfloat end  = ctx->Fog.End;
  36.    GLubyte *cullmask = VB->CullMask + VB->Start;
  37.    GLfloat *v = eye->start;
  38.    GLuint stride = eye->stride;
  39.    GLuint n = VB->Count - VB->Start;
  40.    GLubyte (*out)[4];        
  41.    GLfloat d;
  42.    GLuint i;
  43.  
  44.    (void) cullmask;
  45.    (void) flag;
  46.  
  47.    /* Use specular alpha (front side) as fog coordinate.
  48.     */
  49.    out = VB->Spec[0] + VB->Start;
  50.  
  51.    if (VB->EyePtr->size > 2) {
  52.       switch (ctx->Fog.Mode) {
  53.       case GL_LINEAR:
  54.      d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
  55.      for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
  56.         CULLCHECK {
  57.            GLfloat f = (end - ABSF(v[2])) * d;
  58.            FLOAT_COLOR_TO_UBYTE_COLOR(out[i][3], f);
  59.         }
  60.      }
  61.      break;
  62.       case GL_EXP:
  63.      d = -ctx->Fog.Density;
  64.      for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) {
  65.         CULLCHECK {
  66.            GLfloat f = exp( d*ABSF(v[2]) ); /* already clamped */ 
  67.            FLOAT_COLOR_TO_UBYTE_COLOR(out[i][3], f);
  68.         }
  69.      }
  70.      break;
  71.       case GL_EXP2:
  72.      d = -(ctx->Fog.Density*ctx->Fog.Density);
  73.      for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
  74.         CULLCHECK {
  75.            GLfloat z = v[2];
  76.            GLfloat f = exp( d*z*z ); /* already clamped */
  77.            FLOAT_COLOR_TO_UBYTE_COLOR(out[i][3], f);
  78.         }
  79.      }
  80.      break;
  81.       default:
  82.      gl_problem(ctx, "Bad fog mode in make_fog_coord");
  83.      return;
  84.       }
  85.    }
  86.    else 
  87.    {
  88.       GLubyte r = 0;
  89.  
  90.       if (ctx->Fog.Mode == GL_LINEAR) {
  91.      GLfloat f = ctx->Fog.End * (ctx->Fog.End - ctx->Fog.Start);
  92.      CLAMP_FLOAT_COLOR( f );
  93.      f = 1.0 - f;
  94.      FLOAT_COLOR_TO_UBYTE_COLOR(r, f);
  95.       } 
  96.  
  97.       for (i = 0 ; i < n ; i++) 
  98.      out[i][3] = r;
  99.    }
  100. }
  101.  
  102.  
  103.  
  104.  
  105.  
  106. #if 0
  107. /* For 3.3: use fog coordinates as intermediate step in all fog
  108.  * calculations.
  109.  */
  110.  
  111. static void TAG(fog_rgba_vertices)( struct vertex_buffer *VB,
  112.                     GLuint side,
  113.                     GLubyte flag)
  114. {
  115.    const GLcontext *ctx = VB->ctx;
  116.    const GLubyte rFog = ctx->Fog.ByteColor[0];
  117.    const GLubyte gFog = ctx->Fog.ByteColor[1];
  118.    const GLubyte bFog = ctx->Fog.ByteColor[2];
  119.    GLfloat end  = ctx->Fog.End;
  120.    GLubyte *cullmask = VB->CullMask + VB->Start;
  121.    GLubyte (*fcoord)[4] = VB->SpecPtr[0]->start;
  122.    GLuint stride = VB->SpecPtr[0]->stride;
  123.    GLuint n = VB->Count - VB->Start;
  124.    GLubyte *in;
  125.    GLuint in_stride;
  126.    GLubyte (*out)[4];
  127.    GLfloat d,t;
  128.    GLuint i;
  129.  
  130.    (void) cullmask;
  131.    (void) flag;
  132.  
  133.    /* Get correct source and destination for fogged colors.
  134.     */
  135.    in_stride = VB->Color[side]->stride;
  136.    in = VB->Color[side]->start;
  137.    VB->Color[side] = VB->FoggedColor[side];
  138.    VB->ColorPtr = VB->Color[0];
  139.    out = (GLubyte (*)[4])VB->Color[side]->start;
  140.  
  141.    FLOAT_COLOR_TO_UBYTE_COLOR( rFog, ctx->Fog.Color[0] );
  142.  
  143.    for ( i = 0 ; i < n ; i++, STRIDE_F(spec, sp_stride), in += in_stride) {
  144.       CULLCHECK {
  145.      GLint fc = (GLint) spec[3], ifc = 255 - fc;
  146.      
  147.      out[i][0] = (fc * in[0] + ifc * rFog) >> 8;
  148.      out[i][1] = (fc * in[1] + ifc * gFog) >> 8;
  149.      out[i][2] = (fc * in[2] + ifc * bFog) >> 8;
  150.       }
  151.    }
  152. }
  153.  
  154.  
  155.  
  156. static void TAG(fog_ci_vertices)( struct vertex_buffer *VB,
  157.                   GLuint side,
  158.                   GLubyte flag )
  159. {
  160.    GLcontext *ctx = VB->ctx;
  161.  
  162.    GLubyte *cullmask = VB->CullMask + VB->Start;
  163.   
  164.    GLfloat *v = VB->EyePtr->start;
  165.    GLuint stride = VB->EyePtr->stride;
  166.    GLuint vertex_size = VB->EyePtr->size;
  167.    GLuint n = VB->EyePtr->count;
  168.  
  169.    GLuint *in;
  170.    GLuint in_stride;
  171.    GLuint *out;
  172.    GLuint i;
  173.  
  174.    (void) flag;
  175.    (void) cullmask;
  176.  
  177.  
  178.    in = VB->Index[side]->start;
  179.    in_stride = VB->Index[side]->stride;
  180.    VB->IndexPtr = VB->FoggedIndex[side];
  181.    out = VB->IndexPtr->start;
  182.  
  183.  
  184.    /* NOTE: the extensive use of casts generates better/faster code for MIPS */
  185.    for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
  186.       CULLCHECK {
  187.       GLfloat f = (fogend - ABSF(v[2])) * d;
  188.       f = CLAMP( f, 0.0, 1.0 );
  189.       *out = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
  190.    }
  191. }
  192.  
  193. #endif
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201. static void TAG(fog_rgba_vertices)( struct vertex_buffer *VB,
  202.                     GLuint side,
  203.                     GLubyte flag)
  204. {
  205.    const GLcontext *ctx = VB->ctx;
  206.    GLfloat rFog = ctx->Fog.Color[0];
  207.    GLfloat gFog = ctx->Fog.Color[1];
  208.    GLfloat bFog = ctx->Fog.Color[2];
  209.    GLfloat end  = ctx->Fog.End;
  210.    GLubyte *cullmask = VB->CullMask + VB->Start;
  211.    GLfloat *v = VB->EyePtr->start;
  212.    GLuint stride = VB->EyePtr->stride;
  213.    GLuint n = VB->EyePtr->count;
  214.    GLubyte *in;
  215.    GLuint in_stride;
  216.    GLubyte (*out)[4];
  217.    GLfloat d,t;
  218.    GLuint i;
  219.  
  220.    (void) cullmask;
  221.    (void) flag;
  222.  
  223.    /* Get correct source and destination for fogged colors.
  224.     */
  225.    in_stride = VB->Color[side]->stride;
  226.    in = VB->Color[side]->start;
  227.    VB->Color[side] = VB->FoggedColor[side];
  228.    VB->ColorPtr = VB->Color[0];
  229.    out = (GLubyte (*)[4])VB->Color[side]->start;
  230.  
  231.  
  232.    if (VB->EyePtr->size > 2) {
  233.       switch (ctx->Fog.Mode) {
  234.       case GL_LINEAR:
  235.      d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
  236.      for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride), in += in_stride) {
  237.         CULLCHECK {
  238.            GLfloat f = (end - ABSF(v[2])) * d;
  239.            if (f >= 1.0) continue;
  240.            if (f < 0) {
  241.           CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], rFog);
  242.           CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], gFog);
  243.           CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], bFog);
  244.            } else {
  245.           t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[0]) + (1.0F-f)*rFog;
  246.           CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], t);
  247.            
  248.           t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[1]) + (1.0F-f)*gFog;
  249.           CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], t);
  250.            
  251.           t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[2]) + (1.0F-f)*bFog;
  252.           CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], t);
  253.  
  254.            }
  255.         }
  256.      }
  257.      break;
  258.       case GL_EXP:
  259.      d = -ctx->Fog.Density;
  260.      for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride), in += in_stride) {
  261.         CULLCHECK {
  262.            GLfloat f = exp( d*ABSF(v[2]) ); /* already clamped */ 
  263.  
  264.            t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[0]) + (1.0F-f)*rFog;
  265.            CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], t);
  266.            
  267.            t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[1]) + (1.0F-f)*gFog;
  268.            CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], t);
  269.            
  270.            t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[2]) + (1.0F-f)*bFog;
  271.            CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], t);
  272.         }
  273.      }
  274.      break;
  275.       case GL_EXP2:
  276.      d = -(ctx->Fog.Density*ctx->Fog.Density);
  277.      for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride), in += in_stride) {
  278.         CULLCHECK {
  279.            GLfloat z = v[2];
  280.            GLfloat f = exp( d*z*z ); /* already clamped */
  281.  
  282.            t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[0]) + (1.0F-f)*rFog;
  283.            CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][0], t);
  284.            
  285.            t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[1]) + (1.0F-f)*gFog;
  286.            CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][1], t);
  287.            
  288.            t = f * UBYTE_COLOR_TO_FLOAT_COLOR(in[2]) + (1.0F-f)*bFog;
  289.            CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(out[i][2], t);
  290.         }
  291.      }
  292.      break;
  293.      default:
  294.         gl_problem(ctx, "Bad fog mode in gl_fog_rgba_vertices");
  295.      return;
  296.       }
  297.    }
  298.    else if (ctx->Fog.Mode == GL_LINEAR)
  299.    {
  300.       /* 2-vector vertices */
  301.       GLubyte r,g,b;
  302.       GLfloat f = ctx->Fog.End * (ctx->Fog.End - ctx->Fog.Start);
  303.       CLAMP_FLOAT_COLOR( f );
  304.       f = 1.0 - f;
  305.       rFog *= f;
  306.       bFog *= f;
  307.       gFog *= f;
  308.  
  309.       CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(r, rFog);
  310.       CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(g, gFog);
  311.       CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(b, bFog);
  312.  
  313.       for (i = 0 ; i < n ; i++) {
  314.      /* CULLCHECK */ {
  315.         out[i][0] = r;
  316.         out[i][1] = g;
  317.         out[i][2] = b;
  318.      }
  319.       }
  320.    }
  321. }
  322.  
  323.  
  324.  
  325. /*
  326.  * Compute the fogged color indexes for an array of vertices.
  327.  * Input:  n - number of vertices
  328.  *         v - array of vertices
  329.  * In/Out: indx - array of vertex color indexes
  330.  */
  331. static void TAG(fog_ci_vertices)( struct vertex_buffer *VB,
  332.                   GLuint side,
  333.                   GLubyte flag )
  334. {
  335.    GLcontext *ctx = VB->ctx;
  336.  
  337.    GLubyte *cullmask = VB->CullMask + VB->Start;
  338.   
  339.    GLfloat *v = VB->EyePtr->start;
  340.    GLuint stride = VB->EyePtr->stride;
  341.    GLuint vertex_size = VB->EyePtr->size;
  342.    GLuint n = VB->EyePtr->count;
  343.  
  344.    GLuint *in;
  345.    GLuint in_stride;
  346.    GLuint *out;
  347.    GLuint i;
  348.  
  349.    (void) flag;
  350.    (void) cullmask;
  351.  
  352.  
  353.    in = VB->Index[side]->start;
  354.    in_stride = VB->Index[side]->stride;
  355.    VB->IndexPtr = VB->FoggedIndex[side];
  356.    out = VB->IndexPtr->start;
  357.  
  358.  
  359.    /* NOTE: the extensive use of casts generates better/faster code for MIPS */
  360.    if (vertex_size > 2) {
  361.       switch (ctx->Fog.Mode) {
  362.       case GL_LINEAR:
  363.       {
  364.      GLfloat d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
  365.      GLfloat fogindex = ctx->Fog.Index;
  366.      GLfloat fogend = ctx->Fog.End;
  367.  
  368.       for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
  369.      {
  370.         CULLCHECK {
  371.            GLfloat f = (fogend - ABSF(v[2])) * d;
  372.            f = CLAMP( f, 0.0, 1.0 );
  373.            *out = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
  374.         }
  375.      }
  376.      break;
  377.       }
  378.       case GL_EXP:
  379.       {
  380.      GLfloat d = -ctx->Fog.Density;
  381.      GLfloat fogindex = ctx->Fog.Index;
  382.       for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
  383.      {
  384.         CULLCHECK {
  385.            GLfloat f = exp( d * ABSF(v[2]) );
  386.            *out = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
  387.         }
  388.      }
  389.      break;
  390.       }
  391.       case GL_EXP2:
  392.       {
  393.      GLfloat d = -(ctx->Fog.Density*ctx->Fog.Density);
  394.      GLfloat fogindex = ctx->Fog.Index;
  395.       for ( i = 0; i < n ; i++, STRIDE_F(v,stride),STRIDE_UI(in,in_stride))
  396.      {
  397.         CULLCHECK {
  398.            GLfloat z = v[2]; /*ABSF(v[i][2]);*/
  399.            GLfloat f = exp( d * z*z ); /* was -d ??? */
  400.            out[i] = (GLint) ((GLfloat)(GLint) *in + (1.0F-f) * fogindex);
  401.         }
  402.      }
  403.      break;
  404.       }
  405.       default:
  406.      gl_problem(ctx, "Bad fog mode in gl_fog_ci_vertices");
  407.      return;
  408.       }
  409.    } else if (ctx->Fog.Mode == GL_LINEAR) {
  410.       GLuint fogindex;
  411.       GLfloat f = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start);
  412.  
  413.       f = 1.0 - CLAMP( f, 0.0F, 1.0F );
  414.       fogindex = (GLuint)(f * ctx->Fog.Index);
  415.       if (fogindex) {
  416.       for ( i = 0; i < n ; i++, STRIDE_F(v,stride), STRIDE_UI(in,in_stride))
  417.      {
  418.         CULLCHECK {
  419.            *out = *in + fogindex;
  420.         }
  421.      }
  422.       }
  423.    } 
  424. }
  425.  
  426. static void TAG(init_fog_tab)(void)
  427. {
  428.    fog_ci_tab[IDX] = TAG(fog_ci_vertices);
  429.    fog_rgba_tab[IDX] = TAG(fog_rgba_vertices);
  430.    make_fog_coord_tab[IDX] = TAG(make_fog_coord);
  431. }
  432.  
  433. #undef TAG
  434. #undef CULLCHECK
  435. #undef IDX
  436.