📄 texstore.c
字号:
dst, srcFormat, srcType, src,
srcPacking, transferOps);
dst += srcWidth * components;
src += srcStride;
}
}
}
if (logicalBaseFormat != textureBaseFormat) {
/* more work */
GLint texComponents = _mesa_components_in_format(textureBaseFormat);
GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
GLfloat *newImage;
GLint i, n;
GLubyte map[6];
/* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
textureBaseFormat == GL_LUMINANCE_ALPHA);
/* The actual texture format should have at least as many components
* as the logical texture format.
*/
ASSERT(texComponents >= logComponents);
newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
* texComponents * sizeof(GLfloat));
if (!newImage) {
_mesa_free(tempImage);
return NULL;
}
compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
n = srcWidth * srcHeight * srcDepth;
for (i = 0; i < n; i++) {
GLint k;
for (k = 0; k < texComponents; k++) {
GLint j = map[k];
if (j == ZERO)
newImage[i * texComponents + k] = 0.0F;
else if (j == ONE)
newImage[i * texComponents + k] = 1.0F;
else
newImage[i * texComponents + k] = tempImage[i * logComponents + j];
}
}
_mesa_free(tempImage);
tempImage = newImage;
}
return tempImage;
}
/**
* Make a temporary (color) texture image with GLchan 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 = GLchan.
*/
GLchan *
_mesa_make_temp_chan_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;
const GLint components = _mesa_components_in_format(logicalBaseFormat);
GLboolean freeSrcImage = GL_FALSE;
GLint img, row;
GLchan *tempImage, *dst;
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);
ASSERT(textureBaseFormat == GL_RGBA ||
textureBaseFormat == GL_RGB ||
textureBaseFormat == GL_LUMINANCE_ALPHA ||
textureBaseFormat == GL_LUMINANCE ||
textureBaseFormat == GL_ALPHA ||
textureBaseFormat == GL_INTENSITY);
if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
(dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
(dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
/* get convolved image */
GLfloat *convImage = make_temp_float_image(ctx, dims,
logicalBaseFormat,
logicalBaseFormat,
srcWidth, srcHeight, srcDepth,
srcFormat, srcType,
srcAddr, srcPacking);
if (!convImage)
return NULL;
/* the convolved image is our new source image */
srcAddr = convImage;
srcFormat = logicalBaseFormat;
srcType = GL_FLOAT;
srcPacking = &ctx->DefaultPacking;
_mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
transferOps = 0;
freeSrcImage = GL_TRUE;
}
/* unpack and transfer the source image */
tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
* components * sizeof(GLchan));
if (!tempImage)
return NULL;
dst = tempImage;
for (img = 0; img < srcDepth; img++) {
const GLint srcStride = _mesa_image_row_stride(srcPacking,
srcWidth, srcFormat,
srcType);
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_chan(ctx, srcWidth, logicalBaseFormat, dst,
srcFormat, srcType, src, srcPacking,
transferOps);
dst += srcWidth * components;
src += srcStride;
}
}
/* If we made a temporary image for convolution, free it here */
if (freeSrcImage) {
_mesa_free((void *) srcAddr);
}
if (logicalBaseFormat != textureBaseFormat) {
/* one more conversion step */
GLint texComponents = _mesa_components_in_format(textureBaseFormat);
GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
GLchan *newImage;
GLint i, n;
GLubyte map[6];
/* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
textureBaseFormat == GL_LUMINANCE_ALPHA);
/* The actual texture format should have at least as many components
* as the logical texture format.
*/
ASSERT(texComponents >= logComponents);
newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
* texComponents * sizeof(GLchan));
if (!newImage) {
_mesa_free(tempImage);
return NULL;
}
compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
n = srcWidth * srcHeight * srcDepth;
for (i = 0; i < n; i++) {
GLint k;
for (k = 0; k < texComponents; k++) {
GLint j = map[k];
if (j == ZERO)
newImage[i * texComponents + k] = 0;
else if (j == ONE)
newImage[i * texComponents + k] = CHAN_MAX;
else
newImage[i * texComponents + k] = tempImage[i * logComponents + j];
}
}
_mesa_free(tempImage);
tempImage = newImage;
}
return tempImage;
}
/**
* Copy GLubyte pixels from <src> to <dst> with swizzling.
* \param dst destination pixels
* \param dstComponents number of color components in destination pixels
* \param src source pixels
* \param srcComponents number of color components in source pixels
* \param map the swizzle mapping
* \param count number of pixels to copy/swizzle.
*/
static void
swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
GLuint srcComponents, const GLubyte *map, GLuint count)
{
GLubyte tmp[8];
GLint i;
tmp[ZERO] = 0x0;
tmp[ONE] = 0xff;
switch (dstComponents) {
case 4:
for (i = 0; i < count; i++) {
COPY_4UBV(tmp, src);
src += srcComponents;
dst[0] = tmp[map[0]];
dst[1] = tmp[map[1]];
dst[2] = tmp[map[2]];
dst[3] = tmp[map[3]];
dst += 4;
}
break;
case 3:
for (i = 0; i < count; i++) {
COPY_4UBV(tmp, src);
src += srcComponents;
dst[0] = tmp[map[0]];
dst[1] = tmp[map[1]];
dst[2] = tmp[map[2]];
dst += 3;
}
break;
case 2:
for (i = 0; i < count; i++) {
COPY_4UBV(tmp, src);
src += srcComponents;
dst[0] = tmp[map[0]];
dst[1] = tmp[map[1]];
dst += 2;
}
break;
}
}
/**
* Transfer a GLubyte texture image with component swizzling.
*/
static void
_mesa_swizzle_ubyte_image(GLcontext *ctx,
GLuint dimensions,
GLenum srcFormat,
const GLubyte *dstmap, GLint dstComponents,
GLvoid *dstAddr,
GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
GLint dstRowStride, GLint dstImageStride,
GLint srcWidth, GLint srcHeight, GLint srcDepth,
const GLvoid *srcAddr,
const struct gl_pixelstore_attrib *srcPacking )
{
GLint srcComponents = _mesa_components_in_format(srcFormat);
GLubyte srcmap[6], map[4];
GLint i;
const GLint srcRowStride =
_mesa_image_row_stride(srcPacking, srcWidth,
srcFormat, GL_UNSIGNED_BYTE);
const GLint srcImageStride
= _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
GL_UNSIGNED_BYTE);
const GLubyte *srcImage
= (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
srcWidth, srcHeight, srcFormat,
GL_UNSIGNED_BYTE, 0, 0, 0);
GLubyte *dstImage = (GLubyte *) dstAddr
+ dstZoffset * dstImageStride
+ dstYoffset * dstRowStride
+ dstXoffset * dstComponents;
compute_component_mapping(srcFormat, GL_RGBA, srcmap);
for (i = 0; i < 4; i++)
map[i] = srcmap[dstmap[i]];
if (srcRowStride == srcWidth * srcComponents &&
(srcImageStride == srcWidth * srcHeight * srcComponents ||
srcDepth == 1)) {
swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
srcWidth * srcHeight * srcDepth);
}
else {
GLint img, row;
for (img = 0; img < srcDepth; img++) {
const GLubyte *srcRow = srcImage;
GLubyte *dstRow = dstImage;
for (row = 0; row < srcHeight; row++) {
swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
dstRow += dstRowStride;
srcRow += srcRowStride;
}
srcImage += srcImageStride;
dstImage += dstImageStride;
}
}
}
/**
* Teximage storage routine for when a simple memcpy will do.
* No pixel transfer operations or special texel encodings allowed.
* 1D, 2D and 3D images supported.
*/
static void
memcpy_texture(GLcontext *ctx,
GLuint dimensions,
const struct gl_texture_format *dstFormat,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -