📄 s_span.c
字号:
#endif /* we have to wait until after occlusion to do this test */ if (ctx->Color.IndexMask == 0) { /* write no pixels */ span->arrayMask = origArrayMask; return; } /* Interpolate the color indexes if needed */ if (swrast->_FogEnabled || ctx->Color.IndexLogicOpEnabled || ctx->Color.IndexMask != 0xffffffff || (span->arrayMask & SPAN_COVERAGE)) { if (!(span->arrayMask & SPAN_INDEX) /*span->interpMask & SPAN_INDEX*/) { interpolate_indexes(ctx, span); } } /* Fog */ if (swrast->_FogEnabled) { _swrast_fog_ci_span(ctx, span); } /* Antialias coverage application */ if (span->arrayMask & SPAN_COVERAGE) { const GLfloat *coverage = span->array->coverage; GLuint *index = span->array->index; GLuint i; for (i = 0; i < span->end; i++) { ASSERT(coverage[i] < 16); index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]); } } /* * Write to renderbuffers */ { const GLuint numBuffers = fb->_NumColorDrawBuffers; GLuint buf; for (buf = 0; buf < numBuffers; buf++) { struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf]; GLuint indexSave[MAX_WIDTH]; ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); if (numBuffers > 1) { /* save indexes for second, third renderbuffer writes */ _mesa_memcpy(indexSave, span->array->index, span->end * sizeof(indexSave[0])); } if (ctx->Color.IndexLogicOpEnabled) { _swrast_logicop_ci_span(ctx, rb, span); } if (ctx->Color.IndexMask != 0xffffffff) { _swrast_mask_ci_span(ctx, rb, span); } if (!(span->arrayMask & SPAN_INDEX) && span->indexStep == 0) { /* all fragments have same color index */ GLubyte index8; GLushort index16; GLuint index32; void *value; if (rb->DataType == GL_UNSIGNED_BYTE) { index8 = FixedToInt(span->index); value = &index8; } else if (rb->DataType == GL_UNSIGNED_SHORT) { index16 = FixedToInt(span->index); value = &index16; } else { ASSERT(rb->DataType == GL_UNSIGNED_INT); index32 = FixedToInt(span->index); value = &index32; } if (span->arrayMask & SPAN_XY) { rb->PutMonoValues(ctx, rb, span->end, span->array->x, span->array->y, value, span->array->mask); } else { rb->PutMonoRow(ctx, rb, span->end, span->x, span->y, value, span->array->mask); } } else { /* each fragment is a different color */ GLubyte index8[MAX_WIDTH]; GLushort index16[MAX_WIDTH]; void *values; if (rb->DataType == GL_UNSIGNED_BYTE) { GLuint k; for (k = 0; k < span->end; k++) { index8[k] = (GLubyte) span->array->index[k]; } values = index8; } else if (rb->DataType == GL_UNSIGNED_SHORT) { GLuint k; for (k = 0; k < span->end; k++) { index16[k] = (GLushort) span->array->index[k]; } values = index16; } else { ASSERT(rb->DataType == GL_UNSIGNED_INT); values = span->array->index; } if (span->arrayMask & SPAN_XY) { rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y, values, span->array->mask); } else { rb->PutRow(ctx, rb, span->end, span->x, span->y, values, span->array->mask); } } if (buf + 1 < numBuffers) { /* restore original span values */ _mesa_memcpy(span->array->index, indexSave, span->end * sizeof(indexSave[0])); } } /* for buf */ } span->interpMask = origInterpMask; span->arrayMask = origArrayMask;}/** * Add specular colors to primary colors. * Only called during fixed-function operation. * Result is float color array (FRAG_ATTRIB_COL0). */static INLINE voidadd_specular(GLcontext *ctx, SWspan *span){ const SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLubyte *mask = span->array->mask; GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; GLuint i; ASSERT(!ctx->FragmentProgram._Current); ASSERT(span->arrayMask & SPAN_RGBA); ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1); if (span->array->ChanType == GL_FLOAT) { if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); } } else { /* need float colors */ if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { interpolate_float_colors(span); } } if ((span->arrayAttribs & FRAG_BIT_COL1) == 0) { /* XXX could avoid this and interpolate COL1 in the loop below */ interpolate_active_attribs(ctx, span, FRAG_BIT_COL1); } ASSERT(span->arrayAttribs & FRAG_BIT_COL0); ASSERT(span->arrayAttribs & FRAG_BIT_COL1); for (i = 0; i < span->end; i++) { if (mask[i]) { col0[i][0] += col1[i][0]; col0[i][1] += col1[i][1]; col0[i][2] += col1[i][2]; } } span->array->ChanType = GL_FLOAT;}/** * Apply antialiasing coverage value to alpha values. */static INLINE voidapply_aa_coverage(SWspan *span){ const GLfloat *coverage = span->array->coverage; GLuint i; if (span->array->ChanType == GL_UNSIGNED_BYTE) { GLubyte (*rgba)[4] = span->array->rgba8; for (i = 0; i < span->end; i++) { const GLfloat a = rgba[i][ACOMP] * coverage[i]; rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0); ASSERT(coverage[i] >= 0.0); ASSERT(coverage[i] <= 1.0); } } else if (span->array->ChanType == GL_UNSIGNED_SHORT) { GLushort (*rgba)[4] = span->array->rgba16; for (i = 0; i < span->end; i++) { const GLfloat a = rgba[i][ACOMP] * coverage[i]; rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0); } } else { GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; for (i = 0; i < span->end; i++) { rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i]; /* clamp later */ } }}/** * Clamp span's float colors to [0,1] */static INLINE voidclamp_colors(SWspan *span){ GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; GLuint i; ASSERT(span->array->ChanType == GL_FLOAT); for (i = 0; i < span->end; i++) { rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); }}/** * Convert the span's color arrays to the given type. * The only way 'output' can be greater than zero is when we have a fragment * program that writes to gl_FragData[1] or higher. * \param output which fragment program color output is being processed */static INLINE voidconvert_color_type(SWspan *span, GLenum newType, GLuint output){ GLvoid *src, *dst; if (output > 0 || span->array->ChanType == GL_FLOAT) { src = span->array->attribs[FRAG_ATTRIB_COL0 + output]; span->array->ChanType = GL_FLOAT; } else if (span->array->ChanType == GL_UNSIGNED_BYTE) { src = span->array->rgba8; } else { ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT); src = span->array->rgba16; } if (newType == GL_UNSIGNED_BYTE) { dst = span->array->rgba8; } else if (newType == GL_UNSIGNED_SHORT) { dst = span->array->rgba16; } else { dst = span->array->attribs[FRAG_ATTRIB_COL0]; } _mesa_convert_colors(span->array->ChanType, src, newType, dst, span->end, span->array->mask); span->array->ChanType = newType; span->array->rgba = dst;}/** * Apply fragment shader, fragment program or normal texturing to span. */static INLINE voidshade_texture_span(GLcontext *ctx, SWspan *span){ GLbitfield inputsRead; /* Determine which fragment attributes are actually needed */ if (ctx->FragmentProgram._Current) { inputsRead = ctx->FragmentProgram._Current->Base.InputsRead; } else { /* XXX we could be a bit smarter about this */ inputsRead = ~0; } if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { /* programmable shading */ if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) { convert_color_type(span, GL_FLOAT, 0); } if (span->primitive != GL_POINT || (span->interpMask & SPAN_RGBA) || ctx->Point.PointSprite) { /* for single-pixel points, we populated the arrays already */ interpolate_active_attribs(ctx, span, ~0); } span->array->ChanType = GL_FLOAT; if (!(span->arrayMask & SPAN_Z)) _swrast_span_interpolate_z (ctx, span);#if 0 if (inputsRead & FRAG_BIT_WPOS)#else /* XXX always interpolate wpos so that DDX/DDY work */#endif interpolate_wpos(ctx, span); /* Run fragment program/shader now */ if (ctx->FragmentProgram._Current) { _swrast_exec_fragment_program(ctx, span); } else { ASSERT(ctx->ATIFragmentShader._Enabled); _swrast_exec_fragment_shader(ctx, span); } } else if (ctx->Texture._EnabledUnits) { /* conventional texturing */#if CHAN_BITS == 32 if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { interpolate_int_colors(ctx, span); }#else if (!(span->arrayMask & SPAN_RGBA)) interpolate_int_colors(ctx, span);#endif if ((span->arrayAttribs & FRAG_BITS_TEX_ANY) == 0x0) interpolate_texcoords(ctx, span); _swrast_texture_span(ctx, span); }}/** * Apply all the per-fragment operations to a span. * This now includes texturing (_swrast_write_texture_span() is history). * This function may modify any of the array values in the span. * span->interpMask and span->arrayMask may be changed but will be restored * to their original values before returning. */void_swrast_write_rgba_span( GLcontext *ctx, SWspan *span){ const SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); const GLbitfield origInterpMask = span->interpMask; const GLbitfield origArrayMask = span->arrayMask; const GLbitfield origArrayAttribs = span->arrayAttribs; const GLenum origChanType = span->array->ChanType; void * const origRgba = span->array->rgba; const GLboolean shader = (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled); const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits; struct gl_framebuffer *fb = ctx->DrawBuffer; /* printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask); */ ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); ASSERT(span->end <= MAX_WIDTH); /* Fragment write masks */ if (span->arrayMask & SPAN_MASK) { /* mask was initialized by caller, probably glBitmap */ span->writeAll = GL_FALSE; } else { _mesa_memset(span->array->mask, 1, span->end); span->writeAll = GL_TRUE; } /* Clip to window/scissor box */ if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { if (!clip_span(ctx, span)) { return; } }#ifdef DEBUG /* Make sure all fragments are within window bounds */ if (span->arrayMask & SPAN_XY) { GLuint i; for (i = 0; i < span->end; i++) { if (span->array->mask[i]) { assert(span->array->x[i] >= fb->_Xmin); assert(span->array->x[i] < fb->_Xmax); assert(span->array->y[i] >= fb->_Ymin); assert(span->array->y[i] < fb->_Ymax); } } }#endif /* Polygon Stippling */ if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { stipple_polygon_span(ctx, span); } /* This is the normal place to compute the fragment color/Z * from texturing or shading. */ if (shaderOrTexture && !swrast->_DeferredTexture) { shade_texture_span(ctx, span); } /* Do the alpha test */ if (ctx->Color.AlphaEnabled) { if (!_swrast_alpha_test(ctx, span)) { goto end; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -