📄 s_span.c
字号:
/* * Mesa 3-D graphics library * Version: 7.1 * * Copyright (C) 1999-2007 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. *//** * \file swrast/s_span.c * \brief Span processing functions used by all rasterization functions. * This is where all the per-fragment tests are performed * \author Brian Paul */#include "glheader.h"#include "colormac.h"#include "context.h"#include "macros.h"#include "imports.h"#include "image.h"#include "s_atifragshader.h"#include "s_alpha.h"#include "s_blend.h"#include "s_context.h"#include "s_depth.h"#include "s_fog.h"#include "s_logic.h"#include "s_masking.h"#include "s_fragprog.h"#include "s_span.h"#include "s_stencil.h"#include "s_texcombine.h"/** * Set default fragment attributes for the span using the * current raster values. Used prior to glDraw/CopyPixels * and glBitmap. */void_swrast_span_default_attribs(GLcontext *ctx, SWspan *span){ /* Z*/ { const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; if (ctx->DrawBuffer->Visual.depthBits <= 16) span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); else { GLfloat tmpf = ctx->Current.RasterPos[2] * depthMax; tmpf = MIN2(tmpf, depthMax); span->z = (GLint)tmpf; } span->zStep = 0; span->interpMask |= SPAN_Z; } /* W (for perspective correction) */ span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0; span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0; span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0; /* primary color, or color index */ if (ctx->Visual.rgbMode) { GLchan r, g, b, a; UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]);#if CHAN_TYPE == GL_FLOAT span->red = r; span->green = g; span->blue = b; span->alpha = a;#else span->red = IntToFixed(r); span->green = IntToFixed(g); span->blue = IntToFixed(b); span->alpha = IntToFixed(a);#endif span->redStep = 0; span->greenStep = 0; span->blueStep = 0; span->alphaStep = 0; span->interpMask |= SPAN_RGBA; COPY_4V(span->attrStart[FRAG_ATTRIB_COL0], ctx->Current.RasterColor); ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0); ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0); } else { span->index = FloatToFixed(ctx->Current.RasterIndex); span->indexStep = 0; span->interpMask |= SPAN_INDEX; } /* Secondary color */ if (ctx->Visual.rgbMode && (ctx->Light.Enabled || ctx->Fog.ColorSumEnabled)) { COPY_4V(span->attrStart[FRAG_ATTRIB_COL1], ctx->Current.RasterSecondaryColor); ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0); ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0); } /* fog */ { const SWcontext *swrast = SWRAST_CONTEXT(ctx); GLfloat fogVal; /* a coord or a blend factor */ if (swrast->_PreferPixelFog) { /* fog blend factors will be computed from fog coordinates per pixel */ fogVal = ctx->Current.RasterDistance; } else { /* fog blend factor should be computed from fogcoord now */ fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); } span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal; span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; } /* texcoords */ { GLuint i; for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { const GLuint attr = FRAG_ATTRIB_TEX0 + i; const GLfloat *tc = ctx->Current.RasterTexCoords[i]; if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { COPY_4V(span->attrStart[attr], tc); } else if (tc[3] > 0.0F) { /* use (s/q, t/q, r/q, 1) */ span->attrStart[attr][0] = tc[0] / tc[3]; span->attrStart[attr][1] = tc[1] / tc[3]; span->attrStart[attr][2] = tc[2] / tc[3]; span->attrStart[attr][3] = 1.0; } else { ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F); } ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F); ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F); } }}/** * Interpolate the active attributes (and'd with attrMask) to * fill in span->array->attribs[]. * Perspective correction will be done. The point/line/triangle function * should have computed attrStart/Step values for FRAG_ATTRIB_WPOS[3]! */static INLINE voidinterpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask){ const SWcontext *swrast = SWRAST_CONTEXT(ctx); /* * Don't overwrite existing array values, such as colors that may have * been produced by glDraw/CopyPixels. */ attrMask &= ~span->arrayAttribs; ATTRIB_LOOP_BEGIN if (attrMask & (1 << attr)) { const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; const GLfloat dv0dx = span->attrStepX[attr][0]; const GLfloat dv1dx = span->attrStepX[attr][1]; const GLfloat dv2dx = span->attrStepX[attr][2]; const GLfloat dv3dx = span->attrStepX[attr][3]; GLfloat v0 = span->attrStart[attr][0]; GLfloat v1 = span->attrStart[attr][1]; GLfloat v2 = span->attrStart[attr][2]; GLfloat v3 = span->attrStart[attr][3]; GLuint k; for (k = 0; k < span->end; k++) { const GLfloat invW = 1.0f / w; span->array->attribs[attr][k][0] = v0 * invW; span->array->attribs[attr][k][1] = v1 * invW; span->array->attribs[attr][k][2] = v2 * invW; span->array->attribs[attr][k][3] = v3 * invW; v0 += dv0dx; v1 += dv1dx; v2 += dv2dx; v3 += dv3dx; w += dwdx; } ASSERT((span->arrayAttribs & (1 << attr)) == 0); span->arrayAttribs |= (1 << attr); } ATTRIB_LOOP_END}/** * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16) * color array. */static INLINE voidinterpolate_int_colors(GLcontext *ctx, SWspan *span){ const GLuint n = span->end; GLuint i;#if CHAN_BITS != 32 ASSERT(!(span->arrayMask & SPAN_RGBA));#endif switch (span->array->ChanType) {#if CHAN_BITS != 32 case GL_UNSIGNED_BYTE: { GLubyte (*rgba)[4] = span->array->rgba8; if (span->interpMask & SPAN_FLAT) { GLubyte color[4]; color[RCOMP] = FixedToInt(span->red); color[GCOMP] = FixedToInt(span->green); color[BCOMP] = FixedToInt(span->blue); color[ACOMP] = FixedToInt(span->alpha); for (i = 0; i < n; i++) { COPY_4UBV(rgba[i], color); } } else { GLfixed r = span->red; GLfixed g = span->green; GLfixed b = span->blue; GLfixed a = span->alpha; GLint dr = span->redStep; GLint dg = span->greenStep; GLint db = span->blueStep; GLint da = span->alphaStep; for (i = 0; i < n; i++) { rgba[i][RCOMP] = FixedToChan(r); rgba[i][GCOMP] = FixedToChan(g); rgba[i][BCOMP] = FixedToChan(b); rgba[i][ACOMP] = FixedToChan(a); r += dr; g += dg; b += db; a += da; } } } break; case GL_UNSIGNED_SHORT: { GLushort (*rgba)[4] = span->array->rgba16; if (span->interpMask & SPAN_FLAT) { GLushort color[4]; color[RCOMP] = FixedToInt(span->red); color[GCOMP] = FixedToInt(span->green); color[BCOMP] = FixedToInt(span->blue); color[ACOMP] = FixedToInt(span->alpha); for (i = 0; i < n; i++) { COPY_4V(rgba[i], color); } } else { GLushort (*rgba)[4] = span->array->rgba16; GLfixed r, g, b, a; GLint dr, dg, db, da; r = span->red; g = span->green; b = span->blue; a = span->alpha; dr = span->redStep; dg = span->greenStep; db = span->blueStep; da = span->alphaStep; for (i = 0; i < n; i++) { rgba[i][RCOMP] = FixedToChan(r); rgba[i][GCOMP] = FixedToChan(g); rgba[i][BCOMP] = FixedToChan(b); rgba[i][ACOMP] = FixedToChan(a); r += dr; g += dg; b += db; a += da; } } } break;#endif case GL_FLOAT: interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); break; default: _mesa_problem(NULL, "bad datatype in interpolate_int_colors"); } span->arrayMask |= SPAN_RGBA;}/** * Populate the FRAG_ATTRIB_COL0 array. */static INLINE voidinterpolate_float_colors(SWspan *span){ GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; const GLuint n = span->end; GLuint i; assert(!(span->arrayAttribs & FRAG_BIT_COL0)); if (span->arrayMask & SPAN_RGBA) { /* convert array of int colors */ for (i = 0; i < n; i++) { col0[i][0] = UBYTE_TO_FLOAT(span->array->rgba8[i][0]); col0[i][1] = UBYTE_TO_FLOAT(span->array->rgba8[i][1]); col0[i][2] = UBYTE_TO_FLOAT(span->array->rgba8[i][2]); col0[i][3] = UBYTE_TO_FLOAT(span->array->rgba8[i][3]); } } else { /* interpolate red/green/blue/alpha to get float colors */ ASSERT(span->interpMask & SPAN_RGBA); if (span->interpMask & SPAN_FLAT) { GLfloat r = FixedToFloat(span->red); GLfloat g = FixedToFloat(span->green); GLfloat b = FixedToFloat(span->blue); GLfloat a = FixedToFloat(span->alpha); for (i = 0; i < n; i++) { ASSIGN_4V(col0[i], r, g, b, a); } } else { GLfloat r = FixedToFloat(span->red); GLfloat g = FixedToFloat(span->green); GLfloat b = FixedToFloat(span->blue); GLfloat a = FixedToFloat(span->alpha); GLfloat dr = FixedToFloat(span->redStep); GLfloat dg = FixedToFloat(span->greenStep); GLfloat db = FixedToFloat(span->blueStep); GLfloat da = FixedToFloat(span->alphaStep); for (i = 0; i < n; i++) { col0[i][0] = r; col0[i][1] = g; col0[i][2] = b; col0[i][3] = a; r += dr; g += dg; b += db; a += da; } } } span->arrayAttribs |= FRAG_BIT_COL0; span->array->ChanType = GL_FLOAT;}/* Fill in the span.color.index array from the interpolation values */static INLINE voidinterpolate_indexes(GLcontext *ctx, SWspan *span){ GLfixed index = span->index; const GLint indexStep = span->indexStep; const GLuint n = span->end; GLuint *indexes = span->array->index; GLuint i; (void) ctx; ASSERT(!(span->arrayMask & SPAN_INDEX)); if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) { /* constant color */ index = FixedToInt(index); for (i = 0; i < n; i++) { indexes[i] = index; } } else { /* interpolate */ for (i = 0; i < n; i++) { indexes[i] = FixedToInt(index); index += indexStep; } } span->arrayMask |= SPAN_INDEX; span->interpMask &= ~SPAN_INDEX;}/** * Fill in the span.zArray array from the span->z, zStep values. */void_swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span ){ const GLuint n = span->end; GLuint i; ASSERT(!(span->arrayMask & SPAN_Z)); if (ctx->DrawBuffer->Visual.depthBits <= 16) { GLfixed zval = span->z; GLuint *z = span->array->z; for (i = 0; i < n; i++) { z[i] = FixedToInt(zval); zval += span->zStep; } } else { /* Deep Z buffer, no fixed->int shift */ GLuint zval = span->z; GLuint *z = span->array->z; for (i = 0; i < n; i++) { z[i] = zval; zval += span->zStep; } } span->interpMask &= ~SPAN_Z; span->arrayMask |= SPAN_Z;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -