📄 texcompress_fxt1.c
字号:
lolo <<= 2;
lolo |= texel;
}
cc[0] = lolo;
}
/* right microtile */
cc[1] = 0;
if (minColR != maxColR) {
/* compute interpolation vector */
MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[1]);
/* add in texels */
lohi = 0;
for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
GLint texel;
/* interpolate color */
CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
/* add in texel */
lohi <<= 2;
lohi |= texel;
}
cc[1] = lohi;
}
FX64_MOV32(hi, 7); /* alpha = "011" + lerp = 1 */
for (j = n_vect - 1; j >= 0; j--) {
/* add in alphas */
FX64_SHL(hi, 5);
FX64_OR32(hi, (GLuint)(vec[j][ACOMP] / 8.0F));
}
for (j = n_vect - 1; j >= 0; j--) {
for (i = 0; i < n_comp - 1; i++) {
/* add in colors */
FX64_SHL(hi, 5);
FX64_OR32(hi, (GLuint)(vec[j][i] / 8.0F));
}
}
((Fx64 *)cc)[1] = hi;
}
static void
fxt1_quantize_HI (GLuint *cc,
GLubyte input[N_TEXELS][MAX_COMP],
GLubyte reord[N_TEXELS][MAX_COMP], GLint n)
{
const GLint n_vect = 6; /* highest vector number */
const GLint n_comp = 3; /* 3 components: R, G, B */
GLfloat b = 0.0F; /* phoudoin: silent compiler! */
GLfloat iv[MAX_COMP]; /* interpolation vector */
GLint i, k;
GLuint hihi; /* high quadword: hi dword */
GLint minSum = 2000; /* big enough */
GLint maxSum = -1; /* small enough */
GLint minCol = 0; /* phoudoin: silent compiler! */
GLint maxCol = 0; /* phoudoin: silent compiler! */
/* Our solution here is to find the darkest and brightest colors in
* the 8x4 tile and use those as the two representative colors.
* There are probably better algorithms to use (histogram-based).
*/
for (k = 0; k < n; k++) {
GLint sum = 0;
for (i = 0; i < n_comp; i++) {
sum += reord[k][i];
}
if (minSum > sum) {
minSum = sum;
minCol = k;
}
if (maxSum < sum) {
maxSum = sum;
maxCol = k;
}
}
hihi = 0; /* cc-hi = "00" */
for (i = 0; i < n_comp; i++) {
/* add in colors */
hihi <<= 5;
hihi |= reord[maxCol][i] >> 3;
}
for (i = 0; i < n_comp; i++) {
/* add in colors */
hihi <<= 5;
hihi |= reord[minCol][i] >> 3;
}
cc[3] = hihi;
cc[0] = cc[1] = cc[2] = 0;
/* compute interpolation vector */
if (minCol != maxCol) {
MAKEIVEC(n_vect, n_comp, iv, b, reord[minCol], reord[maxCol]);
}
/* add in texels */
for (k = N_TEXELS - 1; k >= 0; k--) {
GLint t = k * 3;
GLuint *kk = (GLuint *)((char *)cc + t / 8);
GLint texel = n_vect + 1; /* transparent black */
if (!ISTBLACK(input[k])) {
if (minCol != maxCol) {
/* interpolate color */
CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
/* add in texel */
kk[0] |= texel << (t & 7);
}
} else {
/* add in texel */
kk[0] |= texel << (t & 7);
}
}
}
static void
fxt1_quantize_MIXED1 (GLuint *cc,
GLubyte input[N_TEXELS][MAX_COMP])
{
const GLint n_vect = 2; /* highest vector number in each microtile */
const GLint n_comp = 3; /* 3 components: R, G, B */
GLubyte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */
GLfloat b, iv[MAX_COMP]; /* interpolation vector */
GLint i, j, k;
Fx64 hi; /* high quadword */
GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
GLint minSum;
GLint maxSum;
GLint minColL = 0, maxColL = -1;
GLint minColR = 0, maxColR = -1;
/* Our solution here is to find the darkest and brightest colors in
* the 4x4 tile and use those as the two representative colors.
* There are probably better algorithms to use (histogram-based).
*/
minSum = 2000; /* big enough */
maxSum = -1; /* small enough */
for (k = 0; k < N_TEXELS / 2; k++) {
if (!ISTBLACK(input[k])) {
GLint sum = 0;
for (i = 0; i < n_comp; i++) {
sum += input[k][i];
}
if (minSum > sum) {
minSum = sum;
minColL = k;
}
if (maxSum < sum) {
maxSum = sum;
maxColL = k;
}
}
}
minSum = 2000; /* big enough */
maxSum = -1; /* small enough */
for (; k < N_TEXELS; k++) {
if (!ISTBLACK(input[k])) {
GLint sum = 0;
for (i = 0; i < n_comp; i++) {
sum += input[k][i];
}
if (minSum > sum) {
minSum = sum;
minColR = k;
}
if (maxSum < sum) {
maxSum = sum;
maxColR = k;
}
}
}
/* left microtile */
if (maxColL == -1) {
/* all transparent black */
cc[0] = ~0u;
for (i = 0; i < n_comp; i++) {
vec[0][i] = 0;
vec[1][i] = 0;
}
} else {
cc[0] = 0;
for (i = 0; i < n_comp; i++) {
vec[0][i] = input[minColL][i];
vec[1][i] = input[maxColL][i];
}
if (minColL != maxColL) {
/* compute interpolation vector */
MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]);
/* add in texels */
lolo = 0;
for (k = N_TEXELS / 2 - 1; k >= 0; k--) {
GLint texel = n_vect + 1; /* transparent black */
if (!ISTBLACK(input[k])) {
/* interpolate color */
CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
}
/* add in texel */
lolo <<= 2;
lolo |= texel;
}
cc[0] = lolo;
}
}
/* right microtile */
if (maxColR == -1) {
/* all transparent black */
cc[1] = ~0u;
for (i = 0; i < n_comp; i++) {
vec[2][i] = 0;
vec[3][i] = 0;
}
} else {
cc[1] = 0;
for (i = 0; i < n_comp; i++) {
vec[2][i] = input[minColR][i];
vec[3][i] = input[maxColR][i];
}
if (minColR != maxColR) {
/* compute interpolation vector */
MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]);
/* add in texels */
lohi = 0;
for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
GLint texel = n_vect + 1; /* transparent black */
if (!ISTBLACK(input[k])) {
/* interpolate color */
CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
}
/* add in texel */
lohi <<= 2;
lohi |= texel;
}
cc[1] = lohi;
}
}
FX64_MOV32(hi, 9 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */
for (j = 2 * 2 - 1; j >= 0; j--) {
for (i = 0; i < n_comp; i++) {
/* add in colors */
FX64_SHL(hi, 5);
FX64_OR32(hi, vec[j][i] >> 3);
}
}
((Fx64 *)cc)[1] = hi;
}
static void
fxt1_quantize_MIXED0 (GLuint *cc,
GLubyte input[N_TEXELS][MAX_COMP])
{
const GLint n_vect = 3; /* highest vector number in each microtile */
const GLint n_comp = 3; /* 3 components: R, G, B */
GLubyte vec[2 * 2][MAX_COMP]; /* 2 extrema for each sub-block */
GLfloat b, iv[MAX_COMP]; /* interpolation vector */
GLint i, j, k;
Fx64 hi; /* high quadword */
GLuint lohi, lolo; /* low quadword: hi dword, lo dword */
GLint minColL = 0, maxColL = 0;
GLint minColR = 0, maxColR = 0;
#if 0
GLint minSum;
GLint maxSum;
/* Our solution here is to find the darkest and brightest colors in
* the 4x4 tile and use those as the two representative colors.
* There are probably better algorithms to use (histogram-based).
*/
minSum = 2000; /* big enough */
maxSum = -1; /* small enough */
for (k = 0; k < N_TEXELS / 2; k++) {
GLint sum = 0;
for (i = 0; i < n_comp; i++) {
sum += input[k][i];
}
if (minSum > sum) {
minSum = sum;
minColL = k;
}
if (maxSum < sum) {
maxSum = sum;
maxColL = k;
}
}
minSum = 2000; /* big enough */
maxSum = -1; /* small enough */
for (; k < N_TEXELS; k++) {
GLint sum = 0;
for (i = 0; i < n_comp; i++) {
sum += input[k][i];
}
if (minSum > sum) {
minSum = sum;
minColR = k;
}
if (maxSum < sum) {
maxSum = sum;
maxColR = k;
}
}
#else
GLint minVal;
GLint maxVal;
GLint maxVarL = fxt1_variance(NULL, input, n_comp, N_TEXELS / 2);
GLint maxVarR = fxt1_variance(NULL, &input[N_TEXELS / 2], n_comp, N_TEXELS / 2);
/* Scan the channel with max variance for lo & hi
* and use those as the two representative colors.
*/
minVal = 2000; /* big enough */
maxVal = -1; /* small enough */
for (k = 0; k < N_TEXELS / 2; k++) {
GLint t = input[k][maxVarL];
if (minVal > t) {
minVal = t;
minColL = k;
}
if (maxVal < t) {
maxVal = t;
maxColL = k;
}
}
minVal = 2000; /* big enough */
maxVal = -1; /* small enough */
for (; k < N_TEXELS; k++) {
GLint t = input[k][maxVarR];
if (minVal > t) {
minVal = t;
minColR = k;
}
if (maxVal < t) {
maxVal = t;
maxColR = k;
}
}
#endif
/* left microtile */
cc[0] = 0;
for (i = 0; i < n_comp; i++) {
vec[0][i] = input[minColL][i];
vec[1][i] = input[maxColL][i];
}
if (minColL != maxColL) {
/* compute interpolation vector */
MAKEIVEC(n_vect, n_comp, iv, b, vec[0], vec[1]);
/* add in texels */
lolo = 0;
for (k = N_TEXELS / 2 - 1; k >= 0; k--) {
GLint texel;
/* interpolate color */
CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
/* add in texel */
lolo <<= 2;
lolo |= texel;
}
/* funky encoding for LSB of green */
if ((GLint)((lolo >> 1) & 1) != (((vec[1][GCOMP] ^ vec[0][GCOMP]) >> 2) & 1)) {
for (i = 0; i < n_comp; i++) {
vec[1][i] = input[minColL][i];
vec[0][i] = input[maxColL][i];
}
lolo = ~lolo;
}
cc[0] = lolo;
}
/* right microtile */
cc[1] = 0;
for (i = 0; i < n_comp; i++) {
vec[2][i] = input[minColR][i];
vec[3][i] = input[maxColR][i];
}
if (minColR != maxColR) {
/* compute interpolation vector */
MAKEIVEC(n_vect, n_comp, iv, b, vec[2], vec[3]);
/* add in texels */
lohi = 0;
for (k = N_TEXELS - 1; k >= N_TEXELS / 2; k--) {
GLint texel;
/* interpolate color */
CALCCDOT(texel, n_vect, n_comp, iv, b, input[k]);
/* add in texel */
lohi <<= 2;
lohi |= texel;
}
/* funky encoding for LSB of green */
if ((GLint)((lohi >> 1) & 1) != (((vec[3][GCOMP] ^ vec[2][GCOMP]) >> 2) & 1)) {
for (i = 0; i < n_comp; i++) {
vec[3][i] = input[minColR][i];
vec[2][i] = input[maxColR][i];
}
lohi = ~lohi;
}
cc[1] = lohi;
}
FX64_MOV32(hi, 8 | (vec[3][GCOMP] & 4) | ((vec[1][GCOMP] >> 1) & 2)); /* chroma = "1" */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -