📄 s_drawpix.c
字号:
/* convert CI data to RGBA */ if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { /* no zooming */ GLint row; for (row=0; row<drawHeight; row++) { ASSERT(drawWidth <= MAX_WIDTH); _mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba); rb->PutRow(ctx, rb, drawWidth, destX, destY, span.array->rgba, NULL); src += rowLength; destY++; } return GL_TRUE; } else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { /* upside-down */ GLint row; for (row=0; row<drawHeight; row++) { ASSERT(drawWidth <= MAX_WIDTH); _mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba); destY--; rb->PutRow(ctx, rb, drawWidth, destX, destY, span.array->rgba, NULL); src += rowLength; } return GL_TRUE; } else { /* with zooming */ GLint row; for (row=0; row<drawHeight; row++) { ASSERT(drawWidth <= MAX_WIDTH); _mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba); span.x = destX; span.y = destY; span.end = drawWidth; _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, (CONST GLchan (*)[4]) span.array->rgba); src += rowLength; destY++; } return GL_TRUE; } } else if (ctx->_ImageTransferState==0) { /* write CI data to CI frame buffer */ GLint row; if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { /* no zooming */ for (row=0; row<drawHeight; row++) { GLuint index32[MAX_WIDTH]; GLint col; for (col = 0; col < drawWidth; col++) index32[col] = src[col]; rb->PutRow(ctx, rb, drawWidth, destX, destY, index32, NULL); src += rowLength; destY++; } return GL_TRUE; } else { /* with zooming */ return GL_FALSE; } } } else { /* can't handle this pixel format and/or data type here */ return GL_FALSE; } } /* can't do a simple draw, have to use slow path */ return GL_FALSE;}/* * Draw color index image. */static voiddraw_index_pixels( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ){ SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLint imgX = x, imgY = y; const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; GLint row, skipPixels; struct sw_span span; INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX); if (ctx->Depth.Test) _swrast_span_default_z(ctx, &span); if (swrast->_FogEnabled) _swrast_span_default_fog(ctx, &span); /* * General solution */ skipPixels = 0; while (skipPixels < width) { const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); ASSERT(spanWidth <= MAX_WIDTH); for (row = 0; row < height; row++) { const GLvoid *source = _mesa_image_address2d(unpack, pixels, width, height, GL_COLOR_INDEX, type, row, skipPixels); _mesa_unpack_index_span(ctx, spanWidth, GL_UNSIGNED_INT, span.array->index, type, source, unpack, ctx->_ImageTransferState); /* These may get changed during writing/clipping */ span.x = x + skipPixels; span.y = y + row; span.end = spanWidth; if (zoom) _swrast_write_zoomed_index_span(ctx, imgX, imgY, &span); else _swrast_write_index_span(ctx, &span); } skipPixels += spanWidth; }}/* * Draw stencil image. */static voiddraw_stencil_pixels( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ){ const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; GLint skipPixels; /* if width > MAX_WIDTH, have to process image in chunks */ skipPixels = 0; while (skipPixels < width) { const GLint spanX = x + skipPixels; const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); GLint row; for (row = 0; row < height; row++) { const GLint spanY = y + row; GLstencil values[MAX_WIDTH]; GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte)) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT; const GLvoid *source = _mesa_image_address2d(unpack, pixels, width, height, GL_COLOR_INDEX, type, row, skipPixels); _mesa_unpack_index_span(ctx, spanWidth, destType, values, type, source, unpack, ctx->_ImageTransferState); if (ctx->_ImageTransferState & IMAGE_SHIFT_OFFSET_BIT) { _mesa_shift_and_offset_stencil(ctx, spanWidth, values); } if (ctx->Pixel.MapStencilFlag) { _mesa_map_stencil(ctx, spanWidth, values); } if (zoom) { _swrast_write_zoomed_stencil_span(ctx, x, y, spanWidth, spanX, spanY, values); } else { _swrast_write_stencil_span(ctx, spanWidth, spanX, spanY, values); } } skipPixels += spanWidth; }}/* * Draw depth image. */static voiddraw_depth_pixels( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ){ SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLboolean scaleOrBias = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; struct sw_span span; INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z); _swrast_span_default_color(ctx, &span); if (swrast->_FogEnabled) _swrast_span_default_fog(ctx, &span); if (ctx->Texture._EnabledCoordUnits) _swrast_span_default_texcoords(ctx, &span); if (type == GL_UNSIGNED_SHORT && ctx->DrawBuffer->Visual.depthBits == 16 && !scaleOrBias && !zoom && ctx->Visual.rgbMode && width <= MAX_WIDTH) { /* Special case: directly write 16-bit depth values */ GLint row; for (row = 0; row < height; row++) { const GLushort *zSrc = (const GLushort *) _mesa_image_address2d(unpack, pixels, width, height, GL_DEPTH_COMPONENT, type, row, 0); GLint i; for (i = 0; i < width; i++) span.array->z[i] = zSrc[i]; span.x = x; span.y = y + row; span.end = width; _swrast_write_rgba_span(ctx, &span); } } else if (type == GL_UNSIGNED_INT && !scaleOrBias && !zoom && ctx->Visual.rgbMode && width <= MAX_WIDTH) { /* Special case: shift 32-bit values down to Visual.depthBits */ const GLint shift = 32 - ctx->DrawBuffer->Visual.depthBits; GLint row; for (row = 0; row < height; row++) { const GLuint *zSrc = (const GLuint *) _mesa_image_address2d(unpack, pixels, width, height, GL_DEPTH_COMPONENT, type, row, 0); if (shift == 0) { _mesa_memcpy(span.array->z, zSrc, width * sizeof(GLuint)); } else { GLint col; for (col = 0; col < width; col++) span.array->z[col] = zSrc[col] >> shift; } span.x = x; span.y = y + row; span.end = width; _swrast_write_rgba_span(ctx, &span); } } else { /* General case */ const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; GLint skipPixels = 0; /* in case width > MAX_WIDTH do the copy in chunks */ while (skipPixels < width) { const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); GLint row; ASSERT(span.end <= MAX_WIDTH); for (row = 0; row < height; row++) { const GLvoid *zSrc = _mesa_image_address2d(unpack, pixels, width, height, GL_DEPTH_COMPONENT, type, row, skipPixels); /* Set these for each row since the _swrast_write_* function may * change them while clipping. */ span.x = x + skipPixels; span.y = y + row; span.end = spanWidth; _mesa_unpack_depth_span(ctx, spanWidth, GL_UNSIGNED_INT, span.array->z, depthMax, type, zSrc, unpack); if (zoom) { _swrast_write_zoomed_depth_span(ctx, x, y, &span); } else if (ctx->Visual.rgbMode) { _swrast_write_rgba_span(ctx, &span); } else { _swrast_write_index_span(ctx, &span); } } skipPixels += spanWidth; } }}/* * Draw RGBA image. */static voiddraw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ){ SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLint imgX = x, imgY = y; struct gl_renderbuffer *rb = NULL; /* only used for quickDraw path */ const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; GLboolean quickDraw; GLfloat *convImage = NULL; GLuint transferOps = ctx->_ImageTransferState; struct sw_span span; INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA); /* Try an optimized glDrawPixels first */ if (fast_draw_pixels(ctx, x, y, width, height, format, type, unpack, pixels)) return; if (ctx->Depth.Test) _swrast_span_default_z(ctx, &span); if (swrast->_FogEnabled) _swrast_span_default_fog(ctx, &span); if (ctx->Texture._EnabledCoordUnits) _swrast_span_default_texcoords(ctx, &span); if (swrast->_RasterMask == 0 && !zoom && x >= 0 && y >= 0 && x + width <= (GLint) ctx->DrawBuffer->Width && y + height <= (GLint) ctx->DrawBuffer->Height && ctx->DrawBuffer->_NumColorDrawBuffers[0] == 1) { quickDraw = GL_TRUE; rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0]; } else { quickDraw = GL_FALSE; rb = NULL; } if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { /* Convolution has to be handled specially. We'll create an * intermediate image, applying all pixel transfer operations * up to convolution. Then we'll convolve the image. Then * we'll proceed with the rest of the transfer operations and * rasterize the image. */ GLint row; GLfloat *dest, *tmpImage; tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); if (!tmpImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); return; } convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); if (!convImage) { _mesa_free(tmpImage); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); return; } /* Unpack the image and apply transfer ops up to convolution */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -