📄 texstore.c
字号:
/* * Mesa 3-D graphics library * Version: 6.5 * * 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 GL texture image functions in teximage.c basically just do * error checking and data structure allocation. They in turn call * device driver functions which actually copy/convert/store the user's * texture image data. * * However, most device drivers will be able to use the fallback functions * in this file. That is, most drivers will have the following bit of * code: * ctx->Driver.TexImage1D = _mesa_store_teximage1d; * ctx->Driver.TexImage2D = _mesa_store_teximage2d; * ctx->Driver.TexImage3D = _mesa_store_teximage3d; * etc... * * Texture image processing is actually kind of complicated. We have to do: * Format/type conversions * pixel unpacking * pixel transfer (scale, bais, lookup, convolution!, etc) * * These functions can handle most everything, including processing full * images and sub-images. */#include "glheader.h"#include "bufferobj.h"#include "colormac.h"#include "context.h"#include "convolve.h"#include "image.h"#include "macros.h"#include "imports.h"#include "texcompress.h"#include "texformat.h"#include "teximage.h"#include "texstore.h"static const GLint ZERO = 4, ONE = 5;static GLboolean can_swizzle(GLenum logicalBaseFormat){ switch (logicalBaseFormat) { case GL_RGBA: case GL_RGB: case GL_LUMINANCE_ALPHA: case GL_INTENSITY: case GL_ALPHA: case GL_LUMINANCE: return GL_TRUE; default: return GL_FALSE; }}/** * When promoting texture formats (see below) we need to compute the * mapping of dest components back to source components. * This function does that. * \param logicalBaseFormat the logical format of the texture * \param textureBaseFormat the final texture format * \return map[4] the four mapping values */static voidcompute_component_mapping(GLenum logicalBaseFormat, GLenum textureBaseFormat, GLubyte map[6]){ map[ZERO] = ZERO; map[ONE] = ONE; /* compute mapping from dest components back to src components */ switch (textureBaseFormat) { case GL_RGB: case GL_RGBA: switch (logicalBaseFormat) { case GL_LUMINANCE: map[0] = map[1] = map[2] = 0; if (textureBaseFormat == GL_RGBA) map[3] = ONE; break; case GL_ALPHA: ASSERT(textureBaseFormat == GL_RGBA); map[0] = map[1] = map[2] = ZERO; map[3] = 0; break; case GL_INTENSITY: map[0] = map[1] = map[2] = 0; if (textureBaseFormat == GL_RGBA) map[3] = 0; break; case GL_LUMINANCE_ALPHA: ASSERT(textureBaseFormat == GL_RGBA); map[0] = map[1] = map[2] = 0; map[3] = 1; break; case GL_RGB: ASSERT(textureBaseFormat == GL_RGBA); map[0] = 0; map[1] = 1; map[2] = 2; map[3] = ONE; break; case GL_RGBA: ASSERT(textureBaseFormat == GL_RGBA); map[0] = 0; map[1] = 1; map[2] = 2; map[3] = 3; break; default: _mesa_problem(NULL, "Unexpected logicalBaseFormat"); map[0] = map[1] = map[2] = map[3] = 0; } break; case GL_LUMINANCE_ALPHA: switch (logicalBaseFormat) { case GL_LUMINANCE: map[0] = 0; map[1] = ONE; break; case GL_ALPHA: map[0] = ZERO; map[1] = 0; break; case GL_INTENSITY: map[0] = 0; map[1] = 0; break; default: _mesa_problem(NULL, "Unexpected logicalBaseFormat"); map[0] = map[1] = 0; } break; default: _mesa_problem(NULL, "Unexpected logicalBaseFormat"); map[0] = map[1] = 0; break; } }/** * Make a temporary (color) texture image with GLfloat components. * Apply all needed pixel unpacking and pixel transfer operations. * Note that there are both logicalBaseFormat and textureBaseFormat parameters. * Suppose the user specifies GL_LUMINANCE as the internal texture format * but the graphics hardware doesn't support luminance textures. So, might * use an RGB hardware format instead. * If logicalBaseFormat != textureBaseFormat we have some extra work to do. * * \param ctx the rendering context * \param dims image dimensions: 1, 2 or 3 * \param logicalBaseFormat basic texture derived from the user's * internal texture format value * \param textureBaseFormat the actual basic format of the texture * \param srcWidth source image width * \param srcHeight source image height * \param srcDepth source image depth * \param srcFormat source image format * \param srcType source image type * \param srcAddr source image address * \param srcPacking source image pixel packing * \return resulting image with format = textureBaseFormat and type = GLfloat. */static GLfloat *make_temp_float_image(GLcontext *ctx, GLuint dims, GLenum logicalBaseFormat, GLenum textureBaseFormat, GLint srcWidth, GLint srcHeight, GLint srcDepth, GLenum srcFormat, GLenum srcType, const GLvoid *srcAddr, const struct gl_pixelstore_attrib *srcPacking){ GLuint transferOps = ctx->_ImageTransferState; GLfloat *tempImage; ASSERT(dims >= 1 && dims <= 3); ASSERT(logicalBaseFormat == GL_RGBA || logicalBaseFormat == GL_RGB || logicalBaseFormat == GL_LUMINANCE_ALPHA || logicalBaseFormat == GL_LUMINANCE || logicalBaseFormat == GL_ALPHA || logicalBaseFormat == GL_INTENSITY || logicalBaseFormat == GL_COLOR_INDEX || logicalBaseFormat == GL_DEPTH_COMPONENT); ASSERT(textureBaseFormat == GL_RGBA || textureBaseFormat == GL_RGB || textureBaseFormat == GL_LUMINANCE_ALPHA || textureBaseFormat == GL_LUMINANCE || textureBaseFormat == GL_ALPHA || textureBaseFormat == GL_INTENSITY || textureBaseFormat == GL_COLOR_INDEX || textureBaseFormat == GL_DEPTH_COMPONENT); /* conventional color image */ if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) || (dims >= 2 && ctx->Pixel.Convolution2DEnabled) || (dims >= 2 && ctx->Pixel.Separable2DEnabled)) { /* need image convolution */ const GLuint preConvTransferOps = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT; const GLuint postConvTransferOps = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT; GLint img, row; GLint convWidth, convHeight; GLfloat *convImage; /* pre-convolution image buffer (3D) */ tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth * 4 * sizeof(GLfloat)); if (!tempImage) return NULL; /* post-convolution image buffer (2D) */ convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * 4 * sizeof(GLfloat)); if (!convImage) { _mesa_free(tempImage); return NULL; } /* loop over 3D image slices */ for (img = 0; img < srcDepth; img++) { GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4); /* unpack and do transfer ops up to convolution */ for (row = 0; row < srcHeight; row++) { const GLvoid *src = _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst, srcFormat, srcType, src, srcPacking, preConvTransferOps); dst += srcWidth * 4; } /* do convolution */ { GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4); convWidth = srcWidth; convHeight = srcHeight; if (dims == 1) { ASSERT(ctx->Pixel.Convolution1DEnabled); _mesa_convolve_1d_image(ctx, &convWidth, src, convImage); } else { if (ctx->Pixel.Convolution2DEnabled) { _mesa_convolve_2d_image(ctx, &convWidth, &convHeight, src, convImage); } else { ASSERT(ctx->Pixel.Separable2DEnabled); _mesa_convolve_sep_image(ctx, &convWidth, &convHeight, src, convImage); } } } /* do post-convolution transfer and pack into tempImage */ { const GLint logComponents = _mesa_components_in_format(logicalBaseFormat); const GLfloat *src = convImage; GLfloat *dst = tempImage + img * (convWidth * convHeight * 4); for (row = 0; row < convHeight; row++) { _mesa_pack_rgba_span_float(ctx, convWidth, (const GLfloat (*)[4]) src, logicalBaseFormat, GL_FLOAT, dst, &ctx->DefaultPacking, postConvTransferOps); src += convWidth * 4; dst += convWidth * logComponents; } } } /* loop over 3D image slices */ _mesa_free(convImage); /* might need these below */ srcWidth = convWidth; srcHeight = convHeight; } else { /* no convolution */ const GLint components = _mesa_components_in_format(logicalBaseFormat); const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); GLfloat *dst; GLint img, row; tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth * components * sizeof(GLfloat)); if (!tempImage) return NULL; dst = tempImage; for (img = 0; img < srcDepth; img++) { const GLubyte *src = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); for (row = 0; row < srcHeight; row++) { _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat, dst, srcFormat, srcType, src, srcPacking, transferOps); dst += srcWidth * components; src += srcStride; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -