⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s_triangle.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:

#undef SPAN_NEAREST
#undef SPAN_LINEAR

   /* restore state */
   ctx->Texture._EnabledUnits = savedTexEnable;
}


/*
 * Render an perspective corrected RGB/RGBA textured triangle.
 * The Q (aka V in Mesa) coordinate must be zero such that the divide
 * by interpolated Q/W comes out right.
 *
 */
#define NAME persp_textured_triangle
#define INTERP_Z 1
#define INTERP_W 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_TEX 1

#define SETUP_CODE							\
   struct persp_info info;						\
   const struct gl_texture_unit *unit = ctx->Texture.Unit+0;		\
   const struct gl_texture_object *obj = unit->Current2D;		\
   const GLint b = obj->BaseLevel;					\
   info.texture = (const GLchan *) obj->Image[0][b]->Data;		\
   info.twidth_log2 = obj->Image[0][b]->WidthLog2;			\
   info.smask = obj->Image[0][b]->Width - 1;				\
   info.tmask = obj->Image[0][b]->Height - 1;				\
   info.format = obj->Image[0][b]->Format;				\
   info.filter = obj->MinFilter;					\
   info.envmode = unit->EnvMode;					\
									\
   if (info.envmode == GL_BLEND) {					\
      /* potential off-by-one error here? (1.0f -> 2048 -> 0) */	\
      info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF);	\
      info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF);	\
      info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF);	\
      info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF);	\
   }									\
   if (!info.texture) {							\
      /* this shouldn't happen */					\
      return;								\
   }									\
									\
   switch (info.format) {						\
   case GL_ALPHA:							\
   case GL_LUMINANCE:							\
   case GL_INTENSITY:							\
      info.tbytesline = obj->Image[0][b]->Width;			\
      break;								\
   case GL_LUMINANCE_ALPHA:						\
      info.tbytesline = obj->Image[0][b]->Width * 2;			\
      break;								\
   case GL_RGB:								\
      info.tbytesline = obj->Image[0][b]->Width * 3;			\
      break;								\
   case GL_RGBA:							\
      info.tbytesline = obj->Image[0][b]->Width * 4;			\
      break;								\
   default:								\
      _mesa_problem(NULL, "Bad texture format in persp_textured_triangle");\
      return;								\
   }									\
   info.tsize = obj->Image[0][b]->Height * info.tbytesline;

#define RENDER_SPAN( span )			\
   span.interpMask &= ~SPAN_RGBA;		\
   span.arrayMask |= SPAN_RGBA;			\
   fast_persp_span(ctx, &span, &info);

#include "s_tritemp.h"


#endif /* CHAN_BITS != GL_FLOAT */

                


/*
 * Render a smooth-shaded, textured, RGBA triangle.
 * Interpolate S,T,R with perspective correction, w/out mipmapping.
 */
#define NAME general_textured_triangle
#define INTERP_Z 1
#define INTERP_W 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_SPEC 1
#define INTERP_ALPHA 1
#define INTERP_TEX 1
#define RENDER_SPAN( span )   _swrast_write_rgba_span(ctx, &span);
#include "s_tritemp.h"



/*
 * This is the big one!
 * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates.
 * Yup, it's slow.
 */
#define NAME multitextured_triangle
#define INTERP_Z 1
#define INTERP_W 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_SPEC 1
#define INTERP_MULTITEX 1
#define RENDER_SPAN( span )   _swrast_write_rgba_span(ctx, &span);
#include "s_tritemp.h"



/*
 * Special tri function for occlusion testing
 */
#define NAME occlusion_zless_triangle
#define INTERP_Z 1
#define SETUP_CODE						\
   struct gl_renderbuffer *rb					\
      = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;	\
   ASSERT(ctx->Depth.Test);					\
   ASSERT(!ctx->Depth.Mask);					\
   ASSERT(ctx->Depth.Func == GL_LESS);				\
   if (ctx->OcclusionResult && !ctx->Occlusion.Active) {	\
      return;							\
   }
#define RENDER_SPAN( span )						\
   if (ctx->Visual.depthBits <= 16) {					\
      GLuint i;								\
      const GLushort *zRow = (const GLushort *)				\
         rb->GetPointer(ctx, rb, span.x, span.y);			\
      for (i = 0; i < span.end; i++) {					\
         GLdepth z = FixedToDepth(span.z);				\
         if (z < zRow[i]) {						\
            ctx->OcclusionResult = GL_TRUE;				\
            ctx->Occlusion.PassedCounter++;				\
         }								\
         span.z += span.zStep;						\
      }									\
   }									\
   else {								\
      GLuint i;								\
      const GLuint *zRow = (const GLuint *)				\
         rb->GetPointer(ctx, rb, span.x, span.y);			\
      for (i = 0; i < span.end; i++) {					\
         if ((GLuint)span.z < zRow[i]) {				\
            ctx->OcclusionResult = GL_TRUE;				\
            ctx->Occlusion.PassedCounter++;				\
         }								\
         span.z += span.zStep;						\
      }									\
   }
#include "s_tritemp.h"



static void
nodraw_triangle( GLcontext *ctx,
                 const SWvertex *v0,
                 const SWvertex *v1,
                 const SWvertex *v2 )
{
   (void) (ctx && v0 && v1 && v2);
}


/*
 * This is used when separate specular color is enabled, but not
 * texturing.  We add the specular color to the primary color,
 * draw the triangle, then restore the original primary color.
 * Inefficient, but seldom needed.
 */
void _swrast_add_spec_terms_triangle( GLcontext *ctx,
				      const SWvertex *v0,
				      const SWvertex *v1,
				      const SWvertex *v2 )
{
   SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */
   SWvertex *ncv1 = (SWvertex *)v1;
   SWvertex *ncv2 = (SWvertex *)v2;
#if CHAN_TYPE == GL_FLOAT
   GLfloat rSum, gSum, bSum;
#else
   GLint rSum, gSum, bSum;
#endif
   GLchan c[3][4];
   /* save original colors */
   COPY_CHAN4( c[0], ncv0->color );
   COPY_CHAN4( c[1], ncv1->color );
   COPY_CHAN4( c[2], ncv2->color );
   /* sum v0 */
   rSum = ncv0->color[0] + ncv0->specular[0];
   gSum = ncv0->color[1] + ncv0->specular[1];
   bSum = ncv0->color[2] + ncv0->specular[2];
   ncv0->color[0] = MIN2(rSum, CHAN_MAX);
   ncv0->color[1] = MIN2(gSum, CHAN_MAX);
   ncv0->color[2] = MIN2(bSum, CHAN_MAX);
   /* sum v1 */
   rSum = ncv1->color[0] + ncv1->specular[0];
   gSum = ncv1->color[1] + ncv1->specular[1];
   bSum = ncv1->color[2] + ncv1->specular[2];
   ncv1->color[0] = MIN2(rSum, CHAN_MAX);
   ncv1->color[1] = MIN2(gSum, CHAN_MAX);
   ncv1->color[2] = MIN2(bSum, CHAN_MAX);
   /* sum v2 */
   rSum = ncv2->color[0] + ncv2->specular[0];
   gSum = ncv2->color[1] + ncv2->specular[1];
   bSum = ncv2->color[2] + ncv2->specular[2];
   ncv2->color[0] = MIN2(rSum, CHAN_MAX);
   ncv2->color[1] = MIN2(gSum, CHAN_MAX);
   ncv2->color[2] = MIN2(bSum, CHAN_MAX);
   /* draw */
   SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 );
   /* restore original colors */
   COPY_CHAN4( ncv0->color, c[0] );
   COPY_CHAN4( ncv1->color, c[1] );
   COPY_CHAN4( ncv2->color, c[2] );
}



#ifdef DEBUG

/* record the current triangle function name */
const char *_mesa_triFuncName = NULL;

#define USE(triFunc)				\
do {						\
    _mesa_triFuncName = #triFunc;		\
    /*printf("%s\n", _mesa_triFuncName);*/	\
    swrast->Triangle = triFunc;			\
} while (0)

#else

#define USE(triFunc)  swrast->Triangle = triFunc;

#endif




/*
 * Determine which triangle rendering function to use given the current
 * rendering context.
 *
 * Please update the summary flag _SWRAST_NEW_TRIANGLE if you add or
 * remove tests to this code.
 */
void
_swrast_choose_triangle( GLcontext *ctx )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   const GLboolean rgbmode = ctx->Visual.rgbMode;

   if (ctx->Polygon.CullFlag &&
       ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
      USE(nodraw_triangle);
      return;
   }

   if (ctx->RenderMode==GL_RENDER) {

      if (ctx->Polygon.SmoothFlag) {
         _swrast_set_aa_triangle_function(ctx);
         ASSERT(swrast->Triangle);
         return;
      }

      /* special case for occlusion testing */
      if ((ctx->Depth.OcclusionTest || ctx->Occlusion.Active) &&
          ctx->Depth.Test &&
          ctx->Depth.Mask == GL_FALSE &&
          ctx->Depth.Func == GL_LESS &&
          !ctx->Stencil.Enabled) {
         if ((rgbmode &&
              ctx->Color.ColorMask[0] == 0 &&
              ctx->Color.ColorMask[1] == 0 &&
              ctx->Color.ColorMask[2] == 0 &&
              ctx->Color.ColorMask[3] == 0)
             ||
             (!rgbmode && ctx->Color.IndexMask == 0)) {
            USE(occlusion_zless_triangle);
            return;
         }
      }

      if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Active) {
         /* Ugh, we do a _lot_ of tests to pick the best textured tri func */
	 const struct gl_texture_object *texObj2D;
         const struct gl_texture_image *texImg;
         GLenum minFilter, magFilter, envMode;
         GLint format;
         texObj2D = ctx->Texture.Unit[0].Current2D;
         texImg = texObj2D ? texObj2D->Image[0][texObj2D->BaseLevel] : NULL;
         format = texImg ? texImg->TexFormat->MesaFormat : -1;
         minFilter = texObj2D ? texObj2D->MinFilter : (GLenum) 0;
         magFilter = texObj2D ? texObj2D->MagFilter : (GLenum) 0;
         envMode = ctx->Texture.Unit[0].EnvMode;

         /* First see if we can use an optimized 2-D texture function */
         if (ctx->Texture._EnabledCoordUnits == 0x1
             && !ctx->FragmentProgram._Active
             && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
             && texObj2D->WrapS == GL_REPEAT
	     && texObj2D->WrapT == GL_REPEAT
             && texObj2D->_IsPowerOfTwo
             && texImg->Border == 0
             && texImg->Width == texImg->RowStride
             && (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
	     && minFilter == magFilter
	     && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
	     && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) {
	    if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) {
	       if (minFilter == GL_NEAREST
		   && format == MESA_FORMAT_RGB
		   && (envMode == GL_REPLACE || envMode == GL_DECAL)
		   && ((swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)
			&& ctx->Depth.Func == GL_LESS
			&& ctx->Depth.Mask == GL_TRUE)
		       || swrast->_RasterMask == TEXTURE_BIT)
		   && ctx->Polygon.StippleFlag == GL_FALSE
                   && ctx->Visual.depthBits <= 16) {
		  if (swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)) {
		     USE(simple_z_textured_triangle);
		  }
		  else {
		     USE(simple_textured_triangle);
		  }
	       }
	       else {
#if (CHAN_BITS == 16 || CHAN_BITS == 32)
                  USE(general_textured_triangle);
#else
                  USE(affine_textured_triangle);
#endif
	       }
	    }
	    else {
#if (CHAN_BITS == 16 || CHAN_BITS == 32)
               USE(general_textured_triangle);
#else
               USE(persp_textured_triangle);
#endif
	    }
	 }
         else {
            /* general case textured triangles */
            if (ctx->Texture._EnabledCoordUnits > 1) {
               USE(multitextured_triangle);
            }
            else {
               USE(general_textured_triangle);
            }
         }
      }
      else {
         ASSERT(!ctx->Texture._EnabledCoordUnits);
	 if (ctx->Light.ShadeModel==GL_SMOOTH) {
	    /* smooth shaded, no texturing, stippled or some raster ops */
            if (rgbmode) {
	       USE(smooth_rgba_triangle);
            }
            else {
               USE(smooth_ci_triangle);
            }
	 }
	 else {
	    /* flat shaded, no texturing, stippled or some raster ops */
            if (rgbmode) {
	       USE(flat_rgba_triangle);
            }
            else {
               USE(flat_ci_triangle);
            }
	 }
      }
   }
   else if (ctx->RenderMode==GL_FEEDBACK) {
      USE(_swrast_feedback_triangle);
   }
   else {
      /* GL_SELECT mode */
      USE(_swrast_select_triangle);
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -