📄 s_span.c
字号:
ASSERT(x < xmax);
span->end = xmax - x;
}
return GL_TRUE; /* some pixels visible */
}
}
/**
* Apply all the per-fragment opertions to a span of color index fragments
* and write them to the enabled color drawbuffers.
* The 'span' parameter can be considered to be const. Note that
* span->interpMask and span->arrayMask may be changed but will be restored
* to their original values before returning.
*/
void
_swrast_write_index_span( GLcontext *ctx, struct sw_span *span)
{
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
const struct gl_framebuffer *fb = ctx->DrawBuffer;
const GLuint output = 0;
const GLuint origInterpMask = span->interpMask;
const GLuint origArrayMask = span->arrayMask;
GLuint buf;
ASSERT(span->end <= MAX_WIDTH);
ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE ||
span->primitive == GL_POLYGON || span->primitive == GL_BITMAP);
ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);
ASSERT((span->interpMask & span->arrayMask) == 0);
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->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 we get here, something passed the depth test */
if (ctx->Depth.OcclusionTest) {
ctx->OcclusionResult = GL_TRUE;
}
#if FEATURE_ARB_occlusion_query
if (ctx->Occlusion.Active) {
/* update count of 'passed' fragments */
GLuint i;
for (i = 0; i < span->end; i++)
ctx->Occlusion.PassedCounter += 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 (ctx->Fog.Enabled ||
ctx->Color.IndexLogicOpEnabled ||
ctx->Color.IndexMask != 0xffffffff ||
(span->arrayMask & SPAN_COVERAGE)) {
if (span->interpMask & SPAN_INDEX) {
interpolate_indexes(ctx, span);
}
}
/* Fog */
if (ctx->Fog.Enabled) {
_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);
}
}
}
#if OLD_RENDERBUFFER
/* restore default dest buffer */
_swrast_use_draw_buffer(ctx);
#endif
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 void
add_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 void
multi_write_rgba_span( GLcontext *ctx, struct sw_span *span )
{
#if OLD_RENDERBUFFER
SWcontext *swrast = SWRAST_CONTEXT(ctx);
#endif
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];
#if OLD_RENDERBUFFER
/* obsolete code */
GLuint bufferBit = fb->_ColorDrawBit[output][i];
/* Set the current read/draw buffer */
swrast->CurrentBufferBit = bufferBit;
if (swrast->Driver.SetBuffer)
(*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
#endif
/* 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);
}
}
#if OLD_RENDERBUFFER
/* restore default dest buffer */
_swrast_use_draw_buffer(ctx);
#endif
}
/**
* 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 GLuint origInterpMask = span->interpMask;
const GLuint origArrayMask = span->arrayMask;
const GLboolean deferredTexture = !(ctx->Color.AlphaEnabled ||
ctx->FragmentProgram._Active ||
ctx->ATIFragmentShader._Enabled);
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)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -