-/* $Id: s_texture.c,v 1.1 2000/10/31 18:00:04 keithw Exp $ */
+/* $Id: s_texture.c,v 1.12 2001/02/20 16:42:26 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.5
- *
- * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
- *
+ *
+ * Copyright (C) 1999-2001 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
#include "mem.h"
#include "teximage.h"
+#include "s_context.h"
#include "s_pb.h"
#include "s_texture.h"
-
-/*
- * Paletted texture sampling.
- * Input: tObj - the texture object
- * index - the palette index (8-bit only)
- * Output: red, green, blue, alpha - the texel color
- */
-static void palette_sample(const struct gl_texture_object *tObj,
- GLint index, GLchan rgba[4] )
-{
- GLcontext *ctx = _mesa_get_current_context(); /* THIS IS A HACK */
- const GLchan *palette;
- GLenum format;
-
- if (ctx->Texture.SharedPalette) {
- ASSERT(!ctx->Texture.Palette.FloatTable);
- palette = (const GLchan *) ctx->Texture.Palette.Table;
- format = ctx->Texture.Palette.Format;
- }
- else {
- ASSERT(!tObj->Palette.FloatTable);
- palette = (const GLchan *) tObj->Palette.Table;
- format = tObj->Palette.Format;
- }
-
- switch (format) {
- case GL_ALPHA:
- rgba[ACOMP] = palette[index];
- return;
- case GL_LUMINANCE:
- case GL_INTENSITY:
- rgba[RCOMP] = palette[index];
- return;
- case GL_LUMINANCE_ALPHA:
- rgba[RCOMP] = palette[(index << 1) + 0];
- rgba[ACOMP] = palette[(index << 1) + 1];
- return;
- case GL_RGB:
- rgba[RCOMP] = palette[index * 3 + 0];
- rgba[GCOMP] = palette[index * 3 + 1];
- rgba[BCOMP] = palette[index * 3 + 2];
- return;
- case GL_RGBA:
- rgba[RCOMP] = palette[(index << 2) + 0];
- rgba[GCOMP] = palette[(index << 2) + 1];
- rgba[BCOMP] = palette[(index << 2) + 2];
- rgba[ACOMP] = palette[(index << 2) + 3];
- return;
- default:
- gl_problem(NULL, "Bad palette format in palette_sample");
- }
-}
-
-
-
/*
* These values are used in the fixed-point arithmetic used
* for linear filtering.
{ \
if (wrapMode == GL_REPEAT) { \
U = S * SIZE - 0.5F; \
- I0 = ((GLint) myFloor(U)) & (SIZE - 1); \
+ I0 = IFLOOR(U) & (SIZE - 1); \
I1 = (I0 + 1) & (SIZE - 1); \
} \
else { \
else if (U >= SIZE) \
U = SIZE; \
U -= 0.5F; \
- I0 = (GLint) myFloor(U); \
+ I0 = IFLOOR(U); \
I1 = I0 + 1; \
if (wrapMode == GL_CLAMP_TO_EDGE) { \
if (I0 < 0) \
{ \
if (lambda < 0.0F) \
lambda = 0.0F; \
- else if (lambda > tObj->M) \
- lambda = tObj->M; \
+ else if (lambda > tObj->_MaxLambda) \
+ lambda = tObj->_MaxLambda; \
level = (GLint) (tObj->BaseLevel + lambda); \
}
{ \
if (lambda <= 0.5F) \
lambda = 0.0F; \
- else if (lambda > tObj->M + 0.4999F) \
- lambda = tObj->M + 0.4999F; \
+ else if (lambda > tObj->_MaxLambda + 0.4999F) \
+ lambda = tObj->_MaxLambda + 0.4999F; \
level = (GLint) (tObj->BaseLevel + lambda + 0.5F); \
- if (level > tObj->P) \
- level = tObj->P; \
+ if (level > tObj->_MaxLevel) \
+ level = tObj->_MaxLevel; \
}
-
+
/*
* Bitflags for texture border color sampling.
-/**********************************************************************/
-/* 1-D Texture Sampling Functions */
-/**********************************************************************/
-
-
-/*
- * Return floor of x, being careful of negative values.
- */
-static GLfloat myFloor(GLfloat x)
-{
- if (x < 0.0F)
- return (GLfloat) ((GLint) x - 1);
- else
- return (GLfloat) (GLint) x;
-}
-
-
-/*
- * Return the fractional part of x.
- */
-#define myFrac(x) ( (x) - myFloor(x) )
-
-
-
-
/*
- * Given 1-D texture image and an (i) texel column coordinate, return the
- * texel color.
+ * Get texture palette entry.
*/
-static void get_1d_texel( const struct gl_texture_object *tObj,
- const struct gl_texture_image *img, GLint i,
- GLchan rgba[4] )
+static void
+palette_sample(const GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLint index, GLchan rgba[4] )
{
- const GLchan *texel;
+ const GLchan *palette;
+ GLenum format;
-#ifdef DEBUG
- GLint width = img->Width;
- assert(i >= 0);
- assert(i < width);
-#endif
+ if (ctx->Texture.SharedPalette) {
+ ASSERT(!ctx->Texture.Palette.FloatTable);
+ palette = (const GLchan *) ctx->Texture.Palette.Table;
+ format = ctx->Texture.Palette.Format;
+ }
+ else {
+ ASSERT(!tObj->Palette.FloatTable);
+ palette = (const GLchan *) tObj->Palette.Table;
+ format = tObj->Palette.Format;
+ }
- switch (img->Format) {
- case GL_COLOR_INDEX:
- {
- GLint index = img->Data[i];
- palette_sample(tObj, index, rgba);
- return;
- }
+ switch (format) {
case GL_ALPHA:
- rgba[ACOMP] = img->Data[ i ];
+ rgba[ACOMP] = palette[index];
return;
case GL_LUMINANCE:
case GL_INTENSITY:
- rgba[RCOMP] = img->Data[ i ];
+ rgba[RCOMP] = palette[index];
return;
case GL_LUMINANCE_ALPHA:
- texel = img->Data + i * 2;
- rgba[RCOMP] = texel[0];
- rgba[ACOMP] = texel[1];
+ rgba[RCOMP] = palette[(index << 1) + 0];
+ rgba[ACOMP] = palette[(index << 1) + 1];
return;
case GL_RGB:
- texel = img->Data + i * 3;
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
+ rgba[RCOMP] = palette[index * 3 + 0];
+ rgba[GCOMP] = palette[index * 3 + 1];
+ rgba[BCOMP] = palette[index * 3 + 2];
return;
case GL_RGBA:
- texel = img->Data + i * 4;
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
- rgba[ACOMP] = texel[3];
+ rgba[RCOMP] = palette[(index << 2) + 0];
+ rgba[GCOMP] = palette[(index << 2) + 1];
+ rgba[BCOMP] = palette[(index << 2) + 2];
+ rgba[ACOMP] = palette[(index << 2) + 3];
return;
default:
- gl_problem(NULL, "Bad format in get_1d_texel");
- return;
+ gl_problem(ctx, "Bad palette format in palette_sample");
}
}
+/**********************************************************************/
+/* 1-D Texture Sampling Functions */
+/**********************************************************************/
+
/*
* Return the texture sample for coordinate (s) using GL_NEAREST filter.
*/
-static void sample_1d_nearest( const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- GLfloat s, GLchan rgba[4] )
+static void
+sample_1d_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ GLfloat s, GLchan rgba[4])
{
const GLint width = img->Width2; /* without border, power of two */
- const GLchan *texel;
GLint i;
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i);
/* skip over the border, if any */
i += img->Border;
- /* Get the texel */
- switch (img->Format) {
- case GL_COLOR_INDEX:
- {
- GLint index = img->Data[i];
- palette_sample(tObj, index, rgba );
- return;
- }
- case GL_ALPHA:
- rgba[ACOMP] = img->Data[i];
- return;
- case GL_LUMINANCE:
- case GL_INTENSITY:
- rgba[RCOMP] = img->Data[i];
- return;
- case GL_LUMINANCE_ALPHA:
- texel = img->Data + i * 2;
- rgba[RCOMP] = texel[0];
- rgba[ACOMP] = texel[1];
- return;
- case GL_RGB:
- texel = img->Data + i * 3;
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
- return;
- case GL_RGBA:
- texel = img->Data + i * 4;
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
- rgba[ACOMP] = texel[3];
- return;
- default:
- gl_problem(NULL, "Bad format in sample_1d_nearest");
+ (*img->FetchTexel)(img, i, 0, 0, (GLvoid *) rgba);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, rgba[0], rgba);
}
}
/*
* Return the texture sample for coordinate (s) using GL_LINEAR filter.
*/
-static void sample_1d_linear( const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- GLfloat s,
- GLchan rgba[4] )
+static void
+sample_1d_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ GLfloat s, GLchan rgba[4])
{
const GLint width = img->Width2;
GLint i0, i1;
}
{
- const GLfloat a = myFrac(u);
+ const GLfloat a = FRAC(u);
/* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
const GLint w0 = (GLint) ((1.0F-a) * WEIGHT_SCALE + 0.5F);
const GLint w1 = (GLint) ( a * WEIGHT_SCALE + 0.5F);
COPY_CHAN4(t0, tObj->BorderColor);
}
else {
- get_1d_texel( tObj, img, i0, t0 );
+ (*img->FetchTexel)(img, i0, 0, 0, (GLvoid *) t0);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t0[0], t0);
+ }
}
if (useBorderColor & I1BIT) {
COPY_CHAN4(t1, tObj->BorderColor);
}
else {
- get_1d_texel( tObj, img, i1, t1 );
+ (*img->FetchTexel)(img, i1, 0, 0, (GLvoid *) t1);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t1[0], t1);
+ }
}
rgba[0] = (GLchan) ((w0 * t0[0] + w1 * t1[0]) >> WEIGHT_SHIFT);
static void
-sample_1d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat lambda,
- GLchan rgba[4] )
+sample_1d_nearest_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat lambda,
+ GLchan rgba[4])
{
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_1d_nearest( tObj, tObj->Image[level], s, rgba );
+ sample_1d_nearest(ctx, tObj, tObj->Image[level], s, rgba);
}
static void
-sample_1d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat lambda,
- GLchan rgba[4] )
+sample_1d_linear_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat lambda,
+ GLchan rgba[4])
{
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_1d_linear( tObj, tObj->Image[level], s, rgba );
+ sample_1d_linear(ctx, tObj, tObj->Image[level], s, rgba);
}
static void
-sample_1d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat lambda,
- GLchan rgba[4] )
+sample_1d_nearest_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat lambda,
+ GLchan rgba[4])
{
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
- if (level >= tObj->P) {
- sample_1d_nearest( tObj, tObj->Image[tObj->P], s, rgba );
+ if (level >= tObj->_MaxLevel) {
+ sample_1d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, rgba);
}
else {
GLchan t0[4], t1[4];
- const GLfloat f = myFrac(lambda);
- sample_1d_nearest( tObj, tObj->Image[level ], s, t0 );
- sample_1d_nearest( tObj, tObj->Image[level+1], s, t1 );
+ const GLfloat f = FRAC(lambda);
+ sample_1d_nearest(ctx, tObj, tObj->Image[level ], s, t0);
+ sample_1d_nearest(ctx, tObj, tObj->Image[level+1], s, t1);
rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
static void
-sample_1d_linear_mipmap_linear( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat lambda,
- GLchan rgba[4] )
+sample_1d_linear_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat lambda,
+ GLchan rgba[4])
{
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
- if (level >= tObj->P) {
- sample_1d_linear( tObj, tObj->Image[tObj->P], s, rgba );
+ if (level >= tObj->_MaxLevel) {
+ sample_1d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, rgba);
}
else {
GLchan t0[4], t1[4];
- const GLfloat f = myFrac(lambda);
- sample_1d_linear( tObj, tObj->Image[level ], s, t0 );
- sample_1d_linear( tObj, tObj->Image[level+1], s, t1 );
+ const GLfloat f = FRAC(lambda);
+ sample_1d_linear(ctx, tObj, tObj->Image[level ], s, t0);
+ sample_1d_linear(ctx, tObj, tObj->Image[level+1], s, t1);
rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
-static void sample_nearest_1d( const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+static void
+sample_nearest_1d( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) u;
(void) lambda;
for (i=0;i<n;i++) {
- sample_1d_nearest( tObj, image, s[i], rgba[i] );
+ sample_1d_nearest(ctx, tObj, image, s[i], rgba[i]);
}
}
-static void sample_linear_1d( const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+static void
+sample_linear_1d( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) u;
(void) lambda;
for (i=0;i<n;i++) {
- sample_1d_linear( tObj, image, s[i], rgba[i] );
+ sample_1d_linear(ctx, tObj, image, s[i], rgba[i]);
}
}
* return a texture sample.
*
*/
-static void sample_lambda_1d( const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+static void
+sample_lambda_1d( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4] )
{
+ GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
GLuint i;
(void) t;
(void) u;
for (i=0;i<n;i++) {
- if (lambda[i] > tObj->MinMagThresh) {
+ if (lambda[i] > MinMagThresh) {
/* minification */
switch (tObj->MinFilter) {
case GL_NEAREST:
- sample_1d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
+ sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], rgba[i]);
break;
case GL_LINEAR:
- sample_1d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
+ sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], rgba[i]);
break;
case GL_NEAREST_MIPMAP_NEAREST:
- sample_1d_nearest_mipmap_nearest( tObj, lambda[i], s[i], rgba[i] );
+ sample_1d_nearest_mipmap_nearest(ctx, tObj, lambda[i], s[i],
+ rgba[i]);
break;
case GL_LINEAR_MIPMAP_NEAREST:
- sample_1d_linear_mipmap_nearest( tObj, s[i], lambda[i], rgba[i] );
+ sample_1d_linear_mipmap_nearest(ctx, tObj, s[i], lambda[i],
+ rgba[i]);
break;
case GL_NEAREST_MIPMAP_LINEAR:
- sample_1d_nearest_mipmap_linear( tObj, s[i], lambda[i], rgba[i] );
+ sample_1d_nearest_mipmap_linear(ctx, tObj, s[i], lambda[i],
+ rgba[i]);
break;
case GL_LINEAR_MIPMAP_LINEAR:
- sample_1d_linear_mipmap_linear( tObj, s[i], lambda[i], rgba[i] );
+ sample_1d_linear_mipmap_linear(ctx, tObj, s[i], lambda[i],
+ rgba[i]);
break;
default:
gl_problem(NULL, "Bad min filter in sample_1d_texture");
/* magnification */
switch (tObj->MagFilter) {
case GL_NEAREST:
- sample_1d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
+ sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], rgba[i]);
break;
case GL_LINEAR:
- sample_1d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
+ sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], rgba[i]);
break;
default:
gl_problem(NULL, "Bad mag filter in sample_1d_texture");
/**********************************************************************/
-/*
- * Given a texture image and an (i,j) integer texel coordinate, return the
- * texel color.
- */
-static void get_2d_texel( const struct gl_texture_object *tObj,
- const struct gl_texture_image *img, GLint i, GLint j,
- GLchan rgba[4] )
-{
- const GLint width = img->Width; /* includes border */
- const GLchan *texel;
-
-#ifdef DEBUG
- const GLint height = img->Height; /* includes border */
- assert(i >= 0);
- assert(i < width);
- assert(j >= 0);
- assert(j < height);
-#endif
-
- switch (img->Format) {
- case GL_COLOR_INDEX:
- {
- GLint index = img->Data[ width *j + i ];
- palette_sample(tObj, index, rgba );
- return;
- }
- case GL_ALPHA:
- rgba[ACOMP] = img->Data[ width * j + i ];
- return;
- case GL_LUMINANCE:
- case GL_INTENSITY:
- rgba[RCOMP] = img->Data[ width * j + i ];
- return;
- case GL_LUMINANCE_ALPHA:
- texel = img->Data + (width * j + i) * 2;
- rgba[RCOMP] = texel[0];
- rgba[ACOMP] = texel[1];
- return;
- case GL_RGB:
- texel = img->Data + (width * j + i) * 3;
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
- return;
- case GL_RGBA:
- texel = img->Data + (width * j + i) * 4;
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
- rgba[ACOMP] = texel[3];
- return;
- default:
- gl_problem(NULL, "Bad format in get_2d_texel");
- }
-}
-
-
-
/*
* Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
*/
-static void sample_2d_nearest( const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- GLfloat s, GLfloat t,
- GLchan rgba[] )
+static void
+sample_2d_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ GLfloat s, GLfloat t,
+ GLchan rgba[])
{
- const GLint imgWidth = img->Width; /* includes border */
const GLint width = img->Width2; /* without border, power of two */
const GLint height = img->Height2; /* without border, power of two */
- const GLchan *texel;
GLint i, j;
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i);
i += img->Border;
j += img->Border;
- switch (img->Format) {
- case GL_COLOR_INDEX:
- {
- GLint index = img->Data[ j * imgWidth + i ];
- palette_sample(tObj, index, rgba);
- return;
- }
- case GL_ALPHA:
- rgba[ACOMP] = img->Data[ j * imgWidth + i ];
- return;
- case GL_LUMINANCE:
- case GL_INTENSITY:
- rgba[RCOMP] = img->Data[ j * imgWidth + i ];
- return;
- case GL_LUMINANCE_ALPHA:
- texel = img->Data + ((j * imgWidth + i) << 1);
- rgba[RCOMP] = texel[0];
- rgba[ACOMP] = texel[1];
- return;
- case GL_RGB:
- texel = img->Data + (j * imgWidth + i) * 3;
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
- return;
- case GL_RGBA:
- texel = img->Data + ((j * imgWidth + i) << 2);
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
- rgba[ACOMP] = texel[3];
- return;
- default:
- gl_problem(NULL, "Bad format in sample_2d_nearest");
+ (*img->FetchTexel)(img, i, j, 0, (GLvoid *) rgba);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, rgba[0], rgba);
}
}
* Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
* New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
*/
-static void sample_2d_linear( const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- GLfloat s, GLfloat t,
- GLchan rgba[] )
+static void
+sample_2d_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ GLfloat s, GLfloat t,
+ GLchan rgba[])
{
const GLint width = img->Width2;
const GLint height = img->Height2;
}
{
- const GLfloat a = myFrac(u);
- const GLfloat b = myFrac(v);
+ const GLfloat a = FRAC(u);
+ const GLfloat b = FRAC(v);
/* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
const GLint w00 = (GLint) ((1.0F-a)*(1.0F-b) * WEIGHT_SCALE + 0.5F);
const GLint w10 = (GLint) ( a *(1.0F-b) * WEIGHT_SCALE + 0.5F);
COPY_CHAN4(t00, tObj->BorderColor);
}
else {
- get_2d_texel( tObj, img, i0, j0, t00 );
+ (*img->FetchTexel)(img, i0, j0, 0, (GLvoid *) t00);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t00[0], t00);
+ }
}
if (useBorderColor & (I1BIT | J0BIT)) {
COPY_CHAN4(t10, tObj->BorderColor);
}
else {
- get_2d_texel( tObj, img, i1, j0, t10 );
+ (*img->FetchTexel)(img, i1, j0, 0, (GLvoid *) t10);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t10[0], t10);
+ }
}
if (useBorderColor & (I0BIT | J1BIT)) {
COPY_CHAN4(t01, tObj->BorderColor);
}
else {
- get_2d_texel( tObj, img, i0, j1, t01 );
+ (*img->FetchTexel)(img, i0, j1, 0, (GLvoid *) t01);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t01[0], t01);
+ }
}
if (useBorderColor & (I1BIT | J1BIT)) {
COPY_CHAN4(t11, tObj->BorderColor);
}
else {
- get_2d_texel( tObj, img, i1, j1, t11 );
+ (*img->FetchTexel)(img, i1, j1, 0, (GLvoid *) t11);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t11[0], t11);
+ }
}
rgba[0] = (GLchan) ((w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0]) >> WEIGHT_SHIFT);
static void
-sample_2d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat lambda,
- GLchan rgba[4] )
+sample_2d_nearest_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat lambda,
+ GLchan rgba[4])
{
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_2d_nearest( tObj, tObj->Image[level], s, t, rgba );
+ sample_2d_nearest(ctx, tObj, tObj->Image[level], s, t, rgba);
}
static void
-sample_2d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat lambda,
- GLchan rgba[4] )
+sample_2d_linear_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat lambda,
+ GLchan rgba[4])
{
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_2d_linear( tObj, tObj->Image[level], s, t, rgba );
+ sample_2d_linear(ctx, tObj, tObj->Image[level], s, t, rgba);
}
static void
-sample_2d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat lambda,
- GLchan rgba[4] )
+sample_2d_nearest_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat lambda,
+ GLchan rgba[4])
{
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
- if (level >= tObj->P) {
- sample_2d_nearest( tObj, tObj->Image[tObj->P], s, t, rgba );
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, rgba);
}
else {
GLchan t0[4], t1[4]; /* texels */
- const GLfloat f = myFrac(lambda);
- sample_2d_nearest( tObj, tObj->Image[level ], s, t, t0 );
- sample_2d_nearest( tObj, tObj->Image[level+1], s, t, t1 );
+ const GLfloat f = FRAC(lambda);
+ sample_2d_nearest(ctx, tObj, tObj->Image[level ], s, t, t0);
+ sample_2d_nearest(ctx, tObj, tObj->Image[level+1], s, t, t1);
rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
static void
-sample_2d_linear_mipmap_linear( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat lambda,
- GLchan rgba[4] )
+sample_2d_linear_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat lambda,
+ GLchan rgba[4])
{
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
- if (level >= tObj->P) {
- sample_2d_linear( tObj, tObj->Image[tObj->P], s, t, rgba );
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, rgba);
}
else {
GLchan t0[4], t1[4]; /* texels */
- const GLfloat f = myFrac(lambda);
- sample_2d_linear( tObj, tObj->Image[level ], s, t, t0 );
- sample_2d_linear( tObj, tObj->Image[level+1], s, t, t1 );
+ const GLfloat f = FRAC(lambda);
+ sample_2d_linear(ctx, tObj, tObj->Image[level ], s, t, t0);
+ sample_2d_linear(ctx, tObj, tObj->Image[level+1], s, t, t1);
rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
-static void sample_nearest_2d( const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+static void
+sample_nearest_2d( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) u;
(void) lambda;
for (i=0;i<n;i++) {
- sample_2d_nearest( tObj, image, s[i], t[i], rgba[i] );
+ sample_2d_nearest(ctx, tObj, image, s[i], t[i], rgba[i]);
}
}
-static void sample_linear_2d( const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+static void
+sample_linear_2d( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) u;
(void) lambda;
for (i=0;i<n;i++) {
- sample_2d_linear( tObj, image, s[i], t[i], rgba[i] );
+ sample_2d_linear(ctx, tObj, image, s[i], t[i], rgba[i]);
}
}
/*
- * Given an (s,t) texture coordinate and lambda (level of detail) value,
- * return a texture sample.
+ * Given an array of (s,t) texture coordinate and lambda (level of detail)
+ * values, return an array of texture sample.
*/
-static void sample_lambda_2d( const struct gl_texture_object *tObj,
- GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+static void
+sample_lambda_2d( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj,
+ GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4] )
{
+ const GLfloat minMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
GLuint i;
(void) u;
- for (i=0;i<n;i++) {
- if (lambda[i] > tObj->MinMagThresh) {
- /* minification */
- switch (tObj->MinFilter) {
- case GL_NEAREST:
- sample_2d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
- break;
- case GL_LINEAR:
- sample_2d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- sample_2d_nearest_mipmap_nearest( tObj, s[i], t[i], lambda[i], rgba[i] );
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- sample_2d_linear_mipmap_nearest( tObj, s[i], t[i], lambda[i], rgba[i] );
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- sample_2d_nearest_mipmap_linear( tObj, s[i], t[i], lambda[i], rgba[i] );
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- sample_2d_linear_mipmap_linear( tObj, s[i], t[i], lambda[i], rgba[i] );
- break;
- default:
- gl_problem(NULL, "Bad min filter in sample_2d_texture");
- return;
- }
+
+ /* check if lambda is monotonous-array */
+ if (lambda[0] <= minMagThresh && lambda[n-1] <= minMagThresh) {
+ /* magnification */
+ switch (tObj->MagFilter) {
+ case GL_NEAREST:
+ for (i = 0; i < n; i++)
+ sample_2d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], t[i], rgba[i] );
+ break;
+ case GL_LINEAR:
+ for (i = 0; i < n; i++)
+ sample_2d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], t[i], rgba[i] );
+ break;
+ default:
+ gl_problem(NULL, "Bad mag filter in sample_2d_texture");
}
- else {
- /* magnification */
- switch (tObj->MagFilter) {
- case GL_NEAREST:
- sample_2d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
- break;
- case GL_LINEAR:
- sample_2d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
- break;
- default:
- gl_problem(NULL, "Bad mag filter in sample_2d_texture");
+ }
+ else {
+ for (i = 0; i < n; i++) {
+ if (lambda[i] > minMagThresh) {
+ /* minification */
+ switch (tObj->MinFilter) {
+ case GL_NEAREST:
+ sample_2d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], t[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ sample_2d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], t[i], rgba[i]);
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ sample_2d_nearest_mipmap_nearest(ctx, tObj, s[i], t[i],
+ lambda[i], rgba[i]);
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ sample_2d_linear_mipmap_nearest(ctx,tObj, s[i], t[i],
+ lambda[i], rgba[i]);
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ sample_2d_nearest_mipmap_linear(ctx,tObj, s[i], t[i],
+ lambda[i], rgba[i]);
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ sample_2d_linear_mipmap_linear(ctx,tObj, s[i], t[i],
+ lambda[i], rgba[i] );
+ break;
+ default:
+ gl_problem(NULL, "Bad min filter in sample_2d_texture");
+ return;
+ }
+ }
+ else {
+ /* magnification */
+ switch (tObj->MagFilter) {
+ case GL_NEAREST:
+ sample_2d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], t[i], rgba[i]);
+ break;
+ case GL_LINEAR:
+ sample_2d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], t[i], rgba[i] );
+ break;
+ default:
+ gl_problem(NULL, "Bad mag filter in sample_2d_texture");
+ }
}
}
}
* No border
* Format = GL_RGB
*/
-static void opt_sample_rgb_2d( const struct gl_texture_object *tObj,
- GLuint n, const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+static void
+opt_sample_rgb_2d( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4] )
{
const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel];
const GLfloat width = (GLfloat) img->Width;
GLint i = (GLint) ((s[k] + 10000.0) * width) & colMask;
GLint j = (GLint) ((t[k] + 10000.0) * height) & rowMask;
GLint pos = (j << shift) | i;
- GLchan *texel = img->Data + pos + pos + pos; /* pos*3 */
+ GLchan *texel = ((GLchan *) img->Data) + pos + pos + pos; /* pos*3 */
rgba[k][RCOMP] = texel[0];
rgba[k][GCOMP] = texel[1];
rgba[k][BCOMP] = texel[2];
* No border
* Format = GL_RGBA
*/
-static void opt_sample_rgba_2d( const struct gl_texture_object *tObj,
- GLuint n, const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+static void
+opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj,
+ GLuint n, const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4] )
{
const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel];
const GLfloat width = (GLfloat) img->Width;
GLint i = (GLint) ((s[k] + 10000.0) * width) & colMask;
GLint j = (GLint) ((t[k] + 10000.0) * height) & rowMask;
GLint pos = (j << shift) | i;
- GLchan *texel = img->Data + (pos << 2); /* pos*4 */
+ GLchan *texel = ((GLchan *) img->Data) + (pos << 2); /* pos*4 */
rgba[k][RCOMP] = texel[0];
rgba[k][GCOMP] = texel[1];
rgba[k][BCOMP] = texel[2];
/* 3-D Texture Sampling Functions */
/**********************************************************************/
-/*
- * Given a texture image and an (i,j,k) integer texel coordinate, return the
- * texel color.
- */
-static void get_3d_texel( const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- GLint i, GLint j, GLint k,
- GLchan rgba[4] )
-{
- const GLint width = img->Width; /* includes border */
- const GLint height = img->Height; /* includes border */
- const GLint rectarea = width * height;
- const GLchan *texel;
-
-#ifdef DEBUG
- const GLint depth = img->Depth; /* includes border */
- assert(i >= 0);
- assert(i < width);
- assert(j >= 0);
- assert(j < height);
- assert(k >= 0);
- assert(k < depth);
-#endif
-
- switch (img->Format) {
- case GL_COLOR_INDEX:
- {
- GLint index = img->Data[ rectarea * k + width * j + i ];
- palette_sample(tObj, index, rgba );
- return;
- }
- case GL_ALPHA:
- rgba[ACOMP] = img->Data[ rectarea * k + width * j + i ];
- return;
- case GL_LUMINANCE:
- case GL_INTENSITY:
- rgba[RCOMP] = img->Data[ rectarea * k + width * j + i ];
- return;
- case GL_LUMINANCE_ALPHA:
- texel = img->Data + ( rectarea * k + width * j + i) * 2;
- rgba[RCOMP] = texel[0];
- rgba[ACOMP] = texel[1];
- return;
- case GL_RGB:
- texel = img->Data + (rectarea * k + width * j + i) * 3;
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
- return;
- case GL_RGBA:
- texel = img->Data + (rectarea * k + width * j + i) * 4;
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
- rgba[ACOMP] = texel[3];
- return;
- default:
- gl_problem(NULL, "Bad format in get_3d_texel");
- }
-}
-
-
/*
* Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
*/
-static void sample_3d_nearest( const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- GLfloat s, GLfloat t, GLfloat r,
- GLchan rgba[4] )
+static void
+sample_3d_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ GLfloat s, GLfloat t, GLfloat r,
+ GLchan rgba[4])
{
- const GLint imgWidth = img->Width; /* includes border, if any */
- const GLint imgHeight = img->Height; /* includes border, if any */
const GLint width = img->Width2; /* without border, power of two */
const GLint height = img->Height2; /* without border, power of two */
const GLint depth = img->Depth2; /* without border, power of two */
- const GLint rectarea = imgWidth * imgHeight;
- const GLchan *texel;
GLint i, j, k;
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i);
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, t, height, j);
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapR, r, depth, k);
- switch (tObj->Image[0]->Format) {
- case GL_COLOR_INDEX:
- {
- GLint index = img->Data[ rectarea * k + j * imgWidth + i ];
- palette_sample(tObj, index, rgba );
- return;
- }
- case GL_ALPHA:
- rgba[ACOMP] = img->Data[ rectarea * k + j * imgWidth + i ];
- return;
- case GL_LUMINANCE:
- case GL_INTENSITY:
- rgba[RCOMP] = img->Data[ rectarea * k + j * imgWidth + i ];
- return;
- case GL_LUMINANCE_ALPHA:
- texel = img->Data + ((rectarea * k + j * imgWidth + i) << 1);
- rgba[RCOMP] = texel[0];
- rgba[ACOMP] = texel[1];
- return;
- case GL_RGB:
- texel = img->Data + ( rectarea * k + j * imgWidth + i) * 3;
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
- return;
- case GL_RGBA:
- texel = img->Data + ((rectarea * k + j * imgWidth + i) << 2);
- rgba[RCOMP] = texel[0];
- rgba[GCOMP] = texel[1];
- rgba[BCOMP] = texel[2];
- rgba[ACOMP] = texel[3];
- return;
- default:
- gl_problem(NULL, "Bad format in sample_3d_nearest");
+ (*img->FetchTexel)(img, i, j, k, (GLvoid *) rgba);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, rgba[0], rgba);
}
}
/*
* Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
*/
-static void sample_3d_linear( const struct gl_texture_object *tObj,
- const struct gl_texture_image *img,
- GLfloat s, GLfloat t, GLfloat r,
- GLchan rgba[4] )
+static void
+sample_3d_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ const struct gl_texture_image *img,
+ GLfloat s, GLfloat t, GLfloat r,
+ GLchan rgba[4])
{
const GLint width = img->Width2;
const GLint height = img->Height2;
}
{
- const GLfloat a = myFrac(u);
- const GLfloat b = myFrac(v);
- const GLfloat c = myFrac(w);
+ const GLfloat a = FRAC(u);
+ const GLfloat b = FRAC(v);
+ const GLfloat c = FRAC(w);
/* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
GLint w000 = (GLint) ((1.0F-a)*(1.0F-b)*(1.0F-c) * WEIGHT_SCALE + 0.5F);
GLint w100 = (GLint) ( a *(1.0F-b)*(1.0F-c) * WEIGHT_SCALE + 0.5F);
COPY_CHAN4(t000, tObj->BorderColor);
}
else {
- get_3d_texel( tObj, img, i0, j0, k0, t000 );
+ (*img->FetchTexel)(img, i0, j0, k0, (GLvoid *) t000);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t000[0], t000);
+ }
}
if (useBorderColor & (I1BIT | J0BIT | K0BIT)) {
COPY_CHAN4(t100, tObj->BorderColor);
}
else {
- get_3d_texel( tObj, img, i1, j0, k0, t100 );
+ (*img->FetchTexel)(img, i1, j0, k0, (GLvoid *) t100);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t100[0], t100);
+ }
}
if (useBorderColor & (I0BIT | J1BIT | K0BIT)) {
COPY_CHAN4(t010, tObj->BorderColor);
}
else {
- get_3d_texel( tObj, img, i0, j1, k0, t010 );
+ (*img->FetchTexel)(img, i0, j1, k0, (GLvoid *) t010);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t010[0], t010);
+ }
}
if (useBorderColor & (I1BIT | J1BIT | K0BIT)) {
COPY_CHAN4(t110, tObj->BorderColor);
}
else {
- get_3d_texel( tObj, img, i1, j1, k0, t110 );
+ (*img->FetchTexel)(img, i1, j1, k0, (GLvoid *) t110);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t110[0], t110);
+ }
}
if (useBorderColor & (I0BIT | J0BIT | K1BIT)) {
COPY_CHAN4(t001, tObj->BorderColor);
}
else {
- get_3d_texel( tObj, img, i0, j0, k1, t001 );
+ (*img->FetchTexel)(img, i0, j0, k1, (GLvoid *) t001);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t001[0], t001);
+ }
}
if (useBorderColor & (I1BIT | J0BIT | K1BIT)) {
COPY_CHAN4(t101, tObj->BorderColor);
}
else {
- get_3d_texel( tObj, img, i1, j0, k1, t101 );
+ (*img->FetchTexel)(img, i1, j0, k1, (GLvoid *) t101);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t101[0], t101);
+ }
}
if (useBorderColor & (I0BIT | J1BIT | K1BIT)) {
COPY_CHAN4(t011, tObj->BorderColor);
}
else {
- get_3d_texel( tObj, img, i0, j1, k1, t011 );
+ (*img->FetchTexel)(img, i0, j1, k1, (GLvoid *) t011);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t011[0], t011);
+ }
}
if (useBorderColor & (I1BIT | J1BIT | K1BIT)) {
COPY_CHAN4(t111, tObj->BorderColor);
}
else {
- get_3d_texel( tObj, img, i1, j1, k1, t111 );
+ (*img->FetchTexel)(img, i1, j1, k1, (GLvoid *) t111);
+ if (img->Format == GL_COLOR_INDEX) {
+ palette_sample(ctx, tObj, t111[0], t111);
+ }
}
rgba[0] = (GLchan) (
static void
-sample_3d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat r,
- GLfloat lambda, GLchan rgba[4] )
+sample_3d_nearest_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat r,
+ GLfloat lambda, GLchan rgba[4] )
{
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_3d_nearest( tObj, tObj->Image[level], s, t, r, rgba );
+ sample_3d_nearest(ctx, tObj, tObj->Image[level], s, t, r, rgba);
}
static void
-sample_3d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat r,
- GLfloat lambda, GLchan rgba[4] )
+sample_3d_linear_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat r,
+ GLfloat lambda, GLchan rgba[4])
{
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
- sample_3d_linear( tObj, tObj->Image[level], s, t, r, rgba );
+ sample_3d_linear(ctx, tObj, tObj->Image[level], s, t, r, rgba);
}
static void
-sample_3d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat r,
- GLfloat lambda, GLchan rgba[4] )
+sample_3d_nearest_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat r,
+ GLfloat lambda, GLchan rgba[4])
{
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
- if (level >= tObj->P) {
- sample_3d_nearest( tObj, tObj->Image[tObj->P], s, t, r, rgba );
+ if (level >= tObj->_MaxLevel) {
+ sample_3d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel],
+ s, t, r, rgba);
}
else {
GLchan t0[4], t1[4]; /* texels */
- const GLfloat f = myFrac(lambda);
- sample_3d_nearest( tObj, tObj->Image[level ], s, t, r, t0 );
- sample_3d_nearest( tObj, tObj->Image[level+1], s, t, r, t1 );
+ const GLfloat f = FRAC(lambda);
+ sample_3d_nearest(ctx, tObj, tObj->Image[level ], s, t, r, t0);
+ sample_3d_nearest(ctx, tObj, tObj->Image[level+1], s, t, r, t1);
rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
static void
-sample_3d_linear_mipmap_linear( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat r,
- GLfloat lambda, GLchan rgba[4] )
+sample_3d_linear_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat r,
+ GLfloat lambda, GLchan rgba[4] )
{
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
- if (level >= tObj->P) {
- sample_3d_linear( tObj, tObj->Image[tObj->P], s, t, r, rgba );
+ if (level >= tObj->_MaxLevel) {
+ sample_3d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, r, rgba);
}
else {
GLchan t0[4], t1[4]; /* texels */
- const GLfloat f = myFrac(lambda);
- sample_3d_linear( tObj, tObj->Image[level ], s, t, r, t0 );
- sample_3d_linear( tObj, tObj->Image[level+1], s, t, r, t1 );
+ const GLfloat f = FRAC(lambda);
+ sample_3d_linear(ctx, tObj, tObj->Image[level ], s, t, r, t0);
+ sample_3d_linear(ctx, tObj, tObj->Image[level+1], s, t, r, t1);
rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
}
-static void sample_nearest_3d( const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+static void
+sample_nearest_3d(GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4])
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) lambda;
for (i=0;i<n;i++) {
- sample_3d_nearest( tObj, image, s[i], t[i], u[i], rgba[i] );
+ sample_3d_nearest(ctx, tObj, image, s[i], t[i], u[i], rgba[i]);
}
}
-static void sample_linear_3d( const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+static void
+sample_linear_3d( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) lambda;
for (i=0;i<n;i++) {
- sample_3d_linear( tObj, image, s[i], t[i], u[i], rgba[i] );
+ sample_3d_linear(ctx, tObj, image, s[i], t[i], u[i], rgba[i]);
}
}
* Given an (s,t,r) texture coordinate and lambda (level of detail) value,
* return a texture sample.
*/
-static void sample_lambda_3d( const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4] )
+static void
+sample_lambda_3d( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4] )
{
GLuint i;
+ GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
for (i=0;i<n;i++) {
- if (lambda[i] > tObj->MinMagThresh) {
+ if (lambda[i] > MinMagThresh) {
/* minification */
switch (tObj->MinFilter) {
case GL_NEAREST:
- sample_3d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
+ sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], t[i], u[i], rgba[i]);
break;
case GL_LINEAR:
- sample_3d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
+ sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], t[i], u[i], rgba[i]);
break;
case GL_NEAREST_MIPMAP_NEAREST:
- sample_3d_nearest_mipmap_nearest( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
+ sample_3d_nearest_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
+ lambda[i], rgba[i]);
break;
case GL_LINEAR_MIPMAP_NEAREST:
- sample_3d_linear_mipmap_nearest( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
+ sample_3d_linear_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
+ lambda[i], rgba[i]);
break;
case GL_NEAREST_MIPMAP_LINEAR:
- sample_3d_nearest_mipmap_linear( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
+ sample_3d_nearest_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
+ lambda[i], rgba[i]);
break;
case GL_LINEAR_MIPMAP_LINEAR:
- sample_3d_linear_mipmap_linear( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
+ sample_3d_linear_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
+ lambda[i], rgba[i]);
break;
default:
gl_problem(NULL, "Bad min filterin sample_3d_texture");
/* magnification */
switch (tObj->MagFilter) {
case GL_NEAREST:
- sample_3d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
+ sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], t[i], u[i], rgba[i]);
break;
case GL_LINEAR:
- sample_3d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
+ sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
+ s[i], t[i], u[i], rgba[i]);
break;
default:
gl_problem(NULL, "Bad mag filter in sample_3d_texture");
static void
-sample_nearest_cube(const struct gl_texture_object *tObj, GLuint n,
+sample_nearest_cube(GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
const GLfloat s[], const GLfloat t[],
const GLfloat u[], const GLfloat lambda[],
GLchan rgba[][4])
const struct gl_texture_image **images;
GLfloat newS, newT;
images = choose_cube_face(tObj, s[i], t[i], u[i], &newS, &newT);
- sample_2d_nearest( tObj, images[tObj->BaseLevel], newS, newT, rgba[i] );
+ sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
+ newS, newT, rgba[i]);
}
}
static void
-sample_linear_cube(const struct gl_texture_object *tObj, GLuint n,
+sample_linear_cube(GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
const GLfloat s[], const GLfloat t[],
const GLfloat u[], const GLfloat lambda[],
GLchan rgba[][4])
const struct gl_texture_image **images;
GLfloat newS, newT;
images = choose_cube_face(tObj, s[i], t[i], u[i], &newS, &newT);
- sample_2d_linear( tObj, images[tObj->BaseLevel], newS, newT, rgba[i] );
+ sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
+ newS, newT, rgba[i]);
}
}
static void
-sample_cube_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat u,
- GLfloat lambda, GLchan rgba[4] )
+sample_cube_nearest_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat u,
+ GLfloat lambda, GLchan rgba[4])
{
const struct gl_texture_image **images;
GLfloat newS, newT;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
images = choose_cube_face(tObj, s, t, u, &newS, &newT);
- sample_2d_nearest( tObj, images[level], newS, newT, rgba );
+ sample_2d_nearest(ctx, tObj, images[level], newS, newT, rgba);
}
static void
-sample_cube_linear_mipmap_nearest( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat u,
- GLfloat lambda, GLchan rgba[4] )
+sample_cube_linear_mipmap_nearest(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat u,
+ GLfloat lambda, GLchan rgba[4])
{
const struct gl_texture_image **images;
GLfloat newS, newT;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
images = choose_cube_face(tObj, s, t, u, &newS, &newT);
- sample_2d_linear( tObj, images[level], newS, newT, rgba );
+ sample_2d_linear(ctx, tObj, images[level], newS, newT, rgba);
}
static void
-sample_cube_nearest_mipmap_linear( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat u,
- GLfloat lambda, GLchan rgba[4] )
+sample_cube_nearest_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat u,
+ GLfloat lambda, GLchan rgba[4])
{
const struct gl_texture_image **images;
GLfloat newS, newT;
images = choose_cube_face(tObj, s, t, u, &newS, &newT);
- if (level >= tObj->P) {
- sample_2d_nearest( tObj, images[tObj->P], newS, newT, rgba );
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_nearest(ctx, tObj, images[tObj->_MaxLevel], newS, newT, rgba);
}
else {
GLchan t0[4], t1[4]; /* texels */
- const GLfloat f = myFrac(lambda);
- sample_2d_nearest( tObj, images[level ], newS, newT, t0 );
- sample_2d_nearest( tObj, images[level+1], newS, newT, t1 );
+ const GLfloat f = FRAC(lambda);
+ sample_2d_nearest(ctx, tObj, images[level ], newS, newT, t0);
+ sample_2d_nearest(ctx, tObj, images[level+1], newS, newT, t1);
rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
static void
-sample_cube_linear_mipmap_linear( const struct gl_texture_object *tObj,
- GLfloat s, GLfloat t, GLfloat u,
- GLfloat lambda, GLchan rgba[4] )
+sample_cube_linear_mipmap_linear(GLcontext *ctx,
+ const struct gl_texture_object *tObj,
+ GLfloat s, GLfloat t, GLfloat u,
+ GLfloat lambda, GLchan rgba[4])
{
const struct gl_texture_image **images;
GLfloat newS, newT;
images = choose_cube_face(tObj, s, t, u, &newS, &newT);
- if (level >= tObj->P) {
- sample_2d_linear( tObj, images[tObj->P], newS, newT, rgba );
+ if (level >= tObj->_MaxLevel) {
+ sample_2d_linear(ctx, tObj, images[tObj->_MaxLevel], newS, newT, rgba);
}
else {
GLchan t0[4], t1[4];
- const GLfloat f = myFrac(lambda);
- sample_2d_linear( tObj, images[level ], newS, newT, t0 );
- sample_2d_linear( tObj, images[level+1], newS, newT, t1 );
+ const GLfloat f = FRAC(lambda);
+ sample_2d_linear(ctx, tObj, images[level ], newS, newT, t0);
+ sample_2d_linear(ctx, tObj, images[level+1], newS, newT, t1);
rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
static void
-sample_lambda_cube(const struct gl_texture_object *tObj, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat u[], const GLfloat lambda[],
- GLchan rgba[][4])
+sample_lambda_cube( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4])
{
+ GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
GLuint i;
for (i = 0; i < n; i++) {
- if (lambda[i] > tObj->MinMagThresh) {
+ if (lambda[i] > MinMagThresh) {
/* minification */
switch (tObj->MinFilter) {
case GL_NEAREST:
GLfloat newS, newT;
images = choose_cube_face(tObj, s[i], t[i], u[i],
&newS, &newT);
- sample_2d_nearest( tObj, images[tObj->BaseLevel],
- newS, newT, rgba[i] );
+ sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
+ newS, newT, rgba[i]);
}
break;
case GL_LINEAR:
GLfloat newS, newT;
images = choose_cube_face(tObj, s[i], t[i], u[i],
&newS, &newT);
- sample_2d_linear( tObj, images[tObj->BaseLevel],
- newS, newT, rgba[i] );
+ sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
+ newS, newT, rgba[i]);
}
break;
case GL_NEAREST_MIPMAP_NEAREST:
- sample_cube_nearest_mipmap_nearest( tObj, s[i], t[i], u[i],
- lambda[i], rgba[i] );
+ sample_cube_nearest_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
+ lambda[i], rgba[i]);
break;
case GL_LINEAR_MIPMAP_NEAREST:
- sample_cube_linear_mipmap_nearest( tObj, s[i], t[i], u[i],
- lambda[i], rgba[i] );
+ sample_cube_linear_mipmap_nearest(ctx, tObj, s[i], t[i], u[i],
+ lambda[i], rgba[i]);
break;
case GL_NEAREST_MIPMAP_LINEAR:
- sample_cube_nearest_mipmap_linear( tObj, s[i], t[i], u[i],
- lambda[i], rgba[i] );
+ sample_cube_nearest_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
+ lambda[i], rgba[i]);
break;
case GL_LINEAR_MIPMAP_LINEAR:
- sample_cube_linear_mipmap_linear( tObj, s[i], t[i], u[i],
- lambda[i], rgba[i] );
+ sample_cube_linear_mipmap_linear(ctx, tObj, s[i], t[i], u[i],
+ lambda[i], rgba[i]);
break;
default:
gl_problem(NULL, "Bad min filter in sample_lambda_cube");
&newS, &newT);
switch (tObj->MagFilter) {
case GL_NEAREST:
- sample_2d_nearest( tObj, images[tObj->BaseLevel],
- newS, newT, rgba[i] );
+ sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
+ newS, newT, rgba[i]);
break;
case GL_LINEAR:
- sample_2d_linear( tObj, images[tObj->BaseLevel],
- newS, newT, rgba[i] );
+ sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
+ newS, newT, rgba[i]);
break;
default:
gl_problem(NULL, "Bad mag filter in sample_lambda_cube");
}
}
+static void
+null_sample_func( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *tObj, GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat u[], const GLfloat lambda[],
+ GLchan rgba[][4])
+{
+}
/**********************************************************************/
/* Texture Sampling Setup */
* Setup the texture sampling function for this texture object.
*/
void
-_swrast_set_texture_sampler( struct gl_texture_object *t )
+_swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
+ const struct gl_texture_object *t )
{
- if (!t->Complete) {
- t->SampleFunc = NULL;
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+
+ if (!t->Complete) {
+ swrast->TextureSample[texUnit] = null_sample_func;
}
else {
GLboolean needLambda = (GLboolean) (t->MinFilter != t->MagFilter);
if (needLambda) {
/* Compute min/mag filter threshold */
- if (t->MagFilter==GL_LINEAR
- && (t->MinFilter==GL_NEAREST_MIPMAP_NEAREST ||
- t->MinFilter==GL_LINEAR_MIPMAP_NEAREST)) {
- t->MinMagThresh = 0.5F;
+ if (t->MagFilter == GL_LINEAR
+ && (t->MinFilter == GL_NEAREST_MIPMAP_NEAREST ||
+ t->MinFilter == GL_NEAREST_MIPMAP_LINEAR)) {
+ swrast->_MinMagThresh[texUnit] = 0.5F;
}
else {
- t->MinMagThresh = 0.0F;
+ swrast->_MinMagThresh[texUnit] = 0.0F;
}
}
switch (t->Dimensions) {
case 1:
if (needLambda) {
- t->SampleFunc = sample_lambda_1d;
+ swrast->TextureSample[texUnit] = sample_lambda_1d;
}
else if (t->MinFilter==GL_LINEAR) {
- t->SampleFunc = sample_linear_1d;
+ swrast->TextureSample[texUnit] = sample_linear_1d;
}
else {
ASSERT(t->MinFilter==GL_NEAREST);
- t->SampleFunc = sample_nearest_1d;
+ swrast->TextureSample[texUnit] = sample_nearest_1d;
}
break;
case 2:
if (needLambda) {
- t->SampleFunc = sample_lambda_2d;
+ swrast->TextureSample[texUnit] = sample_lambda_2d;
}
else if (t->MinFilter==GL_LINEAR) {
- t->SampleFunc = sample_linear_2d;
+ swrast->TextureSample[texUnit] = sample_linear_2d;
}
else {
+ GLint baseLevel = t->BaseLevel;
ASSERT(t->MinFilter==GL_NEAREST);
- if (t->WrapS==GL_REPEAT && t->WrapT==GL_REPEAT
- && t->Image[0]->Border==0 && t->Image[0]->Format==GL_RGB) {
- t->SampleFunc = opt_sample_rgb_2d;
+ if (t->WrapS == GL_REPEAT &&
+ t->WrapT == GL_REPEAT &&
+ t->Image[baseLevel]->Border == 0 &&
+ t->Image[baseLevel]->Format == GL_RGB &&
+ t->Image[baseLevel]->Type == CHAN_TYPE) {
+ swrast->TextureSample[texUnit] = opt_sample_rgb_2d;
}
- else if (t->WrapS==GL_REPEAT && t->WrapT==GL_REPEAT
- && t->Image[0]->Border==0 && t->Image[0]->Format==GL_RGBA) {
- t->SampleFunc = opt_sample_rgba_2d;
+ else if (t->WrapS == GL_REPEAT &&
+ t->WrapT == GL_REPEAT &&
+ t->Image[baseLevel]->Border == 0 &&
+ t->Image[baseLevel]->Format==GL_RGBA &&
+ t->Image[baseLevel]->Type == CHAN_TYPE) {
+ swrast->TextureSample[texUnit] = opt_sample_rgba_2d;
}
else
- t->SampleFunc = sample_nearest_2d;
+ swrast->TextureSample[texUnit] = sample_nearest_2d;
}
break;
case 3:
if (needLambda) {
- t->SampleFunc = sample_lambda_3d;
+ swrast->TextureSample[texUnit] = sample_lambda_3d;
}
else if (t->MinFilter==GL_LINEAR) {
- t->SampleFunc = sample_linear_3d;
+ swrast->TextureSample[texUnit] = sample_linear_3d;
}
else {
ASSERT(t->MinFilter==GL_NEAREST);
- t->SampleFunc = sample_nearest_3d;
+ swrast->TextureSample[texUnit] = sample_nearest_3d;
}
break;
case 6: /* cube map */
if (needLambda) {
- t->SampleFunc = sample_lambda_cube;
+ swrast->TextureSample[texUnit] = sample_lambda_cube;
}
else if (t->MinFilter==GL_LINEAR) {
- t->SampleFunc = sample_linear_cube;
+ swrast->TextureSample[texUnit] = sample_linear_cube;
}
else {
ASSERT(t->MinFilter==GL_NEAREST);
- t->SampleFunc = sample_nearest_cube;
+ swrast->TextureSample[texUnit] = sample_nearest_cube;
}
break;
default:
#define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) )
+#define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) )
static INLINE void
-_mesa_texture_combine(const GLcontext *ctx,
- const struct gl_texture_unit *textureUnit,
- GLuint n,
- GLchan (*primary_rgba)[4],
- GLchan (*texel)[4],
- GLchan (*rgba)[4])
+texture_combine(const GLcontext *ctx,
+ const struct gl_texture_unit *textureUnit,
+ GLuint n,
+ CONST GLchan (*primary_rgba)[4],
+ CONST GLchan (*texel)[4],
+ GLchan (*rgba)[4])
{
GLchan ccolor [3][3*MAX_WIDTH][4];
- GLchan (*argRGB [3])[4];
- GLchan (*argA [3])[4];
+ const GLchan (*argRGB [3])[4];
+ const GLchan (*argA [3])[4];
GLuint i, j;
const GLuint RGBshift = textureUnit->CombineScaleShiftRGB;
const GLuint Ashift = textureUnit->CombineScaleShiftA;
argA[j] = primary_rgba;
break;
case GL_PREVIOUS_EXT:
- argA[j] = rgba;
+ argA[j] = (const GLchan (*)[4]) rgba;
break;
case GL_CONSTANT_EXT:
{
- GLchan (*c)[4] = ccolor[j];
- GLchan alpha = FLOAT_TO_CHAN(textureUnit->EnvColor[3]);
+ GLchan alpha, (*c)[4] = ccolor[j];
+ UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]);
for (i = 0; i < n; i++)
c[i][ACOMP] = alpha;
- argA[j] = ccolor[j];
+ argA[j] = (const GLchan (*)[4]) ccolor[j];
}
break;
default:
argRGB[j] = primary_rgba;
break;
case GL_PREVIOUS_EXT:
- argRGB[j] = rgba;
+ argRGB[j] = (const GLchan (*)[4]) rgba;
break;
case GL_CONSTANT_EXT:
{
GLchan (*c)[4] = ccolor[j];
- const GLchan red = FLOAT_TO_CHAN(textureUnit->EnvColor[0]);
- const GLchan green = FLOAT_TO_CHAN(textureUnit->EnvColor[1]);
- const GLchan blue = FLOAT_TO_CHAN(textureUnit->EnvColor[2]);
+ GLchan red, green, blue;
+ UNCLAMPED_FLOAT_TO_CHAN(red, textureUnit->EnvColor[0]);
+ UNCLAMPED_FLOAT_TO_CHAN(green, textureUnit->EnvColor[1]);
+ UNCLAMPED_FLOAT_TO_CHAN(blue, textureUnit->EnvColor[2]);
for (i = 0; i < n; i++) {
c[i][RCOMP] = red;
c[i][GCOMP] = green;
c[i][BCOMP] = blue;
}
- argRGB[j] = ccolor[j];
+ argRGB[j] = (const GLchan (*)[4]) ccolor[j];
}
break;
default:
}
if (textureUnit->CombineOperandRGB[j] != GL_SRC_COLOR) {
- GLchan (*src)[4] = argRGB[j];
+ const GLchan (*src)[4] = argRGB[j];
GLchan (*dst)[4] = ccolor[j];
- argRGB[j] = ccolor[j];
+ argRGB[j] = (const GLchan (*)[4]) ccolor[j];
if (textureUnit->CombineOperandRGB[j] == GL_ONE_MINUS_SRC_COLOR) {
for (i = 0; i < n; i++) {
}
}
else if (textureUnit->CombineOperandRGB[j] == GL_SRC_ALPHA) {
- src = argA[j];
+ src = (const GLchan (*)[4]) argA[j];
for (i = 0; i < n; i++) {
dst[i][RCOMP] = src[i][ACOMP];
dst[i][GCOMP] = src[i][ACOMP];
}
}
else { /* GL_ONE_MINUS_SRC_ALPHA */
- src = argA[j];
+ src = (const GLchan (*)[4]) argA[j];
for (i = 0; i < n; i++) {
dst[i][RCOMP] = CHAN_MAX - src[i][ACOMP];
dst[i][GCOMP] = CHAN_MAX - src[i][ACOMP];
}
if (textureUnit->CombineOperandA[j] == GL_ONE_MINUS_SRC_ALPHA) {
- GLchan (*src)[4] = argA[j];
+ const GLchan (*src)[4] = argA[j];
GLchan (*dst)[4] = ccolor[j];
- argA[j] = ccolor[j];
+ argA[j] = (const GLchan (*)[4]) ccolor[j];
for (i = 0; i < n; i++) {
dst[i][ACOMP] = CHAN_MAX - src[i][ACOMP];
}
}
}
break;
+ case GL_DOT3_RGB_EXT:
+ case GL_DOT3_RGBA_EXT:
+ {
+ const GLubyte (*arg0)[4] = (const GLubyte (*)[4]) argRGB[0];
+ const GLubyte (*arg1)[4] = (const GLubyte (*)[4]) argRGB[1];
+ /* ATI's EXT extension has a constant scale by 4. The ARB
+ * one will likely remove this restriction, and we should
+ * drop the EXT extension in favour of the ARB one.
+ */
+ for (i = 0; i < n; i++) {
+ GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - 128,
+ (GLint)arg1[i][RCOMP] - 128) +
+ S_PROD((GLint)arg0[i][GCOMP] - 128,
+ (GLint)arg1[i][GCOMP] - 128) +
+ S_PROD((GLint)arg0[i][BCOMP] - 128,
+ (GLint)arg1[i][BCOMP] - 128)) >> 6;
+ rgba[i][RCOMP] = (GLubyte) CLAMP(dot, 0, 255);
+ rgba[i][GCOMP] = (GLubyte) CLAMP(dot, 0, 255);
+ rgba[i][BCOMP] = (GLubyte) CLAMP(dot, 0, 255);
+ }
+ }
+ break;
default:
gl_problem(NULL, "invalid combine mode");
}
default:
gl_problem(NULL, "invalid combine mode");
}
+
+ /* Fix the alpha component for GL_DOT3_RGBA_EXT combining.
+ */
+ if (textureUnit->CombineModeRGB == GL_DOT3_RGBA_EXT) {
+ for (i = 0; i < n; i++) {
+ rgba[i][ACOMP] = rgba[i][RCOMP];
+ }
+ }
}
#undef PROD
* Input: textureUnit - pointer to texture unit to apply
* format - base internal texture format
* n - number of fragments
- * primary_rgba - primary colors (may be rgba for single texture)
+ * primary_rgba - primary colors (may alias rgba for single texture)
* texels - array of texel colors
* InOut: rgba - incoming fragment colors modified by texel colors
* according to the texture environment mode.
apply_texture( const GLcontext *ctx,
const struct gl_texture_unit *texUnit,
GLuint n,
- GLchan primary_rgba[][4], GLchan texel[][4],
+ CONST GLchan primary_rgba[][4], CONST GLchan texel[][4],
GLchan rgba[][4] )
{
GLint baseLevel;
GLenum format;
ASSERT(texUnit);
- ASSERT(texUnit->Current);
+ ASSERT(texUnit->_Current);
- baseLevel = texUnit->Current->BaseLevel;
- ASSERT(texUnit->Current->Image[baseLevel]);
+ baseLevel = texUnit->_Current->BaseLevel;
+ ASSERT(texUnit->_Current->Image[baseLevel]);
- format = texUnit->Current->Image[baseLevel]->Format;
+ format = texUnit->_Current->Image[baseLevel]->Format;
- if (format==GL_COLOR_INDEX) {
+ if (format==GL_COLOR_INDEX || format==GL_DEPTH_COMPONENT) {
format = GL_RGBA; /* XXXX a hack! */
}
}
break;
- case GL_COMBINE_EXT: /* GL_EXT_combine_ext; we modify texel array */
- switch (format) {
- case GL_ALPHA:
- for (i=0;i<n;i++)
- texel[i][RCOMP] = texel[i][GCOMP] = texel[i][BCOMP] = 0;
- break;
- case GL_LUMINANCE:
- for (i=0;i<n;i++) {
- /* Cv = Lt */
- GLchan Lt = texel[i][RCOMP];
- texel[i][GCOMP] = texel[i][BCOMP] = Lt;
- /* Av = 1 */
- texel[i][ACOMP] = CHAN_MAX;
- }
- break;
- case GL_LUMINANCE_ALPHA:
- for (i=0;i<n;i++) {
- GLchan Lt = texel[i][RCOMP];
- /* Cv = Lt */
- texel[i][GCOMP] = texel[i][BCOMP] = Lt;
- }
- break;
- case GL_INTENSITY:
- for (i=0;i<n;i++) {
- /* Cv = It */
- GLchan It = texel[i][RCOMP];
- texel[i][GCOMP] = texel[i][BCOMP] = It;
- /* Av = It */
- texel[i][ACOMP] = It;
- }
- break;
- case GL_RGB:
- for (i=0;i<n;i++) {
- /* Av = 1 */
- texel[i][ACOMP] = CHAN_MAX;
- }
- break;
- case GL_RGBA: /* do nothing. */
- break;
- default:
- gl_problem(ctx, "Bad format in apply_texture (GL_COMBINE_EXT)");
- return;
- }
- _mesa_texture_combine(ctx, texUnit, n, primary_rgba, texel, rgba);
+ case GL_COMBINE_EXT:
+ texture_combine(ctx, texUnit, n, primary_rgba, texel, rgba);
break;
default:
+/*
+ * Apply a shadow/depth texture to the array of colors.
+ * Input: ctx - context
+ * texUnit - the texture unit
+ * n - number of colors
+ * r - array [n] of texture R coordinates
+ * In/Out: rgba - array [n] of colors.
+ */
+static void
+sample_depth_texture(const GLcontext *ctx,
+ const struct gl_texture_unit *texUnit,
+ GLuint n,
+ const GLfloat s[], const GLfloat t[], const GLfloat r[],
+ GLchan texel[][4])
+{
+ const struct gl_texture_object *texObj = texUnit->_Current;
+ const struct gl_texture_image *texImage = texObj->Image[0]; /* XXX hack */
+ const GLchan ambient = texObj->ShadowAmbient;
+ GLboolean lequal, gequal;
+ GLuint i;
+
+ if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
+ lequal = GL_TRUE;
+ gequal = GL_FALSE;
+ }
+ else {
+ lequal = GL_FALSE;
+ gequal = GL_TRUE;
+ }
+
+ assert(texObj->Dimensions == 2);
+ assert(texImage->Format == GL_DEPTH_COMPONENT);
+
+ for (i = 0; i < n; i++) {
+ const GLfloat *src;
+ GLfloat depthSample;
+ GLint col, row;
+ /* XXX this is a hack - implement proper sampling */
+ COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, s[i], texImage->Width, col);
+ COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, t[i], texImage->Height,row);
+ src = (const GLfloat *) texImage->Data + row * texImage->Width + col;
+ depthSample = *src;
+ if ((depthSample <= r[i] && lequal) ||
+ (depthSample >= r[i] && gequal)) {
+ texel[i][RCOMP] = ambient;
+ texel[i][GCOMP] = ambient;
+ texel[i][BCOMP] = ambient;
+ texel[i][ACOMP] = CHAN_MAX;
+ }
+ else {
+ texel[i][RCOMP] = CHAN_MAX;
+ texel[i][GCOMP] = CHAN_MAX;
+ texel[i][BCOMP] = CHAN_MAX;
+ texel[i][ACOMP] = CHAN_MAX;
+ }
+ }
+}
+
+
+
/*
* Apply a unit of texture mapping to the incoming fragments.
*/
-void gl_texture_pixels( GLcontext *ctx, GLuint texUnit, GLuint n,
- const GLfloat s[], const GLfloat t[],
- const GLfloat r[], GLfloat lambda[],
- GLchan primary_rgba[][4], GLchan rgba[][4] )
+void
+_swrast_texture_fragments( GLcontext *ctx, GLuint texUnit, GLuint n,
+ const GLfloat s[], const GLfloat t[],
+ const GLfloat r[], GLfloat lambda[],
+ CONST GLchan primary_rgba[][4], GLchan rgba[][4] )
{
const GLuint mask = TEXTURE0_ANY << (texUnit * 4);
- if (ctx->Texture.ReallyEnabled & mask) {
+ if (ctx->Texture._ReallyEnabled & mask) {
const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit];
- if (textureUnit->Current && textureUnit->Current->SampleFunc) {
+ if (textureUnit->_Current) { /* XXX need this? */
GLchan texel[PB_SIZE][4];
if (textureUnit->LodBias != 0.0F) {
}
}
- if (textureUnit->Current->MinLod != -1000.0
- || textureUnit->Current->MaxLod != 1000.0) {
+ if (textureUnit->_Current->MinLod != -1000.0
+ || textureUnit->_Current->MaxLod != 1000.0) {
/* apply LOD clamping to lambda */
- GLfloat min = textureUnit->Current->MinLod;
- GLfloat max = textureUnit->Current->MaxLod;
+ const GLfloat min = textureUnit->_Current->MinLod;
+ const GLfloat max = textureUnit->_Current->MaxLod;
GLuint i;
for (i=0;i<n;i++) {
GLfloat l = lambda[i];
}
}
- /* fetch texture images from device driver, if needed */
- if (ctx->Driver.GetTexImage) {
- if (!_mesa_get_teximages_from_driver(ctx, textureUnit->Current)) {
- return;
- }
- }
-
/* Sample the texture. */
- (*textureUnit->Current->SampleFunc)( textureUnit->Current, n,
- s, t, r, lambda, texel );
-
- apply_texture( ctx, textureUnit, n, primary_rgba, texel, rgba );
+ if (textureUnit->_Current->CompareFlag) {
+ /* depth texture */
+ sample_depth_texture(ctx, textureUnit, n, s, t, r, texel);
+ }
+ else {
+ /* color texture */
+ SWRAST_CONTEXT(ctx)->TextureSample[texUnit]( ctx, texUnit,
+ textureUnit->_Current,
+ n, s, t, r,
+ lambda, texel );
+ }
+ apply_texture( ctx, textureUnit, n, primary_rgba,
+ (const GLchan (*)[4]) texel, rgba );
}
}
}