-/* $Id: accum.c,v 1.9 1999/11/03 19:27:41 brianp Exp $ */
+/* $Id: accum.c,v 1.21 2000/06/19 00:42:24 brianp Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.1
+ * Version: 3.3
*
- * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
*/
-/* $XFree86: xc/lib/GL/mesa/src/accum.c,v 1.3 1999/04/04 00:20:17 dawes Exp $ */
-
#ifdef PC_HEADER
#include "all.h"
#else
-#ifndef XFree86Server
-#include <assert.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-#else
-#include "GL/xf86glx.h"
-#endif
+#include "glheader.h"
#include "accum.h"
#include "context.h"
-#include "macros.h"
+#include "mem.h"
#include "masking.h"
#include "span.h"
+#include "state.h"
#include "types.h"
-#ifdef XFree86Server
-#include "GL/xf86glx.h"
-#endif
#endif
-void gl_alloc_accum_buffer( GLcontext *ctx )
+void
+_mesa_alloc_accum_buffer( GLcontext *ctx )
{
GLint n;
- if (ctx->Buffer->Accum) {
- FREE( ctx->Buffer->Accum );
- ctx->Buffer->Accum = NULL;
+ if (ctx->DrawBuffer->Accum) {
+ FREE( ctx->DrawBuffer->Accum );
+ ctx->DrawBuffer->Accum = NULL;
}
/* allocate accumulation buffer if not already present */
- n = ctx->Buffer->Width * ctx->Buffer->Height * 4 * sizeof(GLaccum);
- ctx->Buffer->Accum = (GLaccum *) MALLOC( n );
- if (!ctx->Buffer->Accum) {
+ n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height * 4 * sizeof(GLaccum);
+ ctx->DrawBuffer->Accum = (GLaccum *) MALLOC( n );
+ if (!ctx->DrawBuffer->Accum) {
/* unable to setup accumulation buffer */
gl_error( ctx, GL_OUT_OF_MEMORY, "glAccum" );
}
-void gl_ClearAccum( GLcontext *ctx,
- GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
+void
+_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
{
+ GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glAccum");
ctx->Accum.ClearColor[0] = CLAMP( red, -1.0, 1.0 );
*/
static void rescale_accum( GLcontext *ctx )
{
- const GLuint n = ctx->Buffer->Width * ctx->Buffer->Height * 4;
+ const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height * 4;
const GLfloat fChanMax = (1 << (sizeof(GLchan) * 8)) - 1;
const GLfloat s = ctx->IntegerAccumScaler * (32767.0 / fChanMax);
- GLaccum *accum = ctx->Buffer->Accum;
+ GLaccum *accum = ctx->DrawBuffer->Accum;
GLuint i;
assert(ctx->IntegerAccumMode);
-void gl_Accum( GLcontext *ctx, GLenum op, GLfloat value )
+void
+_mesa_Accum( GLenum op, GLfloat value )
{
+ GET_CURRENT_CONTEXT(ctx);
GLuint xpos, ypos, width, height, width4;
GLfloat acc_scale;
GLubyte rgba[MAX_WIDTH][4];
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glAccum");
- if (ctx->Visual->AccumBits==0 || !ctx->Buffer->Accum) {
- /* No accumulation buffer! */
- gl_warning(ctx, "Calling glAccum() without an accumulation buffer");
+ if (ctx->Visual->AccumRedBits == 0 || ctx->DrawBuffer != ctx->ReadBuffer) {
+ gl_error(ctx, GL_INVALID_OPERATION, "glAccum");
+ return;
+ }
+
+ if (!ctx->DrawBuffer->Accum) {
+ gl_warning(ctx, "Calling glAccum() without an accumulation buffer (low memory?)");
return;
}
/* whole window */
xpos = 0;
ypos = 0;
- width = ctx->Buffer->Width;
- height = ctx->Buffer->Height;
+ width = ctx->DrawBuffer->Width;
+ height = ctx->DrawBuffer->Height;
}
width4 = 4 * width;
switch (op) {
case GL_ADD:
- {
+ if (value != 0.0F) {
const GLaccum intVal = (GLaccum) (value * acc_scale);
GLuint j;
/* Leave optimized accum buffer mode */
if (ctx->IntegerAccumMode)
rescale_accum(ctx);
for (j = 0; j < height; j++) {
- GLaccum * acc = ctx->Buffer->Accum + ypos * width4 + 4 * xpos;
+ GLaccum * acc = ctx->DrawBuffer->Accum + ypos * width4 + 4 * xpos;
GLuint i;
for (i = 0; i < width4; i++) {
acc[i] += intVal;
break;
case GL_MULT:
- {
+ if (value != 1.0F) {
GLuint j;
/* Leave optimized accum buffer mode */
if (ctx->IntegerAccumMode)
rescale_accum(ctx);
for (j = 0; j < height; j++) {
- GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + 4 * xpos;
+ GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + 4 * xpos;
GLuint i;
for (i = 0; i < width4; i++) {
acc[i] = (GLaccum) ( (GLfloat) acc[i] * value );
break;
case GL_ACCUM:
- (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
+ if (value == 0.0F)
+ return;
+
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
+ ctx->Pixel.DriverReadBuffer );
/* May have to leave optimized accum buffer mode */
if (ctx->IntegerAccumScaler == 0.0 && value > 0.0 && value <= 1.0)
if (ctx->IntegerAccumMode) {
/* simply add integer color values into accum buffer */
GLuint j;
- GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos * 4;
+ GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
assert(ctx->IntegerAccumScaler > 0.0);
assert(ctx->IntegerAccumScaler <= 1.0);
for (j = 0; j < height; j++) {
GLuint i, i4;
- gl_read_rgba_span(ctx, width, xpos, ypos, rgba);
+ gl_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
for (i = i4 = 0; i < width; i++, i4+=4) {
acc[i4+0] += rgba[i][RCOMP];
acc[i4+1] += rgba[i][GCOMP];
const GLfloat ascale = value * acc_scale / fChanMax;
GLuint j;
for (j=0;j<height;j++) {
- GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos * 4;
+ GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
GLuint i;
- gl_read_rgba_span(ctx, width, xpos, ypos, rgba);
+ gl_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
for (i=0;i<width;i++) {
*acc += (GLaccum) ( (GLfloat) rgba[i][RCOMP] * rscale ); acc++;
*acc += (GLaccum) ( (GLfloat) rgba[i][GCOMP] * gscale ); acc++;
ypos++;
}
}
- (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
+ /* restore read buffer = draw buffer (the default) */
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
+ ctx->Color.DriverDrawBuffer );
break;
case GL_LOAD:
- (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.DriverReadBuffer );
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
+ ctx->Pixel.DriverReadBuffer );
/* This is a change to go into optimized accum buffer mode */
if (value > 0.0 && value <= 1.0) {
if (ctx->IntegerAccumMode) {
/* just copy values into accum buffer */
GLuint j;
- GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos * 4;
+ GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
assert(ctx->IntegerAccumScaler > 0.0);
assert(ctx->IntegerAccumScaler <= 1.0);
for (j = 0; j < height; j++) {
GLuint i, i4;
- gl_read_rgba_span(ctx, width, xpos, ypos, rgba);
+ gl_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
for (i = i4 = 0; i < width; i++, i4 += 4) {
acc[i4+0] = rgba[i][RCOMP];
acc[i4+1] = rgba[i][GCOMP];
const GLfloat d = 3.0 / acc_scale;
GLuint i, j;
for (j = 0; j < height; j++) {
- GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos * 4;
- gl_read_rgba_span(ctx, width, xpos, ypos, rgba);
+ GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
+ gl_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
for (i=0;i<width;i++) {
*acc++ = (GLaccum) ((GLfloat) rgba[i][RCOMP] * rscale + d);
*acc++ = (GLaccum) ((GLfloat) rgba[i][GCOMP] * gscale + d);
ypos++;
}
}
- (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DriverDrawBuffer );
+
+ /* restore read buffer = draw buffer (the default) */
+ (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
+ ctx->Color.DriverDrawBuffer );
break;
case GL_RETURN:
if (ctx->IntegerAccumMode && value != 1.0)
rescale_accum(ctx);
- if (ctx->IntegerAccumMode) {
+ if (ctx->IntegerAccumMode && ctx->IntegerAccumScaler > 0) {
/* build lookup table to avoid many floating point multiplies */
const GLfloat mult = ctx->IntegerAccumScaler;
static GLchan multTable[32768];
static GLfloat prevMult = 0.0;
GLuint j;
- const GLint max = 256 / mult;
+ const GLint max = (GLint) (256 / mult);
if (mult != prevMult) {
assert(max <= 32768);
for (j = 0; j < max; j++)
assert(ctx->IntegerAccumScaler > 0.0);
assert(ctx->IntegerAccumScaler <= 1.0);
for (j = 0; j < height; j++) {
- const GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos*4;
+ const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4;
GLuint i, i4;
for (i = i4 = 0; i < width; i++, i4 += 4) {
ASSERT(acc[i4+0] < max);
rgba[i][ACOMP] = multTable[acc[i4+3]];
}
if (ctx->Color.SWmasking) {
- gl_mask_rgba_span( ctx, width, xpos, ypos, rgba );
+ _mesa_mask_rgba_span( ctx, width, xpos, ypos, rgba );
}
(*ctx->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
(const GLubyte (*)[4])rgba, NULL );
const GLfloat ascale = value / acc_scale * fChanMax;
GLuint i, j;
for (j=0;j<height;j++) {
- const GLaccum *acc = ctx->Buffer->Accum + ypos * width4 + xpos*4;
+ const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4;
for (i=0;i<width;i++) {
GLint r, g, b, a;
r = (GLint) ( (GLfloat) (*acc++) * rscale + 0.5F );
rgba[i][ACOMP] = CLAMP( a, 0, iChanMax );
}
if (ctx->Color.SWmasking) {
- gl_mask_rgba_span( ctx, width, xpos, ypos, rgba );
+ _mesa_mask_rgba_span( ctx, width, xpos, ypos, rgba );
}
(*ctx->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
(const GLubyte (*)[4])rgba, NULL );
/*
* Clear the accumulation Buffer.
*/
-void gl_clear_accum_buffer( GLcontext *ctx )
+void
+_mesa_clear_accum_buffer( GLcontext *ctx )
{
GLuint buffersize;
GLfloat acc_scale;
- if (ctx->Visual->AccumBits==0) {
+ if (ctx->Visual->AccumRedBits==0) {
/* No accumulation buffer! */
return;
}
}
/* number of pixels */
- buffersize = ctx->Buffer->Width * ctx->Buffer->Height;
+ buffersize = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
- if (!ctx->Buffer->Accum) {
+ if (!ctx->DrawBuffer->Accum) {
/* try to alloc accumulation buffer */
- ctx->Buffer->Accum = (GLaccum *)
+ ctx->DrawBuffer->Accum = (GLaccum *)
MALLOC( buffersize * 4 * sizeof(GLaccum) );
}
- if (ctx->Buffer->Accum) {
+ if (ctx->DrawBuffer->Accum) {
if (ctx->Scissor.Enabled) {
/* Limit clear to scissor box */
GLaccum r, g, b, a;
b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale);
a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale);
/* size of region to clear */
- width = 4 * (ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1);
- height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
+ width = 4 * (ctx->DrawBuffer->Xmax - ctx->DrawBuffer->Xmin + 1);
+ height = ctx->DrawBuffer->Ymax - ctx->DrawBuffer->Ymin + 1;
/* ptr to first element to clear */
- row = ctx->Buffer->Accum
- + 4 * (ctx->Buffer->Ymin * ctx->Buffer->Width
- + ctx->Buffer->Xmin);
+ row = ctx->DrawBuffer->Accum
+ + 4 * (ctx->DrawBuffer->Ymin * ctx->DrawBuffer->Width
+ + ctx->DrawBuffer->Xmin);
for (j=0;j<height;j++) {
for (i=0;i<width;i+=4) {
row[i+0] = r;
row[i+2] = b;
row[i+3] = a;
}
- row += 4 * ctx->Buffer->Width;
+ row += 4 * ctx->DrawBuffer->Width;
}
}
else {
ctx->Accum.ClearColor[2]==0.0 &&
ctx->Accum.ClearColor[3]==0.0) {
/* Black */
- MEMSET( ctx->Buffer->Accum, 0, buffersize * 4 * sizeof(GLaccum) );
+ BZERO( ctx->DrawBuffer->Accum, buffersize * 4 * sizeof(GLaccum) );
}
else {
/* Not black */
GLaccum *acc, r, g, b, a;
GLuint i;
- acc = ctx->Buffer->Accum;
+ acc = ctx->DrawBuffer->Accum;
r = (GLaccum) (ctx->Accum.ClearColor[0] * acc_scale);
g = (GLaccum) (ctx->Accum.ClearColor[1] * acc_scale);
b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale);