📄 s_drawpix.c
字号:
} return GL_TRUE; } } } /* can't handle this pixel format and/or data type */ 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 ){ const GLint imgX = x, imgY = y; const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; GLint row, skipPixels; SWspan span; INIT_SPAN(span, GL_BITMAP); span.arrayMask = SPAN_INDEX; _swrast_span_default_attribs(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_stencil_span(ctx, spanWidth, destType, values, type, source, unpack, ctx->_ImageTransferState); 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 ){ 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; SWspan span; INIT_SPAN(span, GL_BITMAP); span.arrayMask = SPAN_Z; _swrast_span_default_attribs(ctx, &span); if (type == GL_UNSIGNED_SHORT && ctx->DrawBuffer->Visual.depthBits == 16 && !scaleOrBias && !zoom && ctx->Visual.rgbMode && width <= MAX_WIDTH && !unpack->SwapBytes) { /* 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 && !unpack->SwapBytes) { /* 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 GLuint depthMax = ctx->DrawBuffer->_DepthMax; 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 ){ const GLint imgX = x, imgY = y; const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; GLfloat *convImage = NULL; GLbitfield transferOps = ctx->_ImageTransferState; SWspan span; /* Try an optimized glDrawPixels first */ if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels)) { return; } INIT_SPAN(span, GL_BITMAP); _swrast_span_default_attribs(ctx, &span); span.arrayMask = SPAN_RGBA; span.arrayAttribs = FRAG_BIT_COL0; /* we're fill in COL0 attrib values */ 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 */ dest = tmpImage; for (row = 0; row < height; row++) { const GLvoid *source = _mesa_image_address2d(unpack, pixels, width, height, format, type, row, 0); _mesa_unpack_color_span_float(ctx, width, GL_RGBA, (GLfloat *) dest, format, type, source, unpack, transferOps & IMAGE_PRE_CONVOLUTION_BITS); dest += width * 4; } /* do convolution */ if (ctx->Pixel.Convolution2DEnabled) { _mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage); } else { ASSERT(ctx->Pixel.Separable2DEnabled); _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage); } _mesa_free(tmpImage); /* continue transfer ops and draw the convolved image */ unpack = &ctx->DefaultPacking; pixels = convImage; format = GL_RGBA; type = GL_FLOAT; transferOps &= IMAGE_POST_CONVOLUTION_BITS; } else if (ctx->Pixel.Convolution1DEnabled) { /* we only want to apply 1D convolution to glTexImage1D */ transferOps &= ~(IMAGE_CONVOLUTION_BIT | IMAGE_POST_CONVOLUTION_SCALE_BIAS); } if (ctx->DrawBuffer->_NumColorDrawBuffers > 0 && ctx->DrawBuffer->_ColorDrawBuffers[0]->DataType != GL_FLOAT && ctx->Color.ClampFragmentColor != GL_FALSE) { /* need to clamp colors before applying fragment ops */ transferOps |= IMAGE_CLAMP_BIT; } /* * General solution */ { const GLboolean sink = (ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink) || (ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -