void gl_Clear( GLcontext *ctx, GLbitfield mask ) { #ifdef PROFILE GLdouble t0 = gl_time(); #endif if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glClear" ); return; } if (ctx->NewState) { gl_update_state( ctx ); } if (mask & GL_COLOR_BUFFER_BIT) clear_color_buffers( ctx ); if (mask & GL_DEPTH_BUFFER_BIT) (*ctx->Driver.ClearDepthBuffer)( ctx ); if (mask & GL_ACCUM_BUFFER_BIT) gl_clear_accum_buffer( ctx ); if (mask & GL_STENCIL_BUFFER_BIT) gl_clear_stencil_buffer( ctx ); #ifdef PROFILE ctx->ClearTime += gl_time() - t0; ctx->ClearCount++; #endif }
void gl_Hint( GLcontext *ctx, GLenum target, GLenum mode ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glHint" ); return; } if (mode!=GL_DONT_CARE && mode!=GL_FASTEST && mode!=GL_NICEST) { gl_error( ctx, GL_INVALID_ENUM, "glHint(mode)" ); return; } switch (target) { case GL_FOG_HINT: ctx->Hint.Fog = mode; break; case GL_LINE_SMOOTH_HINT: ctx->Hint.LineSmooth = mode; break; case GL_PERSPECTIVE_CORRECTION_HINT: ctx->Hint.PerspectiveCorrection = mode; break; case GL_POINT_SMOOTH_HINT: ctx->Hint.PointSmooth = mode; break; case GL_POLYGON_SMOOTH_HINT: ctx->Hint.PolygonSmooth = mode; break; default: gl_error( ctx, GL_INVALID_ENUM, "glHint(target)" ); } ctx->NewState |= NEW_ALL; /* just to be safe */ }
const GLubyte *gl_GetString( GLcontext *ctx, GLenum name ) { static char *vendor = "Brian Paul"; static char *renderer = "Mesa"; static char *version = "1.1 Mesa 2.2"; static char *extensions = "GL_EXT_blend_color GL_EXT_blend_minmax GL_EXT_blend_logic_op GL_EXT_blend_subtract GL_EXT_polygon_offset GL_EXT_vertex_array GL_EXT_texture_object GL_EXT_texture3D GL_MESA_window_pos GL_MESA_resize_buffers"; if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glGetString" ); return (GLubyte *) 0; } switch (name) { case GL_VENDOR: return (GLubyte *) vendor; case GL_RENDERER: return (GLubyte *) renderer; case GL_VERSION: return (GLubyte *) version; case GL_EXTENSIONS: return (GLubyte *) extensions; default: gl_error( ctx, GL_INVALID_ENUM, "glGetString" ); return (GLubyte *) 0; } }
void gl_DepthRange( GLcontext* ctx, GLclampd nearval, GLclampd farval ) { /* * nearval - specifies mapping of the near clipping plane to window * coordinates, default is 0 * farval - specifies mapping of the far clipping plane to window * coordinates, default is 1 * * After clipping and div by w, z coords are in -1.0 to 1.0, * corresponding to near and far clipping planes. glDepthRange * specifies a linear mapping of the normalized z coords in * this range to window z coords. */ GLfloat n, f; if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glDepthRange" ); return; } n = (GLfloat) CLAMP( nearval, 0.0, 1.0 ); f = (GLfloat) CLAMP( farval, 0.0, 1.0 ); ctx->Viewport.Near = n; ctx->Viewport.Far = f; ctx->Viewport.Sz = DEPTH_SCALE * ((f - n) / 2.0); ctx->Viewport.Tz = DEPTH_SCALE * ((f - n) / 2.0 + n); }
void gl_AlphaFunc( GLcontext* ctx, GLenum func, GLclampf ref ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glAlphaFunc" ); return; } switch (func) { case GL_NEVER: case GL_LESS: case GL_EQUAL: case GL_LEQUAL: case GL_GREATER: case GL_NOTEQUAL: case GL_GEQUAL: case GL_ALWAYS: ctx->Color.AlphaFunc = func; ctx->Color.AlphaRef = CLAMP( ref, 0.0F, 1.0F ); ctx->Color.AlphaRefUbyte = (GLubyte) (ctx->Color.AlphaRef * ctx->Visual->AlphaScale); break; default: gl_error( ctx, GL_INVALID_ENUM, "glAlphaFunc(func)" ); break; } }
void gl_ClearDepth( GLcontext* ctx, GLclampd depth ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glClearDepth" ); return; } ctx->Depth.Clear = (GLfloat) CLAMP( depth, 0.0, 1.0 ); }
void gl_IndexMask( GLcontext *ctx, GLuint mask ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glIndexMask" ); return; } ctx->Color.IndexMask = mask; ctx->NewState |= NEW_RASTER_OPS; }
void gl_LineStipple( GLcontext *ctx, GLint factor, GLushort pattern ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glLineStipple" ); return; } ctx->Line.StippleFactor = CLAMP( factor, 1, 256 ); ctx->Line.StipplePattern = pattern; ctx->NewState |= NEW_RASTER_OPS; }
void gl_ColorMask( GLcontext *ctx, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glColorMask" ); return; } ctx->Color.ColorMask = (red << 3) | (green << 2) | (blue << 1) | alpha; ctx->NewState |= NEW_RASTER_OPS; }
void gl_InitNames( GLcontext *ctx ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glInitNames" ); } ctx->Select.NameStackDepth = 0; ctx->Select.HitFlag = GL_FALSE; ctx->Select.HitMinZ = 1.0; ctx->Select.HitMaxZ = 0.0; }
void gl_Flush( GLcontext *ctx ) { /* Don't compile into display list */ if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glFlush" ); return; } if (ctx->Driver.Flush) { (*ctx->Driver.Flush)( ctx ); } }
void gl_ClearAccum( GLcontext *ctx, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glAccum" ); return; } ctx->Accum.ClearColor[0] = CLAMP( red, -1.0, 1.0 ); ctx->Accum.ClearColor[1] = CLAMP( green, -1.0, 1.0 ); ctx->Accum.ClearColor[2] = CLAMP( blue, -1.0, 1.0 ); ctx->Accum.ClearColor[3] = CLAMP( alpha, -1.0, 1.0 ); }
void gl_PassThrough( GLcontext *ctx, GLfloat token ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glPassThrough" ); return; } if (ctx->RenderMode==GL_FEEDBACK) { FEEDBACK_TOKEN( ctx, (GLfloat) GL_PASS_THROUGH_TOKEN ); FEEDBACK_TOKEN( ctx, token ); } }
void gl_FeedbackBuffer( GLcontext *ctx, GLsizei size, GLenum type, GLfloat *buffer ) { if (ctx->RenderMode==GL_FEEDBACK || INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glFeedbackBuffer" ); return; } if (size<0) { gl_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(size<0)" ); return; } if (!buffer) { gl_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(buffer==NULL)" ); ctx->Feedback.BufferSize = 0; return; } switch (type) { case GL_2D: ctx->Feedback.Mask = 0; ctx->Feedback.Type = type; break; case GL_3D: ctx->Feedback.Mask = FB_3D; ctx->Feedback.Type = type; break; case GL_3D_COLOR: ctx->Feedback.Mask = FB_3D | (ctx->Visual->RGBAflag ? FB_COLOR : FB_INDEX); ctx->Feedback.Type = type; break; case GL_3D_COLOR_TEXTURE: ctx->Feedback.Mask = FB_3D | (ctx->Visual->RGBAflag ? FB_COLOR : FB_INDEX) | FB_TEXTURE; ctx->Feedback.Type = type; break; case GL_4D_COLOR_TEXTURE: ctx->Feedback.Mask = FB_3D | FB_4D | (ctx->Visual->RGBAflag ? FB_COLOR : FB_INDEX) | FB_TEXTURE; ctx->Feedback.Type = type; break; default: ctx->Feedback.Mask = 0; gl_error( ctx, GL_INVALID_ENUM, "glFeedbackBuffer" ); } ctx->Feedback.BufferSize = size; ctx->Feedback.Buffer = buffer; ctx->Feedback.Count = 0; }
void gl_ClearIndex( GLcontext *ctx, GLfloat c ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glClearIndex" ); return; } ctx->Color.ClearIndex = (GLuint) c; if (!ctx->Visual->RGBAflag) { /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */ (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex ); } }
void gl_LineWidth( GLcontext *ctx, GLfloat width ) { if (width<=0.0) { gl_error( ctx, GL_INVALID_VALUE, "glLineWidth" ); return; } if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glLineWidth" ); return; } ctx->Line.Width = width; ctx->NewState |= NEW_RASTER_OPS; }
void gl_Rectf( GLcontext *ctx, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glRect" ); return; } (*ctx->API.Begin)( ctx, GL_QUADS ); (*ctx->API.Vertex4f)( ctx, x1, y1, 0.0F, 1.0F ); (*ctx->API.Vertex4f)( ctx, x2, y1, 0.0F, 1.0F ); (*ctx->API.Vertex4f)( ctx, x2, y2, 0.0F, 1.0F ); (*ctx->API.Vertex4f)( ctx, x1, y2, 0.0F, 1.0F ); (*ctx->API.End)( ctx ); }
void gl_PointSize( GLcontext *ctx, GLfloat size ) { if (size<=0.0) { gl_error( ctx, GL_INVALID_VALUE, "glPointSize" ); return; } if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glPointSize" ); return; } ctx->Point.Size = size; ctx->NewState |= NEW_RASTER_OPS; }
void gl_DepthMask( GLcontext* ctx, GLboolean flag ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glDepthMask" ); return; } /* * GL_TRUE indicates depth buffer writing is enabled (default) * GL_FALSE indicates depth buffer writing is disabled */ ctx->Depth.Mask = flag; ctx->NewState |= NEW_RASTER_OPS; }
/* * NOTE: this function can't be put in a display list. */ void gl_SelectBuffer( GLcontext *ctx, GLsizei size, GLuint *buffer ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glSelectBuffer" ); } if (ctx->RenderMode==GL_SELECT) { gl_error( ctx, GL_INVALID_OPERATION, "glSelectBuffer" ); } ctx->Select.Buffer = buffer; ctx->Select.BufferSize = size; ctx->Select.BufferCount = 0; ctx->Select.HitFlag = GL_FALSE; ctx->Select.HitMinZ = 1.0; ctx->Select.HitMaxZ = 0.0; }
void gl_DrawBuffer( GLcontext *ctx, GLenum mode ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); return; } switch (mode) { case GL_FRONT: case GL_FRONT_LEFT: case GL_FRONT_AND_BACK: if ( (*ctx->Driver.SetBuffer)( ctx, GL_FRONT ) == GL_FALSE ) { gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" ); return; } ctx->Color.DrawBuffer = mode; ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha; ctx->NewState |= NEW_RASTER_OPS; break; case GL_BACK: case GL_BACK_LEFT: if ( (*ctx->Driver.SetBuffer)( ctx, GL_BACK ) == GL_FALSE) { gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" ); return; } ctx->Color.DrawBuffer = mode; ctx->Buffer->Alpha = ctx->Buffer->BackAlpha; ctx->NewState |= NEW_RASTER_OPS; break; case GL_NONE: ctx->Color.DrawBuffer = mode; ctx->Buffer->Alpha = NULL; ctx->NewState |= NEW_RASTER_OPS; break; case GL_FRONT_RIGHT: case GL_BACK_RIGHT: case GL_LEFT: case GL_RIGHT: case GL_AUX0: gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); break; default: gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" ); } }
/* * Execute a glRect*() function. */ void gl_Rectf( GLcontext *ctx, GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) { /* * TODO: we could examine a bunch of state variables and ultimately * call the Driver->RectFunc() function to draw a screen-aligned * filled rectangle. Someday... */ if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glRect" ); return; } gl_Begin( ctx, GL_QUADS ); (*ctx->Exec.Vertex2f)( ctx, x1, y1 ); (*ctx->Exec.Vertex2f)( ctx, x2, y1 ); (*ctx->Exec.Vertex2f)( ctx, x2, y2 ); (*ctx->Exec.Vertex2f)( ctx, x1, y2 ); gl_End( ctx ); }
void gl_PushName( GLcontext *ctx, GLuint name ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glPushName" ); return; } if (ctx->RenderMode!=GL_SELECT) { return; } if (ctx->Select.HitFlag) { write_hit_record( ctx ); } if (ctx->Select.NameStackDepth<MAX_NAME_STACK_DEPTH) { ctx->Select.NameStack[ctx->Select.NameStackDepth++] = name; } else { gl_error( ctx, GL_STACK_OVERFLOW, "glPushName" ); } }
void gl_PopName( GLcontext *ctx ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glPopName" ); return; } if (ctx->RenderMode!=GL_SELECT) { return; } if (ctx->Select.HitFlag) { write_hit_record( ctx ); } if (ctx->Select.NameStackDepth>0) { ctx->Select.NameStackDepth--; } else { gl_error( ctx, GL_STACK_UNDERFLOW, "glPopName" ); } }
void gl_Scissor( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height ) { if (width<0 || height<0) { gl_error( ctx, GL_INVALID_VALUE, "glScissor" ); return; } if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glBegin" ); return; } ctx->Scissor.X = x; ctx->Scissor.Y = y; ctx->Scissor.Width = width; ctx->Scissor.Height = height; ctx->NewState |= NEW_ALL; /* TODO: this is overkill */ }
void gl_TexEnvfv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glTexEnv" ); return; } if (target!=GL_TEXTURE_ENV) { gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(target)" ); return; } if (pname==GL_TEXTURE_ENV_MODE) { GLenum mode = (GLenum) (GLint) *param; switch (mode) { case GL_MODULATE: case GL_BLEND: case GL_DECAL: case GL_REPLACE: ctx->Texture.EnvMode = mode; break; default: gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" ); return; } } else if (pname==GL_TEXTURE_ENV_COLOR) { ctx->Texture.EnvColor[0] = CLAMP( param[0], 0.0, 1.0 ); ctx->Texture.EnvColor[1] = CLAMP( param[1], 0.0, 1.0 ); ctx->Texture.EnvColor[2] = CLAMP( param[2], 0.0, 1.0 ); ctx->Texture.EnvColor[3] = CLAMP( param[3], 0.0, 1.0 ); } else { gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" ); return; } /* Tell device driver about the new texture environment */ if (ctx->Driver.TexEnv) { (*ctx->Driver.TexEnv)( ctx, pname, param ); } }
void gl_ReadBuffer( GLcontext *ctx, GLenum mode ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" ); return; } switch (mode) { case GL_FRONT: case GL_FRONT_LEFT: if ( (*ctx->Driver.SetBuffer)( ctx, GL_FRONT ) == GL_FALSE) { gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" ); return; } ctx->Pixel.ReadBuffer = mode; ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha; ctx->NewState |= NEW_RASTER_OPS; break; case GL_BACK: case GL_BACK_LEFT: if ( (*ctx->Driver.SetBuffer)( ctx, GL_BACK ) == GL_FALSE) { gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" ); return; } ctx->Pixel.ReadBuffer = mode; ctx->Buffer->Alpha = ctx->Buffer->BackAlpha; ctx->NewState |= NEW_RASTER_OPS; break; case GL_FRONT_RIGHT: case GL_BACK_RIGHT: case GL_LEFT: case GL_RIGHT: case GL_AUX0: gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" ); break; default: gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" ); } /* Remember, the draw buffer is the default state */ (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer ); }
void gl_ClearColor( GLcontext *ctx, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glClearColor" ); return; } ctx->Color.ClearColor[0] = CLAMP( red, 0.0F, 1.0F ); ctx->Color.ClearColor[1] = CLAMP( green, 0.0F, 1.0F ); ctx->Color.ClearColor[2] = CLAMP( blue, 0.0F, 1.0F ); ctx->Color.ClearColor[3] = CLAMP( alpha, 0.0F, 1.0F ); if (ctx->Visual->RGBAflag) { GLubyte r = (GLint) (ctx->Color.ClearColor[0] * ctx->Visual->RedScale); GLubyte g = (GLint) (ctx->Color.ClearColor[1] * ctx->Visual->GreenScale); GLubyte b = (GLint) (ctx->Color.ClearColor[2] * ctx->Visual->BlueScale); GLubyte a = (GLint) (ctx->Color.ClearColor[3] * ctx->Visual->AlphaScale); (*ctx->Driver.ClearColor)( ctx, r, g, b, a ); } }
void gl_DepthFunc( GLcontext* ctx, GLenum func ) { if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glDepthFunc" ); return; } switch (func) { case GL_NEVER: case GL_LESS: /* (default) pass if incoming z < stored z */ case GL_GEQUAL: case GL_LEQUAL: case GL_GREATER: case GL_NOTEQUAL: case GL_EQUAL: case GL_ALWAYS: ctx->Depth.Func = func; ctx->NewState |= NEW_RASTER_OPS; break; default: gl_error( ctx, GL_INVALID_ENUM, "glDepth.Func" ); } }
void gl_Accum( GLcontext *ctx, GLenum op, GLfloat value ) { GLuint xpos, ypos, width, height; GLfloat acc_scale; if (ctx->Visual->AccumBits==0 || !ctx->Buffer->Accum) { /* No accumulation buffer! */ return; } if (sizeof(GLaccum)==1) { acc_scale = 127.0; } else if (sizeof(GLaccum)==2) { acc_scale = 32767.0; } else { /* sizeof(GLaccum) > 2 (Cray) */ acc_scale = (float) SHRT_MAX; } if (INSIDE_BEGIN_END(ctx)) { gl_error( ctx, GL_INVALID_OPERATION, "glAccum" ); return; } /* Determine region to operate upon. */ if (ctx->Scissor.Enabled) { xpos = ctx->Scissor.X; ypos = ctx->Scissor.Y; width = ctx->Scissor.Width; height = ctx->Scissor.Height; } else { /* whole window */ xpos = 0; ypos = 0; width = ctx->Buffer->Width; height = ctx->Buffer->Height; } switch (op) { case GL_ADD: { GLaccum ival, *acc; GLuint i, j; ival = (GLaccum) (value * acc_scale); for (j=0;j<height;j++) { acc = ctx->Buffer->Accum + (ypos * ctx->Buffer->Width + xpos) * 4; for (i=0;i<width;i++) { *acc += ival; acc++; /* red */ *acc += ival; acc++; /* green */ *acc += ival; acc++; /* blue */ *acc += ival; acc++; /* alpha */ } ypos++; } } break; case GL_MULT: { GLaccum *acc; GLuint i, j; for (j=0;j<height;j++) { acc = ctx->Buffer->Accum + (ypos * ctx->Buffer->Width + xpos) * 4; for (i=0;i<width;i++) { *acc = (GLaccum) ( (GLfloat) *acc * value ); acc++; /*r*/ *acc = (GLaccum) ( (GLfloat) *acc * value ); acc++; /*g*/ *acc = (GLaccum) ( (GLfloat) *acc * value ); acc++; /*g*/ *acc = (GLaccum) ( (GLfloat) *acc * value ); acc++; /*a*/ } ypos++; } } break; case GL_ACCUM: { GLaccum *acc; GLubyte red[MAX_WIDTH], green[MAX_WIDTH]; GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH]; GLfloat rscale, gscale, bscale, ascale; GLuint i, j; (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer ); /* Accumulate */ rscale = value * acc_scale * ctx->Visual->InvRedScale; gscale = value * acc_scale * ctx->Visual->InvGreenScale; bscale = value * acc_scale * ctx->Visual->InvBlueScale; ascale = value * acc_scale * ctx->Visual->InvAlphaScale; for (j=0;j<height;j++) { (*ctx->Driver.ReadColorSpan)( ctx, width, xpos, ypos, red, green, blue, alpha); acc = ctx->Buffer->Accum + (ypos * ctx->Buffer->Width + xpos) * 4; for (i=0;i<width;i++) { *acc += (GLaccum) ( (GLfloat) red[i] * rscale ); acc++; *acc += (GLaccum) ( (GLfloat) green[i] * gscale ); acc++; *acc += (GLaccum) ( (GLfloat) blue[i] * bscale ); acc++; *acc += (GLaccum) ( (GLfloat) alpha[i] * ascale ); acc++; } ypos++; } (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer ); } break; case GL_LOAD: { GLaccum *acc; GLubyte red[MAX_WIDTH], green[MAX_WIDTH]; GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH]; GLfloat rscale, gscale, bscale, ascale; GLuint i, j; (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer ); /* Load accumulation buffer */ rscale = value * acc_scale * ctx->Visual->InvRedScale; gscale = value * acc_scale * ctx->Visual->InvGreenScale; bscale = value * acc_scale * ctx->Visual->InvBlueScale; ascale = value * acc_scale * ctx->Visual->InvAlphaScale; for (j=0;j<height;j++) { (*ctx->Driver.ReadColorSpan)( ctx, width, xpos, ypos, red, green, blue, alpha); acc = ctx->Buffer->Accum + (ypos * ctx->Buffer->Width + xpos) * 4; for (i=0;i<width;i++) { *acc++ = (GLaccum) ( (GLfloat) red[i] * rscale ); *acc++ = (GLaccum) ( (GLfloat) green[i] * gscale ); *acc++ = (GLaccum) ( (GLfloat) blue[i] * bscale ); *acc++ = (GLaccum) ( (GLfloat) alpha[i] * ascale ); } ypos++; } (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer ); } break; case GL_RETURN: { GLubyte red[MAX_WIDTH], green[MAX_WIDTH]; GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH]; GLaccum *acc; GLfloat rscale, gscale, bscale, ascale; GLint rmax, gmax, bmax, amax; GLuint i, j; rscale = value / acc_scale * ctx->Visual->RedScale; gscale = value / acc_scale * ctx->Visual->GreenScale; bscale = value / acc_scale * ctx->Visual->BlueScale; ascale = value / acc_scale * ctx->Visual->AlphaScale; rmax = (GLint) ctx->Visual->RedScale; gmax = (GLint) ctx->Visual->GreenScale; bmax = (GLint) ctx->Visual->BlueScale; amax = (GLint) ctx->Visual->AlphaScale; for (j=0;j<height;j++) { acc = ctx->Buffer->Accum + (ypos * ctx->Buffer->Width + xpos) * 4; for (i=0;i<width;i++) { GLint r, g, b, a; r = (GLint) ( (GLfloat) (*acc++) * rscale + 0.5F ); g = (GLint) ( (GLfloat) (*acc++) * gscale + 0.5F ); b = (GLint) ( (GLfloat) (*acc++) * bscale + 0.5F ); a = (GLint) ( (GLfloat) (*acc++) * ascale + 0.5F ); red[i] = CLAMP( r, 0, rmax ); green[i] = CLAMP( g, 0, gmax ); blue[i] = CLAMP( b, 0, bmax ); alpha[i] = CLAMP( a, 0, amax ); } (*ctx->Driver.WriteColorSpan)( ctx, width, xpos, ypos, red, green, blue, alpha, NULL ); ypos++; } } break; default: gl_error( ctx, GL_INVALID_ENUM, "glAccum" ); } }