📄 s_drawpix.c
字号:
const GLbitfield interpMask = span.interpMask; const GLbitfield arrayMask = span.arrayMask; const GLint srcStride = _mesa_image_row_stride(unpack, width, format, type); GLint skipPixels = 0; /* use span array for temp color storage */ GLfloat *rgba = (GLfloat *) span.array->attribs[FRAG_ATTRIB_COL0]; /* if the span is wider than MAX_WIDTH we have to do it in chunks */ while (skipPixels < width) { const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); const GLubyte *source = (const GLubyte *) _mesa_image_address2d(unpack, pixels, width, height, format, type, 0, skipPixels); GLint row; for (row = 0; row < height; row++) { /* get image row as float/RGBA */ _mesa_unpack_color_span_float(ctx, spanWidth, GL_RGBA, rgba, format, type, source, unpack, transferOps); /* draw the span */ if (!sink) { /* Set these for each row since the _swrast_write_* functions * may change them while clipping/rendering. */ span.array->ChanType = GL_FLOAT; span.x = x + skipPixels; span.y = y + row; span.end = spanWidth; span.arrayMask = arrayMask; span.interpMask = interpMask; if (zoom) { _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, rgba); } else { _swrast_write_rgba_span(ctx, &span); } } source += srcStride; } /* for row */ skipPixels += spanWidth; } /* while skipPixels < width */ /* XXX this is ugly/temporary, to undo above change */ span.array->ChanType = CHAN_TYPE; } if (convImage) { _mesa_free(convImage); }}/** * This is a bit different from drawing GL_DEPTH_COMPONENT pixels. * The only per-pixel operations that apply are depth scale/bias, * stencil offset/shift, GL_DEPTH_WRITEMASK and GL_STENCIL_WRITEMASK, * and pixel zoom. * Also, only the depth buffer and stencil buffers are touched, not the * color buffer(s). */static voiddraw_depth_stencil_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 scaleOrBias = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0; const GLuint depthMax = ctx->DrawBuffer->_DepthMax; const GLuint stencilMask = ctx->Stencil.WriteMask[0]; const GLuint stencilType = (STENCIL_BITS == 8) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; struct gl_renderbuffer *depthRb, *stencilRb; struct gl_pixelstore_attrib clippedUnpack = *unpack; if (!zoom) { if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, &clippedUnpack)) { /* totally clipped */ return; } } depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; ASSERT(depthRb); ASSERT(stencilRb); if (depthRb->_BaseFormat == GL_DEPTH_STENCIL_EXT && stencilRb->_BaseFormat == GL_DEPTH_STENCIL_EXT && depthRb == stencilRb && !scaleOrBias && !zoom && ctx->Depth.Mask && (stencilMask & 0xff) == 0xff) { /* This is the ideal case. * Drawing GL_DEPTH_STENCIL pixels into a combined depth/stencil buffer. * Plus, no pixel transfer ops, zooming, or masking needed. */ GLint i; for (i = 0; i < height; i++) { const GLuint *src = (const GLuint *) _mesa_image_address2d(&clippedUnpack, pixels, width, height, GL_DEPTH_STENCIL_EXT, type, i, 0); depthRb->PutRow(ctx, depthRb, width, x, y + i, src, NULL); } } else { /* sub-optimal cases: * Separate depth/stencil buffers, or pixel transfer ops required. */ /* XXX need to handle very wide images (skippixels) */ GLint i; depthRb = ctx->DrawBuffer->_DepthBuffer; stencilRb = ctx->DrawBuffer->_StencilBuffer; for (i = 0; i < height; i++) { const GLuint *depthStencilSrc = (const GLuint *) _mesa_image_address2d(&clippedUnpack, pixels, width, height, GL_DEPTH_STENCIL_EXT, type, i, 0); if (ctx->Depth.Mask) { if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 24) { /* fast path 24-bit zbuffer */ GLuint zValues[MAX_WIDTH]; GLint j; ASSERT(depthRb->DataType == GL_UNSIGNED_INT); for (j = 0; j < width; j++) { zValues[j] = depthStencilSrc[j] >> 8; } if (zoom) _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x, y + i, zValues); else depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL); } else if (!scaleOrBias && ctx->DrawBuffer->Visual.depthBits == 16) { /* fast path 16-bit zbuffer */ GLushort zValues[MAX_WIDTH]; GLint j; ASSERT(depthRb->DataType == GL_UNSIGNED_SHORT); for (j = 0; j < width; j++) { zValues[j] = depthStencilSrc[j] >> 16; } if (zoom) _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x, y + i, zValues); else depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL); } else { /* general case */ GLuint zValues[MAX_WIDTH]; /* 16 or 32-bit Z value storage */ _mesa_unpack_depth_span(ctx, width, depthRb->DataType, zValues, depthMax, type, depthStencilSrc, &clippedUnpack); if (zoom) { _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x, y + i, zValues); } else { depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL); } } } if (stencilMask != 0x0) { GLstencil stencilValues[MAX_WIDTH]; /* get stencil values, with shift/offset/mapping */ _mesa_unpack_stencil_span(ctx, width, stencilType, stencilValues, type, depthStencilSrc, &clippedUnpack, ctx->_ImageTransferState); if (zoom) _swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width, x, y + i, stencilValues); else _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues); } } }}/** * Execute software-based glDrawPixels. * By time we get here, all error checking will have been done. */void_swrast_DrawPixels( 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); RENDER_START(swrast,ctx); if (ctx->NewState) _mesa_update_state(ctx); if (swrast->NewState) _swrast_validate_derived( ctx ); pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels); if (!pixels) { RENDER_FINISH(swrast,ctx); return; } switch (format) { case GL_STENCIL_INDEX: draw_stencil_pixels( ctx, x, y, width, height, type, unpack, pixels ); break; case GL_DEPTH_COMPONENT: draw_depth_pixels( ctx, x, y, width, height, type, unpack, pixels ); break; case GL_COLOR_INDEX: if (ctx->Visual.rgbMode) draw_rgba_pixels(ctx, x,y, width, height, format, type, unpack, pixels); else draw_index_pixels(ctx, x, y, width, height, type, unpack, pixels); break; case GL_RED: case GL_GREEN: case GL_BLUE: case GL_ALPHA: 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, unpack, pixels); break; case GL_DEPTH_STENCIL_EXT: draw_depth_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels); break; default: _mesa_problem(ctx, "unexpected format in _swrast_DrawPixels"); /* don't return yet, clean-up */ } RENDER_FINISH(swrast,ctx); _mesa_unmap_drapix_pbo(ctx, unpack);}#if 0 /* experimental *//* * Execute glDrawDepthPixelsMESA(). */void_swrast_DrawDepthPixelsMESA( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum colorFormat, GLenum colorType, const GLvoid *colors, GLenum depthType, const GLvoid *depths, const struct gl_pixelstore_attrib *unpack ){ SWcontext *swrast = SWRAST_CONTEXT(ctx); if (swrast->NewState) _swrast_validate_derived( ctx ); RENDER_START(swrast,ctx); switch (colorFormat) { case GL_COLOR_INDEX: if (ctx->Visual.rgbMode) draw_rgba_pixels(ctx, x,y, width, height, colorFormat, colorType, unpack, colors); else draw_index_pixels(ctx, x, y, width, height, colorType, unpack, colors); break; case GL_RED: case GL_GREEN: case GL_BLUE: case GL_ALPHA: 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, colorFormat, colorType, unpack, colors); break; default: _mesa_problem(ctx, "unexpected format in glDrawDepthPixelsMESA"); } RENDER_FINISH(swrast,ctx);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -