📄 s_accum.c
字号:
GLshort *acc; if (directAccess) { acc = (GLshort *) rb->GetPointer(ctx, rb, xpos, ypos + i); } else { rb->GetRow(ctx, rb, width, xpos, ypos + i, accumRow); acc = accumRow; } /* read colors from color buffer */ _swrast_read_rgba_span(ctx, ctx->ReadBuffer->_ColorReadBuffer, width, xpos, ypos + i, CHAN_TYPE, rgba); /* do accumulation */ if (swrast->_IntegerAccumMode) { /* simply add integer color values into accum buffer */ GLint j; for (j = 0; j < width; j++) { acc[j * 4 + 0] += rgba[j][RCOMP]; acc[j * 4 + 1] += rgba[j][GCOMP]; acc[j * 4 + 2] += rgba[j][BCOMP]; acc[j * 4 + 3] += rgba[j][ACOMP]; } } else { /* scaled integer (or float) accum buffer */ GLint j; for (j = 0; j < width; j++) { acc[j * 4 + 0] += (GLshort) ((GLfloat) rgba[j][RCOMP] * scale); acc[j * 4 + 1] += (GLshort) ((GLfloat) rgba[j][GCOMP] * scale); acc[j * 4 + 2] += (GLshort) ((GLfloat) rgba[j][BCOMP] * scale); acc[j * 4 + 3] += (GLshort) ((GLfloat) rgba[j][ACOMP] * scale); } } if (!directAccess) { rb->PutRow(ctx, rb, width, xpos, ypos + i, accumRow, NULL); } } } else { /* other types someday */ }}static voidaccum_load(GLcontext *ctx, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height ){ SWcontext *swrast = SWRAST_CONTEXT(ctx); struct gl_renderbuffer *rb = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; const GLboolean directAccess = (rb->GetPointer(ctx, rb, 0, 0) != NULL); assert(rb); if (!ctx->ReadBuffer->_ColorReadBuffer) { /* no read buffer - OK */ return; } /* This is a change to go into optimized accum buffer mode */ if (value > 0.0 && value <= 1.0) {#if USE_OPTIMIZED_ACCUM swrast->_IntegerAccumMode = GL_TRUE;#else swrast->_IntegerAccumMode = GL_FALSE;#endif swrast->_IntegerAccumScaler = value; } else { swrast->_IntegerAccumMode = GL_FALSE; swrast->_IntegerAccumScaler = 0.0; } if (rb->DataType == GL_SHORT || rb->DataType == GL_UNSIGNED_SHORT) { const GLfloat scale = value * ACCUM_SCALE16 / CHAN_MAXF; GLshort accumRow[4 * MAX_WIDTH]; GLchan rgba[MAX_WIDTH][4]; GLint i; for (i = 0; i < height; i++) { GLshort *acc; if (directAccess) { acc = (GLshort *) rb->GetPointer(ctx, rb, xpos, ypos + i); } else { rb->GetRow(ctx, rb, width, xpos, ypos + i, accumRow); acc = accumRow; } /* read colors from color buffer */ _swrast_read_rgba_span(ctx, ctx->ReadBuffer->_ColorReadBuffer, width, xpos, ypos + i, CHAN_TYPE, rgba); /* do load */ if (swrast->_IntegerAccumMode) { /* just copy values in */ GLint j; assert(swrast->_IntegerAccumScaler > 0.0); assert(swrast->_IntegerAccumScaler <= 1.0); for (j = 0; j < width; j++) { acc[j * 4 + 0] = rgba[j][RCOMP]; acc[j * 4 + 1] = rgba[j][GCOMP]; acc[j * 4 + 2] = rgba[j][BCOMP]; acc[j * 4 + 3] = rgba[j][ACOMP]; } } else { /* scaled integer (or float) accum buffer */ GLint j; for (j = 0; j < width; j++) { acc[j * 4 + 0] = (GLshort) ((GLfloat) rgba[j][RCOMP] * scale); acc[j * 4 + 1] = (GLshort) ((GLfloat) rgba[j][GCOMP] * scale); acc[j * 4 + 2] = (GLshort) ((GLfloat) rgba[j][BCOMP] * scale); acc[j * 4 + 3] = (GLshort) ((GLfloat) rgba[j][ACOMP] * scale); } } if (!directAccess) { rb->PutRow(ctx, rb, width, xpos, ypos + i, accumRow, NULL); } } }}static voidaccum_return(GLcontext *ctx, GLfloat value, GLint xpos, GLint ypos, GLint width, GLint height ){ SWcontext *swrast = SWRAST_CONTEXT(ctx); struct gl_framebuffer *fb = ctx->DrawBuffer; struct gl_renderbuffer *accumRb = fb->Attachment[BUFFER_ACCUM].Renderbuffer; const GLboolean directAccess = (accumRb->GetPointer(ctx, accumRb, 0, 0) != NULL); const GLboolean masking = (!ctx->Color.ColorMask[RCOMP] || !ctx->Color.ColorMask[GCOMP] || !ctx->Color.ColorMask[BCOMP] || !ctx->Color.ColorMask[ACOMP]); static GLchan multTable[32768]; static GLfloat prevMult = 0.0; const GLfloat mult = swrast->_IntegerAccumScaler; const GLint max = MIN2((GLint) (256 / mult), 32767); /* May have to leave optimized accum buffer mode */ if (swrast->_IntegerAccumMode && value != 1.0) rescale_accum(ctx); if (swrast->_IntegerAccumMode && swrast->_IntegerAccumScaler > 0) { /* build lookup table to avoid many floating point multiplies */ GLint j; assert(swrast->_IntegerAccumScaler <= 1.0); if (mult != prevMult) { for (j = 0; j < max; j++) multTable[j] = IROUND((GLfloat) j * mult); prevMult = mult; } } if (accumRb->DataType == GL_SHORT || accumRb->DataType == GL_UNSIGNED_SHORT) { const GLfloat scale = value * CHAN_MAXF / ACCUM_SCALE16; GLuint buffer; GLint i; /* XXX maybe transpose the 'i' and 'buffer' loops??? */ for (i = 0; i < height; i++) { GLshort accumRow[4 * MAX_WIDTH]; GLshort *acc; SWspan span; /* init color span */ INIT_SPAN(span, GL_BITMAP); span.end = width; span.arrayMask = SPAN_RGBA; span.x = xpos; span.y = ypos + i; if (directAccess) { acc = (GLshort *) accumRb->GetPointer(ctx, accumRb, xpos, ypos +i); } else { accumRb->GetRow(ctx, accumRb, width, xpos, ypos + i, accumRow); acc = accumRow; } /* get the colors to return */ if (swrast->_IntegerAccumMode) { GLint j; for (j = 0; j < width; j++) { ASSERT(acc[j * 4 + 0] < max); ASSERT(acc[j * 4 + 1] < max); ASSERT(acc[j * 4 + 2] < max); ASSERT(acc[j * 4 + 3] < max); span.array->rgba[j][RCOMP] = multTable[acc[j * 4 + 0]]; span.array->rgba[j][GCOMP] = multTable[acc[j * 4 + 1]]; span.array->rgba[j][BCOMP] = multTable[acc[j * 4 + 2]]; span.array->rgba[j][ACOMP] = multTable[acc[j * 4 + 3]]; } } else { /* scaled integer (or float) accum buffer */ GLint j; for (j = 0; j < width; j++) {#if CHAN_BITS==32 GLchan r = acc[j * 4 + 0] * scale; GLchan g = acc[j * 4 + 1] * scale; GLchan b = acc[j * 4 + 2] * scale; GLchan a = acc[j * 4 + 3] * scale;#else GLint r = IROUND( (GLfloat) (acc[j * 4 + 0]) * scale ); GLint g = IROUND( (GLfloat) (acc[j * 4 + 1]) * scale ); GLint b = IROUND( (GLfloat) (acc[j * 4 + 2]) * scale ); GLint a = IROUND( (GLfloat) (acc[j * 4 + 3]) * scale );#endif span.array->rgba[j][RCOMP] = CLAMP( r, 0, CHAN_MAX ); span.array->rgba[j][GCOMP] = CLAMP( g, 0, CHAN_MAX ); span.array->rgba[j][BCOMP] = CLAMP( b, 0, CHAN_MAX ); span.array->rgba[j][ACOMP] = CLAMP( a, 0, CHAN_MAX ); } } /* store colors */ for (buffer = 0; buffer < fb->_NumColorDrawBuffers; buffer++) { struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[buffer]; if (masking) { _swrast_mask_rgba_span(ctx, rb, &span); } rb->PutRow(ctx, rb, width, xpos, ypos + i, span.array->rgba, NULL); } } } else { /* other types someday */ }}/** * Software fallback for glAccum. */void_swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value){ SWcontext *swrast = SWRAST_CONTEXT(ctx); GLint xpos, ypos, width, height; if (SWRAST_CONTEXT(ctx)->NewState) _swrast_validate_derived( ctx ); if (!ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer) { _mesa_warning(ctx, "Calling glAccum() without an accumulation buffer"); return; } RENDER_START(swrast, ctx); /* Compute region after calling RENDER_START so that we know the * drawbuffer's size/bounds are up to date. */ xpos = ctx->DrawBuffer->_Xmin; ypos = ctx->DrawBuffer->_Ymin; width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; switch (op) { case GL_ADD: if (value != 0.0F) { accum_add(ctx, value, xpos, ypos, width, height); } break; case GL_MULT: if (value != 1.0F) { accum_mult(ctx, value, xpos, ypos, width, height); } break; case GL_ACCUM: if (value != 0.0F) { accum_accum(ctx, value, xpos, ypos, width, height); } break; case GL_LOAD: accum_load(ctx, value, xpos, ypos, width, height); break; case GL_RETURN: accum_return(ctx, value, xpos, ypos, width, height); break; default: _mesa_problem(ctx, "invalid mode in _swrast_Accum()"); break; } RENDER_FINISH(swrast, ctx);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -