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

📄 s_texstore.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:  6.5.2 * * Copyright (C) 1999-2006  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. *//* * Authors: *   Brian Paul *//* * The functions in this file are mostly related to software texture fallbacks. * This includes texture image transfer/packing and texel fetching. * Hardware drivers will likely override most of this. */#include "glheader.h"#include "imports.h"#include "colormac.h"#include "context.h"#include "convolve.h"#include "image.h"#include "macros.h"#include "mipmap.h"#include "texformat.h"#include "teximage.h"#include "texstore.h"#include "s_context.h"#include "s_depth.h"#include "s_span.h"/** * Read an RGBA image from the frame buffer. * This is used by glCopyTex[Sub]Image[12]D(). * \param x  window source x * \param y  window source y * \param width  image width * \param height  image height * \param type  datatype for returned GL_RGBA image * \return pointer to image */static GLvoid *read_color_image( GLcontext *ctx, GLint x, GLint y, GLenum type,                  GLsizei width, GLsizei height ){   SWcontext *swrast = SWRAST_CONTEXT(ctx);   struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;   const GLint pixelSize = _mesa_bytes_per_pixel(GL_RGBA, type);   const GLint stride = width * pixelSize;   GLint row;   GLubyte *image, *dst;   image = (GLubyte *) _mesa_malloc(width * height * pixelSize);   if (!image)      return NULL;   RENDER_START(swrast, ctx);   dst = image;   for (row = 0; row < height; row++) {      _swrast_read_rgba_span(ctx, rb, width, x, y + row, type, dst);      dst += stride;   }   RENDER_FINISH(swrast, ctx);   return image;}/** * As above, but read data from depth buffer.  Returned as GLuints. * \sa read_color_image */static GLuint *read_depth_image( GLcontext *ctx, GLint x, GLint y,                  GLsizei width, GLsizei height ){   struct gl_renderbuffer *rb = ctx->ReadBuffer->_DepthBuffer;   SWcontext *swrast = SWRAST_CONTEXT(ctx);   GLuint *image, *dst;   GLint i;   image = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint));   if (!image)      return NULL;   RENDER_START(swrast, ctx);   dst = image;   for (i = 0; i < height; i++) {      _swrast_read_depth_span_uint(ctx, rb, width, x, y + i, dst);      dst += width;   }   RENDER_FINISH(swrast, ctx);   return image;}/** * As above, but read data from depth+stencil buffers. */static GLuint *read_depth_stencil_image(GLcontext *ctx, GLint x, GLint y,                         GLsizei width, GLsizei height){   struct gl_renderbuffer *depthRb = ctx->ReadBuffer->_DepthBuffer;   struct gl_renderbuffer *stencilRb = ctx->ReadBuffer->_StencilBuffer;   SWcontext *swrast = SWRAST_CONTEXT(ctx);   GLuint *image, *dst;   GLint i;   ASSERT(depthRb);   ASSERT(stencilRb);   image = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint));   if (!image)      return NULL;   RENDER_START(swrast, ctx);   /* read from depth buffer */   dst = image;   if (depthRb->DataType == GL_UNSIGNED_INT) {      for (i = 0; i < height; i++) {         _swrast_get_row(ctx, depthRb, width, x, y + i, dst, sizeof(GLuint));         dst += width;      }   }   else {      GLushort z16[MAX_WIDTH];      ASSERT(depthRb->DataType == GL_UNSIGNED_SHORT);      for (i = 0; i < height; i++) {         GLint j;         _swrast_get_row(ctx, depthRb, width, x, y + i, z16, sizeof(GLushort));         /* convert GLushorts to GLuints */         for (j = 0; j < width; j++) {            dst[j] = z16[j];         }         dst += width;      }   }   /* put depth values into bits 0xffffff00 */   if (ctx->ReadBuffer->Visual.depthBits == 24) {      GLint j;      for (j = 0; j < width * height; j++) {         image[j] <<= 8;      }   }   else if (ctx->ReadBuffer->Visual.depthBits == 16) {      GLint j;      for (j = 0; j < width * height; j++) {         image[j] = (image[j] << 16) | (image[j] & 0xff00);      }         }   else {      /* this handles arbitrary depthBits >= 12 */      const GLint rShift = ctx->ReadBuffer->Visual.depthBits;      const GLint lShift = 32 - rShift;      GLint j;      for (j = 0; j < width * height; j++) {         GLuint z = (image[j] << lShift);         image[j] = z | (z >> rShift);      }   }   /* read stencil values and interleave into image array */   dst = image;   for (i = 0; i < height; i++) {      GLstencil stencil[MAX_WIDTH];      GLint j;      ASSERT(8 * sizeof(GLstencil) == stencilRb->StencilBits);      _swrast_get_row(ctx, stencilRb, width, x, y + i,                      stencil, sizeof(GLstencil));      for (j = 0; j < width; j++) {         dst[j] = (dst[j] & 0xffffff00) | (stencil[j] & 0xff);      }      dst += width;   }   RENDER_FINISH(swrast, ctx);   return image;}static GLbooleanis_depth_format(GLenum format){   switch (format) {      case GL_DEPTH_COMPONENT:      case GL_DEPTH_COMPONENT16_SGIX:      case GL_DEPTH_COMPONENT24_SGIX:      case GL_DEPTH_COMPONENT32_SGIX:         return GL_TRUE;      default:         return GL_FALSE;   }}static GLbooleanis_depth_stencil_format(GLenum format){   switch (format) {      case GL_DEPTH_STENCIL_EXT:      case GL_DEPTH24_STENCIL8_EXT:         return GL_TRUE;      default:         return GL_FALSE;   }}/* * Fallback for Driver.CopyTexImage1D(). */void_swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,                         GLenum internalFormat,                         GLint x, GLint y, GLsizei width, GLint border ){   struct gl_texture_unit *texUnit;   struct gl_texture_object *texObj;   struct gl_texture_image *texImage;   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];   texObj = _mesa_select_tex_object(ctx, texUnit, target);   ASSERT(texObj);   texImage = _mesa_select_tex_image(ctx, texObj, target, level);   ASSERT(texImage);   ASSERT(ctx->Driver.TexImage1D);   if (is_depth_format(internalFormat)) {      /* read depth image from framebuffer */      GLuint *image = read_depth_image(ctx, x, y, width, 1);      if (!image) {         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");         return;      }      /* call glTexImage1D to redefine the texture */      ctx->Driver.TexImage1D(ctx, target, level, internalFormat,                             width, border,                             GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image,                             &ctx->DefaultPacking, texObj, texImage);      _mesa_free(image);   }   else if (is_depth_stencil_format(internalFormat)) {      /* read depth/stencil image from framebuffer */      GLuint *image = read_depth_stencil_image(ctx, x, y, width, 1);      if (!image) {         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");         return;      }      /* call glTexImage1D to redefine the texture */      ctx->Driver.TexImage1D(ctx, target, level, internalFormat,                             width, border,                             GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,                             image, &ctx->DefaultPacking, texObj, texImage);      _mesa_free(image);   }   else {      /* read RGBA image from framebuffer */      const GLenum format = GL_RGBA;      const GLenum type = ctx->ReadBuffer->_ColorReadBuffer->DataType;      GLvoid *image = read_color_image(ctx, x, y, type, width, 1);      if (!image) {         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");         return;      }      /* call glTexImage1D to redefine the texture */      ctx->Driver.TexImage1D(ctx, target, level, internalFormat,                             width, border, format, type, image,                             &ctx->DefaultPacking, texObj, texImage);      _mesa_free(image);

⌨️ 快捷键说明

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