📄 s_span.c
字号:
} /* Stencil and Z testing */ if (ctx->Stencil.Enabled || ctx->Depth.Test) { if (!(span->arrayMask & SPAN_Z)) _swrast_span_interpolate_z(ctx, span); if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) { /* Combined Z/stencil tests */ if (!_swrast_stencil_and_ztest_span(ctx, span)) { goto end; } } else if (fb->Visual.depthBits > 0) { /* Just regular depth testing */ ASSERT(ctx->Depth.Test); ASSERT(span->arrayMask & SPAN_Z); if (!_swrast_depth_test_span(ctx, span)) { goto end; } } }#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 had to wait until now to check for glColorMask(0,0,0,0) because of * the occlusion test. */ if (colorMask == 0x0) { goto end; } /* If we were able to defer fragment color computation to now, there's * a good chance that many fragments will have already been killed by * Z/stencil testing. */ if (shaderOrTexture && swrast->_DeferredTexture) { shade_texture_span(ctx, span); }#if CHAN_BITS == 32 if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); }#else if ((span->arrayMask & SPAN_RGBA) == 0) { interpolate_int_colors(ctx, span); }#endif ASSERT(span->arrayMask & SPAN_RGBA); if (!shader) { /* Add base and specular colors */ if (ctx->Fog.ColorSumEnabled || (ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { add_specular(ctx, span); } } /* Fog */ if (swrast->_FogEnabled) { _swrast_fog_rgba_span(ctx, span); } /* Antialias coverage application */ if (span->arrayMask & SPAN_COVERAGE) { apply_aa_coverage(span); } /* Clamp color/alpha values over the range [0.0, 1.0] before storage */ if (ctx->Color.ClampFragmentColor == GL_TRUE && span->array->ChanType == GL_FLOAT) { clamp_colors(span); } /* * Write to renderbuffers */ { const GLuint numBuffers = fb->_NumColorDrawBuffers; const GLboolean multiFragOutputs = numBuffers > 1; GLuint buf; for (buf = 0; buf < numBuffers; buf++) { struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buf]; /* color[fragOutput] will be written to buffer[buf] */ if (rb) { GLchan rgbaSave[MAX_WIDTH][4]; const GLuint fragOutput = multiFragOutputs ? buf : 0; if (rb->DataType != span->array->ChanType || fragOutput > 0) { convert_color_type(span, rb->DataType, fragOutput); } if (!multiFragOutputs && numBuffers > 1) { /* save colors for second, third renderbuffer writes */ _mesa_memcpy(rgbaSave, span->array->rgba, 4 * span->end * sizeof(GLchan)); } ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); if (ctx->Color._LogicOpEnabled) { _swrast_logicop_rgba_span(ctx, rb, span); } else if (ctx->Color.BlendEnabled) { _swrast_blend_span(ctx, rb, span); } if (colorMask != 0xffffffff) { _swrast_mask_rgba_span(ctx, rb, span); } if (span->arrayMask & SPAN_XY) { /* array of pixel coords */ ASSERT(rb->PutValues); rb->PutValues(ctx, rb, span->end, span->array->x, span->array->y, span->array->rgba, span->array->mask); } else { /* horizontal run of pixels */ ASSERT(rb->PutRow); rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba, span->writeAll ? NULL: span->array->mask); } if (!multiFragOutputs && numBuffers > 1) { /* restore original span values */ _mesa_memcpy(span->array->rgba, rgbaSave, 4 * span->end * sizeof(GLchan)); } } /* if rb */ } /* for buf */ }end: /* restore these values before returning */ span->interpMask = origInterpMask; span->arrayMask = origArrayMask; span->arrayAttribs = origArrayAttribs; span->array->ChanType = origChanType; span->array->rgba = origRgba;}/** * Read RGBA pixels from a renderbuffer. Clipping will be done to prevent * reading ouside the buffer's boundaries. * \param dstType datatype for returned colors * \param rgba the returned colors */void_swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, GLenum dstType, GLvoid *rgba){ const GLint bufWidth = (GLint) rb->Width; const GLint bufHeight = (GLint) rb->Height; if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { /* completely above, below, or right */ /* XXX maybe leave rgba values undefined? */ _mesa_bzero(rgba, 4 * n * sizeof(GLchan)); } else { GLint skip, length; if (x < 0) { /* left edge clipping */ skip = -x; length = (GLint) n - skip; if (length < 0) { /* completely left of window */ return; } if (length > bufWidth) { length = bufWidth; } } else if ((GLint) (x + n) > bufWidth) { /* right edge clipping */ skip = 0; length = bufWidth - x; if (length < 0) { /* completely to right of window */ return; } } else { /* no clipping */ skip = 0; length = (GLint) n; } ASSERT(rb); ASSERT(rb->GetRow); ASSERT(rb->_BaseFormat == GL_RGB || rb->_BaseFormat == GL_RGBA); if (rb->DataType == dstType) { rb->GetRow(ctx, rb, length, x + skip, y, (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(rb->DataType)); } else { GLuint temp[MAX_WIDTH * 4]; rb->GetRow(ctx, rb, length, x + skip, y, temp); _mesa_convert_colors(rb->DataType, temp, dstType, (GLubyte *) rgba + skip * RGBA_PIXEL_SIZE(dstType), length, NULL); } }}/** * Read CI pixels from a renderbuffer. Clipping will be done to prevent * reading ouside the buffer's boundaries. */void_swrast_read_index_span( GLcontext *ctx, struct gl_renderbuffer *rb, GLuint n, GLint x, GLint y, GLuint index[] ){ const GLint bufWidth = (GLint) rb->Width; const GLint bufHeight = (GLint) rb->Height; if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) { /* completely above, below, or right */ _mesa_bzero(index, n * sizeof(GLuint)); } else { GLint skip, length; if (x < 0) { /* left edge clipping */ skip = -x; length = (GLint) n - skip; if (length < 0) { /* completely left of window */ return; } if (length > bufWidth) { length = bufWidth; } } else if ((GLint) (x + n) > bufWidth) { /* right edge clipping */ skip = 0; length = bufWidth - x; if (length < 0) { /* completely to right of window */ return; } } else { /* no clipping */ skip = 0; length = (GLint) n; } ASSERT(rb->GetRow); ASSERT(rb->_BaseFormat == GL_COLOR_INDEX); if (rb->DataType == GL_UNSIGNED_BYTE) { GLubyte index8[MAX_WIDTH]; GLint i; rb->GetRow(ctx, rb, length, x + skip, y, index8); for (i = 0; i < length; i++) index[skip + i] = index8[i]; } else if (rb->DataType == GL_UNSIGNED_SHORT) { GLushort index16[MAX_WIDTH]; GLint i; rb->GetRow(ctx, rb, length, x + skip, y, index16); for (i = 0; i < length; i++) index[skip + i] = index16[i]; } else if (rb->DataType == GL_UNSIGNED_INT) { rb->GetRow(ctx, rb, length, x + skip, y, index + skip); } }}/** * Wrapper for gl_renderbuffer::GetValues() which does clipping to avoid * reading values outside the buffer bounds. * We can use this for reading any format/type of renderbuffer. * \param valueSize is the size in bytes of each value (pixel) put into the * values array. */void_swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, const GLint x[], const GLint y[], void *values, GLuint valueSize){ GLuint i, inCount = 0, inStart = 0; for (i = 0; i < count; i++) { if (x[i] >= 0 && y[i] >= 0 && x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) { /* inside */ if (inCount == 0) inStart = i; inCount++; } else { if (inCount > 0) { /* read [inStart, inStart + inCount) */ rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, (GLubyte *) values + inStart * valueSize); inCount = 0; } } } if (inCount > 0) { /* read last values */ rb->GetValues(ctx, rb, inCount, x + inStart, y + inStart, (GLubyte *) values + inStart * valueSize); }}/** * Wrapper for gl_renderbuffer::PutRow() which does clipping. * \param valueSize size of each value (pixel) in bytes */void_swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, GLint x, GLint y, const GLvoid *values, GLuint valueSize){ GLint skip = 0; if (y < 0 || y >= (GLint) rb->Height) return; /* above or below */ if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) return; /* entirely left or right */ if ((GLint) (x + count) > (GLint) rb->Width) { /* right clip */ GLint clip = x + count - rb->Width; count -= clip; } if (x < 0) { /* left clip */ skip = -x; x = 0; count -= skip; } rb->PutRow(ctx, rb, count, x, y, (const GLubyte *) values + skip * valueSize, NULL);}/** * Wrapper for gl_renderbuffer::GetRow() which does clipping. * \param valueSize size of each value (pixel) in bytes */void_swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count, GLint x, GLint y, GLvoid *values, GLuint valueSize){ GLint skip = 0; if (y < 0 || y >= (GLint) rb->Height) return; /* above or below */ if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) return; /* entirely left or right */ if (x + count > rb->Width) { /* right clip */ GLint clip = x + count - rb->Width; count -= clip; } if (x < 0) { /* left clip */ skip = -x; x = 0; count -= skip; } rb->GetRow(ctx, rb, count, x, y, (GLubyte *) values + skip * valueSize);}/** * Get RGBA pixels from the given renderbuffer. Put the pixel colors into * the span's specular color arrays. The specular color arrays should no * longer be needed by time this function is called. * Used by blending, logicop and masking functions. * \return pointer to the colors we read. */void *_swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb, SWspan *span){ const GLuint pixelSize = RGBA_PIXEL_SIZE(span->array->ChanType); void *rbPixels; /* * Point rbPixels to a temporary space (use specular color arrays). */ rbPixels = span->array->attribs[FRAG_ATTRIB_COL1]; /* Get destination values from renderbuffer */ if (span->arrayMask & SPAN_XY) { _swrast_get_values(ctx, rb, span->end, span->array->x, span->array->y, rbPixels, pixelSize); } else { _swrast_get_row(ctx, rb, span->end, span->x, span->y, rbPixels, pixelSize); } return rbPixels;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -