⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s_readpix.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Read R, G, B, A, RGB, L, or LA pixels. */static voidread_rgba_pixels( GLcontext *ctx,                  GLint x, GLint y,                  GLsizei width, GLsizei height,                  GLenum format, GLenum type, GLvoid *pixels,                  const struct gl_pixelstore_attrib *packing ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   GLbitfield transferOps = ctx->_ImageTransferState;   struct gl_framebuffer *fb = ctx->ReadBuffer;   struct gl_renderbuffer *rb = fb->_ColorReadBuffer;   if (!rb)      return;   if (type == GL_FLOAT && ((ctx->Color.ClampReadColor == GL_TRUE) ||                            (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB &&                             rb->DataType != GL_FLOAT)))      transferOps |= IMAGE_CLAMP_BIT;   /* Try optimized path first */   if (fast_read_rgba_pixels(ctx, x, y, width, height,                             format, type, pixels, packing, transferOps)) {      return; /* done! */   }   /* width should never be > MAX_WIDTH since we did clipping earlier */   ASSERT(width <= MAX_WIDTH);   if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {      GLfloat *dest, *src, *tmpImage, *convImage;      GLint row;      tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));      if (!tmpImage) {         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");         return;      }      convImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));      if (!convImage) {         _mesa_free(tmpImage);         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");         return;      }      /* read full RGBA, FLOAT image */      dest = tmpImage;      for (row = 0; row < height; row++, y++) {         if (fb->Visual.rgbMode) {            _swrast_read_rgba_span(ctx, rb, width, x, y, GL_FLOAT, dest);         }         else {            GLuint index[MAX_WIDTH];            ASSERT(rb->DataType == GL_UNSIGNED_INT);            rb->GetRow(ctx, rb, width, x, y, index);            _mesa_apply_ci_transfer_ops(ctx,                                        transferOps & IMAGE_SHIFT_OFFSET_BIT,                                        width, index);            _mesa_map_ci_to_rgba(ctx, width, index, (GLfloat (*)[4]) dest);         }         _mesa_apply_rgba_transfer_ops(ctx,                                       transferOps & IMAGE_PRE_CONVOLUTION_BITS,                                      width, (GLfloat (*)[4]) dest);         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);      /* finish transfer ops and pack the resulting image */      src = convImage;      for (row = 0; row < height; row++) {         GLvoid *dest;         dest = _mesa_image_address2d(packing, pixels, width, height,                                      format, type, row, 0);         _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) src,                                    format, type, dest, packing,                                    transferOps & IMAGE_POST_CONVOLUTION_BITS);         src += width * 4;      }      _mesa_free(convImage);   }   else {      /* no convolution */      const GLint dstStride         = _mesa_image_row_stride(packing, width, format, type);      GLfloat (*rgba)[4] = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL0];      GLint row;      GLubyte *dst         = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,                                             format, type, 0, 0);      /* make sure we don't apply 1D convolution */      transferOps &= ~(IMAGE_CONVOLUTION_BIT |                       IMAGE_POST_CONVOLUTION_SCALE_BIAS);      for (row = 0; row < height; row++, y++) {         /* Get float rgba pixels */         if (fb->Visual.rgbMode) {            _swrast_read_rgba_span(ctx, rb, width, x, y, GL_FLOAT, rgba);         }         else {            /* read CI and convert to RGBA */            GLuint index[MAX_WIDTH];            ASSERT(rb->DataType == GL_UNSIGNED_INT);            rb->GetRow(ctx, rb, width, x, y, index);            _mesa_apply_ci_transfer_ops(ctx,                                        transferOps & IMAGE_SHIFT_OFFSET_BIT,                                        width, index);            _mesa_map_ci_to_rgba(ctx, width, index, rgba);         }         /* apply fudge factor for shallow color buffers */         if (fb->Visual.redBits < 8 ||             fb->Visual.greenBits < 8 ||             fb->Visual.blueBits < 8) {            adjust_colors(ctx, width, rgba);         }         /* pack the row of RGBA pixels into user's buffer */         _mesa_pack_rgba_span_float(ctx, width, rgba, format, type, dst,                                    packing, transferOps);         dst += dstStride;      }   }}/** * Read combined depth/stencil values. * We'll have already done error checking to be sure the expected * depth and stencil buffers really exist. */static voidread_depth_stencil_pixels(GLcontext *ctx,                          GLint x, GLint y,                          GLsizei width, GLsizei height,                          GLenum type, GLvoid *pixels,                          const struct gl_pixelstore_attrib *packing ){   const GLboolean scaleOrBias      = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;   const GLboolean stencilTransfer = ctx->Pixel.IndexShift      || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;   struct gl_renderbuffer *depthRb, *stencilRb;   depthRb = ctx->ReadBuffer->_DepthBuffer;   stencilRb = ctx->ReadBuffer->_StencilBuffer;   if (!depthRb || !stencilRb)      return;   depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;   stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;   if (depthRb->_BaseFormat == GL_DEPTH_STENCIL_EXT &&       stencilRb->_BaseFormat == GL_DEPTH_STENCIL_EXT &&       depthRb == stencilRb &&       !scaleOrBias &&       !stencilTransfer) {      /* This is the ideal case.       * Reading GL_DEPTH_STENCIL pixels from combined depth/stencil buffer.       * Plus, no pixel transfer ops to worry about!       */      GLint i;      GLint dstStride = _mesa_image_row_stride(packing, width,                                               GL_DEPTH_STENCIL_EXT, type);      GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, pixels,                                                       width, height,                                                       GL_DEPTH_STENCIL_EXT,                                                       type, 0, 0);      for (i = 0; i < height; i++) {         depthRb->GetRow(ctx, depthRb, width, x, y + i, dst);         dst += dstStride;      }   }   else {      /* Reading GL_DEPTH_STENCIL pixels from separate depth/stencil buffers,       * or we need pixel transfer.       */      GLint i;      depthRb = ctx->ReadBuffer->_DepthBuffer;      stencilRb = ctx->ReadBuffer->_StencilBuffer;      for (i = 0; i < height; i++) {         GLstencil stencilVals[MAX_WIDTH];         GLuint *depthStencilDst = (GLuint *)            _mesa_image_address2d(packing, pixels, width, height,                                  GL_DEPTH_STENCIL_EXT, type, i, 0);         _swrast_read_stencil_span(ctx, stencilRb, width,                                   x, y + i, stencilVals);         if (!scaleOrBias && !stencilTransfer             && ctx->ReadBuffer->Visual.depthBits == 24) {            /* ideal case */            GLuint zVals[MAX_WIDTH]; /* 24-bit values! */            GLint j;            ASSERT(depthRb->DataType == GL_UNSIGNED_INT);            /* note, we've already been clipped */            depthRb->GetRow(ctx, depthRb, width, x, y + i, zVals);            for (j = 0; j < width; j++) {               depthStencilDst[j] = (zVals[j] << 8) | (stencilVals[j] & 0xff);            }         }         else {            /* general case */            GLfloat depthVals[MAX_WIDTH];            _swrast_read_depth_span_float(ctx, depthRb, width, x, y + i,                                          depthVals);            _mesa_pack_depth_stencil_span(ctx, width, depthStencilDst,                                          depthVals, stencilVals, packing);         }      }   }}/** * Software fallback routine for ctx->Driver.ReadPixels(). * By time we get here, all error checking will have been done. */void_swrast_ReadPixels( GLcontext *ctx,		    GLint x, GLint y, GLsizei width, GLsizei height,		    GLenum format, GLenum type,		    const struct gl_pixelstore_attrib *packing,		    GLvoid *pixels ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   struct gl_pixelstore_attrib clippedPacking = *packing;   /* Need to do RENDER_START before clipping or anything else since this    * is where a driver may grab the hw lock and get an updated window    * size.    */   RENDER_START(swrast, ctx);   if (ctx->NewState)      _mesa_update_state(ctx);   if (swrast->NewState)      _swrast_validate_derived( ctx );   /* Do all needed clipping here, so that we can forget about it later */   if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) {      /* The ReadPixels region is totally outside the window bounds */      RENDER_FINISH(swrast, ctx);      return;   }   pixels = _mesa_map_readpix_pbo(ctx, &clippedPacking, pixels);   if (!pixels)      return;     switch (format) {      case GL_COLOR_INDEX:         read_index_pixels(ctx, x, y, width, height, type, pixels,                           &clippedPacking);	 break;      case GL_STENCIL_INDEX:	 read_stencil_pixels(ctx, x, y, width, height, type, pixels,                             &clippedPacking);         break;      case GL_DEPTH_COMPONENT:	 read_depth_pixels(ctx, x, y, width, height, type, pixels,                           &clippedPacking);	 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_RGBA:      case GL_BGR:      case GL_BGRA:      case GL_ABGR_EXT:         read_rgba_pixels(ctx, x, y, width, height,                          format, type, pixels, &clippedPacking);	 break;      case GL_DEPTH_STENCIL_EXT:         read_depth_stencil_pixels(ctx, x, y, width, height,                                   type, pixels, &clippedPacking);         break;      default:	 _mesa_problem(ctx, "unexpected format in _swrast_ReadPixels");         /* don't return yet, clean-up */   }   RENDER_FINISH(swrast, ctx);   _mesa_unmap_readpix_pbo(ctx, &clippedPacking);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -