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

📄 s_readpix.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Mesa 3-D graphics library * Version:  7.0.3 * * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */#include "glheader.h"#include "bufferobj.h"#include "colormac.h"#include "convolve.h"#include "context.h"#include "feedback.h"#include "image.h"#include "macros.h"#include "imports.h"#include "pixel.h"#include "state.h"#include "s_context.h"#include "s_depth.h"#include "s_span.h"#include "s_stencil.h"/* * Read a block of color index pixels. */static voidread_index_pixels( GLcontext *ctx,                   GLint x, GLint y,                   GLsizei width, GLsizei height,                   GLenum type, GLvoid *pixels,                   const struct gl_pixelstore_attrib *packing ){   struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;   GLint i;   if (!rb)      return;   /* width should never be > MAX_WIDTH since we did clipping earlier */   ASSERT(width <= MAX_WIDTH);   /* process image row by row */   for (i = 0; i < height; i++) {      GLuint index[MAX_WIDTH];      GLvoid *dest;      ASSERT(rb->DataType == GL_UNSIGNED_INT);      rb->GetRow(ctx, rb, width, x, y + i, index);      dest = _mesa_image_address2d(packing, pixels, width, height,                                   GL_COLOR_INDEX, type, i, 0);      _mesa_pack_index_span(ctx, width, type, dest, index,                            &ctx->Pack, ctx->_ImageTransferState);   }}/** * Read pixels for format=GL_DEPTH_COMPONENT. */static voidread_depth_pixels( GLcontext *ctx,                   GLint x, GLint y,                   GLsizei width, GLsizei height,                   GLenum type, GLvoid *pixels,                   const struct gl_pixelstore_attrib *packing ){   struct gl_framebuffer *fb = ctx->ReadBuffer;   struct gl_renderbuffer *rb = fb->_DepthBuffer;   const GLboolean biasOrScale      = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;   if (!rb)      return;   /* clipping should have been done already */   ASSERT(x >= 0);   ASSERT(y >= 0);   ASSERT(x + width <= (GLint) rb->Width);   ASSERT(y + height <= (GLint) rb->Height);   /* width should never be > MAX_WIDTH since we did clipping earlier */   ASSERT(width <= MAX_WIDTH);   if (type == GL_UNSIGNED_SHORT && fb->Visual.depthBits == 16       && !biasOrScale && !packing->SwapBytes) {      /* Special case: directly read 16-bit unsigned depth values. */      GLint j;      ASSERT(rb->InternalFormat == GL_DEPTH_COMPONENT16);      ASSERT(rb->DataType == GL_UNSIGNED_SHORT);      for (j = 0; j < height; j++, y++) {         void *dest =_mesa_image_address2d(packing, pixels, width, height,                                           GL_DEPTH_COMPONENT, type, j, 0);         rb->GetRow(ctx, rb, width, x, y, dest);      }   }   else if (type == GL_UNSIGNED_INT && fb->Visual.depthBits == 24            && !biasOrScale && !packing->SwapBytes) {      /* Special case: directly read 24-bit unsigned depth values. */      GLint j;      ASSERT(rb->InternalFormat == GL_DEPTH_COMPONENT24);      ASSERT(rb->DataType == GL_UNSIGNED_INT);      for (j = 0; j < height; j++, y++) {         GLuint *dest = (GLuint *)            _mesa_image_address2d(packing, pixels, width, height,                                  GL_DEPTH_COMPONENT, type, j, 0);         GLint k;         rb->GetRow(ctx, rb, width, x, y, dest);         /* convert range from 24-bit to 32-bit */         for (k = 0; k < width; k++) {            /* Note: put MSByte of 24-bit value into LSByte */            dest[k] = (dest[k] << 8) | ((dest[k] >> 16) & 0xff);         }      }   }   else if (type == GL_UNSIGNED_INT && fb->Visual.depthBits == 32            && !biasOrScale && !packing->SwapBytes) {      /* Special case: directly read 32-bit unsigned depth values. */      GLint j;      ASSERT(rb->InternalFormat == GL_DEPTH_COMPONENT32);      ASSERT(rb->DataType == GL_UNSIGNED_INT);      for (j = 0; j < height; j++, y++) {         void *dest = _mesa_image_address2d(packing, pixels, width, height,                                            GL_DEPTH_COMPONENT, type, j, 0);         rb->GetRow(ctx, rb, width, x, y, dest);      }   }   else {      /* General case (slower) */      GLint j;      for (j = 0; j < height; j++, y++) {         GLfloat depthValues[MAX_WIDTH];         GLvoid *dest = _mesa_image_address2d(packing, pixels, width, height,                                              GL_DEPTH_COMPONENT, type, j, 0);         _swrast_read_depth_span_float(ctx, rb, width, x, y, depthValues);         _mesa_pack_depth_span(ctx, width, dest, type, depthValues, packing);      }   }}/** * Read pixels for format=GL_STENCIL_INDEX. */static voidread_stencil_pixels( GLcontext *ctx,                     GLint x, GLint y,                     GLsizei width, GLsizei height,                     GLenum type, GLvoid *pixels,                     const struct gl_pixelstore_attrib *packing ){   struct gl_framebuffer *fb = ctx->ReadBuffer;   struct gl_renderbuffer *rb = fb->_StencilBuffer;   GLint j;   if (!rb)      return;   /* width should never be > MAX_WIDTH since we did clipping earlier */   ASSERT(width <= MAX_WIDTH);   /* process image row by row */   for (j=0;j<height;j++,y++) {      GLvoid *dest;      GLstencil stencil[MAX_WIDTH];      _swrast_read_stencil_span(ctx, rb, width, x, y, stencil);      dest = _mesa_image_address2d(packing, pixels, width, height,                                   GL_STENCIL_INDEX, type, j, 0);      _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);   }}/** * Optimized glReadPixels for particular pixel formats when pixel * scaling, biasing, mapping, etc. are disabled. * \return GL_TRUE if success, GL_FALSE if unable to do the readpixels */static GLbooleanfast_read_rgba_pixels( GLcontext *ctx,                       GLint x, GLint y,                       GLsizei width, GLsizei height,                       GLenum format, GLenum type,                       GLvoid *pixels,                       const struct gl_pixelstore_attrib *packing,                       GLbitfield transferOps){   struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;   if (!rb)      return GL_FALSE;   ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB);   /* clipping should have already been done */   ASSERT(x + width <= (GLint) rb->Width);   ASSERT(y + height <= (GLint) rb->Height);   /* check for things we can't handle here */   if (transferOps ||       packing->SwapBytes ||       packing->LsbFirst) {      return GL_FALSE;   }   if (format == GL_RGBA && rb->DataType == type) {      const GLint dstStride = _mesa_image_row_stride(packing, width,                                                     format, type);      GLubyte *dest         = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,                                             format, type, 0, 0);      GLint row;      ASSERT(rb->GetRow);      for (row = 0; row < height; row++) {         rb->GetRow(ctx, rb, width, x, y + row, dest);         dest += dstStride;      }      return GL_TRUE;   }   if (format == GL_RGB &&       rb->DataType == GL_UNSIGNED_BYTE &&       type == GL_UNSIGNED_BYTE) {      const GLint dstStride = _mesa_image_row_stride(packing, width,                                                     format, type);      GLubyte *dest         = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,                                             format, type, 0, 0);      GLint row;      ASSERT(rb->GetRow);      for (row = 0; row < height; row++) {         GLubyte tempRow[MAX_WIDTH][4];         GLint col;         rb->GetRow(ctx, rb, width, x, y + row, tempRow);         /* convert RGBA to RGB */         for (col = 0; col < width; col++) {            dest[col * 3 + 0] = tempRow[col][0];            dest[col * 3 + 1] = tempRow[col][1];            dest[col * 3 + 2] = tempRow[col][2];         }         dest += dstStride;      }      return GL_TRUE;   }   /* not handled */   return GL_FALSE;}/** * When we're using a low-precision color buffer (like 16-bit 5/6/5) * we have to adjust our color values a bit to pass conformance. * The problem is when a 5 or 6-bit color value is convert to an 8-bit * value and then a floating point value, the floating point values don't * increment uniformly as the 5 or 6-bit value is incremented. * * This function adjusts floating point values to compensate. */static voidadjust_colors(GLcontext *ctx, GLuint n, GLfloat rgba[][4]){   const GLuint rShift = 8 - ctx->Visual.redBits;   const GLuint gShift = 8 - ctx->Visual.greenBits;   const GLuint bShift = 8 - ctx->Visual.blueBits;   const GLfloat rScale = 1.0F / (GLfloat) ((1 << ctx->Visual.redBits  ) - 1);   const GLfloat gScale = 1.0F / (GLfloat) ((1 << ctx->Visual.greenBits) - 1);   const GLfloat bScale = 1.0F / (GLfloat) ((1 << ctx->Visual.blueBits ) - 1);   GLuint i;   for (i = 0; i < n; i++) {      GLint r, g, b;      /* convert float back to ubyte */      CLAMPED_FLOAT_TO_UBYTE(r, rgba[i][RCOMP]);      CLAMPED_FLOAT_TO_UBYTE(g, rgba[i][GCOMP]);      CLAMPED_FLOAT_TO_UBYTE(b, rgba[i][BCOMP]);      /* using only the N most significant bits of the ubyte value, convert to       * float in [0,1].       */      rgba[i][RCOMP] = (GLfloat) (r >> rShift) * rScale;      rgba[i][GCOMP] = (GLfloat) (g >> gShift) * gScale;      rgba[i][BCOMP] = (GLfloat) (b >> bShift) * bScale;   }}

⌨️ 快捷键说明

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