1 /* $Id: s_texture.c,v 1.42 2001/11/19 01:18:28 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 #include "texformat.h"
37 #include "s_context.h"
39 #include "s_texture.h"
43 * These values are used in the fixed-point arithmetic used
44 * for linear filtering.
46 #define WEIGHT_SCALE 65536.0F
47 #define WEIGHT_SHIFT 16
51 * Used to compute texel locations for linear sampling.
53 * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER_ARB
54 * S = texcoord in [0,1]
55 * SIZE = width (or height or depth) of texture
57 * U = texcoord in [0, width]
58 * I0, I1 = two nearest texel indexes
60 #define COMPUTE_LINEAR_TEXEL_LOCATIONS(wrapMode, S, U, SIZE, I0, I1) \
62 if (wrapMode == GL_REPEAT) { \
63 U = S * SIZE - 0.5F; \
64 I0 = IFLOOR(U) & (SIZE - 1); \
65 I1 = (I0 + 1) & (SIZE - 1); \
67 else if (wrapMode == GL_CLAMP_TO_EDGE) { \
79 if (I1 >= (GLint) SIZE) \
82 else if (wrapMode == GL_CLAMP_TO_BORDER_ARB) { \
83 const GLfloat min = -1.0F / (2.0F * SIZE); \
84 const GLfloat max = 1.0F - min; \
95 else if (wrapMode == GL_MIRRORED_REPEAT_ARB) { \
96 const GLint flr = IFLOOR(S); \
98 U = 1.0F - (S - (GLfloat) flr); /* flr is odd */ \
100 U = S - (GLfloat) flr; /* flr is even */ \
105 if (I1 >= (GLint) SIZE) \
109 ASSERT(wrapMode == GL_CLAMP); \
112 else if (S >= 1.0F) \
113 U = (GLfloat) SIZE; \
124 * Used to compute texel location for nearest sampling.
126 #define COMPUTE_NEAREST_TEXEL_LOCATION(wrapMode, S, SIZE, I) \
128 if (wrapMode == GL_REPEAT) { \
129 /* s limited to [0,1) */ \
130 /* i limited to [0,size-1] */ \
131 I = IFLOOR(S * SIZE); \
134 else if (wrapMode == GL_CLAMP_TO_EDGE) { \
135 /* s limited to [min,max] */ \
136 /* i limited to [0, size-1] */ \
137 const GLfloat min = 1.0F / (2.0F * SIZE); \
138 const GLfloat max = 1.0F - min; \
144 I = IFLOOR(S * SIZE); \
146 else if (wrapMode == GL_CLAMP_TO_BORDER_ARB) { \
147 /* s limited to [min,max] */ \
148 /* i limited to [-1, size] */ \
149 const GLfloat min = -1.0F / (2.0F * SIZE); \
150 const GLfloat max = 1.0F - min; \
156 I = IFLOOR(S * SIZE); \
158 else if (wrapMode == GL_MIRRORED_REPEAT_ARB) { \
159 const GLfloat min = 1.0F / (2.0F * SIZE); \
160 const GLfloat max = 1.0F - min; \
161 const GLint flr = IFLOOR(S); \
164 u = 1.0F - (S - (GLfloat) flr); /* flr is odd */ \
166 u = S - (GLfloat) flr; /* flr is even */ \
172 I = IFLOOR(u * SIZE); \
175 ASSERT(wrapMode == GL_CLAMP); \
176 /* s limited to [0,1] */ \
177 /* i limited to [0,size-1] */ \
180 else if (S >= 1.0F) \
183 I = IFLOOR(S * SIZE); \
189 * Compute linear mipmap levels for given lambda.
191 #define COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level) \
195 else if (lambda > tObj->_MaxLambda) \
196 lambda = tObj->_MaxLambda; \
197 level = (GLint) (tObj->BaseLevel + lambda); \
202 * Compute nearest mipmap level for given lambda.
204 #define COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level) \
206 if (lambda <= 0.5F) \
208 else if (lambda > tObj->_MaxLambda + 0.4999F) \
209 lambda = tObj->_MaxLambda + 0.4999F; \
210 level = (GLint) (tObj->BaseLevel + lambda + 0.5F); \
211 if (level > tObj->_MaxLevel) \
212 level = tObj->_MaxLevel; \
218 * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes
219 * see 1-pixel bands of improperly weighted linear-sampled texels. The
220 * tests/texwrap.c demo is a good test.
221 * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
222 * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
224 #define FRAC(f) ((f) - IFLOOR(f))
229 * Bitflags for texture border color sampling.
241 * Get texture palette entry.
244 palette_sample(const GLcontext
*ctx
,
245 const struct gl_texture_object
*tObj
,
246 GLint index
, GLchan rgba
[4] )
248 const GLchan
*palette
;
251 if (ctx
->Texture
.SharedPalette
) {
252 ASSERT(!ctx
->Texture
.Palette
.FloatTable
);
253 palette
= (const GLchan
*) ctx
->Texture
.Palette
.Table
;
254 format
= ctx
->Texture
.Palette
.Format
;
257 ASSERT(!tObj
->Palette
.FloatTable
);
258 palette
= (const GLchan
*) tObj
->Palette
.Table
;
259 format
= tObj
->Palette
.Format
;
264 rgba
[ACOMP
] = palette
[index
];
268 rgba
[RCOMP
] = palette
[index
];
270 case GL_LUMINANCE_ALPHA
:
271 rgba
[RCOMP
] = palette
[(index
<< 1) + 0];
272 rgba
[ACOMP
] = palette
[(index
<< 1) + 1];
275 rgba
[RCOMP
] = palette
[index
* 3 + 0];
276 rgba
[GCOMP
] = palette
[index
* 3 + 1];
277 rgba
[BCOMP
] = palette
[index
* 3 + 2];
280 rgba
[RCOMP
] = palette
[(index
<< 2) + 0];
281 rgba
[GCOMP
] = palette
[(index
<< 2) + 1];
282 rgba
[BCOMP
] = palette
[(index
<< 2) + 2];
283 rgba
[ACOMP
] = palette
[(index
<< 2) + 3];
286 _mesa_problem(ctx
, "Bad palette format in palette_sample");
292 /**********************************************************************/
293 /* 1-D Texture Sampling Functions */
294 /**********************************************************************/
297 * Return the texture sample for coordinate (s) using GL_NEAREST filter.
300 sample_1d_nearest(GLcontext
*ctx
,
301 const struct gl_texture_object
*tObj
,
302 const struct gl_texture_image
*img
,
303 GLfloat s
, GLchan rgba
[4])
305 const GLint width
= img
->Width2
; /* without border, power of two */
308 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapS
, s
, width
, i
);
310 /* skip over the border, if any */
313 if (i
< 0 || i
>= (GLint
) img
->Width
) {
314 /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
315 COPY_CHAN4(rgba
, tObj
->BorderColor
);
318 (*img
->FetchTexel
)(img
, i
, 0, 0, (GLvoid
*) rgba
);
319 if (img
->Format
== GL_COLOR_INDEX
) {
320 palette_sample(ctx
, tObj
, rgba
[0], rgba
);
328 * Return the texture sample for coordinate (s) using GL_LINEAR filter.
331 sample_1d_linear(GLcontext
*ctx
,
332 const struct gl_texture_object
*tObj
,
333 const struct gl_texture_image
*img
,
334 GLfloat s
, GLchan rgba
[4])
336 const GLint width
= img
->Width2
;
339 GLuint useBorderColor
;
341 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapS
, s
, u
, width
, i0
, i1
);
349 if (i0
< 0 || i0
>= width
) useBorderColor
|= I0BIT
;
350 if (i1
< 0 || i1
>= width
) useBorderColor
|= I1BIT
;
354 const GLfloat a
= FRAC(u
);
356 #if CHAN_TYPE == GL_FLOAT || CHAN_TYPE == GL_UNSIGNED_SHORT
357 const GLfloat w0
= (1.0F
-a
);
358 const GLfloat w1
= a
;
359 #else /* CHAN_BITS == 8 */
360 /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
361 const GLint w0
= IROUND_POS((1.0F
- a
) * WEIGHT_SCALE
);
362 const GLint w1
= IROUND_POS( a
* WEIGHT_SCALE
);
364 GLchan t0
[4], t1
[4]; /* texels */
366 if (useBorderColor
& I0BIT
) {
367 COPY_CHAN4(t0
, tObj
->BorderColor
);
370 (*img
->FetchTexel
)(img
, i0
, 0, 0, (GLvoid
*) t0
);
371 if (img
->Format
== GL_COLOR_INDEX
) {
372 palette_sample(ctx
, tObj
, t0
[0], t0
);
375 if (useBorderColor
& I1BIT
) {
376 COPY_CHAN4(t1
, tObj
->BorderColor
);
379 (*img
->FetchTexel
)(img
, i1
, 0, 0, (GLvoid
*) t1
);
380 if (img
->Format
== GL_COLOR_INDEX
) {
381 palette_sample(ctx
, tObj
, t1
[0], t1
);
385 #if CHAN_TYPE == GL_FLOAT
386 rgba
[0] = w0
* t0
[0] + w1
* t1
[0];
387 rgba
[1] = w0
* t0
[1] + w1
* t1
[1];
388 rgba
[2] = w0
* t0
[2] + w1
* t1
[2];
389 rgba
[3] = w0
* t0
[3] + w1
* t1
[3];
390 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
391 rgba
[0] = (GLchan
) (w0
* t0
[0] + w1
* t1
[0] + 0.5);
392 rgba
[1] = (GLchan
) (w0
* t0
[1] + w1
* t1
[1] + 0.5);
393 rgba
[2] = (GLchan
) (w0
* t0
[2] + w1
* t1
[2] + 0.5);
394 rgba
[3] = (GLchan
) (w0
* t0
[3] + w1
* t1
[3] + 0.5);
395 #else /* CHAN_BITS == 8 */
396 rgba
[0] = (GLchan
) ((w0
* t0
[0] + w1
* t1
[0]) >> WEIGHT_SHIFT
);
397 rgba
[1] = (GLchan
) ((w0
* t0
[1] + w1
* t1
[1]) >> WEIGHT_SHIFT
);
398 rgba
[2] = (GLchan
) ((w0
* t0
[2] + w1
* t1
[2]) >> WEIGHT_SHIFT
);
399 rgba
[3] = (GLchan
) ((w0
* t0
[3] + w1
* t1
[3]) >> WEIGHT_SHIFT
);
407 sample_1d_nearest_mipmap_nearest(GLcontext
*ctx
,
408 const struct gl_texture_object
*tObj
,
409 GLfloat s
, GLfloat lambda
,
413 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
414 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, rgba
);
419 sample_1d_linear_mipmap_nearest(GLcontext
*ctx
,
420 const struct gl_texture_object
*tObj
,
421 GLfloat s
, GLfloat lambda
,
425 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
426 sample_1d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, rgba
);
432 * This is really just needed in order to prevent warnings with some compilers.
434 #if CHAN_TYPE == GL_FLOAT
437 #define INTCAST (GLint)
442 sample_1d_nearest_mipmap_linear(GLcontext
*ctx
,
443 const struct gl_texture_object
*tObj
,
444 GLfloat s
, GLfloat lambda
,
449 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
451 if (level
>= tObj
->_MaxLevel
) {
452 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, rgba
);
456 const GLfloat f
= FRAC(lambda
);
457 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, t0
);
458 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[level
+1], s
, t1
);
459 rgba
[RCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
460 rgba
[GCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
461 rgba
[BCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
462 rgba
[ACOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
469 sample_1d_linear_mipmap_linear(GLcontext
*ctx
,
470 const struct gl_texture_object
*tObj
,
471 GLfloat s
, GLfloat lambda
,
476 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
478 if (level
>= tObj
->_MaxLevel
) {
479 sample_1d_linear(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, rgba
);
483 const GLfloat f
= FRAC(lambda
);
484 sample_1d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, t0
);
485 sample_1d_linear(ctx
, tObj
, tObj
->Image
[level
+1], s
, t1
);
486 rgba
[RCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
487 rgba
[GCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
488 rgba
[BCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
489 rgba
[ACOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
496 sample_nearest_1d( GLcontext
*ctx
, GLuint texUnit
,
497 const struct gl_texture_object
*tObj
, GLuint n
,
498 const GLfloat s
[], const GLfloat t
[],
499 const GLfloat u
[], const GLfloat lambda
[],
503 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
508 sample_1d_nearest(ctx
, tObj
, image
, s
[i
], rgba
[i
]);
515 sample_linear_1d( GLcontext
*ctx
, GLuint texUnit
,
516 const struct gl_texture_object
*tObj
, GLuint n
,
517 const GLfloat s
[], const GLfloat t
[],
518 const GLfloat u
[], const GLfloat lambda
[],
522 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
527 sample_1d_linear(ctx
, tObj
, image
, s
[i
], rgba
[i
]);
533 * Given an (s) texture coordinate and lambda (level of detail) value,
534 * return a texture sample.
538 sample_lambda_1d( GLcontext
*ctx
, GLuint texUnit
,
539 const struct gl_texture_object
*tObj
, GLuint n
,
540 const GLfloat s
[], const GLfloat t
[],
541 const GLfloat u
[], const GLfloat lambda
[],
544 GLfloat MinMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
551 if (lambda
[i
] > MinMagThresh
) {
553 switch (tObj
->MinFilter
) {
555 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
559 sample_1d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
562 case GL_NEAREST_MIPMAP_NEAREST
:
563 sample_1d_nearest_mipmap_nearest(ctx
, tObj
, lambda
[i
], s
[i
],
566 case GL_LINEAR_MIPMAP_NEAREST
:
567 sample_1d_linear_mipmap_nearest(ctx
, tObj
, s
[i
], lambda
[i
],
570 case GL_NEAREST_MIPMAP_LINEAR
:
571 sample_1d_nearest_mipmap_linear(ctx
, tObj
, s
[i
], lambda
[i
],
574 case GL_LINEAR_MIPMAP_LINEAR
:
575 sample_1d_linear_mipmap_linear(ctx
, tObj
, s
[i
], lambda
[i
],
579 _mesa_problem(NULL
, "Bad min filter in sample_1d_texture");
585 switch (tObj
->MagFilter
) {
587 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
591 sample_1d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
595 _mesa_problem(NULL
, "Bad mag filter in sample_1d_texture");
605 /**********************************************************************/
606 /* 2-D Texture Sampling Functions */
607 /**********************************************************************/
611 * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
614 sample_2d_nearest(GLcontext
*ctx
,
615 const struct gl_texture_object
*tObj
,
616 const struct gl_texture_image
*img
,
617 GLfloat s
, GLfloat t
,
620 const GLint width
= img
->Width2
; /* without border, power of two */
621 const GLint height
= img
->Height2
; /* without border, power of two */
624 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapS
, s
, width
, i
);
625 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapT
, t
, height
, j
);
627 /* skip over the border, if any */
631 if (i
< 0 || i
>= (GLint
) img
->Width
|| j
< 0 || j
>= (GLint
) img
->Height
) {
632 /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
633 COPY_CHAN4(rgba
, tObj
->BorderColor
);
636 (*img
->FetchTexel
)(img
, i
, j
, 0, (GLvoid
*) rgba
);
637 if (img
->Format
== GL_COLOR_INDEX
) {
638 palette_sample(ctx
, tObj
, rgba
[0], rgba
);
646 * Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
647 * New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
650 sample_2d_linear(GLcontext
*ctx
,
651 const struct gl_texture_object
*tObj
,
652 const struct gl_texture_image
*img
,
653 GLfloat s
, GLfloat t
,
656 const GLint width
= img
->Width2
;
657 const GLint height
= img
->Height2
;
658 GLint i0
, j0
, i1
, j1
;
659 GLuint useBorderColor
;
662 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapS
, s
, u
, width
, i0
, i1
);
663 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapT
, t
, v
, height
, j0
, j1
);
673 if (i0
< 0 || i0
>= width
) useBorderColor
|= I0BIT
;
674 if (i1
< 0 || i1
>= width
) useBorderColor
|= I1BIT
;
675 if (j0
< 0 || j0
>= height
) useBorderColor
|= J0BIT
;
676 if (j1
< 0 || j1
>= height
) useBorderColor
|= J1BIT
;
680 const GLfloat a
= FRAC(u
);
681 const GLfloat b
= FRAC(v
);
683 #if CHAN_TYPE == GL_FLOAT || CHAN_TYPE == GL_UNSIGNED_SHORT
684 const GLfloat w00
= (1.0F
-a
) * (1.0F
-b
);
685 const GLfloat w10
= a
* (1.0F
-b
);
686 const GLfloat w01
= (1.0F
-a
) * b
;
687 const GLfloat w11
= a
* b
;
688 #else /* CHAN_BITS == 8 */
689 /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
690 const GLint w00
= IROUND_POS((1.0F
-a
) * (1.0F
-b
) * WEIGHT_SCALE
);
691 const GLint w10
= IROUND_POS( a
* (1.0F
-b
) * WEIGHT_SCALE
);
692 const GLint w01
= IROUND_POS((1.0F
-a
) * b
* WEIGHT_SCALE
);
693 const GLint w11
= IROUND_POS( a
* b
* WEIGHT_SCALE
);
700 if (useBorderColor
& (I0BIT
| J0BIT
)) {
701 COPY_CHAN4(t00
, tObj
->BorderColor
);
704 (*img
->FetchTexel
)(img
, i0
, j0
, 0, (GLvoid
*) t00
);
705 if (img
->Format
== GL_COLOR_INDEX
) {
706 palette_sample(ctx
, tObj
, t00
[0], t00
);
709 if (useBorderColor
& (I1BIT
| J0BIT
)) {
710 COPY_CHAN4(t10
, tObj
->BorderColor
);
713 (*img
->FetchTexel
)(img
, i1
, j0
, 0, (GLvoid
*) t10
);
714 if (img
->Format
== GL_COLOR_INDEX
) {
715 palette_sample(ctx
, tObj
, t10
[0], t10
);
718 if (useBorderColor
& (I0BIT
| J1BIT
)) {
719 COPY_CHAN4(t01
, tObj
->BorderColor
);
722 (*img
->FetchTexel
)(img
, i0
, j1
, 0, (GLvoid
*) t01
);
723 if (img
->Format
== GL_COLOR_INDEX
) {
724 palette_sample(ctx
, tObj
, t01
[0], t01
);
727 if (useBorderColor
& (I1BIT
| J1BIT
)) {
728 COPY_CHAN4(t11
, tObj
->BorderColor
);
731 (*img
->FetchTexel
)(img
, i1
, j1
, 0, (GLvoid
*) t11
);
732 if (img
->Format
== GL_COLOR_INDEX
) {
733 palette_sample(ctx
, tObj
, t11
[0], t11
);
736 #if CHAN_TYPE == GL_FLOAT
737 rgba
[0] = w00
* t00
[0] + w10
* t10
[0] + w01
* t01
[0] + w11
* t11
[0];
738 rgba
[1] = w00
* t00
[1] + w10
* t10
[1] + w01
* t01
[1] + w11
* t11
[1];
739 rgba
[2] = w00
* t00
[2] + w10
* t10
[2] + w01
* t01
[2] + w11
* t11
[2];
740 rgba
[3] = w00
* t00
[3] + w10
* t10
[3] + w01
* t01
[3] + w11
* t11
[3];
741 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
742 rgba
[0] = (GLchan
) (w00
* t00
[0] + w10
* t10
[0] +
743 w01
* t01
[0] + w11
* t11
[0] + 0.5);
744 rgba
[1] = (GLchan
) (w00
* t00
[1] + w10
* t10
[1] +
745 w01
* t01
[1] + w11
* t11
[1] + 0.5);
746 rgba
[2] = (GLchan
) (w00
* t00
[2] + w10
* t10
[2] +
747 w01
* t01
[2] + w11
* t11
[2] + 0.5);
748 rgba
[3] = (GLchan
) (w00
* t00
[3] + w10
* t10
[3] +
749 w01
* t01
[3] + w11
* t11
[3] + 0.5);
750 #else /* CHAN_BITS == 8 */
751 rgba
[0] = (GLchan
) ((w00
* t00
[0] + w10
* t10
[0] +
752 w01
* t01
[0] + w11
* t11
[0]) >> WEIGHT_SHIFT
);
753 rgba
[1] = (GLchan
) ((w00
* t00
[1] + w10
* t10
[1] +
754 w01
* t01
[1] + w11
* t11
[1]) >> WEIGHT_SHIFT
);
755 rgba
[2] = (GLchan
) ((w00
* t00
[2] + w10
* t10
[2] +
756 w01
* t01
[2] + w11
* t11
[2]) >> WEIGHT_SHIFT
);
757 rgba
[3] = (GLchan
) ((w00
* t00
[3] + w10
* t10
[3] +
758 w01
* t01
[3] + w11
* t11
[3]) >> WEIGHT_SHIFT
);
768 sample_2d_nearest_mipmap_nearest(GLcontext
*ctx
,
769 const struct gl_texture_object
*tObj
,
770 GLfloat s
, GLfloat t
, GLfloat lambda
,
774 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
775 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, t
, rgba
);
781 sample_2d_linear_mipmap_nearest(GLcontext
*ctx
,
782 const struct gl_texture_object
*tObj
,
783 GLfloat s
, GLfloat t
, GLfloat lambda
,
787 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
788 sample_2d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, t
, rgba
);
794 sample_2d_nearest_mipmap_linear(GLcontext
*ctx
,
795 const struct gl_texture_object
*tObj
,
796 GLfloat s
, GLfloat t
, GLfloat lambda
,
801 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
803 if (level
>= tObj
->_MaxLevel
) {
804 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, t
, rgba
);
807 GLchan t0
[4], t1
[4]; /* texels */
808 const GLfloat f
= FRAC(lambda
);
809 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, t
, t0
);
810 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[level
+1], s
, t
, t1
);
811 rgba
[RCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
812 rgba
[GCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
813 rgba
[BCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
814 rgba
[ACOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
821 sample_2d_linear_mipmap_linear(GLcontext
*ctx
,
822 const struct gl_texture_object
*tObj
,
823 GLfloat s
, GLfloat t
, GLfloat lambda
,
828 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
830 if (level
>= tObj
->_MaxLevel
) {
831 sample_2d_linear(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, t
, rgba
);
834 GLchan t0
[4], t1
[4]; /* texels */
835 const GLfloat f
= FRAC(lambda
);
836 sample_2d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, t
, t0
);
837 sample_2d_linear(ctx
, tObj
, tObj
->Image
[level
+1], s
, t
, t1
);
838 rgba
[RCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
839 rgba
[GCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
840 rgba
[BCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
841 rgba
[ACOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
848 sample_nearest_2d( GLcontext
*ctx
, GLuint texUnit
,
849 const struct gl_texture_object
*tObj
, GLuint n
,
850 const GLfloat s
[], const GLfloat t
[],
851 const GLfloat u
[], const GLfloat lambda
[],
855 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
859 sample_2d_nearest(ctx
, tObj
, image
, s
[i
], t
[i
], rgba
[i
]);
866 sample_linear_2d( GLcontext
*ctx
, GLuint texUnit
,
867 const struct gl_texture_object
*tObj
, GLuint n
,
868 const GLfloat s
[], const GLfloat t
[],
869 const GLfloat u
[], const GLfloat lambda
[],
873 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
877 sample_2d_linear(ctx
, tObj
, image
, s
[i
], t
[i
], rgba
[i
]);
883 * Optimized 2-D texture sampling:
884 * S and T wrap mode == GL_REPEAT
885 * GL_NEAREST min/mag filter
890 opt_sample_rgb_2d( GLcontext
*ctx
, GLuint texUnit
,
891 const struct gl_texture_object
*tObj
,
892 GLuint n
, const GLfloat s
[], const GLfloat t
[],
893 const GLfloat u
[], const GLfloat lambda
[],
896 const struct gl_texture_image
*img
= tObj
->Image
[tObj
->BaseLevel
];
897 const GLfloat width
= (GLfloat
) img
->Width
;
898 const GLfloat height
= (GLfloat
) img
->Height
;
899 const GLint colMask
= img
->Width
- 1;
900 const GLint rowMask
= img
->Height
- 1;
901 const GLint shift
= img
->WidthLog2
;
905 ASSERT(tObj
->WrapS
==GL_REPEAT
);
906 ASSERT(tObj
->WrapT
==GL_REPEAT
);
907 ASSERT(img
->Border
==0);
908 ASSERT(img
->Format
==GL_RGB
);
910 for (k
=0; k
<n
; k
++) {
911 GLint i
= IFLOOR(s
[k
] * width
) & colMask
;
912 GLint j
= IFLOOR(t
[k
] * height
) & rowMask
;
913 GLint pos
= (j
<< shift
) | i
;
914 GLchan
*texel
= ((GLchan
*) img
->Data
) + 3*pos
;
915 rgba
[k
][RCOMP
] = texel
[0];
916 rgba
[k
][GCOMP
] = texel
[1];
917 rgba
[k
][BCOMP
] = texel
[2];
923 * Optimized 2-D texture sampling:
924 * S and T wrap mode == GL_REPEAT
925 * GL_NEAREST min/mag filter
930 opt_sample_rgba_2d( GLcontext
*ctx
, GLuint texUnit
,
931 const struct gl_texture_object
*tObj
,
932 GLuint n
, const GLfloat s
[], const GLfloat t
[],
933 const GLfloat u
[], const GLfloat lambda
[],
936 const struct gl_texture_image
*img
= tObj
->Image
[tObj
->BaseLevel
];
937 const GLfloat width
= (GLfloat
) img
->Width
;
938 const GLfloat height
= (GLfloat
) img
->Height
;
939 const GLint colMask
= img
->Width
- 1;
940 const GLint rowMask
= img
->Height
- 1;
941 const GLint shift
= img
->WidthLog2
;
945 ASSERT(tObj
->WrapS
==GL_REPEAT
);
946 ASSERT(tObj
->WrapT
==GL_REPEAT
);
947 ASSERT(img
->Border
==0);
948 ASSERT(img
->Format
==GL_RGBA
);
950 for (i
= 0; i
< n
; i
++) {
951 const GLint col
= IFLOOR(s
[i
] * width
) & colMask
;
952 const GLint row
= IFLOOR(t
[i
] * height
) & rowMask
;
953 const GLint pos
= (row
<< shift
) | col
;
954 const GLchan
*texel
= ((GLchan
*) img
->Data
) + (pos
<< 2); /* pos*4 */
955 COPY_CHAN4(rgba
[i
], texel
);
961 span_is_monotonous (GLuint n
, const GLfloat lambda
[])
965 if (n
<= 1) /* array too short */
967 else if (lambda
[0] >= lambda
[n
-1]) { /* decreasing */
968 for (i
=0; i
<n
-1; i
++)
969 if (lambda
[i
] < lambda
[i
+1])
972 else { /* increasing */
973 for (i
=0; i
<n
-1; i
++)
974 if (lambda
[i
] > lambda
[i
+1])
983 * Given an array of (s,t) texture coordinate and lambda (level of detail)
984 * values, return an array of texture sample.
987 sample_lambda_2d( GLcontext
*ctx
, GLuint texUnit
,
988 const struct gl_texture_object
*tObj
,
990 const GLfloat s
[], const GLfloat t
[],
991 const GLfloat u
[], const GLfloat lambda
[],
994 const GLfloat minMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
999 ASSERT (span_is_monotonous(n
, lambda
) == GL_TRUE
);
1002 /* since lambda is monotonous-array use this check first */
1003 if (lambda
[0] <= minMagThresh
&& lambda
[n
-1] <= minMagThresh
) {
1004 /* magnification for whole span */
1005 const struct gl_texture_image
*img
= tObj
->Image
[tObj
->BaseLevel
];
1006 switch (tObj
->MagFilter
) {
1008 if (tObj
->WrapS
== GL_REPEAT
&& tObj
->WrapT
== GL_REPEAT
&&
1010 switch (img
->Format
) {
1012 opt_sample_rgb_2d(ctx
, texUnit
, tObj
, n
, s
, t
, NULL
,
1016 opt_sample_rgba_2d(ctx
, texUnit
, tObj
, n
, s
, t
, NULL
,
1020 sample_nearest_2d(ctx
, texUnit
, tObj
, n
, s
, t
, NULL
,
1025 sample_nearest_2d(ctx
, texUnit
, tObj
, n
, s
, t
, NULL
,
1030 sample_linear_2d(ctx
, texUnit
, tObj
, n
, s
, t
, NULL
,
1034 _mesa_problem(NULL
, "Bad mag filter in sample_lambda_2d");
1038 for (i
= 0; i
< n
; i
++) {
1039 if (lambda
[i
] > minMagThresh
) {
1041 switch (tObj
->MinFilter
) {
1043 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1044 s
[i
], t
[i
], rgba
[i
]);
1047 sample_2d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1048 s
[i
], t
[i
], rgba
[i
]);
1050 case GL_NEAREST_MIPMAP_NEAREST
:
1051 sample_2d_nearest_mipmap_nearest(ctx
, tObj
, s
[i
], t
[i
],
1052 lambda
[i
], rgba
[i
]);
1054 case GL_LINEAR_MIPMAP_NEAREST
:
1055 sample_2d_linear_mipmap_nearest(ctx
,tObj
, s
[i
], t
[i
],
1056 lambda
[i
], rgba
[i
]);
1058 case GL_NEAREST_MIPMAP_LINEAR
:
1059 sample_2d_nearest_mipmap_linear(ctx
,tObj
, s
[i
], t
[i
],
1060 lambda
[i
], rgba
[i
]);
1062 case GL_LINEAR_MIPMAP_LINEAR
:
1063 sample_2d_linear_mipmap_linear(ctx
,tObj
, s
[i
], t
[i
],
1064 lambda
[i
], rgba
[i
] );
1067 _mesa_problem(NULL
, "Bad min filter in sample_2d_texture");
1073 switch (tObj
->MagFilter
) {
1075 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1076 s
[i
], t
[i
], rgba
[i
]);
1079 sample_2d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1080 s
[i
], t
[i
], rgba
[i
] );
1083 _mesa_problem(NULL
, "Bad mag filter in sample_2d_texture");
1092 /**********************************************************************/
1093 /* 3-D Texture Sampling Functions */
1094 /**********************************************************************/
1097 * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
1100 sample_3d_nearest(GLcontext
*ctx
,
1101 const struct gl_texture_object
*tObj
,
1102 const struct gl_texture_image
*img
,
1103 GLfloat s
, GLfloat t
, GLfloat r
,
1106 const GLint width
= img
->Width2
; /* without border, power of two */
1107 const GLint height
= img
->Height2
; /* without border, power of two */
1108 const GLint depth
= img
->Depth2
; /* without border, power of two */
1111 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapS
, s
, width
, i
);
1112 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapT
, t
, height
, j
);
1113 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapR
, r
, depth
, k
);
1115 if (i
< 0 || i
>= (GLint
) img
->Width
||
1116 j
< 0 || j
>= (GLint
) img
->Height
||
1117 k
< 0 || k
>= (GLint
) img
->Depth
) {
1118 /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
1119 COPY_CHAN4(rgba
, tObj
->BorderColor
);
1122 (*img
->FetchTexel
)(img
, i
, j
, k
, (GLvoid
*) rgba
);
1123 if (img
->Format
== GL_COLOR_INDEX
) {
1124 palette_sample(ctx
, tObj
, rgba
[0], rgba
);
1132 * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
1135 sample_3d_linear(GLcontext
*ctx
,
1136 const struct gl_texture_object
*tObj
,
1137 const struct gl_texture_image
*img
,
1138 GLfloat s
, GLfloat t
, GLfloat r
,
1141 const GLint width
= img
->Width2
;
1142 const GLint height
= img
->Height2
;
1143 const GLint depth
= img
->Depth2
;
1144 GLint i0
, j0
, k0
, i1
, j1
, k1
;
1145 GLuint useBorderColor
;
1148 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapS
, s
, u
, width
, i0
, i1
);
1149 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapT
, t
, v
, height
, j0
, j1
);
1150 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapR
, r
, w
, depth
, k0
, k1
);
1162 /* check if sampling texture border color */
1163 if (i0
< 0 || i0
>= width
) useBorderColor
|= I0BIT
;
1164 if (i1
< 0 || i1
>= width
) useBorderColor
|= I1BIT
;
1165 if (j0
< 0 || j0
>= height
) useBorderColor
|= J0BIT
;
1166 if (j1
< 0 || j1
>= height
) useBorderColor
|= J1BIT
;
1167 if (k0
< 0 || k0
>= depth
) useBorderColor
|= K0BIT
;
1168 if (k1
< 0 || k1
>= depth
) useBorderColor
|= K1BIT
;
1172 const GLfloat a
= FRAC(u
);
1173 const GLfloat b
= FRAC(v
);
1174 const GLfloat c
= FRAC(w
);
1176 #if CHAN_TYPE == GL_FLOAT || CHAN_TYPE == GL_UNSIGNED_SHORT
1177 /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
1178 GLfloat w000
= (1.0F
-a
) * (1.0F
-b
) * (1.0F
-c
);
1179 GLfloat w100
= a
* (1.0F
-b
) * (1.0F
-c
);
1180 GLfloat w010
= (1.0F
-a
) * b
* (1.0F
-c
);
1181 GLfloat w110
= a
* b
* (1.0F
-c
);
1182 GLfloat w001
= (1.0F
-a
) * (1.0F
-b
) * c
;
1183 GLfloat w101
= a
* (1.0F
-b
) * c
;
1184 GLfloat w011
= (1.0F
-a
) * b
* c
;
1185 GLfloat w111
= a
* b
* c
;
1186 #else /* CHAN_BITS == 8 */
1187 /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
1188 GLint w000
= IROUND_POS((1.0F
-a
) * (1.0F
-b
) * (1.0F
-c
) * WEIGHT_SCALE
);
1189 GLint w100
= IROUND_POS( a
* (1.0F
-b
) * (1.0F
-c
) * WEIGHT_SCALE
);
1190 GLint w010
= IROUND_POS((1.0F
-a
) * b
* (1.0F
-c
) * WEIGHT_SCALE
);
1191 GLint w110
= IROUND_POS( a
* b
* (1.0F
-c
) * WEIGHT_SCALE
);
1192 GLint w001
= IROUND_POS((1.0F
-a
) * (1.0F
-b
) * c
* WEIGHT_SCALE
);
1193 GLint w101
= IROUND_POS( a
* (1.0F
-b
) * c
* WEIGHT_SCALE
);
1194 GLint w011
= IROUND_POS((1.0F
-a
) * b
* c
* WEIGHT_SCALE
);
1195 GLint w111
= IROUND_POS( a
* b
* c
* WEIGHT_SCALE
);
1198 GLchan t000
[4], t010
[4], t001
[4], t011
[4];
1199 GLchan t100
[4], t110
[4], t101
[4], t111
[4];
1201 if (useBorderColor
& (I0BIT
| J0BIT
| K0BIT
)) {
1202 COPY_CHAN4(t000
, tObj
->BorderColor
);
1205 (*img
->FetchTexel
)(img
, i0
, j0
, k0
, (GLvoid
*) t000
);
1206 if (img
->Format
== GL_COLOR_INDEX
) {
1207 palette_sample(ctx
, tObj
, t000
[0], t000
);
1210 if (useBorderColor
& (I1BIT
| J0BIT
| K0BIT
)) {
1211 COPY_CHAN4(t100
, tObj
->BorderColor
);
1214 (*img
->FetchTexel
)(img
, i1
, j0
, k0
, (GLvoid
*) t100
);
1215 if (img
->Format
== GL_COLOR_INDEX
) {
1216 palette_sample(ctx
, tObj
, t100
[0], t100
);
1219 if (useBorderColor
& (I0BIT
| J1BIT
| K0BIT
)) {
1220 COPY_CHAN4(t010
, tObj
->BorderColor
);
1223 (*img
->FetchTexel
)(img
, i0
, j1
, k0
, (GLvoid
*) t010
);
1224 if (img
->Format
== GL_COLOR_INDEX
) {
1225 palette_sample(ctx
, tObj
, t010
[0], t010
);
1228 if (useBorderColor
& (I1BIT
| J1BIT
| K0BIT
)) {
1229 COPY_CHAN4(t110
, tObj
->BorderColor
);
1232 (*img
->FetchTexel
)(img
, i1
, j1
, k0
, (GLvoid
*) t110
);
1233 if (img
->Format
== GL_COLOR_INDEX
) {
1234 palette_sample(ctx
, tObj
, t110
[0], t110
);
1238 if (useBorderColor
& (I0BIT
| J0BIT
| K1BIT
)) {
1239 COPY_CHAN4(t001
, tObj
->BorderColor
);
1242 (*img
->FetchTexel
)(img
, i0
, j0
, k1
, (GLvoid
*) t001
);
1243 if (img
->Format
== GL_COLOR_INDEX
) {
1244 palette_sample(ctx
, tObj
, t001
[0], t001
);
1247 if (useBorderColor
& (I1BIT
| J0BIT
| K1BIT
)) {
1248 COPY_CHAN4(t101
, tObj
->BorderColor
);
1251 (*img
->FetchTexel
)(img
, i1
, j0
, k1
, (GLvoid
*) t101
);
1252 if (img
->Format
== GL_COLOR_INDEX
) {
1253 palette_sample(ctx
, tObj
, t101
[0], t101
);
1256 if (useBorderColor
& (I0BIT
| J1BIT
| K1BIT
)) {
1257 COPY_CHAN4(t011
, tObj
->BorderColor
);
1260 (*img
->FetchTexel
)(img
, i0
, j1
, k1
, (GLvoid
*) t011
);
1261 if (img
->Format
== GL_COLOR_INDEX
) {
1262 palette_sample(ctx
, tObj
, t011
[0], t011
);
1265 if (useBorderColor
& (I1BIT
| J1BIT
| K1BIT
)) {
1266 COPY_CHAN4(t111
, tObj
->BorderColor
);
1269 (*img
->FetchTexel
)(img
, i1
, j1
, k1
, (GLvoid
*) t111
);
1270 if (img
->Format
== GL_COLOR_INDEX
) {
1271 palette_sample(ctx
, tObj
, t111
[0], t111
);
1275 #if CHAN_TYPE == GL_FLOAT
1276 rgba
[0] = w000
*t000
[0] + w010
*t010
[0] + w001
*t001
[0] + w011
*t011
[0] +
1277 w100
*t100
[0] + w110
*t110
[0] + w101
*t101
[0] + w111
*t111
[0];
1278 rgba
[1] = w000
*t000
[1] + w010
*t010
[1] + w001
*t001
[1] + w011
*t011
[1] +
1279 w100
*t100
[1] + w110
*t110
[1] + w101
*t101
[1] + w111
*t111
[1];
1280 rgba
[2] = w000
*t000
[2] + w010
*t010
[2] + w001
*t001
[2] + w011
*t011
[2] +
1281 w100
*t100
[2] + w110
*t110
[2] + w101
*t101
[2] + w111
*t111
[2];
1282 rgba
[3] = w000
*t000
[3] + w010
*t010
[3] + w001
*t001
[3] + w011
*t011
[3] +
1283 w100
*t100
[3] + w110
*t110
[3] + w101
*t101
[3] + w111
*t111
[3];
1284 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
1285 rgba
[0] = (GLchan
) (w000
*t000
[0] + w010
*t010
[0] +
1286 w001
*t001
[0] + w011
*t011
[0] +
1287 w100
*t100
[0] + w110
*t110
[0] +
1288 w101
*t101
[0] + w111
*t111
[0] + 0.5);
1289 rgba
[1] = (GLchan
) (w000
*t000
[1] + w010
*t010
[1] +
1290 w001
*t001
[1] + w011
*t011
[1] +
1291 w100
*t100
[1] + w110
*t110
[1] +
1292 w101
*t101
[1] + w111
*t111
[1] + 0.5);
1293 rgba
[2] = (GLchan
) (w000
*t000
[2] + w010
*t010
[2] +
1294 w001
*t001
[2] + w011
*t011
[2] +
1295 w100
*t100
[2] + w110
*t110
[2] +
1296 w101
*t101
[2] + w111
*t111
[2] + 0.5);
1297 rgba
[3] = (GLchan
) (w000
*t000
[3] + w010
*t010
[3] +
1298 w001
*t001
[3] + w011
*t011
[3] +
1299 w100
*t100
[3] + w110
*t110
[3] +
1300 w101
*t101
[3] + w111
*t111
[3] + 0.5);
1301 #else /* CHAN_BITS == 8 */
1302 rgba
[0] = (GLchan
) (
1303 (w000
*t000
[0] + w010
*t010
[0] + w001
*t001
[0] + w011
*t011
[0] +
1304 w100
*t100
[0] + w110
*t110
[0] + w101
*t101
[0] + w111
*t111
[0] )
1306 rgba
[1] = (GLchan
) (
1307 (w000
*t000
[1] + w010
*t010
[1] + w001
*t001
[1] + w011
*t011
[1] +
1308 w100
*t100
[1] + w110
*t110
[1] + w101
*t101
[1] + w111
*t111
[1] )
1310 rgba
[2] = (GLchan
) (
1311 (w000
*t000
[2] + w010
*t010
[2] + w001
*t001
[2] + w011
*t011
[2] +
1312 w100
*t100
[2] + w110
*t110
[2] + w101
*t101
[2] + w111
*t111
[2] )
1314 rgba
[3] = (GLchan
) (
1315 (w000
*t000
[3] + w010
*t010
[3] + w001
*t001
[3] + w011
*t011
[3] +
1316 w100
*t100
[3] + w110
*t110
[3] + w101
*t101
[3] + w111
*t111
[3] )
1326 sample_3d_nearest_mipmap_nearest(GLcontext
*ctx
,
1327 const struct gl_texture_object
*tObj
,
1328 GLfloat s
, GLfloat t
, GLfloat r
,
1329 GLfloat lambda
, GLchan rgba
[4] )
1332 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1333 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, t
, r
, rgba
);
1338 sample_3d_linear_mipmap_nearest(GLcontext
*ctx
,
1339 const struct gl_texture_object
*tObj
,
1340 GLfloat s
, GLfloat t
, GLfloat r
,
1341 GLfloat lambda
, GLchan rgba
[4])
1344 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1345 sample_3d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, t
, r
, rgba
);
1350 sample_3d_nearest_mipmap_linear(GLcontext
*ctx
,
1351 const struct gl_texture_object
*tObj
,
1352 GLfloat s
, GLfloat t
, GLfloat r
,
1353 GLfloat lambda
, GLchan rgba
[4])
1357 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1359 if (level
>= tObj
->_MaxLevel
) {
1360 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
],
1364 GLchan t0
[4], t1
[4]; /* texels */
1365 const GLfloat f
= FRAC(lambda
);
1366 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, t
, r
, t0
);
1367 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[level
+1], s
, t
, r
, t1
);
1368 rgba
[RCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1369 rgba
[GCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1370 rgba
[BCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1371 rgba
[ACOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1377 sample_3d_linear_mipmap_linear(GLcontext
*ctx
,
1378 const struct gl_texture_object
*tObj
,
1379 GLfloat s
, GLfloat t
, GLfloat r
,
1380 GLfloat lambda
, GLchan rgba
[4] )
1384 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1386 if (level
>= tObj
->_MaxLevel
) {
1387 sample_3d_linear(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, t
, r
, rgba
);
1390 GLchan t0
[4], t1
[4]; /* texels */
1391 const GLfloat f
= FRAC(lambda
);
1392 sample_3d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, t
, r
, t0
);
1393 sample_3d_linear(ctx
, tObj
, tObj
->Image
[level
+1], s
, t
, r
, t1
);
1394 rgba
[RCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1395 rgba
[GCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1396 rgba
[BCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1397 rgba
[ACOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1403 sample_nearest_3d(GLcontext
*ctx
, GLuint texUnit
,
1404 const struct gl_texture_object
*tObj
, GLuint n
,
1405 const GLfloat s
[], const GLfloat t
[],
1406 const GLfloat u
[], const GLfloat lambda
[],
1410 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
1413 sample_3d_nearest(ctx
, tObj
, image
, s
[i
], t
[i
], u
[i
], rgba
[i
]);
1420 sample_linear_3d( GLcontext
*ctx
, GLuint texUnit
,
1421 const struct gl_texture_object
*tObj
, GLuint n
,
1422 const GLfloat s
[], const GLfloat t
[],
1423 const GLfloat u
[], const GLfloat lambda
[],
1427 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
1430 sample_3d_linear(ctx
, tObj
, image
, s
[i
], t
[i
], u
[i
], rgba
[i
]);
1436 * Given an (s,t,r) texture coordinate and lambda (level of detail) value,
1437 * return a texture sample.
1440 sample_lambda_3d( GLcontext
*ctx
, GLuint texUnit
,
1441 const struct gl_texture_object
*tObj
, GLuint n
,
1442 const GLfloat s
[], const GLfloat t
[],
1443 const GLfloat u
[], const GLfloat lambda
[],
1447 GLfloat MinMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
1451 if (lambda
[i
] > MinMagThresh
) {
1453 switch (tObj
->MinFilter
) {
1455 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1456 s
[i
], t
[i
], u
[i
], rgba
[i
]);
1459 sample_3d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1460 s
[i
], t
[i
], u
[i
], rgba
[i
]);
1462 case GL_NEAREST_MIPMAP_NEAREST
:
1463 sample_3d_nearest_mipmap_nearest(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1464 lambda
[i
], rgba
[i
]);
1466 case GL_LINEAR_MIPMAP_NEAREST
:
1467 sample_3d_linear_mipmap_nearest(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1468 lambda
[i
], rgba
[i
]);
1470 case GL_NEAREST_MIPMAP_LINEAR
:
1471 sample_3d_nearest_mipmap_linear(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1472 lambda
[i
], rgba
[i
]);
1474 case GL_LINEAR_MIPMAP_LINEAR
:
1475 sample_3d_linear_mipmap_linear(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1476 lambda
[i
], rgba
[i
]);
1479 _mesa_problem(NULL
, "Bad min filterin sample_3d_texture");
1484 switch (tObj
->MagFilter
) {
1486 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1487 s
[i
], t
[i
], u
[i
], rgba
[i
]);
1490 sample_3d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1491 s
[i
], t
[i
], u
[i
], rgba
[i
]);
1494 _mesa_problem(NULL
, "Bad mag filter in sample_3d_texture");
1501 /**********************************************************************/
1502 /* Texture Cube Map Sampling Functions */
1503 /**********************************************************************/
1506 * Choose one of six sides of a texture cube map given the texture
1507 * coord (rx,ry,rz). Return pointer to corresponding array of texture
1510 static const struct gl_texture_image
**
1511 choose_cube_face(const struct gl_texture_object
*texObj
,
1512 GLfloat rx
, GLfloat ry
, GLfloat rz
,
1513 GLfloat
*newS
, GLfloat
*newT
)
1517 direction target sc tc ma
1518 ---------- ------------------------------- --- --- ---
1519 +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
1520 -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
1521 +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
1522 -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry
1523 +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
1524 -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
1526 const struct gl_texture_image
**imgArray
;
1527 const GLfloat arx
= ABSF(rx
), ary
= ABSF(ry
), arz
= ABSF(rz
);
1530 if (arx
> ary
&& arx
> arz
) {
1532 imgArray
= (const struct gl_texture_image
**) texObj
->Image
;
1538 imgArray
= (const struct gl_texture_image
**) texObj
->NegX
;
1544 else if (ary
> arx
&& ary
> arz
) {
1546 imgArray
= (const struct gl_texture_image
**) texObj
->PosY
;
1552 imgArray
= (const struct gl_texture_image
**) texObj
->NegY
;
1560 imgArray
= (const struct gl_texture_image
**) texObj
->PosZ
;
1566 imgArray
= (const struct gl_texture_image
**) texObj
->NegZ
;
1573 *newS
= ( sc
/ ma
+ 1.0F
) * 0.5F
;
1574 *newT
= ( tc
/ ma
+ 1.0F
) * 0.5F
;
1580 sample_nearest_cube(GLcontext
*ctx
, GLuint texUnit
,
1581 const struct gl_texture_object
*tObj
, GLuint n
,
1582 const GLfloat s
[], const GLfloat t
[],
1583 const GLfloat u
[], const GLfloat lambda
[],
1588 for (i
= 0; i
< n
; i
++) {
1589 const struct gl_texture_image
**images
;
1591 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
], &newS
, &newT
);
1592 sample_2d_nearest(ctx
, tObj
, images
[tObj
->BaseLevel
],
1593 newS
, newT
, rgba
[i
]);
1599 sample_linear_cube(GLcontext
*ctx
, GLuint texUnit
,
1600 const struct gl_texture_object
*tObj
, GLuint n
,
1601 const GLfloat s
[], const GLfloat t
[],
1602 const GLfloat u
[], const GLfloat lambda
[],
1607 for (i
= 0; i
< n
; i
++) {
1608 const struct gl_texture_image
**images
;
1610 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
], &newS
, &newT
);
1611 sample_2d_linear(ctx
, tObj
, images
[tObj
->BaseLevel
],
1612 newS
, newT
, rgba
[i
]);
1618 sample_cube_nearest_mipmap_nearest(GLcontext
*ctx
,
1619 const struct gl_texture_object
*tObj
,
1620 GLfloat s
, GLfloat t
, GLfloat u
,
1621 GLfloat lambda
, GLchan rgba
[4])
1623 const struct gl_texture_image
**images
;
1627 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1629 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1630 sample_2d_nearest(ctx
, tObj
, images
[level
], newS
, newT
, rgba
);
1635 sample_cube_linear_mipmap_nearest(GLcontext
*ctx
,
1636 const struct gl_texture_object
*tObj
,
1637 GLfloat s
, GLfloat t
, GLfloat u
,
1638 GLfloat lambda
, GLchan rgba
[4])
1640 const struct gl_texture_image
**images
;
1644 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1646 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1647 sample_2d_linear(ctx
, tObj
, images
[level
], newS
, newT
, rgba
);
1652 sample_cube_nearest_mipmap_linear(GLcontext
*ctx
,
1653 const struct gl_texture_object
*tObj
,
1654 GLfloat s
, GLfloat t
, GLfloat u
,
1655 GLfloat lambda
, GLchan rgba
[4])
1657 const struct gl_texture_image
**images
;
1661 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1663 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1665 if (level
>= tObj
->_MaxLevel
) {
1666 sample_2d_nearest(ctx
, tObj
, images
[tObj
->_MaxLevel
], newS
, newT
, rgba
);
1669 GLchan t0
[4], t1
[4]; /* texels */
1670 const GLfloat f
= FRAC(lambda
);
1671 sample_2d_nearest(ctx
, tObj
, images
[level
], newS
, newT
, t0
);
1672 sample_2d_nearest(ctx
, tObj
, images
[level
+1], newS
, newT
, t1
);
1673 rgba
[RCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1674 rgba
[GCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1675 rgba
[BCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1676 rgba
[ACOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1682 sample_cube_linear_mipmap_linear(GLcontext
*ctx
,
1683 const struct gl_texture_object
*tObj
,
1684 GLfloat s
, GLfloat t
, GLfloat u
,
1685 GLfloat lambda
, GLchan rgba
[4])
1687 const struct gl_texture_image
**images
;
1691 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1693 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1695 if (level
>= tObj
->_MaxLevel
) {
1696 sample_2d_linear(ctx
, tObj
, images
[tObj
->_MaxLevel
], newS
, newT
, rgba
);
1699 GLchan t0
[4], t1
[4];
1700 const GLfloat f
= FRAC(lambda
);
1701 sample_2d_linear(ctx
, tObj
, images
[level
], newS
, newT
, t0
);
1702 sample_2d_linear(ctx
, tObj
, images
[level
+1], newS
, newT
, t1
);
1703 rgba
[RCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1704 rgba
[GCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1705 rgba
[BCOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1706 rgba
[ACOMP
] = (GLchan
) INTCAST ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1712 sample_lambda_cube( GLcontext
*ctx
, GLuint texUnit
,
1713 const struct gl_texture_object
*tObj
, GLuint n
,
1714 const GLfloat s
[], const GLfloat t
[],
1715 const GLfloat u
[], const GLfloat lambda
[],
1718 GLfloat MinMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
1721 for (i
= 0; i
< n
; i
++) {
1722 if (lambda
[i
] > MinMagThresh
) {
1724 switch (tObj
->MinFilter
) {
1727 const struct gl_texture_image
**images
;
1729 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
],
1731 sample_2d_nearest(ctx
, tObj
, images
[tObj
->BaseLevel
],
1732 newS
, newT
, rgba
[i
]);
1737 const struct gl_texture_image
**images
;
1739 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
],
1741 sample_2d_linear(ctx
, tObj
, images
[tObj
->BaseLevel
],
1742 newS
, newT
, rgba
[i
]);
1745 case GL_NEAREST_MIPMAP_NEAREST
:
1746 sample_cube_nearest_mipmap_nearest(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1747 lambda
[i
], rgba
[i
]);
1749 case GL_LINEAR_MIPMAP_NEAREST
:
1750 sample_cube_linear_mipmap_nearest(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1751 lambda
[i
], rgba
[i
]);
1753 case GL_NEAREST_MIPMAP_LINEAR
:
1754 sample_cube_nearest_mipmap_linear(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1755 lambda
[i
], rgba
[i
]);
1757 case GL_LINEAR_MIPMAP_LINEAR
:
1758 sample_cube_linear_mipmap_linear(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1759 lambda
[i
], rgba
[i
]);
1762 _mesa_problem(NULL
, "Bad min filter in sample_lambda_cube");
1767 const struct gl_texture_image
**images
;
1769 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
],
1771 switch (tObj
->MagFilter
) {
1773 sample_2d_nearest(ctx
, tObj
, images
[tObj
->BaseLevel
],
1774 newS
, newT
, rgba
[i
]);
1777 sample_2d_linear(ctx
, tObj
, images
[tObj
->BaseLevel
],
1778 newS
, newT
, rgba
[i
]);
1781 _mesa_problem(NULL
, "Bad mag filter in sample_lambda_cube");
1789 null_sample_func( GLcontext
*ctx
, GLuint texUnit
,
1790 const struct gl_texture_object
*tObj
, GLuint n
,
1791 const GLfloat s
[], const GLfloat t
[],
1792 const GLfloat u
[], const GLfloat lambda
[],
1799 /**********************************************************************/
1800 /* Texture Sampling Setup */
1801 /**********************************************************************/
1805 * Setup the texture sampling function for this texture object.
1808 _swrast_choose_texture_sample_func( GLcontext
*ctx
, GLuint texUnit
,
1809 const struct gl_texture_object
*t
)
1811 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1814 swrast
->TextureSample
[texUnit
] = null_sample_func
;
1817 GLboolean needLambda
= (GLboolean
) (t
->MinFilter
!= t
->MagFilter
);
1820 /* Compute min/mag filter threshold */
1821 if (t
->MagFilter
== GL_LINEAR
1822 && (t
->MinFilter
== GL_NEAREST_MIPMAP_NEAREST
||
1823 t
->MinFilter
== GL_NEAREST_MIPMAP_LINEAR
)) {
1824 swrast
->_MinMagThresh
[texUnit
] = 0.5F
;
1827 swrast
->_MinMagThresh
[texUnit
] = 0.0F
;
1831 switch (t
->Dimensions
) {
1834 swrast
->TextureSample
[texUnit
] = sample_lambda_1d
;
1836 else if (t
->MinFilter
==GL_LINEAR
) {
1837 swrast
->TextureSample
[texUnit
] = sample_linear_1d
;
1840 ASSERT(t
->MinFilter
==GL_NEAREST
);
1841 swrast
->TextureSample
[texUnit
] = sample_nearest_1d
;
1846 swrast
->TextureSample
[texUnit
] = sample_lambda_2d
;
1848 else if (t
->MinFilter
==GL_LINEAR
) {
1849 swrast
->TextureSample
[texUnit
] = sample_linear_2d
;
1852 GLint baseLevel
= t
->BaseLevel
;
1853 ASSERT(t
->MinFilter
==GL_NEAREST
);
1854 if (t
->WrapS
== GL_REPEAT
&&
1855 t
->WrapT
== GL_REPEAT
&&
1856 t
->Image
[baseLevel
]->Border
== 0 &&
1857 t
->Image
[baseLevel
]->TexFormat
->MesaFormat
== MESA_FORMAT_RGB
) {
1858 swrast
->TextureSample
[texUnit
] = opt_sample_rgb_2d
;
1860 else if (t
->WrapS
== GL_REPEAT
&&
1861 t
->WrapT
== GL_REPEAT
&&
1862 t
->Image
[baseLevel
]->Border
== 0 &&
1863 t
->Image
[baseLevel
]->TexFormat
->MesaFormat
== MESA_FORMAT_RGBA
) {
1864 swrast
->TextureSample
[texUnit
] = opt_sample_rgba_2d
;
1867 swrast
->TextureSample
[texUnit
] = sample_nearest_2d
;
1872 swrast
->TextureSample
[texUnit
] = sample_lambda_3d
;
1874 else if (t
->MinFilter
==GL_LINEAR
) {
1875 swrast
->TextureSample
[texUnit
] = sample_linear_3d
;
1878 ASSERT(t
->MinFilter
==GL_NEAREST
);
1879 swrast
->TextureSample
[texUnit
] = sample_nearest_3d
;
1882 case 6: /* cube map */
1884 swrast
->TextureSample
[texUnit
] = sample_lambda_cube
;
1886 else if (t
->MinFilter
==GL_LINEAR
) {
1887 swrast
->TextureSample
[texUnit
] = sample_linear_cube
;
1890 ASSERT(t
->MinFilter
==GL_NEAREST
);
1891 swrast
->TextureSample
[texUnit
] = sample_nearest_cube
;
1895 _mesa_problem(NULL
, "invalid dimensions in _mesa_set_texture_sampler");
1901 #define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) )
1902 #define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) )
1905 texture_combine(const GLcontext
*ctx
,
1906 const struct gl_texture_unit
*textureUnit
,
1908 CONST
GLchan (*primary_rgba
)[4],
1909 CONST
GLchan (*texel
)[4],
1912 const GLchan (*argRGB
[3])[4];
1913 const GLchan (*argA
[3])[4];
1915 const GLuint RGBshift
= textureUnit
->CombineScaleShiftRGB
;
1916 const GLuint Ashift
= textureUnit
->CombineScaleShiftA
;
1917 #if CHAN_TYPE == GL_FLOAT
1918 const GLchan RGBmult
= (GLfloat
) (1 << RGBshift
);
1919 const GLchan Amult
= (GLfloat
) (1 << Ashift
);
1921 const GLint half
= (CHAN_MAX
+ 1) / 2;
1924 DEFMNARRAY(GLchan
, ccolor
, 3, 3 * MAX_WIDTH
, 4); /* mac 32k limitation */
1925 CHECKARRAY(ccolor
, return); /* mac 32k limitation */
1927 ASSERT(ctx
->Extensions
.EXT_texture_env_combine
||
1928 ctx
->Extensions
.ARB_texture_env_combine
);
1931 * Do operand setup for up to 3 operands. Loop over the terms.
1933 for (j
= 0; j
< 3; j
++) {
1934 switch (textureUnit
->CombineSourceA
[j
]) {
1938 case GL_PRIMARY_COLOR_EXT
:
1939 argA
[j
] = primary_rgba
;
1941 case GL_PREVIOUS_EXT
:
1942 argA
[j
] = (const GLchan (*)[4]) rgba
;
1944 case GL_CONSTANT_EXT
:
1946 GLchan alpha
, (*c
)[4] = ccolor
[j
];
1947 UNCLAMPED_FLOAT_TO_CHAN(alpha
, textureUnit
->EnvColor
[3]);
1948 for (i
= 0; i
< n
; i
++)
1949 c
[i
][ACOMP
] = alpha
;
1950 argA
[j
] = (const GLchan (*)[4]) ccolor
[j
];
1954 _mesa_problem(NULL
, "invalid combine source");
1957 switch (textureUnit
->CombineSourceRGB
[j
]) {
1961 case GL_PRIMARY_COLOR_EXT
:
1962 argRGB
[j
] = primary_rgba
;
1964 case GL_PREVIOUS_EXT
:
1965 argRGB
[j
] = (const GLchan (*)[4]) rgba
;
1967 case GL_CONSTANT_EXT
:
1969 GLchan (*c
)[4] = ccolor
[j
];
1970 GLchan red
, green
, blue
, alpha
;
1971 UNCLAMPED_FLOAT_TO_CHAN(red
, textureUnit
->EnvColor
[0]);
1972 UNCLAMPED_FLOAT_TO_CHAN(green
, textureUnit
->EnvColor
[1]);
1973 UNCLAMPED_FLOAT_TO_CHAN(blue
, textureUnit
->EnvColor
[2]);
1974 UNCLAMPED_FLOAT_TO_CHAN(alpha
, textureUnit
->EnvColor
[3]);
1975 for (i
= 0; i
< n
; i
++) {
1977 c
[i
][GCOMP
] = green
;
1979 c
[i
][ACOMP
] = alpha
;
1981 argRGB
[j
] = (const GLchan (*)[4]) ccolor
[j
];
1985 _mesa_problem(NULL
, "invalid combine source");
1988 if (textureUnit
->CombineOperandRGB
[j
] != GL_SRC_COLOR
) {
1989 const GLchan (*src
)[4] = argRGB
[j
];
1990 GLchan (*dst
)[4] = ccolor
[j
];
1992 /* point to new arg[j] storage */
1993 argRGB
[j
] = (const GLchan (*)[4]) ccolor
[j
];
1995 if (textureUnit
->CombineOperandRGB
[j
] == GL_ONE_MINUS_SRC_COLOR
) {
1996 for (i
= 0; i
< n
; i
++) {
1997 dst
[i
][RCOMP
] = CHAN_MAX
- src
[i
][RCOMP
];
1998 dst
[i
][GCOMP
] = CHAN_MAX
- src
[i
][GCOMP
];
1999 dst
[i
][BCOMP
] = CHAN_MAX
- src
[i
][BCOMP
];
2002 else if (textureUnit
->CombineOperandRGB
[j
] == GL_SRC_ALPHA
) {
2003 for (i
= 0; i
< n
; i
++) {
2004 dst
[i
][RCOMP
] = src
[i
][ACOMP
];
2005 dst
[i
][GCOMP
] = src
[i
][ACOMP
];
2006 dst
[i
][BCOMP
] = src
[i
][ACOMP
];
2010 ASSERT(textureUnit
->CombineOperandRGB
[j
] ==GL_ONE_MINUS_SRC_ALPHA
);
2011 for (i
= 0; i
< n
; i
++) {
2012 dst
[i
][RCOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
2013 dst
[i
][GCOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
2014 dst
[i
][BCOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
2019 if (textureUnit
->CombineOperandA
[j
] == GL_ONE_MINUS_SRC_ALPHA
) {
2020 const GLchan (*src
)[4] = argA
[j
];
2021 GLchan (*dst
)[4] = ccolor
[j
];
2022 argA
[j
] = (const GLchan (*)[4]) ccolor
[j
];
2023 for (i
= 0; i
< n
; i
++) {
2024 dst
[i
][ACOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
2028 if (textureUnit
->CombineModeRGB
== GL_REPLACE
&&
2029 textureUnit
->CombineModeA
== GL_REPLACE
) {
2030 break; /* done, we need only arg0 */
2034 textureUnit
->CombineModeRGB
!= GL_INTERPOLATE_EXT
&&
2035 textureUnit
->CombineModeA
!= GL_INTERPOLATE_EXT
) {
2036 break; /* arg0 and arg1 are done. we don't need arg2. */
2041 * Do the texture combine.
2043 switch (textureUnit
->CombineModeRGB
) {
2046 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
2048 for (i
= 0; i
< n
; i
++) {
2049 #if CHAN_TYPE == GL_FLOAT
2050 rgba
[i
][RCOMP
] = arg0
[i
][RCOMP
] * RGBmult
;
2051 rgba
[i
][GCOMP
] = arg0
[i
][GCOMP
] * RGBmult
;
2052 rgba
[i
][BCOMP
] = arg0
[i
][BCOMP
] * RGBmult
;
2054 GLuint r
= (GLuint
) arg0
[i
][RCOMP
] << RGBshift
;
2055 GLuint g
= (GLuint
) arg0
[i
][GCOMP
] << RGBshift
;
2056 GLuint b
= (GLuint
) arg0
[i
][BCOMP
] << RGBshift
;
2057 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2058 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2059 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2064 for (i
= 0; i
< n
; i
++) {
2065 rgba
[i
][RCOMP
] = arg0
[i
][RCOMP
];
2066 rgba
[i
][GCOMP
] = arg0
[i
][GCOMP
];
2067 rgba
[i
][BCOMP
] = arg0
[i
][BCOMP
];
2074 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
2075 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
2076 #if CHAN_TYPE != GL_FLOAT
2077 const GLint shift
= 8 - RGBshift
;
2079 for (i
= 0; i
< n
; i
++) {
2080 #if CHAN_TYPE == GL_FLOAT
2081 rgba
[i
][RCOMP
] = arg0
[i
][RCOMP
] * arg1
[i
][RCOMP
] * RGBmult
;
2082 rgba
[i
][GCOMP
] = arg0
[i
][GCOMP
] * arg1
[i
][GCOMP
] * RGBmult
;
2083 rgba
[i
][BCOMP
] = arg0
[i
][BCOMP
] * arg1
[i
][BCOMP
] * RGBmult
;
2085 GLuint r
= PROD(arg0
[i
][RCOMP
], arg1
[i
][RCOMP
]) >> shift
;
2086 GLuint g
= PROD(arg0
[i
][GCOMP
], arg1
[i
][GCOMP
]) >> shift
;
2087 GLuint b
= PROD(arg0
[i
][BCOMP
], arg1
[i
][BCOMP
]) >> shift
;
2088 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
2089 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
2090 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
2097 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
2098 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
2099 for (i
= 0; i
< n
; i
++) {
2100 #if CHAN_TYPE == GL_FLOAT
2101 rgba
[i
][RCOMP
] = (arg0
[i
][RCOMP
] + arg1
[i
][RCOMP
]) * RGBmult
;
2102 rgba
[i
][GCOMP
] = (arg0
[i
][GCOMP
] + arg1
[i
][GCOMP
]) * RGBmult
;
2103 rgba
[i
][BCOMP
] = (arg0
[i
][BCOMP
] + arg1
[i
][BCOMP
]) * RGBmult
;
2105 GLint r
= ((GLint
) arg0
[i
][RCOMP
] + (GLint
) arg1
[i
][RCOMP
]) << RGBshift
;
2106 GLint g
= ((GLint
) arg0
[i
][GCOMP
] + (GLint
) arg1
[i
][GCOMP
]) << RGBshift
;
2107 GLint b
= ((GLint
) arg0
[i
][BCOMP
] + (GLint
) arg1
[i
][BCOMP
]) << RGBshift
;
2108 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
2109 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
2110 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
2115 case GL_ADD_SIGNED_EXT
:
2117 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
2118 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
2119 for (i
= 0; i
< n
; i
++) {
2120 #if CHAN_TYPE == GL_FLOAT
2121 rgba
[i
][RCOMP
] = (arg0
[i
][RCOMP
] + arg1
[i
][RCOMP
] - 0.5) * RGBmult
;
2122 rgba
[i
][GCOMP
] = (arg0
[i
][GCOMP
] + arg1
[i
][GCOMP
] - 0.5) * RGBmult
;
2123 rgba
[i
][BCOMP
] = (arg0
[i
][BCOMP
] + arg1
[i
][BCOMP
] - 0.5) * RGBmult
;
2125 GLint r
= (GLint
) arg0
[i
][RCOMP
] + (GLint
) arg1
[i
][RCOMP
] -half
;
2126 GLint g
= (GLint
) arg0
[i
][GCOMP
] + (GLint
) arg1
[i
][GCOMP
] -half
;
2127 GLint b
= (GLint
) arg0
[i
][BCOMP
] + (GLint
) arg1
[i
][BCOMP
] -half
;
2128 r
= (r
< 0) ? 0 : r
<< RGBshift
;
2129 g
= (g
< 0) ? 0 : g
<< RGBshift
;
2130 b
= (b
< 0) ? 0 : b
<< RGBshift
;
2131 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
2132 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
2133 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
2138 case GL_INTERPOLATE_EXT
:
2140 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
2141 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
2142 const GLchan (*arg2
)[4] = (const GLchan (*)[4]) argRGB
[2];
2143 #if CHAN_TYPE != GL_FLOAT
2144 const GLint shift
= 8 - RGBshift
;
2146 for (i
= 0; i
< n
; i
++) {
2147 #if CHAN_TYPE == GL_FLOAT
2148 rgba
[i
][RCOMP
] = (arg0
[i
][RCOMP
] * arg2
[i
][RCOMP
] +
2149 arg1
[i
][RCOMP
] * (CHAN_MAXF
- arg2
[i
][RCOMP
])) * RGBmult
;
2150 rgba
[i
][GCOMP
] = (arg0
[i
][GCOMP
] * arg2
[i
][GCOMP
] +
2151 arg1
[i
][GCOMP
] * (CHAN_MAXF
- arg2
[i
][GCOMP
])) * RGBmult
;
2152 rgba
[i
][BCOMP
] = (arg0
[i
][BCOMP
] * arg2
[i
][BCOMP
] +
2153 arg1
[i
][BCOMP
] * (CHAN_MAXF
- arg2
[i
][BCOMP
])) * RGBmult
;
2155 GLuint r
= (PROD(arg0
[i
][RCOMP
], arg2
[i
][RCOMP
])
2156 + PROD(arg1
[i
][RCOMP
], CHAN_MAX
- arg2
[i
][RCOMP
]))
2158 GLuint g
= (PROD(arg0
[i
][GCOMP
], arg2
[i
][GCOMP
])
2159 + PROD(arg1
[i
][GCOMP
], CHAN_MAX
- arg2
[i
][GCOMP
]))
2161 GLuint b
= (PROD(arg0
[i
][BCOMP
], arg2
[i
][BCOMP
])
2162 + PROD(arg1
[i
][BCOMP
], CHAN_MAX
- arg2
[i
][BCOMP
]))
2164 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
2165 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
2166 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
2171 case GL_SUBTRACT_ARB
:
2173 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
2174 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
2175 for (i
= 0; i
< n
; i
++) {
2176 #if CHAN_TYPE == GL_FLOAT
2177 rgba
[i
][RCOMP
] = (arg0
[i
][RCOMP
] - arg1
[i
][RCOMP
]) * RGBmult
;
2178 rgba
[i
][GCOMP
] = (arg0
[i
][GCOMP
] - arg1
[i
][GCOMP
]) * RGBmult
;
2179 rgba
[i
][BCOMP
] = (arg0
[i
][BCOMP
] - arg1
[i
][BCOMP
]) * RGBmult
;
2181 GLint r
= ((GLint
) arg0
[i
][RCOMP
] - (GLint
) arg1
[i
][RCOMP
]) << RGBshift
;
2182 GLint g
= ((GLint
) arg0
[i
][GCOMP
] - (GLint
) arg1
[i
][GCOMP
]) << RGBshift
;
2183 GLint b
= ((GLint
) arg0
[i
][BCOMP
] - (GLint
) arg1
[i
][BCOMP
]) << RGBshift
;
2184 rgba
[i
][RCOMP
] = (GLchan
) CLAMP(r
, 0, CHAN_MAX
);
2185 rgba
[i
][GCOMP
] = (GLchan
) CLAMP(g
, 0, CHAN_MAX
);
2186 rgba
[i
][BCOMP
] = (GLchan
) CLAMP(b
, 0, CHAN_MAX
);
2191 case GL_DOT3_RGB_ARB
:
2192 case GL_DOT3_RGBA_ARB
:
2194 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
2195 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
2196 /* ATI's EXT extension has a constant scale by 4. The ARB
2197 * one will likely remove this restriction, and we should
2198 * drop the EXT extension in favour of the ARB one.
2200 for (i
= 0; i
< n
; i
++) {
2201 #if CHAN_TYPE == GL_FLOAT
2202 GLchan dot
= ((arg0
[i
][RCOMP
]-0.5F
) * (arg1
[i
][RCOMP
]-0.5F
) +
2203 (arg0
[i
][GCOMP
]-0.5F
) * (arg1
[i
][GCOMP
]-0.5F
) +
2204 (arg0
[i
][BCOMP
]-0.5F
) * (arg1
[i
][BCOMP
]-0.5F
))
2207 GLint dot
= (S_PROD((GLint
)arg0
[i
][RCOMP
] - half
,
2208 (GLint
)arg1
[i
][RCOMP
] - half
) +
2209 S_PROD((GLint
)arg0
[i
][GCOMP
] - half
,
2210 (GLint
)arg1
[i
][GCOMP
] - half
) +
2211 S_PROD((GLint
)arg0
[i
][BCOMP
] - half
,
2212 (GLint
)arg1
[i
][BCOMP
] - half
)) >> 6;
2214 dot
= CLAMP(dot
, 0, CHAN_MAX
);
2215 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = (GLchan
) dot
;
2220 _mesa_problem(NULL
, "invalid combine mode");
2223 switch (textureUnit
->CombineModeA
) {
2226 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
2228 for (i
= 0; i
< n
; i
++) {
2229 #if CHAN_TYPE == GL_FLOAT
2230 GLchan a
= arg0
[i
][ACOMP
] * Amult
;
2232 GLuint a
= (GLuint
) arg0
[i
][ACOMP
] << Ashift
;
2234 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
2238 for (i
= 0; i
< n
; i
++) {
2239 rgba
[i
][ACOMP
] = arg0
[i
][ACOMP
];
2246 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
2247 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
2248 #if CHAN_TYPE != GL_FLOAT
2249 const GLint shift
= 8 - Ashift
;
2251 for (i
= 0; i
< n
; i
++) {
2252 #if CHAN_TYPE == GL_FLOAT
2253 rgba
[i
][ACOMP
] = arg0
[i
][ACOMP
] * arg1
[i
][ACOMP
] * Amult
;
2255 GLuint a
= (PROD(arg0
[i
][ACOMP
], arg1
[i
][ACOMP
]) >> shift
);
2256 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
2263 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
2264 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
2265 for (i
= 0; i
< n
; i
++) {
2266 #if CHAN_TYPE == GL_FLOAT
2267 rgba
[i
][ACOMP
] = (arg0
[i
][ACOMP
] + arg1
[i
][ACOMP
]) * Amult
;
2269 GLint a
= ((GLint
) arg0
[i
][ACOMP
] + arg1
[i
][ACOMP
]) << Ashift
;
2270 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
2275 case GL_ADD_SIGNED_EXT
:
2277 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
2278 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
2279 for (i
= 0; i
< n
; i
++) {
2280 #if CHAN_TYPE == GL_FLOAT
2281 rgba
[i
][ACOMP
] = (arg0
[i
][ACOMP
] + arg1
[i
][ACOMP
] - 0.5F
) * Amult
;
2283 GLint a
= (GLint
) arg0
[i
][ACOMP
] + (GLint
) arg1
[i
][ACOMP
] -half
;
2284 a
= (a
< 0) ? 0 : a
<< Ashift
;
2285 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
2290 case GL_INTERPOLATE_EXT
:
2292 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
2293 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
2294 const GLchan (*arg2
)[4] = (const GLchan (*)[4]) argA
[2];
2295 #if CHAN_TYPE != GL_FLOAT
2296 const GLint shift
= 8 - Ashift
;
2298 for (i
=0; i
<n
; i
++) {
2299 #if CHAN_TYPE == GL_FLOAT
2300 rgba
[i
][ACOMP
] = (arg0
[i
][ACOMP
] * arg2
[i
][ACOMP
] +
2301 arg1
[i
][ACOMP
] * (CHAN_MAXF
- arg2
[i
][ACOMP
]))
2304 GLuint a
= (PROD(arg0
[i
][ACOMP
], arg2
[i
][ACOMP
])
2305 + PROD(arg1
[i
][ACOMP
], CHAN_MAX
- arg2
[i
][ACOMP
]))
2307 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
2312 case GL_SUBTRACT_ARB
:
2314 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
2315 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
2316 for (i
= 0; i
< n
; i
++) {
2317 #if CHAN_TYPE == GL_FLOAT
2318 rgba
[i
][ACOMP
] = (arg0
[i
][ACOMP
] - arg1
[i
][ACOMP
]) * Amult
;
2320 GLint a
= ((GLint
) arg0
[i
][ACOMP
] - (GLint
) arg1
[i
][ACOMP
]) << RGBshift
;
2321 rgba
[i
][ACOMP
] = (GLchan
) CLAMP(a
, 0, CHAN_MAX
);
2328 _mesa_problem(NULL
, "invalid combine mode");
2331 /* Fix the alpha component for GL_DOT3_RGBA_EXT combining.
2333 if (textureUnit
->CombineModeRGB
== GL_DOT3_RGBA_EXT
||
2334 textureUnit
->CombineModeRGB
== GL_DOT3_RGBA_ARB
) {
2335 for (i
= 0; i
< n
; i
++) {
2336 rgba
[i
][ACOMP
] = rgba
[i
][RCOMP
];
2339 UNDEFARRAY(ccolor
); /* mac 32k limitation */
2345 /**********************************************************************/
2346 /* Texture Application */
2347 /**********************************************************************/
2351 * Combine incoming fragment color with texel color to produce output color.
2352 * Input: textureUnit - pointer to texture unit to apply
2353 * format - base internal texture format
2354 * n - number of fragments
2355 * primary_rgba - primary colors (may alias rgba for single texture)
2356 * texels - array of texel colors
2357 * InOut: rgba - incoming fragment colors modified by texel colors
2358 * according to the texture environment mode.
2361 apply_texture( const GLcontext
*ctx
,
2362 const struct gl_texture_unit
*texUnit
,
2364 CONST GLchan primary_rgba
[][4], CONST GLchan texel
[][4],
2369 GLint Rc
, Gc
, Bc
, Ac
;
2373 ASSERT(texUnit
->_Current
);
2375 baseLevel
= texUnit
->_Current
->BaseLevel
;
2376 ASSERT(texUnit
->_Current
->Image
[baseLevel
]);
2378 format
= texUnit
->_Current
->Image
[baseLevel
]->Format
;
2380 if (format
==GL_COLOR_INDEX
|| format
==GL_DEPTH_COMPONENT
) {
2381 format
= GL_RGBA
; /* XXXX a hack! */
2384 switch (texUnit
->EnvMode
) {
2391 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
2397 GLchan Lt
= texel
[i
][RCOMP
];
2398 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = Lt
;
2402 case GL_LUMINANCE_ALPHA
:
2404 GLchan Lt
= texel
[i
][RCOMP
];
2406 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = Lt
;
2408 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
2414 GLchan It
= texel
[i
][RCOMP
];
2415 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = It
;
2417 rgba
[i
][ACOMP
] = It
;
2423 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
2424 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
2425 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
2432 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
2433 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
2434 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
2436 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
2440 _mesa_problem(ctx
, "Bad format (GL_REPLACE) in apply_texture");
2451 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], texel
[i
][ACOMP
] );
2457 GLchan Lt
= texel
[i
][RCOMP
];
2458 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], Lt
);
2459 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], Lt
);
2460 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], Lt
);
2464 case GL_LUMINANCE_ALPHA
:
2467 GLchan Lt
= texel
[i
][RCOMP
];
2468 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], Lt
);
2469 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], Lt
);
2470 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], Lt
);
2472 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], texel
[i
][ACOMP
] );
2478 GLchan It
= texel
[i
][RCOMP
];
2479 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], It
);
2480 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], It
);
2481 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], It
);
2483 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], It
);
2489 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], texel
[i
][RCOMP
] );
2490 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], texel
[i
][GCOMP
] );
2491 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], texel
[i
][BCOMP
] );
2498 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], texel
[i
][RCOMP
] );
2499 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], texel
[i
][GCOMP
] );
2500 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], texel
[i
][BCOMP
] );
2502 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], texel
[i
][ACOMP
] );
2506 _mesa_problem(ctx
, "Bad format (GL_MODULATE) in apply_texture");
2515 case GL_LUMINANCE_ALPHA
:
2522 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
2523 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
2524 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
2530 /* Cv = Cf(1-At) + CtAt */
2531 GLint t
= texel
[i
][ACOMP
], s
= CHAN_MAX
- t
;
2532 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(texel
[i
][RCOMP
],t
);
2533 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(texel
[i
][GCOMP
],t
);
2534 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(texel
[i
][BCOMP
],t
);
2539 _mesa_problem(ctx
, "Bad format (GL_DECAL) in apply_texture");
2545 Rc
= (GLint
) (texUnit
->EnvColor
[0] * CHAN_MAXF
);
2546 Gc
= (GLint
) (texUnit
->EnvColor
[1] * CHAN_MAXF
);
2547 Bc
= (GLint
) (texUnit
->EnvColor
[2] * CHAN_MAXF
);
2548 Ac
= (GLint
) (texUnit
->EnvColor
[3] * CHAN_MAXF
);
2554 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2559 /* Cv = Cf(1-Lt) + CcLt */
2560 GLchan Lt
= texel
[i
][RCOMP
], s
= CHAN_MAX
- Lt
;
2561 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(Rc
, Lt
);
2562 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(Gc
, Lt
);
2563 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(Bc
, Lt
);
2567 case GL_LUMINANCE_ALPHA
:
2569 /* Cv = Cf(1-Lt) + CcLt */
2570 GLchan Lt
= texel
[i
][RCOMP
], s
= CHAN_MAX
- Lt
;
2571 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(Rc
, Lt
);
2572 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(Gc
, Lt
);
2573 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(Bc
, Lt
);
2575 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
],texel
[i
][ACOMP
]);
2580 /* Cv = Cf(1-It) + CcLt */
2581 GLchan It
= texel
[i
][RCOMP
], s
= CHAN_MAX
- It
;
2582 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(Rc
, It
);
2583 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(Gc
, It
);
2584 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(Bc
, It
);
2585 /* Av = Af(1-It) + Ac*It */
2586 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], s
) + CHAN_PRODUCT(Ac
, It
);
2591 /* Cv = Cf(1-Ct) + CcCt */
2592 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], (CHAN_MAX
-texel
[i
][RCOMP
])) + CHAN_PRODUCT(Rc
,texel
[i
][RCOMP
]);
2593 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], (CHAN_MAX
-texel
[i
][GCOMP
])) + CHAN_PRODUCT(Gc
,texel
[i
][GCOMP
]);
2594 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], (CHAN_MAX
-texel
[i
][BCOMP
])) + CHAN_PRODUCT(Bc
,texel
[i
][BCOMP
]);
2600 /* Cv = Cf(1-Ct) + CcCt */
2601 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], (CHAN_MAX
-texel
[i
][RCOMP
])) + CHAN_PRODUCT(Rc
,texel
[i
][RCOMP
]);
2602 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], (CHAN_MAX
-texel
[i
][GCOMP
])) + CHAN_PRODUCT(Gc
,texel
[i
][GCOMP
]);
2603 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], (CHAN_MAX
-texel
[i
][BCOMP
])) + CHAN_PRODUCT(Bc
,texel
[i
][BCOMP
]);
2605 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
],texel
[i
][ACOMP
]);
2609 _mesa_problem(ctx
, "Bad format (GL_BLEND) in apply_texture");
2614 /* XXX don't clamp results if GLchan is float??? */
2616 case GL_ADD
: /* GL_EXT_texture_add_env */
2623 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2628 GLuint Lt
= texel
[i
][RCOMP
];
2629 GLuint r
= rgba
[i
][RCOMP
] + Lt
;
2630 GLuint g
= rgba
[i
][GCOMP
] + Lt
;
2631 GLuint b
= rgba
[i
][BCOMP
] + Lt
;
2632 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2633 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2634 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2638 case GL_LUMINANCE_ALPHA
:
2640 GLuint Lt
= texel
[i
][RCOMP
];
2641 GLuint r
= rgba
[i
][RCOMP
] + Lt
;
2642 GLuint g
= rgba
[i
][GCOMP
] + Lt
;
2643 GLuint b
= rgba
[i
][BCOMP
] + Lt
;
2644 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2645 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2646 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2647 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2652 GLchan It
= texel
[i
][RCOMP
];
2653 GLuint r
= rgba
[i
][RCOMP
] + It
;
2654 GLuint g
= rgba
[i
][GCOMP
] + It
;
2655 GLuint b
= rgba
[i
][BCOMP
] + It
;
2656 GLuint a
= rgba
[i
][ACOMP
] + It
;
2657 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2658 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2659 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2660 rgba
[i
][ACOMP
] = MIN2(a
, CHAN_MAX
);
2665 GLuint r
= rgba
[i
][RCOMP
] + texel
[i
][RCOMP
];
2666 GLuint g
= rgba
[i
][GCOMP
] + texel
[i
][GCOMP
];
2667 GLuint b
= rgba
[i
][BCOMP
] + texel
[i
][BCOMP
];
2668 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2669 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2670 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2676 GLuint r
= rgba
[i
][RCOMP
] + texel
[i
][RCOMP
];
2677 GLuint g
= rgba
[i
][GCOMP
] + texel
[i
][GCOMP
];
2678 GLuint b
= rgba
[i
][BCOMP
] + texel
[i
][BCOMP
];
2679 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2680 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2681 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2682 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2686 _mesa_problem(ctx
, "Bad format (GL_ADD) in apply_texture");
2691 case GL_COMBINE_EXT
:
2692 texture_combine(ctx
, texUnit
, n
, primary_rgba
, texel
, rgba
);
2696 _mesa_problem(ctx
, "Bad env mode in apply_texture");
2704 * Sample a shadow/depth texture.
2705 * Input: ctx - context
2706 * texUnit - the texture unit
2707 * n - number of samples
2708 * s,t,r - array [n] of texture coordinates
2709 * In/Out: rgba - array [n] of texel colors.
2712 sample_depth_texture(const GLcontext
*ctx
,
2713 const struct gl_texture_unit
*texUnit
,
2715 const GLfloat s
[], const GLfloat t
[], const GLfloat r
[],
2718 const struct gl_texture_object
*texObj
= texUnit
->_Current
;
2719 const GLint baseLevel
= texObj
->BaseLevel
;
2720 const struct gl_texture_image
*texImage
= texObj
->Image
[baseLevel
];
2721 const GLuint width
= texImage
->Width
;
2722 const GLuint height
= texImage
->Height
;
2723 const GLchan ambient
= texObj
->ShadowAmbient
;
2724 GLboolean lequal
, gequal
;
2726 if (texObj
->Dimensions
!= 2) {
2727 _mesa_problem(ctx
, "only 2-D depth textures supported at this time");
2731 if (texObj
->MinFilter
!= texObj
->MagFilter
) {
2732 _mesa_problem(ctx
, "mipmapped depth textures not supported at this time");
2736 /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if
2737 * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object
2738 * isn't a depth texture.
2740 if (texImage
->Format
!= GL_DEPTH_COMPONENT
) {
2741 _mesa_problem(ctx
,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture");
2745 if (texObj
->CompareOperator
== GL_TEXTURE_LEQUAL_R_SGIX
) {
2754 if (texObj
->MagFilter
== GL_NEAREST
) {
2756 for (i
= 0; i
< n
; i
++) {
2757 GLfloat depthSample
;
2759 COMPUTE_NEAREST_TEXEL_LOCATION(texObj
->WrapS
, s
[i
], width
, col
);
2760 COMPUTE_NEAREST_TEXEL_LOCATION(texObj
->WrapT
, t
[i
], height
, row
);
2761 depthSample
= *((const GLfloat
*) texImage
->Data
+ row
* width
+ col
);
2762 if ((r
[i
] <= depthSample
&& lequal
) ||
2763 (r
[i
] >= depthSample
&& gequal
)) {
2764 texel
[i
][RCOMP
] = CHAN_MAX
;
2765 texel
[i
][GCOMP
] = CHAN_MAX
;
2766 texel
[i
][BCOMP
] = CHAN_MAX
;
2767 texel
[i
][ACOMP
] = CHAN_MAX
;
2770 texel
[i
][RCOMP
] = ambient
;
2771 texel
[i
][GCOMP
] = ambient
;
2772 texel
[i
][BCOMP
] = ambient
;
2773 texel
[i
][ACOMP
] = CHAN_MAX
;
2779 ASSERT(texObj
->MagFilter
== GL_LINEAR
);
2780 for (i
= 0; i
< n
; i
++) {
2781 GLfloat depth00
, depth01
, depth10
, depth11
;
2782 GLint i0
, i1
, j0
, j1
;
2784 GLuint useBorderTexel
;
2786 COMPUTE_LINEAR_TEXEL_LOCATIONS(texObj
->WrapS
, s
[i
], u
, width
, i0
, i1
);
2787 COMPUTE_LINEAR_TEXEL_LOCATIONS(texObj
->WrapT
, t
[i
], v
, height
,j0
, j1
);
2790 if (texImage
->Border
) {
2791 i0
+= texImage
->Border
;
2792 i1
+= texImage
->Border
;
2793 j0
+= texImage
->Border
;
2794 j1
+= texImage
->Border
;
2797 if (i0
< 0 || i0
>= (GLint
) width
) useBorderTexel
|= I0BIT
;
2798 if (i1
< 0 || i1
>= (GLint
) width
) useBorderTexel
|= I1BIT
;
2799 if (j0
< 0 || j0
>= (GLint
) height
) useBorderTexel
|= J0BIT
;
2800 if (j1
< 0 || j1
>= (GLint
) height
) useBorderTexel
|= J1BIT
;
2803 /* get four depth samples from the texture */
2804 if (useBorderTexel
& (I0BIT
| J0BIT
)) {
2808 depth00
= *((const GLfloat
*) texImage
->Data
+ j0
* width
+ i0
);
2810 if (useBorderTexel
& (I1BIT
| J0BIT
)) {
2814 depth10
= *((const GLfloat
*) texImage
->Data
+ j0
* width
+ i1
);
2816 if (useBorderTexel
& (I0BIT
| J1BIT
)) {
2820 depth01
= *((const GLfloat
*) texImage
->Data
+ j1
* width
+ i0
);
2822 if (useBorderTexel
& (I1BIT
| J1BIT
)) {
2826 depth11
= *((const GLfloat
*) texImage
->Data
+ j1
* width
+ i1
);
2830 /* compute a single weighted depth sample and do one comparison */
2831 const GLfloat a
= FRAC(u
+ 1.0F
);
2832 const GLfloat b
= FRAC(v
+ 1.0F
);
2833 const GLfloat w00
= (1.0F
- a
) * (1.0F
- b
);
2834 const GLfloat w10
= ( a
) * (1.0F
- b
);
2835 const GLfloat w01
= (1.0F
- a
) * ( b
);
2836 const GLfloat w11
= ( a
) * ( b
);
2837 const GLfloat depthSample
= w00
* depth00
+ w10
* depth10
2838 + w01
* depth01
+ w11
* depth11
;
2839 if ((depthSample
<= r
[i
] && lequal
) ||
2840 (depthSample
>= r
[i
] && gequal
)) {
2841 texel
[i
][RCOMP
] = ambient
;
2842 texel
[i
][GCOMP
] = ambient
;
2843 texel
[i
][BCOMP
] = ambient
;
2844 texel
[i
][ACOMP
] = CHAN_MAX
;
2847 texel
[i
][RCOMP
] = CHAN_MAX
;
2848 texel
[i
][GCOMP
] = CHAN_MAX
;
2849 texel
[i
][BCOMP
] = CHAN_MAX
;
2850 texel
[i
][ACOMP
] = CHAN_MAX
;
2854 /* Do four depth/R comparisons and compute a weighted result.
2855 * If this touches on somebody's I.P., I'll remove this code
2858 const GLfloat d
= (CHAN_MAXF
- (GLfloat
) ambient
) * 0.25F
;
2859 GLfloat luminance
= CHAN_MAXF
;
2862 if (depth00
<= r
[i
]) luminance
-= d
;
2863 if (depth01
<= r
[i
]) luminance
-= d
;
2864 if (depth10
<= r
[i
]) luminance
-= d
;
2865 if (depth11
<= r
[i
]) luminance
-= d
;
2868 if (depth00
>= r
[i
]) luminance
-= d
;
2869 if (depth01
>= r
[i
]) luminance
-= d
;
2870 if (depth10
>= r
[i
]) luminance
-= d
;
2871 if (depth11
>= r
[i
]) luminance
-= d
;
2873 lum
= (GLchan
) luminance
;
2874 texel
[i
][RCOMP
] = lum
;
2875 texel
[i
][GCOMP
] = lum
;
2876 texel
[i
][BCOMP
] = lum
;
2877 texel
[i
][ACOMP
] = CHAN_MAX
;
2886 * Experimental depth texture sampling function.
2889 sample_depth_texture2(const GLcontext
*ctx
,
2890 const struct gl_texture_unit
*texUnit
,
2892 const GLfloat s
[], const GLfloat t
[], const GLfloat r
[],
2895 const struct gl_texture_object
*texObj
= texUnit
->_Current
;
2896 const GLint baseLevel
= texObj
->BaseLevel
;
2897 const struct gl_texture_image
*texImage
= texObj
->Image
[baseLevel
];
2898 const GLuint width
= texImage
->Width
;
2899 const GLuint height
= texImage
->Height
;
2900 const GLchan ambient
= texObj
->ShadowAmbient
;
2901 GLboolean lequal
, gequal
;
2903 if (texObj
->Dimensions
!= 2) {
2904 _mesa_problem(ctx
, "only 2-D depth textures supported at this time");
2908 if (texObj
->MinFilter
!= texObj
->MagFilter
) {
2909 _mesa_problem(ctx
, "mipmapped depth textures not supported at this time");
2913 /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if
2914 * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object
2915 * isn't a depth texture.
2917 if (texImage
->Format
!= GL_DEPTH_COMPONENT
) {
2918 _mesa_problem(ctx
,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture");
2922 if (texObj
->CompareOperator
== GL_TEXTURE_LEQUAL_R_SGIX
) {
2933 for (i
= 0; i
< n
; i
++) {
2935 GLint col
, row
, ii
, jj
, imin
, imax
, jmin
, jmax
, samples
, count
;
2938 COMPUTE_NEAREST_TEXEL_LOCATION(texObj
->WrapS
, s
[i
], width
, col
);
2939 COMPUTE_NEAREST_TEXEL_LOCATION(texObj
->WrapT
, t
[i
], height
, row
);
2946 if (imin
< 0) imin
= 0;
2947 if (imax
>= width
) imax
= width
- 1;
2948 if (jmin
< 0) jmin
= 0;
2949 if (jmax
>= height
) jmax
= height
- 1;
2951 samples
= (imax
- imin
+ 1) * (jmax
- jmin
+ 1);
2953 for (jj
= jmin
; jj
<= jmax
; jj
++) {
2954 for (ii
= imin
; ii
<= imax
; ii
++) {
2955 GLfloat depthSample
= *((const GLfloat
*) texImage
->Data
2957 if ((depthSample
<= r
[i
] && lequal
) ||
2958 (depthSample
>= r
[i
] && gequal
)) {
2964 w
= (GLfloat
) count
/ (GLfloat
) samples
;
2965 w
= CHAN_MAXF
- w
* (CHAN_MAXF
- (GLfloat
) ambient
);
2968 texel
[i
][RCOMP
] = lum
;
2969 texel
[i
][GCOMP
] = lum
;
2970 texel
[i
][BCOMP
] = lum
;
2971 texel
[i
][ACOMP
] = CHAN_MAX
;
2979 * Apply a unit of texture mapping to the incoming fragments.
2982 _swrast_texture_fragments( GLcontext
*ctx
, GLuint texUnit
, GLuint n
,
2983 const GLfloat s
[], const GLfloat t
[],
2984 const GLfloat r
[], GLfloat lambda
[],
2985 CONST GLchan primary_rgba
[][4], GLchan rgba
[][4] )
2987 const GLuint mask
= TEXTURE0_ANY
<< (texUnit
* 4);
2989 if (ctx
->Texture
._ReallyEnabled
& mask
) {
2990 const struct gl_texture_unit
*textureUnit
= &ctx
->Texture
.Unit
[texUnit
];
2992 if (textureUnit
->_Current
) { /* XXX need this? */
2993 GLchan texel
[PB_SIZE
][4];
2995 if (textureUnit
->LodBias
!= 0.0F
) {
2996 /* apply LOD bias, but don't clamp yet */
2999 lambda
[i
] += textureUnit
->LodBias
;
3003 if ((textureUnit
->_Current
->MinLod
!= -1000.0
3004 || textureUnit
->_Current
->MaxLod
!= 1000.0)
3006 /* apply LOD clamping to lambda */
3007 const GLfloat min
= textureUnit
->_Current
->MinLod
;
3008 const GLfloat max
= textureUnit
->_Current
->MaxLod
;
3011 GLfloat l
= lambda
[i
];
3012 lambda
[i
] = CLAMP(l
, min
, max
);
3016 /* Sample the texture. */
3017 if (textureUnit
->_Current
->CompareFlag
) {
3019 sample_depth_texture(ctx
, textureUnit
, n
, s
, t
, r
, texel
);
3023 SWRAST_CONTEXT(ctx
)->TextureSample
[texUnit
]( ctx
, texUnit
,
3024 textureUnit
->_Current
,
3028 apply_texture( ctx
, textureUnit
, n
, primary_rgba
,
3029 (const GLchan (*)[4]) texel
, rgba
);