drawpix.c revision f93b3dd69e744cf1dd6b102a11cdb07c2df4a967
1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* $Id: drawpix.c,v 1.31 2000/08/30 18:22:28 brianp Exp $ */ 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Mesa 3-D graphics library 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Version: 3.5 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Permission is hereby granted, free of charge, to any person obtaining a 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * copy of this software and associated documentation files (the "Software"), 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * to deal in the Software without restriction, including without limitation 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * and/or sell copies of the Software, and to permit persons to whom the 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Software is furnished to do so, subject to the following conditions: 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * The above copyright notice and this permission notice shall be included 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * in all copies or substantial portions of the Software. 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef PC_HEADER 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "all.h" 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "glheader.h" 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "context.h" 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "convolve.h" 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drawpix.h" 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "feedback.h" 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "image.h" 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "macros.h" 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "mem.h" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "mmath.h" 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pixel.h" 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pixeltex.h" 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "span.h" 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "state.h" 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "stencil.h" 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "texture.h" 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "types.h" 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "zoom.h" 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Given the dest position, size and skipPixels and skipRows values 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * for a glDrawPixels command, perform clipping of the image bounds 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * so the result lies withing the context's buffer bounds. 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Return: GL_TRUE if image is ready for drawing 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * GL_FALSE if image was completely clipped away (draw nothing) 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownGLboolean 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown_mesa_clip_pixelrect(const GLcontext *ctx, 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint *destX, GLint *destY, 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLsizei *width, GLsizei *height, 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint *skipPixels, GLint *skipRows) 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const GLframebuffer *buffer = ctx->DrawBuffer; 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* left clipping */ 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*destX < buffer->Xmin) { 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *skipPixels += (buffer->Xmin - *destX); 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *width -= (buffer->Xmin - *destX); 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *destX = buffer->Xmin; 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* right clipping */ 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*destX + *width > buffer->Xmax) 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *width -= (*destX + *width - buffer->Xmax - 1); 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*width <= 0) 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_FALSE; 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* bottom clipping */ 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*destY < buffer->Ymin) { 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *skipRows += (buffer->Ymin - *destY); 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *height -= (buffer->Ymin - *destY); 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *destY = buffer->Ymin; 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* top clipping */ 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*destY + *height > buffer->Ymax) 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *height -= (*destY + *height - buffer->Ymax - 1); 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*height <= 0) 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Try to do a fast and simple RGB(a) glDrawPixels. 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic GLboolean 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfast_draw_pixels(GLcontext *ctx, GLint x, GLint y, 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLsizei width, GLsizei height, 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLenum format, GLenum type, const GLvoid *pixels) 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const GLuint cantTransferBits = 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IMAGE_SCALE_BIAS_BIT | 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IMAGE_SHIFT_OFFSET_BIT | 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IMAGE_MAP_COLOR_BIT | 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IMAGE_COLOR_TABLE_BIT | 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IMAGE_CONVOLUTION_BIT | 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT | 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IMAGE_COLOR_MATRIX_BIT | 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT | 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IMAGE_HISTOGRAM_BIT | 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IMAGE_MIN_MAX_BIT; 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLubyte rgb[MAX_WIDTH][3]; 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLubyte rgba[MAX_WIDTH][4]; 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glDrawPixels", 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GL_FALSE); 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!ctx->Current.RasterPosValid) { 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; /* no-op */ 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((ctx->RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (ctx->ImageTransferState & cantTransferBits) == 0 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && ctx->Texture.ReallyEnabled == 0 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && unpack->Alignment == 1 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && !unpack->SwapBytes 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && !unpack->LsbFirst) { 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint destX = x; 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint destY = y; 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint drawWidth = width; /* actual width drawn */ 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint drawHeight = height; /* actual height drawn */ 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint skipPixels = unpack->SkipPixels; 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint skipRows = unpack->SkipRows; 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint rowLength; 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLdepth zSpan[MAX_WIDTH]; /* only used when zooming */ 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint zoomY0; 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (unpack->RowLength > 0) 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rowLength = unpack->RowLength; 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rowLength = width; 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If we're not using pixel zoom then do all clipping calculations 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * now. Otherwise, we'll let the gl_write_zoomed_*_span() functions 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * handle the clipping. 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* horizontal clipping */ 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (destX < ctx->DrawBuffer->Xmin) { 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown skipPixels += (ctx->DrawBuffer->Xmin - destX); 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drawWidth -= (ctx->DrawBuffer->Xmin - destX); 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destX = ctx->DrawBuffer->Xmin; 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (destX + drawWidth > ctx->DrawBuffer->Xmax) 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drawWidth -= (destX + drawWidth - ctx->DrawBuffer->Xmax - 1); 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (drawWidth <= 0) 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vertical clipping */ 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (destY < ctx->DrawBuffer->Ymin) { 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown skipRows += (ctx->DrawBuffer->Ymin - destY); 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drawHeight -= (ctx->DrawBuffer->Ymin - destY); 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY = ctx->DrawBuffer->Ymin; 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (destY + drawHeight > ctx->DrawBuffer->Ymax) 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drawHeight -= (destY + drawHeight - ctx->DrawBuffer->Ymax - 1); 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (drawHeight <= 0) 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zoomY0 = 0; /* not used - silence compiler warning */ 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* upside-down image */ 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* horizontal clipping */ 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (destX < ctx->DrawBuffer->Xmin) { 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown skipPixels += (ctx->DrawBuffer->Xmin - destX); 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drawWidth -= (ctx->DrawBuffer->Xmin - destX); 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destX = ctx->DrawBuffer->Xmin; 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (destX + drawWidth > ctx->DrawBuffer->Xmax) 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drawWidth -= (destX + drawWidth - ctx->DrawBuffer->Xmax - 1); 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (drawWidth <= 0) 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vertical clipping */ 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (destY > ctx->DrawBuffer->Ymax) { 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown skipRows += (destY - ctx->DrawBuffer->Ymax - 1); 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drawHeight -= (destY - ctx->DrawBuffer->Ymax - 1); 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY = ctx->DrawBuffer->Ymax + 1; 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (destY - drawHeight < ctx->DrawBuffer->Ymin) 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drawHeight -= (ctx->DrawBuffer->Ymin - (destY - drawHeight)); 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (drawHeight <= 0) 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* setup array of fragment Z value to pass to zoom function */ 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual->DepthMaxF); 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint i; 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ASSERT(drawWidth < MAX_WIDTH); 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i=0; i<drawWidth; i++) 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zSpan[i] = z; 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* save Y value of first row */ 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zoomY0 = (GLint) (ctx->Current.RasterPos[1] + 0.5F); 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Ready to draw! 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * The window region at (destX, destY) of size (drawWidth, drawHeight) 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * will be written to. 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * We'll take pixel data from buffer pointed to by "pixels" but we'll 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * skip "skipRows" rows and skip "skipPixels" pixels/row. 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (format==GL_RGBA && type==GL_UNSIGNED_BYTE) { 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Visual->RGBAflag) { 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLubyte *src = (GLubyte *) pixels 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + (skipRows * rowLength + skipPixels) * 4; 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* no zooming */ 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *) src, NULL); 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength * 4; 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY++; 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* upside-down */ 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY--; 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *) src, NULL); 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength * 4; 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* with zooming */ 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY, 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zSpan, (void *) src, zoomY0); 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength * 4; 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY++; 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (format==GL_RGB && type==GL_UNSIGNED_BYTE) { 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Visual->RGBAflag) { 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLubyte *src = (GLubyte *) pixels 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + (skipRows * rowLength + skipPixels) * 3; 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *) src, NULL); 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength * 3; 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY++; 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* upside-down */ 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY--; 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *) src, NULL); 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength * 3; 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* with zooming */ 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY, 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zSpan, (void *) src, zoomY0); 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength * 3; 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY++; 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (format==GL_LUMINANCE && type==GL_UNSIGNED_BYTE) { 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Visual->RGBAflag) { 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLubyte *src = (GLubyte *) pixels 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + (skipRows * rowLength + skipPixels); 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* no zooming */ 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ASSERT(drawWidth < MAX_WIDTH); 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint i; 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i=0;i<drawWidth;i++) { 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgb[i][0] = src[i]; 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgb[i][1] = src[i]; 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgb[i][2] = src[i]; 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *) rgb, NULL); 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength; 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY++; 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* upside-down */ 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ASSERT(drawWidth < MAX_WIDTH); 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint i; 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i=0;i<drawWidth;i++) { 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgb[i][0] = src[i]; 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgb[i][1] = src[i]; 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgb[i][2] = src[i]; 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY--; 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*ctx->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY, 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *) rgb, NULL); 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength; 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* with zooming */ 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ASSERT(drawWidth < MAX_WIDTH); 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint i; 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i=0;i<drawWidth;i++) { 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgb[i][0] = src[i]; 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgb[i][1] = src[i]; 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgb[i][2] = src[i]; 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gl_write_zoomed_rgb_span(ctx, drawWidth, destX, destY, 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zSpan, (void *) rgb, zoomY0); 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength; 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY++; 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (format==GL_LUMINANCE_ALPHA && type==GL_UNSIGNED_BYTE) { 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Visual->RGBAflag) { 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLubyte *src = (GLubyte *) pixels 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + (skipRows * rowLength + skipPixels)*2; 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* no zooming */ 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ASSERT(drawWidth < MAX_WIDTH); 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint i; 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLubyte *ptr = src; 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i=0;i<drawWidth;i++) { 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][0] = *ptr; 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][1] = *ptr; 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][2] = *ptr++; 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][3] = *ptr++; 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *) rgba, NULL); 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength*2; 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY++; 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* upside-down */ 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ASSERT(drawWidth < MAX_WIDTH); 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint i; 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLubyte *ptr = src; 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i=0;i<drawWidth;i++) { 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][0] = *ptr; 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][1] = *ptr; 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][2] = *ptr++; 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][3] = *ptr++; 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY--; 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *) rgba, NULL); 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength*2; 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* with zooming */ 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ASSERT(drawWidth < MAX_WIDTH); 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLubyte *ptr = src; 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint i; 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i=0;i<drawWidth;i++) { 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][0] = *ptr; 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][1] = *ptr; 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][2] = *ptr++; 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rgba[i][3] = *ptr++; 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY, 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zSpan, (void *) rgba, zoomY0); 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength*2; 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY++; 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (format==GL_COLOR_INDEX && type==GL_UNSIGNED_BYTE) { 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLubyte *src = (GLubyte *) pixels + skipRows * rowLength + skipPixels; 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Visual->RGBAflag) { 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* convert CI data to RGBA */ 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* no zooming */ 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ASSERT(drawWidth < MAX_WIDTH); 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba); 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (const GLubyte (*)[4])rgba, 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown NULL); 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength; 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY++; 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* upside-down */ 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ASSERT(drawWidth < MAX_WIDTH); 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba); 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY--; 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*ctx->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY, 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (const GLubyte (*)[4])rgba, 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown NULL); 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength; 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* with zooming */ 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ASSERT(drawWidth < MAX_WIDTH); 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _mesa_map_ci8_to_rgba(ctx, drawWidth, src, rgba); 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gl_write_zoomed_rgba_span(ctx, drawWidth, destX, destY, 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zSpan, (void *) rgba, zoomY0); 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength; 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY++; 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* write CI data to CI frame buffer */ 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GLint row; 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* no zooming */ 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (row=0; row<drawHeight; row++) { 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*ctx->Driver.WriteCI8Span)(ctx, drawWidth, destX, destY, 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src, NULL); 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src += rowLength; 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown destY++; 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_TRUE; 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* with zooming */ 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_FALSE; 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* can't handle this pixel format and/or data type here */ 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_FALSE; 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* can't do a simple draw, have to use slow path */ 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return GL_FALSE; 494} 495 496 497 498/* 499 * Do glDrawPixels of index pixels. 500 */ 501static void 502draw_index_pixels( GLcontext *ctx, GLint x, GLint y, 503 GLsizei width, GLsizei height, 504 GLenum type, const GLvoid *pixels ) 505{ 506 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 507 const GLint desty = y; 508 GLint row, drawWidth; 509 GLdepth zspan[MAX_WIDTH]; 510 511 drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; 512 513 /* Fragment depth values */ 514 if (ctx->Depth.Test || ctx->Fog.Enabled) { 515 GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual->DepthMaxF); 516 GLint i; 517 for (i = 0; i < drawWidth; i++) { 518 zspan[i] = zval; 519 } 520 } 521 522 /* 523 * General solution 524 */ 525 for (row = 0; row < height; row++, y++) { 526 GLuint indexes[MAX_WIDTH]; 527 const GLvoid *source = _mesa_image_address(&ctx->Unpack, 528 pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0); 529 _mesa_unpack_index_span(ctx, drawWidth, GL_UNSIGNED_INT, indexes, 530 type, source, &ctx->Unpack, 531 ctx->ImageTransferState); 532 if (zoom) { 533 gl_write_zoomed_index_span(ctx, drawWidth, x, y, zspan, indexes, desty); 534 } 535 else { 536 gl_write_index_span(ctx, drawWidth, x, y, zspan, indexes, GL_BITMAP); 537 } 538 } 539} 540 541 542 543/* 544 * Do glDrawPixels of stencil image. The image datatype may either 545 * be GLubyte or GLbitmap. 546 */ 547static void 548draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y, 549 GLsizei width, GLsizei height, 550 GLenum type, const GLvoid *pixels ) 551{ 552 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 553 const GLint desty = y; 554 GLint row, drawWidth; 555 556 if (type != GL_BYTE && 557 type != GL_UNSIGNED_BYTE && 558 type != GL_SHORT && 559 type != GL_UNSIGNED_SHORT && 560 type != GL_INT && 561 type != GL_UNSIGNED_INT && 562 type != GL_FLOAT && 563 type != GL_BITMAP) { 564 gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(stencil type)"); 565 return; 566 } 567 568 drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; 569 570 for (row = 0; row < height; row++, y++) { 571 GLstencil values[MAX_WIDTH]; 572 GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte)) 573 ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT; 574 const GLvoid *source = _mesa_image_address(&ctx->Unpack, 575 pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0); 576 _mesa_unpack_index_span(ctx, drawWidth, destType, values, 577 type, source, &ctx->Unpack, 578 ctx->ImageTransferState); 579 if (ctx->ImageTransferState & IMAGE_SHIFT_OFFSET_BIT) { 580 _mesa_shift_and_offset_stencil( ctx, drawWidth, values ); 581 } 582 if (ctx->Pixel.MapStencilFlag) { 583 _mesa_map_stencil( ctx, drawWidth, values ); 584 } 585 586 if (zoom) { 587 gl_write_zoomed_stencil_span( ctx, (GLuint) drawWidth, x, y, 588 values, desty ); 589 } 590 else { 591 _mesa_write_stencil_span( ctx, (GLuint) drawWidth, x, y, values ); 592 } 593 } 594} 595 596 597 598/* 599 * Do a glDrawPixels of depth values. 600 */ 601static void 602draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, 603 GLsizei width, GLsizei height, 604 GLenum type, const GLvoid *pixels ) 605{ 606 const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0; 607 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 608 const GLint desty = y; 609 GLubyte rgba[MAX_WIDTH][4]; 610 GLuint ispan[MAX_WIDTH]; 611 GLint drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; 612 613 if (type != GL_BYTE 614 && type != GL_UNSIGNED_BYTE 615 && type != GL_SHORT 616 && type != GL_UNSIGNED_SHORT 617 && type != GL_INT 618 && type != GL_UNSIGNED_INT 619 && type != GL_FLOAT) { 620 gl_error(ctx, GL_INVALID_ENUM, "glDrawPixels(type)"); 621 return; 622 } 623 624 /* Colors or indexes */ 625 if (ctx->Visual->RGBAflag) { 626 GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0F); 627 GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0F); 628 GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0F); 629 GLint a = (GLint) (ctx->Current.RasterColor[3] * 255.0F); 630 GLint i; 631 for (i = 0; i < drawWidth; i++) { 632 rgba[i][RCOMP] = r; 633 rgba[i][GCOMP] = g; 634 rgba[i][BCOMP] = b; 635 rgba[i][ACOMP] = a; 636 } 637 } 638 else { 639 GLint i; 640 for (i = 0; i < drawWidth; i++) { 641 ispan[i] = ctx->Current.RasterIndex; 642 } 643 } 644 645 if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort) 646 && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) { 647 /* Special case: directly write 16-bit depth values */ 648 GLint row; 649 for (row = 0; row < height; row++, y++) { 650 GLdepth zspan[MAX_WIDTH]; 651 const GLushort *zptr = _mesa_image_address(&ctx->Unpack, 652 pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); 653 GLint i; 654 for (i = 0; i < width; i++) 655 zspan[i] = zptr[i]; 656 gl_write_rgba_span( ctx, width, x, y, zspan, rgba, GL_BITMAP ); 657 } 658 } 659 else if (type==GL_UNSIGNED_INT && ctx->Visual->DepthBits == 32 660 && !bias_or_scale && !zoom && ctx->Visual->RGBAflag) { 661 /* Special case: directly write 32-bit depth values */ 662 GLint row; 663 for (row = 0; row < height; row++, y++) { 664 const GLuint *zptr = _mesa_image_address(&ctx->Unpack, 665 pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); 666 gl_write_rgba_span( ctx, width, x, y, zptr, rgba, GL_BITMAP ); 667 } 668 } 669 else { 670 /* General case */ 671 GLint row; 672 for (row = 0; row < height; row++, y++) { 673 GLdepth zspan[MAX_WIDTH]; 674 const GLvoid *src = _mesa_image_address(&ctx->Unpack, 675 pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); 676 _mesa_unpack_depth_span( ctx, drawWidth, zspan, type, src, 677 &ctx->Unpack, ctx->ImageTransferState ); 678 if (ctx->Visual->RGBAflag) { 679 if (zoom) { 680 gl_write_zoomed_rgba_span(ctx, width, x, y, zspan, 681 (const GLubyte (*)[4])rgba, desty); 682 } 683 else { 684 gl_write_rgba_span(ctx, width, x, y, zspan, rgba, GL_BITMAP); 685 } 686 } 687 else { 688 if (zoom) { 689 gl_write_zoomed_index_span(ctx, width, x, y, zspan, 690 ispan, GL_BITMAP); 691 } 692 else { 693 gl_write_index_span(ctx, width, x, y, zspan, ispan, GL_BITMAP); 694 } 695 } 696 697 } 698 } 699} 700 701 702/* 703 * Do glDrawPixels of RGBA pixels. 704 */ 705static void 706draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, 707 GLsizei width, GLsizei height, 708 GLenum format, GLenum type, const GLvoid *pixels ) 709{ 710 const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; 711 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 712 const GLint desty = y; 713 GLdepth zspan[MAX_WIDTH]; 714 GLboolean quickDraw; 715 GLfloat *convImage = NULL; 716 GLuint transferOps = ctx->ImageTransferState; 717 718 /* Try an optimized glDrawPixels first */ 719 if (fast_draw_pixels(ctx, x, y, width, height, format, type, pixels)) 720 return; 721 722 /* Fragment depth values */ 723 if (ctx->Depth.Test || ctx->Fog.Enabled) { 724 /* fill in array of z values */ 725 GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->Visual->DepthMaxF); 726 GLint i; 727 for (i=0;i<width;i++) { 728 zspan[i] = z; 729 } 730 } 731 732 733 if (ctx->RasterMask == 0 && !zoom && x >= 0 && y >= 0 734 && x + width <= ctx->DrawBuffer->Width 735 && y + height <= ctx->DrawBuffer->Height) { 736 quickDraw = GL_TRUE; 737 } 738 else { 739 quickDraw = GL_FALSE; 740 } 741 742 if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { 743 /* Convolution has to be handled specially. We'll create an 744 * intermediate image, applying all pixel transfer operations 745 * up to convolution. Then we'll convolve the image. Then 746 * we'll proceed with the rest of the transfer operations and 747 * rasterize the image. 748 */ 749 GLint row; 750 GLfloat *dest, *tmpImage; 751 752 tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); 753 if (!tmpImage) { 754 gl_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 755 return; 756 } 757 convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); 758 if (!convImage) { 759 FREE(tmpImage); 760 gl_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 761 return; 762 } 763 764 /* Unpack the image and apply transfer ops up to convolution */ 765 dest = tmpImage; 766 for (row = 0; row < height; row++) { 767 const GLvoid *source = _mesa_image_address(unpack, 768 pixels, width, height, format, type, 0, row, 0); 769 _mesa_unpack_float_color_span(ctx, width, GL_RGBA, (void *) dest, 770 format, type, source, unpack, 771 transferOps & IMAGE_PRE_CONVOLUTION_BITS, 772 GL_FALSE); 773 dest += width * 4; 774 } 775 776 /* do convolution */ 777 if (ctx->Pixel.Convolution2DEnabled) { 778 _mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage); 779 } 780 else { 781 ASSERT(ctx->Pixel.Separable2DEnabled); 782 _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage); 783 } 784 FREE(tmpImage); 785 786 /* continue transfer ops and draw the convolved image */ 787 unpack = &_mesa_native_packing; 788 pixels = convImage; 789 format = GL_RGBA; 790 type = GL_FLOAT; 791 transferOps &= IMAGE_POST_CONVOLUTION_BITS; 792 } 793 794 /* 795 * General solution 796 */ 797 { 798 GLubyte rgba[MAX_WIDTH][4]; 799 GLint row; 800 if (width > MAX_WIDTH) 801 width = MAX_WIDTH; 802 for (row = 0; row < height; row++, y++) { 803 const GLvoid *source = _mesa_image_address(unpack, 804 pixels, width, height, format, type, 0, row, 0); 805 _mesa_unpack_ubyte_color_span(ctx, width, GL_RGBA, (void*) rgba, 806 format, type, source, unpack, 807 transferOps); 808 if ((ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink) || 809 (ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink)) 810 continue; 811 812 if (ctx->Texture.ReallyEnabled && ctx->Pixel.PixelTextureEnabled) { 813 GLfloat s[MAX_WIDTH], t[MAX_WIDTH], r[MAX_WIDTH], q[MAX_WIDTH]; 814 GLubyte primary_rgba[MAX_WIDTH][4]; 815 GLuint unit; 816 /* XXX not sure how multitexture is supposed to work here */ 817 818 MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLubyte)); 819 820 for (unit = 0; unit < MAX_TEXTURE_UNITS; unit++) { 821 _mesa_pixeltexgen(ctx, width, (const GLubyte (*)[4]) rgba, 822 s, t, r, q); 823 gl_texture_pixels(ctx, unit, width, s, t, r, NULL, 824 primary_rgba, rgba); 825 } 826 } 827 828 if (quickDraw) { 829 (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, 830 (CONST GLubyte (*)[]) rgba, NULL); 831 } 832 else if (zoom) { 833 gl_write_zoomed_rgba_span( ctx, width, x, y, zspan, 834 (CONST GLubyte (*)[]) rgba, desty ); 835 } 836 else { 837 gl_write_rgba_span( ctx, (GLuint) width, x, y, zspan, rgba, GL_BITMAP); 838 } 839 } 840 } 841 842 if (convImage) { 843 FREE(convImage); 844 } 845} 846 847 848 849/* 850 * Execute glDrawPixels 851 */ 852void 853_mesa_DrawPixels( GLsizei width, GLsizei height, 854 GLenum format, GLenum type, const GLvoid *pixels ) 855{ 856 GET_CURRENT_CONTEXT(ctx); 857 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawPixels"); 858 859 if (ctx->RenderMode==GL_RENDER) { 860 GLint x, y; 861 if (!pixels || !ctx->Current.RasterPosValid) { 862 return; 863 } 864 865 if (ctx->NewState) { 866 gl_update_state(ctx); 867 } 868 869 if (ctx->ImageTransferState == UPDATE_IMAGE_TRANSFER_STATE) 870 _mesa_update_image_transfer_state(ctx); 871 872 x = (GLint) (ctx->Current.RasterPos[0] + 0.5F); 873 y = (GLint) (ctx->Current.RasterPos[1] + 0.5F); 874 875 ctx->OcclusionResult = GL_TRUE; 876 877 /* see if device driver can do the drawpix */ 878 if (ctx->Driver.DrawPixels 879 && (*ctx->Driver.DrawPixels)(ctx, x, y, width, height, format, type, 880 &ctx->Unpack, pixels)) { 881 return; 882 } 883 884 switch (format) { 885 case GL_STENCIL_INDEX: 886 draw_stencil_pixels( ctx, x, y, width, height, type, pixels ); 887 break; 888 case GL_DEPTH_COMPONENT: 889 draw_depth_pixels( ctx, x, y, width, height, type, pixels ); 890 break; 891 case GL_COLOR_INDEX: 892 if (ctx->Visual->RGBAflag) 893 draw_rgba_pixels(ctx, x,y, width, height, format, type, pixels); 894 else 895 draw_index_pixels(ctx, x, y, width, height, type, pixels); 896 break; 897 case GL_RED: 898 case GL_GREEN: 899 case GL_BLUE: 900 case GL_ALPHA: 901 case GL_LUMINANCE: 902 case GL_LUMINANCE_ALPHA: 903 case GL_RGB: 904 case GL_BGR: 905 case GL_RGBA: 906 case GL_BGRA: 907 case GL_ABGR_EXT: 908 draw_rgba_pixels(ctx, x, y, width, height, format, type, pixels); 909 break; 910 default: 911 gl_error( ctx, GL_INVALID_ENUM, "glDrawPixels(format)" ); 912 return; 913 } 914 } 915 else if (ctx->RenderMode==GL_FEEDBACK) { 916 if (ctx->Current.RasterPosValid) { 917 GLfloat color[4]; 918 GLfloat texcoord[4], invq; 919 UBYTE_RGBA_TO_FLOAT_RGBA(color, ctx->Current.ByteColor); 920 invq = 1.0F / ctx->Current.Texcoord[0][3]; 921 texcoord[0] = ctx->Current.Texcoord[0][0] * invq; 922 texcoord[1] = ctx->Current.Texcoord[0][1] * invq; 923 texcoord[2] = ctx->Current.Texcoord[0][2] * invq; 924 texcoord[3] = ctx->Current.Texcoord[0][3]; 925 FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN ); 926 gl_feedback_vertex( ctx, 927 ctx->Current.RasterPos, 928 color, ctx->Current.Index, texcoord ); 929 } 930 } 931 else if (ctx->RenderMode==GL_SELECT) { 932 if (ctx->Current.RasterPosValid) { 933 gl_update_hitflag( ctx, ctx->Current.RasterPos[2] ); 934 } 935 } 936} 937 938