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

📄 texcompress_fxt1.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Mesa 3-D graphics library * Version:  6.5 * * Copyright (C) 1999-2005  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. *//** * \file texcompress_fxt1.c * GL_EXT_texture_compression_fxt1 support. */#include "glheader.h"#include "imports.h"#include "colormac.h"#include "context.h"#include "convolve.h"#include "image.h"#include "texcompress.h"#include "texformat.h"#include "texstore.h"static voidfxt1_encode (GLuint width, GLuint height, GLint comps,             const void *source, GLint srcRowStride,             void *dest, GLint destRowStride);voidfxt1_decode_1 (const void *texture, GLint stride,               GLint i, GLint j, GLchan *rgba);/** * Called during context initialization. */void_mesa_init_texture_fxt1( GLcontext *ctx ){   (void) ctx;}/** * Called via TexFormat->StoreImage to store an RGB_FXT1 texture. */static GLbooleantexstore_rgb_fxt1(STORE_PARAMS){   const GLchan *pixels;   GLint srcRowStride;   GLubyte *dst;   const GLint texWidth = dstRowStride * 8 / 16; /* a bit of a hack */   const GLchan *tempImage = NULL;   ASSERT(dstFormat == &_mesa_texformat_rgb_fxt1);   ASSERT(dstXoffset % 8 == 0);   ASSERT(dstYoffset % 4 == 0);   ASSERT(dstZoffset     == 0);   (void) dstZoffset; (void) dstImageStride;   if (srcFormat != GL_RGB ||       srcType != CHAN_TYPE ||       ctx->_ImageTransferState ||       srcPacking->SwapBytes) {      /* convert image to RGB/GLchan */      tempImage = _mesa_make_temp_chan_image(ctx, dims,                                             baseInternalFormat,                                             dstFormat->BaseFormat,                                             srcWidth, srcHeight, srcDepth,                                             srcFormat, srcType, srcAddr,                                             srcPacking);      if (!tempImage)         return GL_FALSE; /* out of memory */      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);      pixels = tempImage;      srcRowStride = 3 * srcWidth;      srcFormat = GL_RGB;   }   else {      pixels = (const GLchan *) srcAddr;      srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,                                            srcType) / sizeof(GLchan);   }   dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,                                        GL_COMPRESSED_RGB_FXT1_3DFX,                                        texWidth, (GLubyte *) dstAddr);   fxt1_encode(srcWidth, srcHeight, 3, pixels, srcRowStride,               dst, dstRowStride);   if (tempImage)      _mesa_free((void*) tempImage);   return GL_TRUE;}/** * Called via TexFormat->StoreImage to store an RGBA_FXT1 texture. */static GLbooleantexstore_rgba_fxt1(STORE_PARAMS){   const GLchan *pixels;   GLint srcRowStride;   GLubyte *dst;   GLint texWidth = dstRowStride * 8 / 16; /* a bit of a hack */   const GLchan *tempImage = NULL;   ASSERT(dstFormat == &_mesa_texformat_rgba_fxt1);   ASSERT(dstXoffset % 8 == 0);   ASSERT(dstYoffset % 4 == 0);   ASSERT(dstZoffset     == 0);   (void) dstZoffset; (void) dstImageStride;   if (srcFormat != GL_RGBA ||       srcType != CHAN_TYPE ||       ctx->_ImageTransferState ||       srcPacking->SwapBytes) {      /* convert image to RGBA/GLchan */      tempImage = _mesa_make_temp_chan_image(ctx, dims,                                             baseInternalFormat,                                             dstFormat->BaseFormat,                                             srcWidth, srcHeight, srcDepth,                                             srcFormat, srcType, srcAddr,                                             srcPacking);      if (!tempImage)         return GL_FALSE; /* out of memory */      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);      pixels = tempImage;      srcRowStride = 4 * srcWidth;      srcFormat = GL_RGBA;   }   else {      pixels = (const GLchan *) srcAddr;      srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,                                            srcType) / sizeof(GLchan);   }   dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,                                        GL_COMPRESSED_RGBA_FXT1_3DFX,                                        texWidth, (GLubyte *) dstAddr);   fxt1_encode(srcWidth, srcHeight, 4, pixels, srcRowStride,               dst, dstRowStride);   if (tempImage)      _mesa_free((void*) tempImage);   return GL_TRUE;}static voidfetch_texel_2d_rgba_fxt1( const struct gl_texture_image *texImage,                          GLint i, GLint j, GLint k, GLchan *texel ){   (void) k;   fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, texel);}static voidfetch_texel_2d_f_rgba_fxt1( const struct gl_texture_image *texImage,                            GLint i, GLint j, GLint k, GLfloat *texel ){   /* just sample as GLchan and convert to float here */   GLchan rgba[4];   (void) k;   fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, rgba);   texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);   texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);   texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);   texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);}static voidfetch_texel_2d_rgb_fxt1( const struct gl_texture_image *texImage,                         GLint i, GLint j, GLint k, GLchan *texel ){   (void) k;   fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, texel);   texel[ACOMP] = 255;}static voidfetch_texel_2d_f_rgb_fxt1( const struct gl_texture_image *texImage,                           GLint i, GLint j, GLint k, GLfloat *texel ){   /* just sample as GLchan and convert to float here */   GLchan rgba[4];   (void) k;   fxt1_decode_1(texImage->Data, texImage->RowStride, i, j, rgba);   texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);   texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);   texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);   texel[ACOMP] = 1.0F;}const struct gl_texture_format _mesa_texformat_rgb_fxt1 = {   MESA_FORMAT_RGB_FXT1,		/* MesaFormat */   GL_RGB,				/* BaseFormat */   GL_UNSIGNED_NORMALIZED_ARB,		/* DataType */   4, /*approx*/			/* RedBits */   4, /*approx*/			/* GreenBits */   4, /*approx*/			/* BlueBits */   0,					/* AlphaBits */   0,					/* LuminanceBits */   0,					/* IntensityBits */   0,					/* IndexBits */   0,					/* DepthBits */   0,					/* StencilBits */   0,					/* TexelBytes */   texstore_rgb_fxt1,			/* StoreTexImageFunc */   NULL, /*impossible*/ 		/* FetchTexel1D */   fetch_texel_2d_rgb_fxt1, 		/* FetchTexel2D */   NULL, /*impossible*/ 		/* FetchTexel3D */   NULL, /*impossible*/ 		/* FetchTexel1Df */   fetch_texel_2d_f_rgb_fxt1, 		/* FetchTexel2Df */   NULL, /*impossible*/ 		/* FetchTexel3Df */};const struct gl_texture_format _mesa_texformat_rgba_fxt1 = {   MESA_FORMAT_RGBA_FXT1,		/* MesaFormat */   GL_RGBA,				/* BaseFormat */   GL_UNSIGNED_NORMALIZED_ARB,		/* DataType */   4, /*approx*/			/* RedBits */   4, /*approx*/			/* GreenBits */   4, /*approx*/			/* BlueBits */   1, /*approx*/			/* AlphaBits */   0,					/* LuminanceBits */   0,					/* IntensityBits */   0,					/* IndexBits */   0,					/* DepthBits */   0,					/* StencilBits */   0,					/* TexelBytes */   texstore_rgba_fxt1,			/* StoreTexImageFunc */   NULL, /*impossible*/ 		/* FetchTexel1D */   fetch_texel_2d_rgba_fxt1, 		/* FetchTexel2D */   NULL, /*impossible*/ 		/* FetchTexel3D */   NULL, /*impossible*/ 		/* FetchTexel1Df */   fetch_texel_2d_f_rgba_fxt1, 		/* FetchTexel2Df */   NULL, /*impossible*/ 		/* FetchTexel3Df */};/***************************************************************************\ * FXT1 encoder * * The encoder was built by reversing the decoder, * and is vaguely based on Texus2 by 3dfx. Note that this code * is merely a proof of concept, since it is highly UNoptimized; * moreover, it is sub-optimal due to initial conditions passed * to Lloyd's algorithm (the interpolation modes are even worse).\***************************************************************************/#define MAX_COMP 4 /* ever needed maximum number of components in texel */#define MAX_VECT 4 /* ever needed maximum number of base vectors to find */#define N_TEXELS 32 /* number of texels in a block (always 32) */#define LL_N_REP 50 /* number of iterations in lloyd's vq */#define LL_RMS_D 10 /* fault tolerance (maximum delta) */#define LL_RMS_E 255 /* fault tolerance (maximum error) */#define ALPHA_TS 2 /* alpha threshold: (255 - ALPHA_TS) deemed opaque */#define ISTBLACK(v) (*((GLuint *)(v)) == 0)/* * Define a 64-bit unsigned integer type and macros */#if defined(__GNUC__) && !defined(__cplusplus)#define FX64_NATIVE 1typedef unsigned long long Fx64;#define FX64_MOV32(a, b) a = b#define FX64_OR32(a, b)  a |= b#define FX64_SHL(a, c)   a <<= c#else  /* !__GNUC__ */#define FX64_NATIVE 0typedef struct {   GLuint lo, hi;} Fx64;#define FX64_MOV32(a, b) a.lo = b#define FX64_OR32(a, b)  a.lo |= b#define FX64_SHL(a, c)                                 \   do {                                                \       if ((c) >= 32) {                                \          a.hi = a.lo << ((c) - 32);                   \          a.lo = 0;                                    \       } else {                                        \          a.hi = (a.hi << (c)) | (a.lo >> (32 - (c))); \          a.lo <<= (c);                                \       }                                               \   } while (0)#endif /* !__GNUC__ */#define F(i) (GLfloat)1 /* can be used to obtain an oblong metric: 0.30 / 0.59 / 0.11 */#define SAFECDOT 1 /* for paranoids */#define MAKEIVEC(NV, NC, IV, B, V0, V1)  \   do {                                  \      /* compute interpolation vector */ \      GLfloat d2 = 0.0F;                 \      GLfloat rd2;                       \                                         \      for (i = 0; i < NC; i++) {         \         IV[i] = (V1[i] - V0[i]) * F(i); \         d2 += IV[i] * IV[i];            \      }                                  \      rd2 = (GLfloat)NV / d2;            \      B = 0;                             \      for (i = 0; i < NC; i++) {         \         IV[i] *= F(i);                  \         B -= IV[i] * V0[i];             \         IV[i] *= rd2;                   \      }                                  \      B = B * rd2 + 0.5f;                \   } while (0)#define CALCCDOT(TEXEL, NV, NC, IV, B, V)\   do {                                  \      GLfloat dot = 0.0F;                \      for (i = 0; i < NC; i++) {         \         dot += V[i] * IV[i];            \      }                                  \      TEXEL = (GLint)(dot + B);          \      if (SAFECDOT) {                    \         if (TEXEL < 0) {                \            TEXEL = 0;                   \         } else if (TEXEL > NV) {        \            TEXEL = NV;                  \         }                               \      }                                  \   } while (0)static GLintfxt1_bestcol (GLfloat vec[][MAX_COMP], GLint nv,              GLubyte input[MAX_COMP], GLint nc){   GLint i, j, best = -1;   GLfloat err = 1e9; /* big enough */   for (j = 0; j < nv; j++) {      GLfloat e = 0.0F;      for (i = 0; i < nc; i++) {         e += (vec[j][i] - input[i]) * (vec[j][i] - input[i]);      }      if (e < err) {         err = e;         best = j;      }   }   return best;}static GLintfxt1_worst (GLfloat vec[MAX_COMP],            GLubyte input[N_TEXELS][MAX_COMP], GLint nc, GLint n){   GLint i, k, worst = -1;   GLfloat err = -1.0F; /* small enough */   for (k = 0; k < n; k++) {      GLfloat e = 0.0F;      for (i = 0; i < nc; i++) {         e += (vec[i] - input[k][i]) * (vec[i] - input[k][i]);      }      if (e > err) {         err = e;         worst = k;      }   }   return worst;}static GLintfxt1_variance (GLdouble variance[MAX_COMP],               GLubyte input[N_TEXELS][MAX_COMP], GLint nc, GLint n){   GLint i, k, best = 0;   GLint sx, sx2;   GLdouble var, maxvar = -1; /* small enough */   GLdouble teenth = 1.0 / n;   for (i = 0; i < nc; i++) {      sx = sx2 = 0;      for (k = 0; k < n; k++) {         GLint t = input[k][i];         sx += t;

⌨️ 快捷键说明

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