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

📄 s_context.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Mesa 3-D graphics library
 * Version:  6.3
 *
 * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *    Keith Whitwell <keith@tungstengraphics.com>
 *    Brian Paul
 */

#include "imports.h"
#include "bufferobj.h"
#include "context.h"
#include "colormac.h"
#include "mtypes.h"
#include "program.h"
#include "texobj.h"
#include "nvfragprog.h"

#include "swrast.h"
#include "s_blend.h"
#include "s_context.h"
#include "s_lines.h"
#include "s_points.h"
#include "s_span.h"
#include "s_triangle.h"
#include "s_texture.h"


/**
 * Recompute the value of swrast->_RasterMask, etc. according to
 * the current context.  The _RasterMask field can be easily tested by
 * drivers to determine certain basic GL state (does the primitive need
 * stenciling, logic-op, fog, etc?).
 */
static void
_swrast_update_rasterflags( GLcontext *ctx )
{
   GLuint rasterMask = 0;

   if (ctx->Color.AlphaEnabled)           rasterMask |= ALPHATEST_BIT;
   if (ctx->Color.BlendEnabled)           rasterMask |= BLEND_BIT;
   if (ctx->Depth.Test)                   rasterMask |= DEPTH_BIT;
   if (ctx->Fog.Enabled)                  rasterMask |= FOG_BIT;
   if (ctx->Scissor.Enabled)              rasterMask |= CLIP_BIT;
   if (ctx->Stencil.Enabled)              rasterMask |= STENCIL_BIT;
   if (ctx->Visual.rgbMode) {
      const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
      if (colorMask != 0xffffffff)        rasterMask |= MASKING_BIT;
      if (ctx->Color._LogicOpEnabled)     rasterMask |= LOGIC_OP_BIT;
      if (ctx->Texture._EnabledUnits)     rasterMask |= TEXTURE_BIT;
   }
   else {
      if (ctx->Color.IndexMask != 0xffffffff) rasterMask |= MASKING_BIT;
      if (ctx->Color.IndexLogicOpEnabled)     rasterMask |= LOGIC_OP_BIT;
   }

   if (   ctx->Viewport.X < 0
       || ctx->Viewport.X + ctx->Viewport.Width > (GLint) ctx->DrawBuffer->Width
       || ctx->Viewport.Y < 0
       || ctx->Viewport.Y + ctx->Viewport.Height > (GLint) ctx->DrawBuffer->Height) {
      rasterMask |= CLIP_BIT;
   }

   if (ctx->Depth.OcclusionTest || ctx->Occlusion.Active)
      rasterMask |= OCCLUSION_BIT;


   /* If we're not drawing to exactly one color buffer set the
    * MULTI_DRAW_BIT flag.  Also set it if we're drawing to no
    * buffers or the RGBA or CI mask disables all writes.
    */
   if (ctx->DrawBuffer->_NumColorDrawBuffers[0] != 1) {
      /* more than one color buffer designated for writing (or zero buffers) */
      rasterMask |= MULTI_DRAW_BIT;
   }
   else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) {
      rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */
   }
   else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) {
      rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */
   }

   if (ctx->FragmentProgram._Active) {
      rasterMask |= FRAGPROG_BIT;
   }

   if (ctx->ATIFragmentShader._Enabled) {
      rasterMask |= ATIFRAGSHADER_BIT;
   }

   SWRAST_CONTEXT(ctx)->_RasterMask = rasterMask;
}


/**
 * Examine polycon culls tate to compute the _BackfaceSign field.
 * _BackfaceSign will be 0 if no culling, -1 if culling back-faces,
 * and 1 if culling front-faces.  The Polygon FrontFace state also
 * factors in.
 */
static void
_swrast_update_polygon( GLcontext *ctx )
{
   GLfloat backface_sign = 1;

   if (ctx->Polygon.CullFlag) {
      backface_sign = 1;
      switch(ctx->Polygon.CullFaceMode) {
      case GL_BACK:
	 if(ctx->Polygon.FrontFace==GL_CCW)
	    backface_sign = -1;
	 break;
      case GL_FRONT:
	 if(ctx->Polygon.FrontFace!=GL_CCW)
	    backface_sign = -1;
	 break;
      default:
      case GL_FRONT_AND_BACK:
	 backface_sign = 0;
	 break;
      }
   }
   else {
      backface_sign = 0;
   }

   SWRAST_CONTEXT(ctx)->_BackfaceSign = backface_sign;
}


/**
 * Update the _PreferPixelFog field to indicate if we need to compute
 * fog factors per-fragment.
 */
static void
_swrast_update_fog_hint( GLcontext *ctx )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||
                              ctx->FragmentProgram._Enabled || /* not _Active! */
			      (ctx->Hint.Fog == GL_NICEST &&
			       swrast->AllowPixelFog));
}



/**
 * Update the swrast->_AnyTextureCombine flag.
 */
static void
_swrast_update_texture_env( GLcontext *ctx )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLuint i;
   swrast->_AnyTextureCombine = GL_FALSE;
   for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
      if (ctx->Texture.Unit[i].EnvMode == GL_COMBINE_EXT ||
          ctx->Texture.Unit[i].EnvMode == GL_COMBINE4_NV) {
         swrast->_AnyTextureCombine = GL_TRUE;
         return;
      }
   }
}


/**
 * Update swrast->_FogColor and swrast->_FogEnable values.
 */
static void
_swrast_update_fog_state( GLcontext *ctx )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   /* convert fog color to GLchan values */
   CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[RCOMP], ctx->Fog.Color[RCOMP]);
   CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[GCOMP], ctx->Fog.Color[GCOMP]);
   CLAMPED_FLOAT_TO_CHAN(swrast->_FogColor[BCOMP], ctx->Fog.Color[BCOMP]);

   /* determine if fog is needed, and if so, which fog mode */
   swrast->_FogEnabled = GL_FALSE;
   if (ctx->FragmentProgram._Active) {
      if (ctx->FragmentProgram._Current->Base.Target==GL_FRAGMENT_PROGRAM_ARB) {
         const struct fragment_program *p
            = (struct fragment_program *) ctx->FragmentProgram._Current;
         if (p->FogOption != GL_NONE) {
            swrast->_FogEnabled = GL_TRUE;
            swrast->_FogMode = p->FogOption;
         }
      }
   }
   else if (ctx->Fog.Enabled) {
      swrast->_FogEnabled = GL_TRUE;
      swrast->_FogMode = ctx->Fog.Mode;
   }
}


/**
 * Update state for running fragment programs.  Basically, load the
 * program parameters with current state values.
 */
static void
_swrast_update_fragment_program( GLcontext *ctx )
{
   if (ctx->FragmentProgram._Active) {
      struct fragment_program *program = ctx->FragmentProgram._Current;
      _mesa_load_state_parameters(ctx, program->Parameters);
   }
}



#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK |	\
			     _NEW_TEXTURE |		\
			     _NEW_HINT |		\
			     _NEW_POLYGON )

/* State referenced by _swrast_choose_triangle, _swrast_choose_line.
 */
#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED |		\
			      _NEW_RENDERMODE|			\
                              _NEW_POLYGON|			\
                              _NEW_DEPTH|			\
                              _NEW_STENCIL|			\
                              _NEW_COLOR|			\
                              _NEW_TEXTURE|			\
                              _SWRAST_NEW_RASTERMASK|		\
                              _NEW_LIGHT|			\
                              _NEW_FOG |			\
			      _DD_NEW_SEPARATE_SPECULAR)

#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED |		\
			  _NEW_RENDERMODE|		\
                          _NEW_LINE|			\
                          _NEW_TEXTURE|			\
                          _NEW_LIGHT|			\
                          _NEW_FOG|			\
                          _NEW_DEPTH |			\
                          _DD_NEW_SEPARATE_SPECULAR)

#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED |	\
			   _NEW_RENDERMODE |		\
			   _NEW_POINT |			\
			   _NEW_TEXTURE |		\
			   _NEW_LIGHT |			\
			   _NEW_FOG |			\
                           _DD_NEW_SEPARATE_SPECULAR)

#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE

#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE

#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR



/**
 * Stub for swrast->Triangle to select a true triangle function
 * after a state change.
 */
static void
_swrast_validate_triangle( GLcontext *ctx,
			   const SWvertex *v0,
                           const SWvertex *v1,
                           const SWvertex *v2 )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );
   swrast->choose_triangle( ctx );

   if (ctx->Texture._EnabledUnits == 0
       && NEED_SECONDARY_COLOR(ctx)
       && !ctx->FragmentProgram._Active) {
      /* separate specular color, but no texture */
      swrast->SpecTriangle = swrast->Triangle;
      swrast->Triangle = _swrast_add_spec_terms_triangle;
   }

   swrast->Triangle( ctx, v0, v1, v2 );
}

/**
 * Called via swrast->Line.  Examine current GL state and choose a software
 * line routine.  Then call it.
 */
static void
_swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );
   swrast->choose_line( ctx );

   if (ctx->Texture._EnabledUnits == 0
       && NEED_SECONDARY_COLOR(ctx)
       && !ctx->FragmentProgram._Active) {
      swrast->SpecLine = swrast->Line;
      swrast->Line = _swrast_add_spec_terms_line;
   }


   swrast->Line( ctx, v0, v1 );
}

/**
 * Called via swrast->Point.  Examine current GL state and choose a software
 * point routine.  Then call it.
 */
static void
_swrast_validate_point( GLcontext *ctx, const SWvertex *v0 )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );
   swrast->choose_point( ctx );

   if (ctx->Texture._EnabledUnits == 0
       && NEED_SECONDARY_COLOR(ctx)
       && !ctx->FragmentProgram._Active) {
      swrast->SpecPoint = swrast->Point;
      swrast->Point = _swrast_add_spec_terms_point;
   }

   swrast->Point( ctx, v0 );
}


/**
 * Called via swrast->BlendFunc.  Examine GL state to choose a blending
 * function, then call it.
 */
static void _ASMAPI
_swrast_validate_blend_func( GLcontext *ctx, GLuint n,
			     const GLubyte mask[],
			     GLchan src[][4],
			     CONST GLchan dst[][4] )
{
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   _swrast_validate_derived( ctx );
   _swrast_choose_blend_func( ctx );

   swrast->BlendFunc( ctx, n, mask, src, dst );
}


/**
 * Called via the swrast->TextureSample[i] function pointer.
 * Basically, given a texture object, an array of texture coords
 * and an array of level-of-detail values, return an array of colors.
 * In this case, determine the correct texture sampling routine
 * (depending on filter mode, texture dimensions, etc) then call the
 * sampler routine.
 */
static void

⌨️ 快捷键说明

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