diff options
author | Brian Paul <[email protected]> | 1999-11-26 16:28:03 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 1999-11-26 16:28:03 +0000 |
commit | 9afe0e42783c14bcb6f1ba6a76ff777d55d3e20a (patch) | |
tree | 15587c483c545f4bf1b3a2990d8eddd270c9af61 /src/mesa | |
parent | 3e63be01d1888149c1c4181d0572f14952f3407c (diff) |
generate Z values when fog enabled (Andree Borrmann)
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/main/drawpix.c | 577 |
1 files changed, 416 insertions, 161 deletions
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index 103855f7fa8..cc9edadf893 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -1,8 +1,8 @@ -/* $Id: drawpix.c,v 1.6 1999/11/11 01:22:26 brianp Exp $ */ +/* $Id: drawpix.c,v 1.5.2.1 1999/11/26 16:28:03 brianp Exp $ */ /* * Mesa 3-D graphics library - * Version: 3.3 + * Version: 3.1 * * Copyright (C) 1999 Brian Paul All Rights Reserved. * @@ -25,10 +25,19 @@ */ + + + #ifdef PC_HEADER #include "all.h" #else -#include "glheader.h" +#ifndef XFree86Server +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#else +#include "GL/xf86glx.h" +#endif #include "context.h" #include "drawpix.h" #include "feedback.h" @@ -44,16 +53,23 @@ +/* TODO: apply texture mapping to fragments */ + + /* - * Try to do a fast and simple RGB(a) glDrawPixels. + * Try to do a fast glDrawPixels. Conditions include: + * not using a display list + * simple pixel unpacking + * no raster ops + * etc.... * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead */ -static GLboolean -simple_DrawPixels( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, GLenum format, GLenum type, - const GLvoid *pixels ) +GLboolean gl_direct_DrawPixels( GLcontext *ctx, + const struct gl_pixelstore_attrib *unpack, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ) { - const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; GLubyte rgb[MAX_WIDTH][3]; GLubyte rgba[MAX_WIDTH][4]; @@ -71,10 +87,12 @@ simple_DrawPixels( GLcontext *ctx, GLint x, GLint y, } /* see if device driver can do the drawpix */ - if (ctx->Driver.DrawPixels - && (*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type, - unpack, pixels)) { - return GL_TRUE; + if (ctx->Driver.DrawPixels) { + GLint x = (GLint) (ctx->Current.RasterPos[0] + 0.5F); + GLint y = (GLint) (ctx->Current.RasterPos[1] + 0.5F); + if ((*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type, + unpack, pixels)) + return GL_TRUE; } if ((ctx->RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0 @@ -88,8 +106,8 @@ simple_DrawPixels( GLcontext *ctx, GLint x, GLint y, && !unpack->SwapBytes && !unpack->LsbFirst) { - GLint destX = x; - GLint destY = y; + GLint destX = (GLint) (ctx->Current.RasterPos[0] + 0.5F); + GLint destY = (GLint) (ctx->Current.RasterPos[1] + 0.5F); GLint drawWidth = width; /* actual width drawn */ GLint drawHeight = height; /* actual height drawn */ GLint skipPixels = unpack->SkipPixels; @@ -346,9 +364,10 @@ simple_DrawPixels( GLcontext *ctx, GLint x, GLint y, return GL_FALSE; } } - - /* can't do a simple draw, have to use slow path */ - return GL_FALSE; + else { + /* can't do direct render, have to use slow path */ + return GL_FALSE; + } } @@ -356,43 +375,99 @@ simple_DrawPixels( GLcontext *ctx, GLint x, GLint y, /* * Do glDrawPixels of index pixels. */ -static void -draw_index_pixels( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum type, const GLvoid *pixels ) +static void draw_index_pixels( GLcontext *ctx, GLint x, GLint y, + const struct gl_image *image ) { - const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; + GLint width, height, widthInBytes; const GLint desty = y; - GLint row, drawWidth; + GLint i, j; GLdepth zspan[MAX_WIDTH]; + const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; - drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + assert(image); + assert(image->Format == GL_COLOR_INDEX); + + width = image->Width; + height = image->Height; + if (image->Type == GL_BITMAP) + widthInBytes = (width + 7) / 8; + else + widthInBytes = width; /* Fragment depth values */ - if (ctx->Depth.Test) { + if (ctx->Depth.Test || ctx->Fog.Enabled) { GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE); - GLint i; - for (i = 0; i < drawWidth; i++) { + for (i=0;i<width;i++) { zspan[i] = zval; } } - /* - * General solution - */ - for (row = 0; row < height; row++, y++) { - GLuint indexes[MAX_WIDTH]; - const GLvoid *source = gl_pixel_addr_in_image(&ctx->Unpack, - pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0); - _mesa_unpack_index_span(ctx, drawWidth, GL_UNSIGNED_INT, indexes, - type, source, &ctx->Unpack, GL_TRUE); - if (zoom) { - gl_write_zoomed_index_span(ctx, drawWidth, x, y, zspan, indexes, desty); + /* process the image row by row */ + for (i=0;i<height;i++,y++) { + GLuint ispan[MAX_WIDTH]; + + /* convert to uints */ + switch (image->Type) { + case GL_UNSIGNED_BYTE: + { + GLubyte *src = (GLubyte *) image->Data + i * width; + for (j=0;j<width;j++) { + ispan[j] = (GLuint) *src++; + } + } + break; + case GL_FLOAT: + { + GLfloat *src = (GLfloat *) image->Data + i * width; + for (j=0;j<width;j++) { + ispan[j] = (GLuint) (GLint) *src++; + } + } + break; + case GL_BITMAP: + { + GLubyte *src = (GLubyte *) image->Data + i * widthInBytes; + for (j=0;j<width;j++) { + ispan[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1; + } + } + break; + default: + gl_problem( ctx, "draw_index_pixels type" ); + return; + } + + /* apply shift and offset */ + if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) { + gl_shift_and_offset_ci( ctx, width, ispan ); + } + + if (ctx->Visual->RGBAflag) { + /* Convert index to RGBA and write to frame buffer */ + GLubyte rgba[MAX_WIDTH][4]; + gl_map_ci_to_rgba( ctx, width, ispan, rgba ); + if (zoom) { + gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, + (const GLubyte (*)[4])rgba, desty ); + } + else { + gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP ); + } } else { - gl_write_index_span(ctx, drawWidth, x, y, zspan, indexes, GL_BITMAP); + /* optionally apply index map then write to frame buffer */ + if (ctx->Pixel.MapColorFlag) { + gl_map_ci(ctx, width, ispan); + } + if (zoom) { + gl_write_zoomed_index_span( ctx, width, x, y, zspan, ispan, desty ); + } + else { + gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP ); + } } } + } @@ -401,44 +476,83 @@ draw_index_pixels( GLcontext *ctx, GLint x, GLint y, * Do glDrawPixels of stencil image. The image datatype may either * be GLubyte or GLbitmap. */ -static void -draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum type, const GLvoid *pixels ) +static void draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y, + const struct gl_image *image ) { - const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; + GLint widthInBytes, width, height; const GLint desty = y; - GLint row, drawWidth; - - if (type != GL_BYTE && - type != GL_UNSIGNED_BYTE && - type != GL_SHORT && - type != GL_UNSIGNED_SHORT && - type != GL_INT && - type != GL_UNSIGNED_INT && - type != GL_FLOAT && - type != GL_BITMAP) { - gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(stencil type)"); + GLint i; + const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; + + if (image->Type != GL_BYTE && + image->Type != GL_UNSIGNED_BYTE && + image->Type != GL_SHORT && + image->Type != GL_UNSIGNED_SHORT && + image->Type != GL_INT && + image->Type != GL_UNSIGNED_INT && + image->Type != GL_FLOAT && + image->Type != GL_BITMAP) { + gl_error( ctx, GL_INVALID_OPERATION, "glDrawPixels(stencil type)"); return; } - drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + assert(image); + assert(image->Format == GL_STENCIL_INDEX); + assert(image->Type == GL_UNSIGNED_BYTE || image->Type == GL_BITMAP); + + if (image->Type == GL_UNSIGNED_BYTE) + widthInBytes = image->Width; + else + widthInBytes = (image->Width + 7) / 8; + width = image->Width; + height = image->Height; + + /* process the image row by row */ + for (i=0;i<height;i++,y++) { + GLstencil *src = (GLstencil*)image->Data + i * widthInBytes; + GLstencil *stencilValues; + GLstencil stencilCopy[MAX_WIDTH]; + + if (image->Type == GL_BITMAP) { + /* convert bitmap data to GLubyte (0 or 1) data */ + GLint j; + for (j = 0; j < width; j++) { + stencilCopy[j] = ( src[j >> 3] >> (7 - (j & 0x7)) ) & 1; + } + src = stencilCopy; + } + + if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift + || ctx->Pixel.MapStencilFlag) { - for (row = 0; row < height; row++, y++) { - GLstencil values[MAX_WIDTH]; - GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte)) - ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT; - const GLvoid *source = gl_pixel_addr_in_image(&ctx->Unpack, - pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0); - _mesa_unpack_index_span(ctx, drawWidth, destType, values, - type, source, &ctx->Unpack, GL_TRUE); + /* make copy of stencil values */ + if (src != stencilCopy) + MEMCPY( stencilCopy, src, width * sizeof(GLstencil)); + /* apply shift and offset */ + if (ctx->Pixel.IndexOffset || ctx->Pixel.IndexShift) { + gl_shift_and_offset_stencil( ctx, width, stencilCopy ); + } + + /* mapping */ + if (ctx->Pixel.MapStencilFlag) { + gl_map_stencil( ctx, width, stencilCopy ); + } + + stencilValues = stencilCopy; + } + else { + /* use stencil values in-place */ + stencilValues = src; + } + + /* write stencil values to stencil buffer */ if (zoom) { - gl_write_zoomed_stencil_span( ctx, (GLuint) drawWidth, x, y, - values, desty ); + gl_write_zoomed_stencil_span( ctx, (GLuint) width, x, y, + stencilValues, desty ); } else { - gl_write_stencil_span( ctx, (GLuint) drawWidth, x, y, values ); + gl_write_stencil_span( ctx, (GLuint) width, x, y, stencilValues ); } } } @@ -448,37 +562,30 @@ draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y, /* * Do a glDrawPixels of depth values. */ -static void -draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum type, const GLvoid *pixels ) +static void draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, + const struct gl_image *image ) { - const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0; - const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; + GLint width, height; const GLint desty = y; GLubyte rgba[MAX_WIDTH][4]; GLuint ispan[MAX_WIDTH]; - GLint drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; - - if (type != GL_UNSIGNED_BYTE - && type != GL_UNSIGNED_BYTE - && type != GL_UNSIGNED_SHORT - && type != GL_UNSIGNED_SHORT - && type != GL_UNSIGNED_INT - && type != GL_UNSIGNED_INT - && type != GL_FLOAT) { - gl_error(ctx, GL_INVALID_ENUM, "glDrawPixels(type)"); - return; - } + const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0; + const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; + + assert(image); + assert(image->Format == GL_DEPTH_COMPONENT); - /* Colors or indexes */ + width = image->Width; + height = image->Height; + + /* Color or index */ if (ctx->Visual->RGBAflag) { GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0F); GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0F); GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0F); GLint a = (GLint) (ctx->Current.RasterColor[3] * 255.0F); GLint i; - for (i = 0; i < drawWidth; i++) { + for (i=0; i<width; i++) { rgba[i][RCOMP] = r; rgba[i][GCOMP] = g; rgba[i][BCOMP] = b; @@ -487,36 +594,34 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, } else { GLint i; - for (i = 0; i < drawWidth; i++) { + for (i=0;i<width;i++) { ispan[i] = ctx->Current.RasterIndex; } } - if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort) + if (image->Type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort) && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) { /* Special case: directly write 16-bit depth values */ - GLint row; - for (row = 0; row < height; row++, y++) { - const GLdepth *zptr = gl_pixel_addr_in_image(&ctx->Unpack, - pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); + GLint j; + for (j=0;j<height;j++,y++) { + GLdepth *zptr = (GLdepth *) image->Data + j * width; gl_write_rgba_span( ctx, width, x, y, zptr, rgba, GL_BITMAP ); } } - else if (type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint) + else if (image->Type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint) && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) { /* Special case: directly write 32-bit depth values */ - GLint i, row; + GLint i, j; /* Compute shift value to scale 32-bit uints down to depth values. */ GLuint shift = 0; GLuint max = MAX_DEPTH; - while ((max & 0x80000000) == 0) { + while ((max&0x80000000)==0) { max = max << 1; shift++; } - for (row = 0; row < height; row++, y++) { + for (j=0;j<height;j++,y++) { GLdepth zspan[MAX_WIDTH]; - const GLdepth *zptr = gl_pixel_addr_in_image(&ctx->Unpack, - pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); + GLuint *zptr = (GLuint *) image->Data + j * width; for (i=0;i<width;i++) { zspan[i] = zptr[i] >> shift; } @@ -524,30 +629,72 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, } } else { - /* General case */ - GLint row; - for (row = 0; row < height; row++, y++) { + /* General case (slower) */ + GLint i, j; + + /* process image row by row */ + for (i=0;i<height;i++,y++) { + GLfloat depth[MAX_WIDTH]; GLdepth zspan[MAX_WIDTH]; - const GLvoid *src = gl_pixel_addr_in_image(&ctx->Unpack, - pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); - _mesa_unpack_depth_span( ctx, drawWidth, zspan, type, src, - &ctx->Unpack, GL_TRUE ); + + switch (image->Type) { + case GL_UNSIGNED_SHORT: + { + GLushort *src = (GLushort *) image->Data + i * width; + for (j=0;j<width;j++) { + depth[j] = USHORT_TO_FLOAT( *src++ ); + } + } + break; + case GL_UNSIGNED_INT: + { + GLuint *src = (GLuint *) image->Data + i * width; + for (j=0;j<width;j++) { + depth[j] = UINT_TO_FLOAT( *src++ ); + } + } + break; + case GL_FLOAT: + { + GLfloat *src = (GLfloat *) image->Data + i * width; + for (j=0;j<width;j++) { + depth[j] = *src++; + } + } + break; + default: + gl_problem(ctx, "Bad type in draw_depth_pixels"); + return; + } + + /* apply depth scale and bias */ + if (ctx->Pixel.DepthScale!=1.0 || ctx->Pixel.DepthBias!=0.0) { + for (j=0;j<width;j++) { + depth[j] = depth[j] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias; + } + } + + /* clamp depth values to [0,1] and convert from floats to integers */ + for (j=0;j<width;j++) { + zspan[j] = (GLdepth) (CLAMP( depth[j], 0.0F, 1.0F ) * DEPTH_SCALE); + } + if (ctx->Visual->RGBAflag) { if (zoom) { - gl_write_zoomed_rgba_span(ctx, width, x, y, zspan, - (const GLubyte (*)[4])rgba, desty); + gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, + (const GLubyte (*)[4])rgba, desty ); } else { - gl_write_rgba_span(ctx, width, x, y, zspan, rgba, GL_BITMAP); + gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP ); } } else { if (zoom) { - gl_write_zoomed_index_span(ctx, width, x, y, zspan, - ispan, GL_BITMAP); + gl_write_zoomed_index_span( ctx, width, x, y, zspan, + ispan, GL_BITMAP ); } else { - gl_write_index_span(ctx, width, x, y, zspan, ispan, GL_BITMAP); + gl_write_index_span( ctx, width, x, y, zspan, ispan, GL_BITMAP ); } } @@ -556,71 +703,184 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, } + +/* Simple unpacking parameters: */ +static struct gl_pixelstore_attrib NoUnpack = { + 1, /* Alignment */ + 0, /* RowLength */ + 0, /* SkipPixels */ + 0, /* SkipRows */ + 0, /* ImageHeight */ + 0, /* SkipImages */ + GL_FALSE, /* SwapBytes */ + GL_FALSE /* LsbFirst */ +}; + + /* * Do glDrawPixels of RGBA pixels. */ -static void -draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid *pixels ) +static void draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, + const struct gl_image *image ) { - const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; - const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; + GLint width, height; + GLint i, j; const GLint desty = y; GLdepth zspan[MAX_WIDTH]; GLboolean quickDraw; + const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; + + assert(image); /* Try an optimized glDrawPixels first */ - if (simple_DrawPixels(ctx, x, y, width, height, format, type, pixels)) + if (gl_direct_DrawPixels(ctx, &NoUnpack, image->Width, image->Height, + image->Format, image->Type, image->Data )) return; + width = image->Width; + height = image->Height; + /* Fragment depth values */ - if (ctx->Depth.Test) { + if (ctx->Depth.Test || ctx->Fog.Enabled) { /* fill in array of z values */ GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * DEPTH_SCALE); - GLint i; for (i=0;i<width;i++) { zspan[i] = z; } } - - if (ctx->RasterMask == 0 && !zoom - && x >= 0 && y >= 0 - && x + width <= ctx->Buffer->Width - && y + height <= ctx->Buffer->Height) { + if (ctx->RasterMask==0 && !zoom && x>=0 && y>=0 + && x+width<=ctx->Buffer->Width && y+height<=ctx->Buffer->Height) { quickDraw = GL_TRUE; } else { quickDraw = GL_FALSE; } - /* - * General solution - */ { + /* General solution */ + GLboolean r_flag, g_flag, b_flag, a_flag, l_flag; + GLuint components; GLubyte rgba[MAX_WIDTH][4]; - GLint row; - if (width > MAX_WIDTH) - width = MAX_WIDTH; - for (row = 0; row < height; row++, y++) { - const GLvoid *source = gl_pixel_addr_in_image(unpack, - pixels, width, height, format, type, 0, row, 0); - _mesa_unpack_ubyte_color_span(ctx, width, GL_RGBA, (void*) rgba, - format, type, source, unpack, GL_TRUE); + GLfloat rf[MAX_WIDTH]; + GLfloat gf[MAX_WIDTH]; + GLfloat bf[MAX_WIDTH]; + DEFARRAY(GLfloat,af,MAX_WIDTH); + CHECKARRAY(af,return); + + r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE; + switch (image->Format) { + case GL_RED: + r_flag = GL_TRUE; + components = 1; + break; + case GL_GREEN: + g_flag = GL_TRUE; + components = 1; + break; + case GL_BLUE: + b_flag = GL_TRUE; + components = 1; + break; + case GL_ALPHA: + a_flag = GL_TRUE; + components = 1; + break; + case GL_RGB: + r_flag = g_flag = b_flag = GL_TRUE; + components = 3; + break; + case GL_LUMINANCE: + l_flag = GL_TRUE; + components = 1; + break; + case GL_LUMINANCE_ALPHA: + l_flag = a_flag = GL_TRUE; + components = 2; + break; + case GL_RGBA: + r_flag = g_flag = b_flag = a_flag = GL_TRUE; + components = 4; + break; + default: + gl_problem(ctx, "Bad type in draw_rgba_pixels"); + goto cleanup; + } + /* process the image row by row */ + for (i=0;i<height;i++,y++) { + /* convert to floats */ + switch (image->Type) { + case GL_UNSIGNED_BYTE: + { + GLubyte *src = (GLubyte *) image->Data + i * width * components; + for (j=0;j<width;j++) { + if (l_flag) { + rf[j] = gf[j] = bf[j] = UBYTE_TO_FLOAT(*src++); + } + else { + rf[j] = r_flag ? UBYTE_TO_FLOAT(*src++) : 0.0; + gf[j] = g_flag ? UBYTE_TO_FLOAT(*src++) : 0.0; + bf[j] = b_flag ? UBYTE_TO_FLOAT(*src++) : 0.0; + } + af[j] = a_flag ? UBYTE_TO_FLOAT(*src++) : 1.0; + } + } + break; + case GL_FLOAT: + { + GLfloat *src = (GLfloat *) image->Data + i * width * components; + for (j=0;j<width;j++) { + if (l_flag) { + rf[j] = gf[j] = bf[j] = *src++; + } + else { + rf[j] = r_flag ? *src++ : 0.0; + gf[j] = g_flag ? *src++ : 0.0; + bf[j] = b_flag ? *src++ : 0.0; + } + af[j] = a_flag ? *src++ : 1.0; + } + } + break; + default: + gl_problem( ctx, "draw_rgba_pixels type" ); + goto cleanup; + } + + /* apply scale and bias */ + if (ctx->Pixel.ScaleOrBiasRGBA) { + gl_scale_and_bias_color(ctx, width, rf, gf, bf, af); + } + + /* apply pixel mappings */ + if (ctx->Pixel.MapColorFlag) { + gl_map_color(ctx, width, rf, gf, bf, af); + } + + /* convert to integers */ + for (j=0;j<width;j++) { + rgba[j][RCOMP] = (GLint) (rf[j] * 255.0F); + rgba[j][GCOMP] = (GLint) (gf[j] * 255.0F); + rgba[j][BCOMP] = (GLint) (bf[j] * 255.0F); + rgba[j][ACOMP] = (GLint) (af[j] * 255.0F); + } + + /* write to frame buffer */ if (quickDraw) { - (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, - (CONST GLubyte (*)[]) rgba, NULL); + (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, + (const GLubyte (*)[4])rgba, NULL); } else if (zoom) { gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, - (CONST GLubyte (*)[]) rgba, desty ); + (const GLubyte (*)[4])rgba, desty ); } else { gl_write_rgba_span( ctx, (GLuint) width, x, y, zspan, rgba, GL_BITMAP); } } +cleanup: + UNDEFARRAY(af); } } @@ -629,50 +889,45 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, /* * Execute glDrawPixels */ -void -_mesa_DrawPixels( GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid *pixels ) +void gl_DrawPixels( GLcontext* ctx, struct gl_image *image ) { - GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawPixels"); + + if (gl_image_error_test( ctx, image, "glDrawPixels" )) + return; + if (ctx->RenderMode==GL_RENDER) { GLint x, y; - if (!pixels || !ctx->Current.RasterPosValid) { + if (!ctx->Current.RasterPosValid) { return; } x = (GLint) (ctx->Current.RasterPos[0] + 0.5F); y = (GLint) (ctx->Current.RasterPos[1] + 0.5F); - switch (format) { + switch (image->Format) { + case GL_COLOR_INDEX: + draw_index_pixels( ctx, x, y, image ); + break; case GL_STENCIL_INDEX: - draw_stencil_pixels( ctx, x, y, width, height, type, pixels ); + draw_stencil_pixels( ctx, x, y, image ); break; case GL_DEPTH_COMPONENT: - draw_depth_pixels( ctx, x, y, width, height, type, pixels ); - break; - case GL_COLOR_INDEX: - if (ctx->Visual->RGBAflag) - draw_index_pixels(ctx, x, y, width, height, type, pixels); - else - draw_rgba_pixels(ctx, x,y, width, height, format, type, pixels); + draw_depth_pixels( ctx, x, y, image ); break; case GL_RED: case GL_GREEN: case GL_BLUE: case GL_ALPHA: + case GL_RGB: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: - case GL_RGB: - case GL_BGR: case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - draw_rgba_pixels(ctx, x, y, width, height, format, type, pixels); + draw_rgba_pixels( ctx, x, y, image ); break; default: - gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(format)" ); + gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels" ); return; } } |