📄 s_span.c
字号:
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; } /* Clipping */ if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { if (!clip_span(ctx, span)) { return; } } /* Depth bounds test */ if (ctx->Depth.BoundsTest && ctx->DrawBuffer->Visual.depthBits > 0) { if (!_swrast_depth_bounds_test(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] >= ctx->DrawBuffer->_Xmin); assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); } } }#endif /* Polygon Stippling */ if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { stipple_polygon_span(ctx, span); } /* Stencil and Z testing */ if (ctx->Depth.Test || ctx->Stencil.Enabled) { if (span->interpMask & SPAN_Z) _swrast_span_interpolate_z(ctx, span); if (ctx->Stencil.Enabled) { if (!_swrast_stencil_and_ztest_span(ctx, span)) { span->arrayMask = origArrayMask; return; } } else { ASSERT(ctx->Depth.Test); if (!_swrast_depth_test_span(ctx, span)) { span->interpMask = origInterpMask; span->arrayMask = origArrayMask; return; } } }#if FEATURE_ARB_occlusion_query if (ctx->Query.CurrentOcclusionObject) { /* update count of 'passed' fragments */ struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; GLuint i; for (i = 0; i < span->end; i++) q->Result += span->array->mask[i]; }#endif /* we have to wait until after occlusion to do this test */ if (ctx->Color.DrawBuffer == GL_NONE || 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->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]); } } /* Loop over drawing buffers */ for (buf = 0; buf < fb->_NumColorDrawBuffers[output]; buf++) { struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; GLuint indexTemp[MAX_WIDTH], *index32; ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); if (ctx->Color.IndexLogicOpEnabled || ctx->Color.IndexMask != 0xffffffff) { /* make copy of incoming indexes */ MEMCPY(indexTemp, span->array->index, span->end * sizeof(GLuint)); if (ctx->Color.IndexLogicOpEnabled) { _swrast_logicop_ci_span(ctx, rb, span, indexTemp); } if (ctx->Color.IndexMask != 0xffffffff) { _swrast_mask_ci_span(ctx, rb, span, indexTemp); } index32 = indexTemp; } else { index32 = span->array->index; } if ((span->interpMask & 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) index32[k]; } values = index8; } else if (rb->DataType == GL_UNSIGNED_SHORT) { GLuint k; for (k = 0; k < span->end; k++) { index16[k] = (GLushort) index32[k]; } values = index16; } else { ASSERT(rb->DataType == GL_UNSIGNED_INT); values = index32; } 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); } } } span->interpMask = origInterpMask; span->arrayMask = origArrayMask;}/** * Add specular color to base color. This is used only when * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. */static voidadd_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] ){ GLuint i; for (i = 0; i < n; i++) {#if CHAN_TYPE == GL_FLOAT /* no clamping */ rgba[i][RCOMP] += specular[i][RCOMP]; rgba[i][GCOMP] += specular[i][GCOMP]; rgba[i][BCOMP] += specular[i][BCOMP];#else GLint r = rgba[i][RCOMP] + specular[i][RCOMP]; GLint g = rgba[i][GCOMP] + specular[i][GCOMP]; GLint b = rgba[i][BCOMP] + specular[i][BCOMP]; rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);#endif }}/** * XXX merge this code into the _swrast_write_rgba_span() routine! * * Draw to more than one RGBA color buffer (or none). * All fragment operations, up to (but not) blending/logicop should * have been done first. */static voidmulti_write_rgba_span( GLcontext *ctx, struct sw_span *span ){ const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); struct gl_framebuffer *fb = ctx->DrawBuffer; const GLuint output = 0; GLuint i; ASSERT(span->end < MAX_WIDTH); ASSERT(colorMask != 0x0); for (i = 0; i < fb->_NumColorDrawBuffers[output]; i++) { struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][i]; GLchan rgbaTmp[MAX_WIDTH][4]; /* make copy of incoming colors */ MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) ); if (ctx->Color._LogicOpEnabled) { _swrast_logicop_rgba_span(ctx, rb, span, rgbaTmp); } else if (ctx->Color.BlendEnabled) { _swrast_blend_span(ctx, rb, span, rgbaTmp); } if (colorMask != 0xffffffff) { _swrast_mask_rgba_span(ctx, rb, span, rgbaTmp); } if (span->arrayMask & SPAN_XY) { /* array of pixel coords */ ASSERT(rb->PutValues); rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y, rgbaTmp, span->array->mask); } else { /* horizontal run of pixels */ ASSERT(rb->PutRow); rb->PutRow(ctx, rb, span->end, span->x, span->y, rgbaTmp, span->array->mask); } }}/** * 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, struct sw_span *span){ const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLbitfield origInterpMask = span->interpMask; const GLbitfield origArrayMask = span->arrayMask; const GLboolean deferredTexture = !(ctx->Color.AlphaEnabled || ctx->FragmentProgram._Active || ctx->ShaderObjects._FragmentShaderPresent); ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); ASSERT(span->end <= MAX_WIDTH); ASSERT((span->interpMask & span->arrayMask) == 0); /* printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask); */ 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] >= ctx->DrawBuffer->_Xmin); assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); } } }#endif /* Polygon Stippling */ if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) { stipple_polygon_span(ctx, span); } /* Interpolate texcoords? */ if (ctx->Texture._EnabledCoordUnits && (span->interpMask & SPAN_TEXTURE) && (span->arrayMask & SPAN_TEXTURE) == 0) { interpolate_texcoords(ctx, span); } /* This is the normal place to compute the resulting fragment color/Z. * As an optimization, we try to defer this until after Z/stencil * testing in order to try to avoid computing colors that we won't * actually need. */ if (!deferredTexture) { /* Now we need the rgba array, fill it in if needed */ if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) interpolate_colors(ctx, span); if (span->interpMask & SPAN_SPEC) interpolate_specular(ctx, span); if (span->interpMask & SPAN_FOG) interpolate_fog(ctx, span); /* Compute fragment colors with fragment program or texture lookups */
if (ctx->ShaderObjects._FragmentShaderPresent) {
if (span->interpMask & SPAN_Z)
_swrast_span_interpolate_z (ctx, span);
_swrast_exec_arbshader (ctx, span);
} else if (ctx->FragmentProgram._Active) { /* frag prog may need Z values */ if (span->interpMask & SPAN_Z) _swrast_span_interpolate_z(ctx, span); _swrast_exec_fragment_program( ctx, span ); } else if (ctx->ATIFragmentShader._Enabled) _swrast_exec_fragment_shader( ctx, span ); else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) _swrast_texture_span( ctx, span ); /* Do the alpha test */ if (ctx->Color.AlphaEnabled) { if (!_swrast_alpha_test(ctx, span)) { span->arrayMask = origArrayMask; return; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -