Beispiel #1
0
static void build_f2( GLfloat *f,
		      GLuint fstride,
		      const GLvector4f *normal,
		      const GLvector4f *eye )
{
   GLuint stride = eye->stride;
   GLfloat *coord = eye->start;
   GLuint count = eye->count;
   GLfloat *norm = normal->start;
   GLuint i;

   for (i=0;i<count;i++) {

      GLfloat u[3], two_nu;
      COPY_2V( u, coord );
      u[2] = 0;
      NORMALIZE_3FV( u );
      two_nu = 2.0F * DOT3(norm,u);
      f[0] = u[0] - norm[0] * two_nu;
      f[1] = u[1] - norm[1] * two_nu;
      f[2] = u[2] - norm[2] * two_nu;

      STRIDE_F(coord,stride);
      STRIDE_F(f,fstride);
      STRIDE_F(norm, normal->stride);
   }
}
Beispiel #2
0
static void build_m2( GLfloat f[][3], GLfloat m[],
		      const GLvector4f *normal,
		      const GLvector4f *eye )
{
   GLuint stride = eye->stride;
   GLfloat *coord = eye->start;
   GLuint count = eye->count;

   GLfloat *norm = normal->start;
   GLuint i;

   for (i=0;i<count;i++,STRIDE_F(coord,stride),STRIDE_F(norm,normal->stride)) {
      GLfloat u[3], two_nu, fx, fy, fz;
      COPY_2V( u, coord );
      u[2] = 0;
      NORMALIZE_3FV( u );
      two_nu = 2.0F * DOT3(norm,u);
      fx = f[i][0] = u[0] - norm[0] * two_nu;
      fy = f[i][1] = u[1] - norm[1] * two_nu;
      fz = f[i][2] = u[2] - norm[2] * two_nu;
      m[i] = fx * fx + fy * fy + (fz + 1.0F) * (fz + 1.0F);
      if (m[i] != 0.0F) {
	 m[i] = 0.5F * (1.0f / sqrtf(m[i]));
      }
   }
}
Beispiel #3
0
/**
 * For debugging
 */
void
_mesa_vector4f_print( const GLvector4f *v, const GLubyte *cullmask,
                      GLboolean culling )
{
   static const GLfloat c[4] = { 0, 0, 0, 1 };
   static const char *templates[5] = {
      "%d:\t0, 0, 0, 1\n",
      "%d:\t%f, 0, 0, 1\n",
      "%d:\t%f, %f, 0, 1\n",
      "%d:\t%f, %f, %f, 1\n",
      "%d:\t%f, %f, %f, %f\n"
   };

   const char *t = templates[v->size];
   GLfloat *d = (GLfloat *)v->data;
   GLuint j, i = 0, count;

   printf("data-start\n");
   for (; d != v->start; STRIDE_F(d, v->stride), i++)
      printf(t, i, d[0], d[1], d[2], d[3]);

   printf("start-count(%u)\n", v->count);
   count = i + v->count;

   if (culling) {
      for (; i < count; STRIDE_F(d, v->stride), i++)
	 if (cullmask[i])
	    printf(t, i, d[0], d[1], d[2], d[3]);
   }
   else {
      for (; i < count; STRIDE_F(d, v->stride), i++)
	 printf(t, i, d[0], d[1], d[2], d[3]);
   }

   for (j = v->size; j < 4; j++) {
      if ((v->flags & (1<<j)) == 0) {

	 printf("checking col %u is clean as advertised ", j);

	 for (i = 0, d = (GLfloat *) v->data;
	      i < count && d[j] == c[j];
	      i++, STRIDE_F(d, v->stride)) {
            /* no-op */
         }

	 if (i == count)
	    printf(" --> ok\n");
	 else
	    printf(" --> Failed at %u ******\n", i);
      }
   }
}
Beispiel #4
0
static GLvector4f * ref_cliptest_points2( GLvector4f *clip_vec,
					  GLvector4f *proj_vec,
					  GLubyte clipMask[],
					  GLubyte *orMask,
					  GLubyte *andMask,
                                          GLboolean viewport_z_clip )
{
   const GLuint stride = clip_vec->stride;
   const GLuint count = clip_vec->count;
   const GLfloat *from = (GLfloat *)clip_vec->start;

   GLubyte tmpOrMask = *orMask;
   GLubyte tmpAndMask = *andMask;
   GLuint i;

   (void) viewport_z_clip;

   for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) {
      const GLfloat cx = from[0], cy = from[1];
      GLubyte mask = 0;
      if ( cx >  1.0 )		mask |= CLIP_RIGHT_BIT;
      else if ( cx < -1.0 )	mask |= CLIP_LEFT_BIT;
      if ( cy >  1.0 )		mask |= CLIP_TOP_BIT;
      else if ( cy < -1.0 )	mask |= CLIP_BOTTOM_BIT;
      clipMask[i] = mask;
      tmpOrMask |= mask;
      tmpAndMask &= mask;
   }

   *orMask = tmpOrMask;
   *andMask = tmpAndMask;
   return clip_vec;
}
Beispiel #5
0
static void texgen_normal_map_nv( struct gl_context *ctx,
				  struct texgen_stage_data *store,
				  GLuint unit )
{
   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
   GLvector4f *in = VB->AttribPtr[VERT_ATTRIB_TEX0 + unit];
   GLvector4f *out = &store->texcoord[unit];
   GLvector4f *normal = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
   GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->start;
   GLuint count = VB->Count;
   GLuint i;
   const GLfloat *norm = normal->start;

   for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) {
      texcoord[i][0] = norm[0];
      texcoord[i][1] = norm[1];
      texcoord[i][2] = norm[2];
   }


   out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_3;
   out->count = count;
   out->size = MAX2(in->size, 3);
   if (in->size == 4) 
      _mesa_copy_tab[0x8]( out, in );
}
Beispiel #6
0
/**
 * Compute per-vertex fog blend factors from fog coordinates by
 * evaluating the GL_LINEAR, GL_EXP or GL_EXP2 fog function.
 * Fog coordinates are distances from the eye (typically between the
 * near and far clip plane distances).
 * Note that fogcoords may be negative, if eye z is source absolute
 * value must be taken earlier.
 * Fog blend factors are in the range [0,1].
 */
static void
compute_fog_blend_factors(struct gl_context *ctx, GLvector4f *out, const GLvector4f *in)
{
   GLfloat end  = ctx->Fog.End;
   GLfloat *v = in->start;
   GLuint stride = in->stride;
   GLuint n = in->count;
   GLfloat (*data)[4] = out->data;
   GLfloat d;
   GLuint i;

   out->count = in->count;

   switch (ctx->Fog.Mode) {
   case GL_LINEAR:
      if (ctx->Fog.Start == ctx->Fog.End)
         d = 1.0F;
      else
         d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
      for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
         const GLfloat z = *v;
         GLfloat f = (end - z) * d;
	 data[i][0] = CLAMP(f, 0.0F, 1.0F);
      }
      break;
   case GL_EXP:
      d = ctx->Fog.Density;
      for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) {
         const GLfloat z = *v;
         NEG_EXP( data[i][0], d * z );
      }
      break;
   case GL_EXP2:
      d = ctx->Fog.Density*ctx->Fog.Density;
      for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) {
         const GLfloat z = *v;
         NEG_EXP( data[i][0], d * z * z );
      }
      break;
   default:
      _mesa_problem(ctx, "Bad fog mode in make_fog_coord");
      return;
   }
}
Beispiel #7
0
static GLvector4f *ref_cliptest_points4( GLvector4f *clip_vec,
					 GLvector4f *proj_vec,
					 GLubyte clipMask[],
					 GLubyte *orMask,
					 GLubyte *andMask,
					 GLboolean viewport_z_clip )
{
   const GLuint stride = clip_vec->stride;
   const GLuint count = clip_vec->count;
   const GLfloat *from = (GLfloat *)clip_vec->start;
   GLuint c = 0;
   GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start;
   GLubyte tmpAndMask = *andMask;
   GLubyte tmpOrMask = *orMask;
   GLuint i;
   for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) {
      const GLfloat cx = from[0];
      const GLfloat cy = from[1];
      const GLfloat cz = from[2];
      const GLfloat cw = from[3];
      GLubyte mask = 0;
      if ( -cx + cw < 0 ) mask |= CLIP_RIGHT_BIT;
      if (  cx + cw < 0 ) mask |= CLIP_LEFT_BIT;
      if ( -cy + cw < 0 ) mask |= CLIP_TOP_BIT;
      if (  cy + cw < 0 ) mask |= CLIP_BOTTOM_BIT;
      if (viewport_z_clip) {
	 if ( -cz + cw < 0 ) mask |= CLIP_FAR_BIT;
	 if (  cz + cw < 0 ) mask |= CLIP_NEAR_BIT;
      }
      clipMask[i] = mask;
      if ( mask ) {
	 c++;
	 tmpAndMask &= mask;
	 tmpOrMask |= mask;
	 vProj[i][0] = 0;
	 vProj[i][1] = 0;
	 vProj[i][2] = 0;
	 vProj[i][3] = 1;
      } else {
	 GLfloat oow = 1.0F / cw;
	 vProj[i][0] = cx * oow;
	 vProj[i][1] = cy * oow;
	 vProj[i][2] = cz * oow;
	 vProj[i][3] = oow;
      }
   }

   *orMask = tmpOrMask;
   *andMask = (GLubyte) (c < count ? 0 : tmpAndMask);

   proj_vec->flags |= VEC_SIZE_4;
   proj_vec->size = 4;
   proj_vec->count = clip_vec->count;
   return proj_vec;
}
Beispiel #8
0
static void
userclip( struct gl_context *ctx,
          GLvector4f *clip,
          GLubyte *clipmask,
          GLubyte *clipormask,
          GLubyte *clipandmask )
{
   GLuint p;

   for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
      if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
	 GLuint nr, i;
	 const GLfloat a = ctx->Transform._ClipUserPlane[p][0];
	 const GLfloat b = ctx->Transform._ClipUserPlane[p][1];
	 const GLfloat c = ctx->Transform._ClipUserPlane[p][2];
	 const GLfloat d = ctx->Transform._ClipUserPlane[p][3];
         GLfloat *coord = (GLfloat *)clip->data;
         GLuint stride = clip->stride;
         GLuint count = clip->count;

	 for (nr = 0, i = 0 ; i < count ; i++) {
	    GLfloat dp = (coord[0] * a + 
			  coord[1] * b +
			  coord[2] * c +
			  coord[3] * d);

	    if (dp < 0) {
	       nr++;
	       clipmask[i] |= CLIP_USER_BIT;
	    }

	    STRIDE_F(coord, stride);
	 }

	 if (nr > 0) {
	    *clipormask |= CLIP_USER_BIT;
	    if (nr == count) {
	       *clipandmask |= CLIP_USER_BIT;
	       return;
	    }
	 }
      }
   }
}
Beispiel #9
0
/* EXT_vertex_cull.  Not really a big win, but probably depends on
 * your application.  This stage not included in the default pipeline.
 */
static GLboolean run_cull_stage( GLcontext *ctx,
				 struct tnl_pipeline_stage *stage )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   struct vertex_buffer *VB = &tnl->vb;

   const GLfloat a = ctx->Transform.CullObjPos[0];
   const GLfloat b = ctx->Transform.CullObjPos[1];
   const GLfloat c = ctx->Transform.CullObjPos[2];
   GLfloat *norm = (GLfloat *)VB->NormalPtr->data;
   GLuint stride = VB->NormalPtr->stride;
   GLuint count = VB->Count;
   GLuint i;

   if (ctx->ShaderObjects._VertexShaderPresent)
      return GL_TRUE;

   if (ctx->VertexProgram._Enabled ||
       !ctx->Transform.CullVertexFlag) 
      return GL_TRUE;

   VB->ClipOrMask &= ~CLIP_CULL_BIT;
   VB->ClipAndMask |= CLIP_CULL_BIT;

   for (i = 0 ; i < count ; i++) {
      GLfloat dp = (norm[0] * a + 
		    norm[1] * b +
		    norm[2] * c);

      if (dp < 0) {
	 VB->ClipMask[i] |= CLIP_CULL_BIT;
	 VB->ClipOrMask |= CLIP_CULL_BIT;
      }
      else {
	 VB->ClipMask[i] &= ~CLIP_CULL_BIT;
	 VB->ClipAndMask &= ~CLIP_CULL_BIT;
      }

      STRIDE_F(norm, stride);
   }

   return !(VB->ClipAndMask & CLIP_CULL_BIT);
}
Beispiel #10
0
/**
 * In the case of colormaterial, the effected material attributes
 * should already have been bound to point to the incoming color data,
 * prior to running the pipeline.
 * This function copies the vertex's color to the material attributes
 * which are tracking glColor.
 * It's called per-vertex in the lighting loop.
 */
static void
update_materials(GLcontext *ctx, struct light_stage_data *store)
{
   GLuint i;

   for (i = 0 ; i < store->mat_count ; i++) {
      /* update the material */
      COPY_CLEAN_4V(store->mat[i].current, store->mat[i].size, store->mat[i].ptr);
      /* increment src vertex color pointer */
      STRIDE_F(store->mat[i].ptr, store->mat[i].stride);
   }
      
   /* recompute derived light/material values */
   _mesa_update_material( ctx, store->mat_bitmask );
   /* XXX we should only call this if we're tracking/changing the specular
    * exponent.
    */
   _mesa_validate_all_lighting_tables( ctx );
}
Beispiel #11
0
GLvector4f *_mesa_project_points( GLvector4f *proj_vec,
				  const GLvector4f *clip_vec )
{
   const GLuint stride = clip_vec->stride;
   const GLfloat *from = (GLfloat *)clip_vec->start;
   const GLuint count = clip_vec->count;
   GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start;
   GLuint i;

   for (i = 0 ; i < count ; i++, STRIDE_F(from, stride))
   {
	 GLfloat oow = 1.0F / from[3];
	 vProj[i][3] = oow;
	 vProj[i][0] = from[0] * oow;
	 vProj[i][1] = from[1] * oow;
	 vProj[i][2] = from[2] * oow;
   }

   proj_vec->flags |= VEC_SIZE_4;
   proj_vec->size = 3;
   proj_vec->count = clip_vec->count;
   return proj_vec;
}
Beispiel #12
0
static int test_cliptest_function( clip_func func, int np,
				   int psize, long *cycles )
{
   GLvector4f source[1], dest[1], ref[1];
   GLubyte dm[TEST_COUNT], dco, dca;
   GLubyte rm[TEST_COUNT], rco, rca;
   int i, j;
#ifdef  RUN_DEBUG_BENCHMARK
   int cycle_i;                /* the counter for the benchmarks we run */
#endif
   GLboolean viewport_z_clip = GL_TRUE;

   (void) cycles;

   if ( psize > 4 ) {
      _mesa_problem( NULL, "test_cliptest_function called with psize > 4\n" );
      return 0;
   }

   for ( i = 0 ; i < TEST_COUNT ; i++) {
      ASSIGN_4V( d[i], 0.0, 0.0, 0.0, 1.0 );
      ASSIGN_4V( s[i], 0.0, 0.0, 0.0, 1.0 );
      for ( j = 0 ; j < psize ; j++ )
         s[i][j] = rnd();
   }

   source->data = (GLfloat(*)[4])s;
   source->start = (GLfloat *)s;
   source->count = TEST_COUNT;
   source->stride = sizeof(s[0]);
   source->size = 4;
   source->flags = 0;

   dest->data = (GLfloat(*)[4])d;
   dest->start = (GLfloat *)d;
   dest->count = TEST_COUNT;
   dest->stride = sizeof(float[4]);
   dest->size = 0;
   dest->flags = 0;

   ref->data = (GLfloat(*)[4])r;
   ref->start = (GLfloat *)r;
   ref->count = TEST_COUNT;
   ref->stride = sizeof(float[4]);
   ref->size = 0;
   ref->flags = 0;

   dco = rco = 0;
   dca = rca = CLIP_FRUSTUM_BITS;

   ref_cliptest[psize]( source, ref, rm, &rco, &rca, viewport_z_clip );

   if ( mesa_profile ) {
      BEGIN_RACE( *cycles );
      func( source, dest, dm, &dco, &dca, viewport_z_clip );
      END_RACE( *cycles );
   }
   else {
      func( source, dest, dm, &dco, &dca, viewport_z_clip );
   }

   if ( dco != rco ) {
      printf( "\n-----------------------------\n" );
      printf( "dco = 0x%02x   rco = 0x%02x\n", dco, rco );
      return 0;
   }
   if ( dca != rca ) {
      printf( "\n-----------------------------\n" );
      printf( "dca = 0x%02x   rca = 0x%02x\n", dca, rca );
      return 0;
   }
   for ( i = 0 ; i < TEST_COUNT ; i++ ) {
      if ( dm[i] != rm[i] ) {
         GLfloat *c = source->start;
         STRIDE_F(c, source->stride * i);
         if (psize == 4 && xyz_close_to_w(c)) {
            /* The coordinate is very close to the clip plane.  The clipmask
             * may vary depending on code path, but that's OK.
             */
            continue;
         }
	 printf( "\n-----------------------------\n" );
	 printf( "mask[%d] = 0x%02x   ref mask[%d] = 0x%02x\n", i, dm[i], i,rm[i] );
         printf(" coord = %f, %f, %f, %f\n",
                c[0], c[1], c[2], c[3]);
	 return 0;
      }
   }

   /* Only verify output on projected points4 case.  FIXME: Do we need
    * to test other cases?
    */
   if ( np || psize < 4 )
      return 1;

   for ( i = 0 ; i < TEST_COUNT ; i++ ) {
      for ( j = 0 ; j < 4 ; j++ ) {
         if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) {
            printf( "\n-----------------------------\n" );
            printf( "(i = %i, j = %i)  dm = 0x%02x   rm = 0x%02x\n",
		    i, j, dm[i], rm[i] );
            printf( "%f \t %f \t [diff = %e - %i bit missed]\n",
		    d[i][0], r[i][0], r[i][0]-d[i][0],
		    MAX_PRECISION - significand_match( d[i][0], r[i][0] ) );
            printf( "%f \t %f \t [diff = %e - %i bit missed]\n",
		    d[i][1], r[i][1], r[i][1]-d[i][1],
		    MAX_PRECISION - significand_match( d[i][1], r[i][1] ) );
            printf( "%f \t %f \t [diff = %e - %i bit missed]\n",
		    d[i][2], r[i][2], r[i][2]-d[i][2],
		    MAX_PRECISION - significand_match( d[i][2], r[i][2] ) );
            printf( "%f \t %f \t [diff = %e - %i bit missed]\n",
		    d[i][3], r[i][3], r[i][3]-d[i][3],
		    MAX_PRECISION - significand_match( d[i][3], r[i][3] ) );
            return 0;
         }
      }
   }

   return 1;
}
Beispiel #13
0
static void texgen( struct gl_context *ctx,
		    struct texgen_stage_data *store,
		    GLuint unit )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   struct vertex_buffer *VB = &tnl->vb;
   GLvector4f *in = VB->AttribPtr[VERT_ATTRIB_TEX0 + unit];
   GLvector4f *out = &store->texcoord[unit];
   const struct gl_fixedfunc_texture_unit *texUnit =
      &ctx->Texture.FixedFuncUnit[unit];
   const GLvector4f *obj = VB->AttribPtr[_TNL_ATTRIB_POS];
   const GLvector4f *eye = VB->EyePtr;
   const GLvector4f *normal = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
   const GLfloat *m = store->tmp_m;
   const GLuint count = VB->Count;
   GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->data;
   GLfloat (*f)[3] = store->tmp_f;
   GLuint copy;

   if (texUnit->_GenFlags & TEXGEN_NEED_M) {
      build_m_tab[eye->size]( store->tmp_f, store->tmp_m, normal, eye );
   } else if (texUnit->_GenFlags & TEXGEN_NEED_F) {
      build_f_tab[eye->size]( (GLfloat *)store->tmp_f, 3, normal, eye );
   }


   out->size = MAX2(in->size, store->TexgenSize[unit]);
   out->flags |= (in->flags & VEC_SIZE_FLAGS) | texUnit->TexGenEnabled;
   out->count = count;

   copy = (all_bits[in->size] & ~texUnit->TexGenEnabled);
   if (copy)
      _mesa_copy_tab[copy]( out, in );

   if (texUnit->TexGenEnabled & S_BIT) {
      GLuint i;
      switch (texUnit->GenS.Mode) {
      case GL_OBJECT_LINEAR:
	 _mesa_dotprod_tab[obj->size]( (GLfloat *)out->data,
				       sizeof(out->data[0]), obj,
				       texUnit->GenS.ObjectPlane );
	 break;
      case GL_EYE_LINEAR:
	 _mesa_dotprod_tab[eye->size]( (GLfloat *)out->data,
				       sizeof(out->data[0]), eye,
				       texUnit->GenS.EyePlane );
	 break;
      case GL_SPHERE_MAP:
         for (i = 0; i < count; i++)
            texcoord[i][0] = f[i][0] * m[i] + 0.5F;
	 break;
      case GL_REFLECTION_MAP_NV:
	 for (i=0;i<count;i++)
	     texcoord[i][0] = f[i][0];
	 break;
      case GL_NORMAL_MAP_NV: {
	 const GLfloat *norm = normal->start;
	 for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) {
	     texcoord[i][0] = norm[0];
	 }
	 break;
      }
      default:
	 _mesa_problem(ctx, "Bad S texgen");
      }
   }

   if (texUnit->TexGenEnabled & T_BIT) {
      GLuint i;
      switch (texUnit->GenT.Mode) {
      case GL_OBJECT_LINEAR:
	 _mesa_dotprod_tab[obj->size]( &(out->data[0][1]),
				       sizeof(out->data[0]), obj,
				       texUnit->GenT.ObjectPlane );
	 break;
      case GL_EYE_LINEAR:
	 _mesa_dotprod_tab[eye->size]( &(out->data[0][1]),
				       sizeof(out->data[0]), eye,
				       texUnit->GenT.EyePlane );
	 break;
      case GL_SPHERE_MAP:
         for (i = 0; i < count; i++)
            texcoord[i][1] = f[i][1] * m[i] + 0.5F;
	 break;
      case GL_REFLECTION_MAP_NV:
	 for (i=0;i<count;i++)
	     texcoord[i][1] = f[i][1];
	 break;
      case GL_NORMAL_MAP_NV: {
	 const GLfloat *norm = normal->start;
	 for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) {
	     texcoord[i][1] = norm[1];
	 }
	 break;
      }
      default:
	 _mesa_problem(ctx, "Bad T texgen");
      }
   }

   if (texUnit->TexGenEnabled & R_BIT) {
      GLuint i;
      switch (texUnit->GenR.Mode) {
      case GL_OBJECT_LINEAR:
	 _mesa_dotprod_tab[obj->size]( &(out->data[0][2]),
				       sizeof(out->data[0]), obj,
				       texUnit->GenR.ObjectPlane );
	 break;
      case GL_EYE_LINEAR:
	 _mesa_dotprod_tab[eye->size]( &(out->data[0][2]),
				       sizeof(out->data[0]), eye,
				       texUnit->GenR.EyePlane );
	 break;
      case GL_REFLECTION_MAP_NV:
	 for (i=0;i<count;i++)
	     texcoord[i][2] = f[i][2];
	 break;
      case GL_NORMAL_MAP_NV: {
	 const GLfloat *norm = normal->start;
	 for (i=0;i<count;i++,STRIDE_F(norm, normal->stride)) {
	     texcoord[i][2] = norm[2];
	 }
	 break;
      }
      default:
	 _mesa_problem(ctx, "Bad R texgen");
      }
   }

   if (texUnit->TexGenEnabled & Q_BIT) {
      switch (texUnit->GenQ.Mode) {
      case GL_OBJECT_LINEAR:
	 _mesa_dotprod_tab[obj->size]( &(out->data[0][3]),
				       sizeof(out->data[0]), obj,
				       texUnit->GenQ.ObjectPlane );
	 break;
      case GL_EYE_LINEAR:
	 _mesa_dotprod_tab[eye->size]( &(out->data[0][3]),
				       sizeof(out->data[0]), eye,
				       texUnit->GenQ.EyePlane );
	 break;
      default:
	 _mesa_problem(ctx, "Bad Q texgen");
      }
   }
}
Beispiel #14
0
static GLboolean
run_fog_stage(struct gl_context *ctx, struct tnl_pipeline_stage *stage)
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   struct vertex_buffer *VB = &tnl->vb;
   struct fog_stage_data *store = FOG_STAGE_DATA(stage);
   GLvector4f *input;


   if (!ctx->Fog.Enabled)
      return GL_TRUE;

   if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT && !ctx->VertexProgram._Current) {
      GLuint i;
      GLfloat *coord;
      /* Fog is computed from vertex or fragment Z values */
      /* source = VB->AttribPtr[_TNL_ATTRIB_POS] or VB->EyePtr coords */
      /* dest = VB->AttribPtr[_TNL_ATTRIB_FOG] = fog stage private storage */
      VB->AttribPtr[_TNL_ATTRIB_FOG] = &store->fogcoord;

      if (!ctx->_NeedEyeCoords) {
         /* compute fog coords from object coords */
	 const GLfloat *m = ctx->ModelviewMatrixStack.Top->m;
	 GLfloat plane[4];

	 /* Use this to store calculated eye z values:
	  */
	 input = &store->fogcoord;

	 plane[0] = m[2];
	 plane[1] = m[6];
	 plane[2] = m[10];
	 plane[3] = m[14];
	 /* Full eye coords weren't required, just calculate the
	  * eye Z values.
	  */
	 _mesa_dotprod_tab[VB->AttribPtr[_TNL_ATTRIB_POS]->size]
	    ( (GLfloat *) input->data,
	      4 * sizeof(GLfloat),
	      VB->AttribPtr[_TNL_ATTRIB_POS], plane );

	 input->count = VB->AttribPtr[_TNL_ATTRIB_POS]->count;

	 /* make sure coords are really positive
	    NOTE should avoid going through array twice */
	 coord = input->start;
	 for (i = 0; i < input->count; i++) {
	    *coord = fabsf(*coord);
	    STRIDE_F(coord, input->stride);
	 }
      }
      else {
         /* fog coordinates = eye Z coordinates - need to copy for ABS */
	 input = &store->fogcoord;

	 if (VB->EyePtr->size < 2)
	    _mesa_vector4f_clean_elem( VB->EyePtr, VB->Count, 2 );

	 input->stride = 4 * sizeof(GLfloat);
	 input->count = VB->EyePtr->count;
	 coord = VB->EyePtr->start;
	 for (i = 0 ; i < VB->EyePtr->count; i++) {
	    input->data[i][0] = fabsf(coord[2]);
	    STRIDE_F(coord, VB->EyePtr->stride);
	 }
      }
   }
   else {
      /* use glFogCoord() coordinates */
      input = VB->AttribPtr[_TNL_ATTRIB_FOG];  /* source data */

      /* input->count may be one if glFogCoord was only called once
       * before glBegin.  But we need to compute fog for all vertices.
       */
      input->count = VB->AttribPtr[_TNL_ATTRIB_POS]->count;

      VB->AttribPtr[_TNL_ATTRIB_FOG] = &store->fogcoord;  /* dest data */
   }

   if (tnl->_DoVertexFog) {
      /* compute blend factors from fog coordinates */
      compute_fog_blend_factors( ctx, VB->AttribPtr[_TNL_ATTRIB_FOG], input );
   }
   else {
      /* results = incoming fog coords (compute fog per-fragment later) */
      VB->AttribPtr[_TNL_ATTRIB_FOG] = input;
   }

   return GL_TRUE;
}