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

  1. /* $Id: texgen_tmp.h,v 1.3 1999/11/08 15:30:49 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.1
  6.  * 
  7.  * Copyright (C) 1999  Brian Paul   All Rights Reserved.
  8.  * 
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  * 
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  * 
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27. /*
  28.  * New (3.1) transformation code written by Keith Whitwell.
  29.  */
  30.  
  31.  
  32. /* Need to transform the eye plane equations into object space, and
  33.  * use ctx->EyeZDir in spheregen.
  34.  */
  35.  
  36. #define CULL IDX&1
  37.  
  38. /* 
  39.  */
  40. static void TAG(build_m3)(GLfloat      f[][3],
  41.               GLfloat      m[],
  42.               const GLvector3f  *normals, 
  43.               const GLvector4f  *coord_vec, 
  44.               const GLuint       flags[],
  45.               const GLubyte      cullmask[] )
  46. {
  47.    GLuint stride = coord_vec->stride;
  48.    GLfloat *coord = (GLfloat *)coord_vec->start;
  49.    GLuint count = coord_vec->count;
  50.  
  51.    const GLfloat *normal = FIRST_NORMAL;
  52.    GLuint i;
  53.  
  54.    LOCAL_VARS;
  55.  
  56.    (void) flags;
  57.    (void) cullmask;
  58.  
  59.    /* KW: Had to rearrange this loop to avoid a compiler bug with gcc
  60.     *     2.7.3.1 at -O3 optimization.  Using -fno-strength-reduce
  61.     *     also fixed the bug - is this generally necessary?  
  62.     */
  63.    for (i=0;i<count;i++,STRIDE_F(coord,stride)) {
  64.       CHECK {
  65.      const GLfloat *norm = normal;
  66.      GLfloat u[3], two_nu, fx, fy, fz;
  67.      COPY_3V( u, coord ); 
  68.      NORMALIZE_3FV( u );
  69.      two_nu = 2.0F * DOT3(norm,u);
  70.      fx = f[i][0] = u[0] - norm[0] * two_nu;
  71.      fy = f[i][1] = u[1] - norm[1] * two_nu;
  72.      fz = f[i][2] = u[2] - norm[2] * two_nu;
  73.      m[i] = fx*fx + fy*fy + (fz + 1.0F) * (fz + 1.0F);
  74.      if (m[i] != 0.0F) {
  75.         m[i] = 0.5F / (GLfloat) GL_SQRT(m[i]);
  76.      }
  77.       }
  78.       NEXT_NORMAL;
  79.    }
  80. }
  81.  
  82.  
  83.  
  84. static void TAG(build_m2)(GLfloat f[][3],
  85.               GLfloat m[],
  86.               const GLvector3f  *normals, 
  87.               const GLvector4f  *coord_vec, 
  88.               const GLuint       flags[],
  89.               const GLubyte      cullmask[] )
  90. {
  91.    GLuint stride = coord_vec->stride;
  92.    GLfloat *coord = coord_vec->start;
  93.    GLuint count = coord_vec->count;
  94.  
  95.    GLfloat *normal = FIRST_NORMAL;
  96.    GLuint i;
  97.  
  98.    LOCAL_VARS;
  99.  
  100.    (void) flags;
  101.    (void) cullmask;
  102.  
  103.    for (i=0;i<count;i++,STRIDE_F(coord,stride)) {
  104.       CHECK {
  105.      GLfloat *norm = normal;
  106.      GLfloat u[3], two_nu, fx, fy, fz;
  107.      COPY_2V( u, coord ); 
  108.      u[2] = 0;
  109.      NORMALIZE_3FV( u );
  110.      two_nu = 2.0F * DOT3(norm,u);
  111.      fx = f[i][0] = u[0] - norm[0] * two_nu;
  112.      fy = f[i][1] = u[1] - norm[1] * two_nu;
  113.      fz = f[i][2] = u[2] - norm[2] * two_nu;
  114.      m[i] = fx*fx + fy*fy + (fz + 1.0F) * (fz + 1.0F);
  115.      if (m[i] != 0.0F) {
  116.         m[i] = 0.5F / (GLfloat) GL_SQRT(m[i]);
  117.      }
  118.       }
  119.       NEXT_NORMAL;
  120.    }
  121. }
  122.  
  123.  
  124.  
  125. static build_m_func TAG(build_m_tab)[5] = {
  126.    0,
  127.    0,
  128.    TAG(build_m2),
  129.    TAG(build_m3),
  130.    TAG(build_m3)
  131. };
  132.  
  133.  
  134. /* This is unusual in that we respect the stride of the output vector
  135.  * (f).  This allows us to pass in either a texcoord vector4f, or a
  136.  * temporary vector3f.  
  137.  */
  138. static void TAG(build_f3)( GLfloat *f, 
  139.                GLuint fstride,
  140.                const GLvector3f *normals,
  141.                const GLvector4f *coord_vec, 
  142.                const GLuint       flags[],
  143.                const GLubyte cullmask[] )
  144. {
  145.    GLuint stride = coord_vec->stride;
  146.    GLfloat *coord = coord_vec->start;
  147.    GLuint count = coord_vec->count;
  148.  
  149.    GLfloat *normal = FIRST_NORMAL;
  150.    GLuint i;
  151.  
  152.    LOCAL_VARS;
  153.  
  154.    (void) flags;
  155.    (void) cullmask;
  156.  
  157.    for (i=0;i<count;i++, STRIDE_F(coord,stride), STRIDE_F(f,fstride), NEXT_NORMAL) {
  158.       CHECK {
  159.      GLfloat u[3], two_nu;
  160.      COPY_3V( u, coord ); 
  161.      NORMALIZE_3FV( u );
  162.      two_nu = 2.0F * DOT3(normal,u);
  163.      f[0] = u[0] - normal[0] * two_nu;
  164.      f[1] = u[1] - normal[1] * two_nu;
  165.      f[2] = u[2] - normal[2] * two_nu;
  166.       }
  167.    }
  168. }
  169.  
  170.  
  171. static void TAG(build_f2)( GLfloat *f, 
  172.                GLuint fstride,
  173.                const GLvector3f *normals,
  174.                const GLvector4f *coord_vec, 
  175.                const GLuint      flags[],
  176.                const GLubyte     cullmask[] )
  177. {
  178.    GLuint stride = coord_vec->stride;
  179.    GLfloat *coord = coord_vec->start;
  180.    GLuint count = coord_vec->count;
  181.  
  182.    GLfloat *normal = FIRST_NORMAL;
  183.    GLuint i;
  184.  
  185.    LOCAL_VARS;
  186.  
  187.    (void) flags;
  188.    (void) cullmask;
  189.  
  190.    for (i=0;i<count;i++,STRIDE_F(coord,stride), STRIDE_F(f,fstride), NEXT_NORMAL) {
  191.       CHECK {
  192.      GLfloat u[3], two_nu;
  193.      COPY_2V( u, coord ); 
  194.      u[2] = 0;
  195.      NORMALIZE_3FV( u );
  196.      two_nu = 2.0F * DOT3(normal,u);
  197.      f[0] = u[0] - normal[0] * two_nu;
  198.      f[1] = u[1] - normal[1] * two_nu;
  199.      f[2] = u[2] - normal[2] * two_nu;
  200.       }
  201.    }
  202. }
  203.  
  204. /* Just treat 4-vectors as 3-vectors. 
  205.  */
  206. static build_f_func TAG(build_f_tab)[5] = {
  207.    0,
  208.    0,
  209.    TAG(build_f2),
  210.    TAG(build_f3),
  211.    TAG(build_f3)        
  212. };
  213.  
  214.  
  215. /* Special case texgen functions.
  216.  */
  217. static void TAG(texgen_reflection_map_nv)( struct vertex_buffer *VB, 
  218.                        GLuint textureUnit )
  219. {
  220.    GLvector4f *in = VB->TexCoordPtr[textureUnit];
  221.    GLvector4f *out = VB->store.TexCoord[textureUnit];
  222.    GLubyte *cullmask = VB->CullMask + VB->Start;
  223.  
  224.    TAG(build_f_tab)[VB->Unprojected->size]( out->start,
  225.                         out->stride,
  226.                         VB->NormalPtr, 
  227.                         VB->Unprojected, 
  228.                         VB->Flag + VB->Start,
  229.                         cullmask ); 
  230.  
  231.    if (!in) in = out;
  232.  
  233.    if (in != out && in->size == 4) {
  234.       gl_copy_tab[CULL][0x8](out, in, cullmask);
  235.    }
  236.  
  237.    VB->TexCoordPtr[textureUnit] = out;
  238.    out->size = MAX2(in->size, 3);
  239.    out->flags |= in->flags | VEC_SIZE_3;
  240. }
  241.  
  242.  
  243.  
  244. static void TAG(texgen_normal_map_nv)( struct vertex_buffer *VB, 
  245.                        GLuint textureUnit )
  246. {
  247.    GLvector4f *in = VB->TexCoordPtr[textureUnit];
  248.    GLvector4f *out = VB->store.TexCoord[textureUnit];
  249.    GLvector3f *normals = VB->NormalPtr;   
  250.    GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->start;
  251.    GLubyte *cullmask = VB->CullMask + VB->Start;
  252.    GLuint *flags = VB->Flag + VB->Start;
  253.    GLuint count = VB->Count;
  254.    GLuint i;
  255.    const GLfloat *normal = FIRST_NORMAL;
  256.  
  257.    LOCAL_VARS;
  258.  
  259.    (void) flags;
  260.    
  261.  
  262.    for (i=0;i<count;i++, NEXT_NORMAL) {
  263.       CHECK {
  264.      texcoord[i][0] = normal[0];
  265.      texcoord[i][1] = normal[1];
  266.      texcoord[i][2] = normal[2];
  267.       }
  268.    }
  269.  
  270.    if (!in) in = out;
  271.  
  272.    if (in != out && in->size == 4) {
  273.       gl_copy_tab[CULL][0x8](out, in, cullmask);
  274.    }
  275.  
  276.    VB->TexCoordPtr[textureUnit] = out;
  277.    out->size = MAX2(in->size, 3);
  278.    out->flags |= in->flags | VEC_SIZE_3;
  279. }
  280.  
  281.  
  282. static void TAG(texgen_sphere_map)( struct vertex_buffer *VB, 
  283.                     GLuint textureUnit )
  284. {
  285.    GLvector4f *in = VB->TexCoordPtr[textureUnit];
  286.    GLvector4f *out = VB->store.TexCoord[textureUnit];
  287.    GLfloat (*texcoord)[4] = (GLfloat (*)[4]) out->start;
  288.    GLubyte *cullmask = VB->CullMask + VB->Start;
  289.    GLuint count = VB->Count;
  290.    GLuint i;
  291.    GLfloat (*f)[3], *m;
  292.  
  293.    if (!VB->tmp_f) 
  294.       VB->tmp_f = (GLfloat (*)[3])malloc(VB->Size * sizeof(GLfloat) * 3);
  295.  
  296.    if (!VB->tmp_m) 
  297.       VB->tmp_m = (GLfloat *)malloc(VB->Size * sizeof(GLfloat));
  298.    
  299.    f = VB->tmp_f;
  300.    m = VB->tmp_m;
  301.  
  302.    (TAG(build_m_tab)[VB->Unprojected->size])( f, m, 
  303.                           VB->NormalPtr, 
  304.                           VB->Unprojected, 
  305.                           VB->Flag + VB->Start,
  306.                           cullmask ); 
  307.  
  308.    for (i=0;i<count;i++) {
  309.       CHECK {
  310.      texcoord[i][0] = f[i][0] * m[i] + 0.5F;
  311.      texcoord[i][1] = f[i][1] * m[i] + 0.5F;
  312.       }
  313.    }
  314.  
  315.  
  316.    if (!in) in = out;
  317.  
  318.    if (in != out) {
  319.       struct gl_texture_unit *texUnit = &VB->ctx->Texture.Unit[textureUnit];
  320.       GLuint copy = (all_bits[in->size] & ~texUnit->TexGenEnabled);
  321.       if (copy)
  322.      gl_copy_tab[CULL][copy](out, in, cullmask);
  323.    }
  324.  
  325.    VB->TexCoordPtr[textureUnit] = out;
  326.    out->size = MAX2(in->size,2);
  327.    out->flags |= in->flags | VEC_SIZE_2;
  328. }
  329.  
  330.  
  331.  
  332. static void TAG(texgen)( struct vertex_buffer *VB, GLuint textureUnit )
  333. {
  334.    GLcontext *ctx = VB->ctx;
  335.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[textureUnit];
  336.    const GLvector4f *obj = VB->ObjPtr;
  337.    const GLvector4f *eye = VB->EyePtr;
  338.    const GLvector3f *normals = VB->NormalPtr;
  339.    const GLubyte *cullmask = VB->CullMask + VB->Start;
  340.    const GLuint *flags = VB->Flag + VB->Start;
  341.  
  342.    GLvector4f *in = VB->TexCoordPtr[textureUnit];
  343.    GLvector4f *out = VB->store.TexCoord[textureUnit];
  344.    GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->start;
  345.    GLfloat *indata;
  346.    GLuint instride;
  347.    GLuint count = VB->Count;
  348.    GLfloat (*f)[3], *m;
  349.  
  350.    LOCAL_VARS;
  351.  
  352.    if (!VB->tmp_f) 
  353.       VB->tmp_f = (GLfloat (*)[3])malloc(VB->Size * sizeof(GLfloat) * 3);
  354.  
  355.    if (!VB->tmp_m) 
  356.       VB->tmp_m = (GLfloat *)malloc(VB->Size * sizeof(GLfloat));
  357.    
  358.    f = VB->tmp_f;
  359.    m = VB->tmp_m;
  360.  
  361.    if (!in) in = out;
  362.    instride = in->stride;
  363.  
  364.  
  365.  
  366.    if (texUnit->GenFlags & TEXGEN_NEED_M) {
  367.       TAG(build_m_tab)[in->size]( f, m, normals, eye, flags, cullmask ); 
  368.    } else if (texUnit->GenFlags & TEXGEN_NEED_F) {
  369.       TAG(build_f_tab)[in->size]( (GLfloat *)f, 3, normals, eye, 
  370.                   flags, cullmask ); 
  371.    }
  372.  
  373.    if (in != out) {
  374.       GLuint copy = (all_bits[in->size] & ~texUnit->TexGenEnabled);
  375.       if (copy)
  376.      gl_copy_tab[CULL][copy](out, in, cullmask);
  377.    }
  378.  
  379.    if (texUnit->Holes)
  380.    {
  381.       GLubyte holes = (GLubyte) (texUnit->Holes & ~all_bits[in->size]);
  382.       if (holes) {
  383.      if (holes & VEC_DIRTY_2) gl_vector4f_clean_elem(out, count, 2);
  384.      if (holes & VEC_DIRTY_1) gl_vector4f_clean_elem(out, count, 1);
  385.      if (holes & VEC_DIRTY_0) gl_vector4f_clean_elem(out, count, 0);
  386.       }
  387.    }
  388.  
  389.    VB->TexCoordPtr[textureUnit] = out;
  390.    out->size = MAX2(in->size, texUnit->TexgenSize);
  391.    out->flags |= in->flags | texUnit->TexGenEnabled;
  392.  
  393.    if (texUnit->TexGenEnabled & S_BIT) {
  394.       GLuint i;
  395.       switch (texUnit->GenModeS) {
  396.       case GL_OBJECT_LINEAR:
  397.      (gl_dotprod_tab[CULL][obj->size])(out, 0, obj, 
  398.                        texUnit->ObjectPlaneS, cullmask);
  399.      break;
  400.       case GL_EYE_LINEAR:
  401.      (gl_dotprod_tab[CULL][eye->size])(out, 0, eye,
  402.                        texUnit->EyePlaneS, cullmask);
  403.      break;
  404.       case GL_SPHERE_MAP: 
  405.      for (indata=in->start,i=0 ; i<count ; i++, STRIDE_F(indata,instride) )
  406.         CHECK texcoord[i][0] = indata[0] * m[i] + 0.5F;
  407.      break;
  408.       case GL_REFLECTION_MAP_NV: 
  409.      for (i=0;i<count;i++) 
  410.         CHECK texcoord[i][0] = f[i][0];
  411.      break;
  412.       case GL_NORMAL_MAP_NV: {
  413.  
  414.      const GLfloat *normal = FIRST_NORMAL;
  415.      for (i=0;i<count;i++, NEXT_NORMAL) {
  416.         CHECK texcoord[i][0] = normal[0];
  417.      }
  418.      break;
  419.       }
  420.       default:
  421.      gl_problem(ctx, "Bad S texgen");
  422.       }
  423.    } 
  424.  
  425.    if (texUnit->TexGenEnabled & T_BIT) {
  426.       GLuint i;
  427.       switch (texUnit->GenModeT) {
  428.       case GL_OBJECT_LINEAR:
  429.      (gl_dotprod_tab[CULL][obj->size])(out, 1, obj, 
  430.                        texUnit->ObjectPlaneT, cullmask);
  431.      break;
  432.       case GL_EYE_LINEAR:
  433.      (gl_dotprod_tab[CULL][eye->size])(out, 1, eye, 
  434.                        texUnit->EyePlaneT, cullmask);
  435.      break; 
  436.       case GL_SPHERE_MAP: 
  437.      for (indata=in->start,i=0; i<count ;i++,STRIDE_F(indata,instride)) 
  438.         CHECK texcoord[i][1] = indata[1] * m[i] + 0.5F;
  439.      break;      
  440.       case GL_REFLECTION_MAP_NV: 
  441.      for (i=0;i<count;i++) 
  442.         CHECK texcoord[i][0] = f[i][0];
  443.      break;
  444.       case GL_NORMAL_MAP_NV: {
  445.      const GLfloat *normal = FIRST_NORMAL;
  446.      for (i=0;i<count;i++, NEXT_NORMAL) {
  447.         CHECK texcoord[i][1] = normal[1];
  448.      }
  449.      break;
  450.       }
  451.       default:
  452.      gl_problem(ctx, "Bad T texgen");
  453.       }
  454.    }
  455.  
  456.    if (texUnit->TexGenEnabled & R_BIT) {
  457.       GLuint i;
  458.       switch (texUnit->GenModeR) {
  459.       case GL_OBJECT_LINEAR:
  460.      (gl_dotprod_tab[CULL][obj->size])(out, 2, obj, 
  461.                       texUnit->ObjectPlaneR, cullmask);
  462.      break;
  463.       case GL_EYE_LINEAR:
  464.      (gl_dotprod_tab[CULL][eye->size])(out, 2, eye,
  465.                       texUnit->EyePlaneR, cullmask);
  466.      break;
  467.       case GL_REFLECTION_MAP_NV: 
  468.      for (i=0;i<count;i++) 
  469.         CHECK texcoord[i][2] = f[i][2];
  470.      break;
  471.       case GL_NORMAL_MAP_NV: {
  472.      const GLfloat *normal = FIRST_NORMAL;
  473.      for (i=0;i<count;i++,NEXT_NORMAL) {
  474.         CHECK texcoord[i][2] = normal[2];
  475.      }
  476.      break;
  477.       }
  478.       default:
  479.      gl_problem(ctx, "Bad R texgen");
  480.       }
  481.    }
  482.  
  483.    if (texUnit->TexGenEnabled & Q_BIT) {
  484.       switch (texUnit->GenModeQ) {
  485.       case GL_OBJECT_LINEAR:
  486.      (gl_dotprod_tab[CULL][obj->size])(out, 3, obj, 
  487.                        texUnit->ObjectPlaneQ, cullmask);
  488.      break;
  489.       case GL_EYE_LINEAR:
  490.      (gl_dotprod_tab[CULL][eye->size])(out, 3, eye,
  491.                        texUnit->EyePlaneQ, cullmask);
  492.      break;
  493.       default:
  494.      gl_problem(ctx, "Bad Q texgen");
  495.       }
  496.    }
  497. }
  498.  
  499. static void TAG(init_texgen)( void )
  500. {
  501.    texgen_generic_tab[IDX] = TAG(texgen);
  502.    texgen_reflection_map_nv_tab[IDX] = TAG(texgen_reflection_map_nv);
  503.    texgen_normal_map_nv_tab[IDX] = TAG(texgen_normal_map_nv);
  504.    texgen_sphere_map_tab[IDX] = TAG(texgen_sphere_map);
  505. }
  506.  
  507. #undef TAG
  508. #undef IDX
  509. #undef CULL
  510. #undef FIRST_NORMAL  
  511. #undef NEXT_NORMAL
  512. #undef LOCAL_VARS
  513. #undef CHECK
  514.  
  515.  
  516.