1 /* $Id: s_texture.c,v 1.8 2001/01/06 22:46:13 gareth Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 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.
36 #include "s_context.h"
38 #include "s_texture.h"
44 * Paletted texture sampling.
45 * Input: tObj - the texture object
46 * index - the palette index (8-bit only)
47 * Output: red, green, blue, alpha - the texel color
50 palette_sample(const struct gl_texture_object
*tObj
,
51 GLint index
, GLchan rgba
[4] )
53 GLcontext
*ctx
= _mesa_get_current_context(); /* THIS IS A HACK */
54 const GLchan
*palette
;
57 if (ctx
->Texture
.SharedPalette
) {
58 ASSERT(!ctx
->Texture
.Palette
.FloatTable
);
59 palette
= (const GLchan
*) ctx
->Texture
.Palette
.Table
;
60 format
= ctx
->Texture
.Palette
.Format
;
63 ASSERT(!tObj
->Palette
.FloatTable
);
64 palette
= (const GLchan
*) tObj
->Palette
.Table
;
65 format
= tObj
->Palette
.Format
;
70 rgba
[ACOMP
] = palette
[index
];
74 rgba
[RCOMP
] = palette
[index
];
76 case GL_LUMINANCE_ALPHA
:
77 rgba
[RCOMP
] = palette
[(index
<< 1) + 0];
78 rgba
[ACOMP
] = palette
[(index
<< 1) + 1];
81 rgba
[RCOMP
] = palette
[index
* 3 + 0];
82 rgba
[GCOMP
] = palette
[index
* 3 + 1];
83 rgba
[BCOMP
] = palette
[index
* 3 + 2];
86 rgba
[RCOMP
] = palette
[(index
<< 2) + 0];
87 rgba
[GCOMP
] = palette
[(index
<< 2) + 1];
88 rgba
[BCOMP
] = palette
[(index
<< 2) + 2];
89 rgba
[ACOMP
] = palette
[(index
<< 2) + 3];
92 gl_problem(NULL
, "Bad palette format in palette_sample");
99 * These values are used in the fixed-point arithmetic used
100 * for linear filtering.
102 #define WEIGHT_SCALE 65536.0F
103 #define WEIGHT_SHIFT 16
107 * Used to compute texel locations for linear sampling.
109 #define COMPUTE_LINEAR_TEXEL_LOCATIONS(wrapMode, S, U, SIZE, I0, I1) \
111 if (wrapMode == GL_REPEAT) { \
112 U = S * SIZE - 0.5F; \
113 I0 = IFLOOR(U) & (SIZE - 1); \
114 I1 = (I0 + 1) & (SIZE - 1); \
120 else if (U >= SIZE) \
125 if (wrapMode == GL_CLAMP_TO_EDGE) { \
136 * Used to compute texel location for nearest sampling.
138 #define COMPUTE_NEAREST_TEXEL_LOCATION(wrapMode, S, SIZE, I) \
140 if (wrapMode == GL_REPEAT) { \
141 /* s limited to [0,1) */ \
142 /* i limited to [0,width-1] */ \
143 I = (GLint) (S * SIZE); \
148 else if (wrapMode == GL_CLAMP_TO_EDGE) { \
149 const GLfloat min = 1.0F / (2.0F * SIZE); \
150 const GLfloat max = 1.0F - min; \
156 I = (GLint) (S * SIZE); \
159 ASSERT(wrapMode == GL_CLAMP); \
160 /* s limited to [0,1] */ \
161 /* i limited to [0,width-1] */ \
164 else if (S >= 1.0F) \
167 I = (GLint) (S * SIZE); \
173 * Compute linear mipmap levels for given lambda.
175 #define COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level) \
179 else if (lambda > tObj->_MaxLambda) \
180 lambda = tObj->_MaxLambda; \
181 level = (GLint) (tObj->BaseLevel + lambda); \
186 * Compute nearest mipmap level for given lambda.
188 #define COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level) \
190 if (lambda <= 0.5F) \
192 else if (lambda > tObj->_MaxLambda + 0.4999F) \
193 lambda = tObj->_MaxLambda + 0.4999F; \
194 level = (GLint) (tObj->BaseLevel + lambda + 0.5F); \
195 if (level > tObj->_MaxLevel) \
196 level = tObj->_MaxLevel; \
203 * Bitflags for texture border color sampling.
214 /**********************************************************************/
215 /* 1-D Texture Sampling Functions */
216 /**********************************************************************/
220 * Given 1-D texture image and an (i) texel column coordinate, return the
224 get_1d_texel( const struct gl_texture_object
*tObj
,
225 const struct gl_texture_image
*img
, GLint i
,
231 GLint width
= img
->Width
;
236 switch (img
->Format
) {
239 GLint index
= img
->Data
[i
];
240 palette_sample(tObj
, index
, rgba
);
244 rgba
[ACOMP
] = img
->Data
[ i
];
248 rgba
[RCOMP
] = img
->Data
[ i
];
250 case GL_LUMINANCE_ALPHA
:
251 texel
= img
->Data
+ i
* 2;
252 rgba
[RCOMP
] = texel
[0];
253 rgba
[ACOMP
] = texel
[1];
256 texel
= img
->Data
+ i
* 3;
257 rgba
[RCOMP
] = texel
[0];
258 rgba
[GCOMP
] = texel
[1];
259 rgba
[BCOMP
] = texel
[2];
262 texel
= img
->Data
+ i
* 4;
263 rgba
[RCOMP
] = texel
[0];
264 rgba
[GCOMP
] = texel
[1];
265 rgba
[BCOMP
] = texel
[2];
266 rgba
[ACOMP
] = texel
[3];
269 gl_problem(NULL
, "Bad format in get_1d_texel");
277 * Return the texture sample for coordinate (s) using GL_NEAREST filter.
280 sample_1d_nearest( const struct gl_texture_object
*tObj
,
281 const struct gl_texture_image
*img
,
282 GLfloat s
, GLchan rgba
[4] )
284 const GLint width
= img
->Width2
; /* without border, power of two */
288 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapS
, s
, width
, i
);
290 /* skip over the border, if any */
294 switch (img
->Format
) {
297 GLint index
= img
->Data
[i
];
298 palette_sample(tObj
, index
, rgba
);
302 rgba
[ACOMP
] = img
->Data
[i
];
306 rgba
[RCOMP
] = img
->Data
[i
];
308 case GL_LUMINANCE_ALPHA
:
309 texel
= img
->Data
+ i
* 2;
310 rgba
[RCOMP
] = texel
[0];
311 rgba
[ACOMP
] = texel
[1];
314 texel
= img
->Data
+ i
* 3;
315 rgba
[RCOMP
] = texel
[0];
316 rgba
[GCOMP
] = texel
[1];
317 rgba
[BCOMP
] = texel
[2];
320 texel
= img
->Data
+ i
* 4;
321 rgba
[RCOMP
] = texel
[0];
322 rgba
[GCOMP
] = texel
[1];
323 rgba
[BCOMP
] = texel
[2];
324 rgba
[ACOMP
] = texel
[3];
327 gl_problem(NULL
, "Bad format in sample_1d_nearest");
334 * Return the texture sample for coordinate (s) using GL_LINEAR filter.
337 sample_1d_linear( const struct gl_texture_object
*tObj
,
338 const struct gl_texture_image
*img
,
339 GLfloat s
, GLchan rgba
[4] )
341 const GLint width
= img
->Width2
;
344 GLuint useBorderColor
;
346 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapS
, s
, u
, width
, i0
, i1
);
354 if (i0
< 0 || i0
>= width
) useBorderColor
|= I0BIT
;
355 if (i1
< 0 || i1
>= width
) useBorderColor
|= I1BIT
;
359 const GLfloat a
= FRAC(u
);
360 /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
361 const GLint w0
= (GLint
) ((1.0F
-a
) * WEIGHT_SCALE
+ 0.5F
);
362 const GLint w1
= (GLint
) ( a
* WEIGHT_SCALE
+ 0.5F
);
364 GLchan t0
[4], t1
[4]; /* texels */
366 if (useBorderColor
& I0BIT
) {
367 COPY_CHAN4(t0
, tObj
->BorderColor
);
370 get_1d_texel( tObj
, img
, i0
, t0
);
372 if (useBorderColor
& I1BIT
) {
373 COPY_CHAN4(t1
, tObj
->BorderColor
);
376 get_1d_texel( tObj
, img
, i1
, t1
);
379 rgba
[0] = (GLchan
) ((w0
* t0
[0] + w1
* t1
[0]) >> WEIGHT_SHIFT
);
380 rgba
[1] = (GLchan
) ((w0
* t0
[1] + w1
* t1
[1]) >> WEIGHT_SHIFT
);
381 rgba
[2] = (GLchan
) ((w0
* t0
[2] + w1
* t1
[2]) >> WEIGHT_SHIFT
);
382 rgba
[3] = (GLchan
) ((w0
* t0
[3] + w1
* t1
[3]) >> WEIGHT_SHIFT
);
388 sample_1d_nearest_mipmap_nearest( const struct gl_texture_object
*tObj
,
389 GLfloat s
, GLfloat lambda
,
393 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
394 sample_1d_nearest( tObj
, tObj
->Image
[level
], s
, rgba
);
399 sample_1d_linear_mipmap_nearest( const struct gl_texture_object
*tObj
,
400 GLfloat s
, GLfloat lambda
,
404 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
405 sample_1d_linear( tObj
, tObj
->Image
[level
], s
, rgba
);
411 sample_1d_nearest_mipmap_linear( const struct gl_texture_object
*tObj
,
412 GLfloat s
, GLfloat lambda
,
417 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
419 if (level
>= tObj
->_MaxLevel
) {
420 sample_1d_nearest( tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, rgba
);
424 const GLfloat f
= FRAC(lambda
);
425 sample_1d_nearest( tObj
, tObj
->Image
[level
], s
, t0
);
426 sample_1d_nearest( tObj
, tObj
->Image
[level
+1], s
, t1
);
427 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
428 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
429 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
430 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
437 sample_1d_linear_mipmap_linear( const struct gl_texture_object
*tObj
,
438 GLfloat s
, GLfloat lambda
,
443 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
445 if (level
>= tObj
->_MaxLevel
) {
446 sample_1d_linear( tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, rgba
);
450 const GLfloat f
= FRAC(lambda
);
451 sample_1d_linear( tObj
, tObj
->Image
[level
], s
, t0
);
452 sample_1d_linear( tObj
, tObj
->Image
[level
+1], s
, t1
);
453 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
454 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
455 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
456 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
463 sample_nearest_1d( GLcontext
*ctx
, GLuint texUnit
,
464 const struct gl_texture_object
*tObj
, GLuint n
,
465 const GLfloat s
[], const GLfloat t
[],
466 const GLfloat u
[], const GLfloat lambda
[],
470 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
475 sample_1d_nearest( tObj
, image
, s
[i
], rgba
[i
] );
482 sample_linear_1d( GLcontext
*ctx
, GLuint texUnit
,
483 const struct gl_texture_object
*tObj
, GLuint n
,
484 const GLfloat s
[], const GLfloat t
[],
485 const GLfloat u
[], const GLfloat lambda
[],
489 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
494 sample_1d_linear( tObj
, image
, s
[i
], rgba
[i
] );
500 * Given an (s) texture coordinate and lambda (level of detail) value,
501 * return a texture sample.
505 sample_lambda_1d( GLcontext
*ctx
, GLuint texUnit
,
506 const struct gl_texture_object
*tObj
, GLuint n
,
507 const GLfloat s
[], const GLfloat t
[],
508 const GLfloat u
[], const GLfloat lambda
[],
511 GLfloat MinMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
518 if (lambda
[i
] > MinMagThresh
) {
520 switch (tObj
->MinFilter
) {
522 sample_1d_nearest( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], rgba
[i
] );
525 sample_1d_linear( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], rgba
[i
] );
527 case GL_NEAREST_MIPMAP_NEAREST
:
528 sample_1d_nearest_mipmap_nearest( tObj
, lambda
[i
], s
[i
], rgba
[i
] );
530 case GL_LINEAR_MIPMAP_NEAREST
:
531 sample_1d_linear_mipmap_nearest( tObj
, s
[i
], lambda
[i
], rgba
[i
] );
533 case GL_NEAREST_MIPMAP_LINEAR
:
534 sample_1d_nearest_mipmap_linear( tObj
, s
[i
], lambda
[i
], rgba
[i
] );
536 case GL_LINEAR_MIPMAP_LINEAR
:
537 sample_1d_linear_mipmap_linear( tObj
, s
[i
], lambda
[i
], rgba
[i
] );
540 gl_problem(NULL
, "Bad min filter in sample_1d_texture");
546 switch (tObj
->MagFilter
) {
548 sample_1d_nearest( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], rgba
[i
] );
551 sample_1d_linear( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], rgba
[i
] );
554 gl_problem(NULL
, "Bad mag filter in sample_1d_texture");
564 /**********************************************************************/
565 /* 2-D Texture Sampling Functions */
566 /**********************************************************************/
570 * Given a texture image and an (i,j) integer texel coordinate, return the
574 get_2d_texel( const struct gl_texture_object
*tObj
,
575 const struct gl_texture_image
*img
, GLint i
, GLint j
,
578 const GLint width
= img
->Width
; /* includes border */
582 const GLint height
= img
->Height
; /* includes border */
589 switch (img
->Format
) {
592 GLint index
= img
->Data
[ width
*j
+ i
];
593 palette_sample(tObj
, index
, rgba
);
597 rgba
[ACOMP
] = img
->Data
[ width
* j
+ i
];
601 rgba
[RCOMP
] = img
->Data
[ width
* j
+ i
];
603 case GL_LUMINANCE_ALPHA
:
604 texel
= img
->Data
+ (width
* j
+ i
) * 2;
605 rgba
[RCOMP
] = texel
[0];
606 rgba
[ACOMP
] = texel
[1];
609 texel
= img
->Data
+ (width
* j
+ i
) * 3;
610 rgba
[RCOMP
] = texel
[0];
611 rgba
[GCOMP
] = texel
[1];
612 rgba
[BCOMP
] = texel
[2];
615 texel
= img
->Data
+ (width
* j
+ i
) * 4;
616 rgba
[RCOMP
] = texel
[0];
617 rgba
[GCOMP
] = texel
[1];
618 rgba
[BCOMP
] = texel
[2];
619 rgba
[ACOMP
] = texel
[3];
622 gl_problem(NULL
, "Bad format in get_2d_texel");
629 * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
632 sample_2d_nearest( const struct gl_texture_object
*tObj
,
633 const struct gl_texture_image
*img
,
634 GLfloat s
, GLfloat t
,
637 const GLint imgWidth
= img
->Width
; /* includes border */
638 const GLint width
= img
->Width2
; /* without border, power of two */
639 const GLint height
= img
->Height2
; /* without border, power of two */
643 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapS
, s
, width
, i
);
644 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapT
, t
, height
, j
);
646 /* skip over the border, if any */
650 switch (img
->Format
) {
653 GLint index
= img
->Data
[ j
* imgWidth
+ i
];
654 palette_sample(tObj
, index
, rgba
);
658 rgba
[ACOMP
] = img
->Data
[ j
* imgWidth
+ i
];
662 rgba
[RCOMP
] = img
->Data
[ j
* imgWidth
+ i
];
664 case GL_LUMINANCE_ALPHA
:
665 texel
= img
->Data
+ ((j
* imgWidth
+ i
) << 1);
666 rgba
[RCOMP
] = texel
[0];
667 rgba
[ACOMP
] = texel
[1];
670 texel
= img
->Data
+ (j
* imgWidth
+ i
) * 3;
671 rgba
[RCOMP
] = texel
[0];
672 rgba
[GCOMP
] = texel
[1];
673 rgba
[BCOMP
] = texel
[2];
676 texel
= img
->Data
+ ((j
* imgWidth
+ i
) << 2);
677 rgba
[RCOMP
] = texel
[0];
678 rgba
[GCOMP
] = texel
[1];
679 rgba
[BCOMP
] = texel
[2];
680 rgba
[ACOMP
] = texel
[3];
683 gl_problem(NULL
, "Bad format in sample_2d_nearest");
690 * Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
691 * New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
694 sample_2d_linear( const struct gl_texture_object
*tObj
,
695 const struct gl_texture_image
*img
,
696 GLfloat s
, GLfloat t
,
699 const GLint width
= img
->Width2
;
700 const GLint height
= img
->Height2
;
701 GLint i0
, j0
, i1
, j1
;
702 GLuint useBorderColor
;
705 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapS
, s
, u
, width
, i0
, i1
);
706 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapT
, t
, v
, height
, j0
, j1
);
716 if (i0
< 0 || i0
>= width
) useBorderColor
|= I0BIT
;
717 if (i1
< 0 || i1
>= width
) useBorderColor
|= I1BIT
;
718 if (j0
< 0 || j0
>= height
) useBorderColor
|= J0BIT
;
719 if (j1
< 0 || j1
>= height
) useBorderColor
|= J1BIT
;
723 const GLfloat a
= FRAC(u
);
724 const GLfloat b
= FRAC(v
);
725 /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
726 const GLint w00
= (GLint
) ((1.0F
-a
)*(1.0F
-b
) * WEIGHT_SCALE
+ 0.5F
);
727 const GLint w10
= (GLint
) ( a
*(1.0F
-b
) * WEIGHT_SCALE
+ 0.5F
);
728 const GLint w01
= (GLint
) ((1.0F
-a
)* b
* WEIGHT_SCALE
+ 0.5F
);
729 const GLint w11
= (GLint
) ( a
* b
* WEIGHT_SCALE
+ 0.5F
);
735 if (useBorderColor
& (I0BIT
| J0BIT
)) {
736 COPY_CHAN4(t00
, tObj
->BorderColor
);
739 get_2d_texel( tObj
, img
, i0
, j0
, t00
);
741 if (useBorderColor
& (I1BIT
| J0BIT
)) {
742 COPY_CHAN4(t10
, tObj
->BorderColor
);
745 get_2d_texel( tObj
, img
, i1
, j0
, t10
);
747 if (useBorderColor
& (I0BIT
| J1BIT
)) {
748 COPY_CHAN4(t01
, tObj
->BorderColor
);
751 get_2d_texel( tObj
, img
, i0
, j1
, t01
);
753 if (useBorderColor
& (I1BIT
| J1BIT
)) {
754 COPY_CHAN4(t11
, tObj
->BorderColor
);
757 get_2d_texel( tObj
, img
, i1
, j1
, t11
);
760 rgba
[0] = (GLchan
) ((w00
* t00
[0] + w10
* t10
[0] + w01
* t01
[0] + w11
* t11
[0]) >> WEIGHT_SHIFT
);
761 rgba
[1] = (GLchan
) ((w00
* t00
[1] + w10
* t10
[1] + w01
* t01
[1] + w11
* t11
[1]) >> WEIGHT_SHIFT
);
762 rgba
[2] = (GLchan
) ((w00
* t00
[2] + w10
* t10
[2] + w01
* t01
[2] + w11
* t11
[2]) >> WEIGHT_SHIFT
);
763 rgba
[3] = (GLchan
) ((w00
* t00
[3] + w10
* t10
[3] + w01
* t01
[3] + w11
* t11
[3]) >> WEIGHT_SHIFT
);
771 sample_2d_nearest_mipmap_nearest( const struct gl_texture_object
*tObj
,
772 GLfloat s
, GLfloat t
, GLfloat lambda
,
776 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
777 sample_2d_nearest( tObj
, tObj
->Image
[level
], s
, t
, rgba
);
783 sample_2d_linear_mipmap_nearest( const struct gl_texture_object
*tObj
,
784 GLfloat s
, GLfloat t
, GLfloat lambda
,
788 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
789 sample_2d_linear( tObj
, tObj
->Image
[level
], s
, t
, rgba
);
795 sample_2d_nearest_mipmap_linear( 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( 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( tObj
, tObj
->Image
[level
], s
, t
, t0
);
810 sample_2d_nearest( tObj
, tObj
->Image
[level
+1], s
, t
, t1
);
811 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
812 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
813 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
814 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
821 sample_2d_linear_mipmap_linear( const struct gl_texture_object
*tObj
,
822 GLfloat s
, GLfloat t
, GLfloat lambda
,
827 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
829 if (level
>= tObj
->_MaxLevel
) {
830 sample_2d_linear( tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, t
, rgba
);
833 GLchan t0
[4], t1
[4]; /* texels */
834 const GLfloat f
= FRAC(lambda
);
835 sample_2d_linear( tObj
, tObj
->Image
[level
], s
, t
, t0
);
836 sample_2d_linear( tObj
, tObj
->Image
[level
+1], s
, t
, t1
);
837 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
838 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
839 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
840 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
847 sample_nearest_2d( GLcontext
*ctx
, GLuint texUnit
,
848 const struct gl_texture_object
*tObj
, GLuint n
,
849 const GLfloat s
[], const GLfloat t
[],
850 const GLfloat u
[], const GLfloat lambda
[],
854 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
858 sample_2d_nearest( tObj
, image
, s
[i
], t
[i
], rgba
[i
] );
865 sample_linear_2d( GLcontext
*ctx
, GLuint texUnit
,
866 const struct gl_texture_object
*tObj
, GLuint n
,
867 const GLfloat s
[], const GLfloat t
[],
868 const GLfloat u
[], const GLfloat lambda
[],
872 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
876 sample_2d_linear( tObj
, image
, s
[i
], t
[i
], rgba
[i
] );
882 * Given an (s,t) texture coordinate and lambda (level of detail) value,
883 * return a texture sample.
886 sample_lambda_2d( GLcontext
*ctx
, GLuint texUnit
,
887 const struct gl_texture_object
*tObj
,
889 const GLfloat s
[], const GLfloat t
[],
890 const GLfloat u
[], const GLfloat lambda
[],
893 GLfloat MinMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
897 if (lambda
[i
] > MinMagThresh
) {
899 switch (tObj
->MinFilter
) {
901 sample_2d_nearest( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], t
[i
], rgba
[i
] );
904 sample_2d_linear( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], t
[i
], rgba
[i
] );
906 case GL_NEAREST_MIPMAP_NEAREST
:
907 sample_2d_nearest_mipmap_nearest( tObj
, s
[i
], t
[i
], lambda
[i
], rgba
[i
] );
909 case GL_LINEAR_MIPMAP_NEAREST
:
910 sample_2d_linear_mipmap_nearest( tObj
, s
[i
], t
[i
], lambda
[i
], rgba
[i
] );
912 case GL_NEAREST_MIPMAP_LINEAR
:
913 sample_2d_nearest_mipmap_linear( tObj
, s
[i
], t
[i
], lambda
[i
], rgba
[i
] );
915 case GL_LINEAR_MIPMAP_LINEAR
:
916 sample_2d_linear_mipmap_linear( tObj
, s
[i
], t
[i
], lambda
[i
], rgba
[i
] );
919 gl_problem(NULL
, "Bad min filter in sample_2d_texture");
925 switch (tObj
->MagFilter
) {
927 sample_2d_nearest( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], t
[i
], rgba
[i
] );
930 sample_2d_linear( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], t
[i
], rgba
[i
] );
933 gl_problem(NULL
, "Bad mag filter in sample_2d_texture");
941 * Optimized 2-D texture sampling:
942 * S and T wrap mode == GL_REPEAT
943 * GL_NEAREST min/mag filter
948 opt_sample_rgb_2d( GLcontext
*ctx
, GLuint texUnit
,
949 const struct gl_texture_object
*tObj
,
950 GLuint n
, const GLfloat s
[], const GLfloat t
[],
951 const GLfloat u
[], const GLfloat lambda
[],
954 const struct gl_texture_image
*img
= tObj
->Image
[tObj
->BaseLevel
];
955 const GLfloat width
= (GLfloat
) img
->Width
;
956 const GLfloat height
= (GLfloat
) img
->Height
;
957 const GLint colMask
= img
->Width
- 1;
958 const GLint rowMask
= img
->Height
- 1;
959 const GLint shift
= img
->WidthLog2
;
963 ASSERT(tObj
->WrapS
==GL_REPEAT
);
964 ASSERT(tObj
->WrapT
==GL_REPEAT
);
965 ASSERT(tObj
->MinFilter
==GL_NEAREST
);
966 ASSERT(tObj
->MagFilter
==GL_NEAREST
);
967 ASSERT(img
->Border
==0);
968 ASSERT(img
->Format
==GL_RGB
);
970 /* NOTE: negative float->int doesn't floor, add 10000 as to work-around */
972 GLint i
= (GLint
) ((s
[k
] + 10000.0) * width
) & colMask
;
973 GLint j
= (GLint
) ((t
[k
] + 10000.0) * height
) & rowMask
;
974 GLint pos
= (j
<< shift
) | i
;
975 GLchan
*texel
= img
->Data
+ pos
+ pos
+ pos
; /* pos*3 */
976 rgba
[k
][RCOMP
] = texel
[0];
977 rgba
[k
][GCOMP
] = texel
[1];
978 rgba
[k
][BCOMP
] = texel
[2];
984 * Optimized 2-D texture sampling:
985 * S and T wrap mode == GL_REPEAT
986 * GL_NEAREST min/mag filter
991 opt_sample_rgba_2d( GLcontext
*ctx
, GLuint texUnit
,
992 const struct gl_texture_object
*tObj
,
993 GLuint n
, const GLfloat s
[], const GLfloat t
[],
994 const GLfloat u
[], const GLfloat lambda
[],
997 const struct gl_texture_image
*img
= tObj
->Image
[tObj
->BaseLevel
];
998 const GLfloat width
= (GLfloat
) img
->Width
;
999 const GLfloat height
= (GLfloat
) img
->Height
;
1000 const GLint colMask
= img
->Width
- 1;
1001 const GLint rowMask
= img
->Height
- 1;
1002 const GLint shift
= img
->WidthLog2
;
1006 ASSERT(tObj
->WrapS
==GL_REPEAT
);
1007 ASSERT(tObj
->WrapT
==GL_REPEAT
);
1008 ASSERT(tObj
->MinFilter
==GL_NEAREST
);
1009 ASSERT(tObj
->MagFilter
==GL_NEAREST
);
1010 ASSERT(img
->Border
==0);
1011 ASSERT(img
->Format
==GL_RGBA
);
1013 /* NOTE: negative float->int doesn't floor, add 10000 as to work-around */
1015 GLint i
= (GLint
) ((s
[k
] + 10000.0) * width
) & colMask
;
1016 GLint j
= (GLint
) ((t
[k
] + 10000.0) * height
) & rowMask
;
1017 GLint pos
= (j
<< shift
) | i
;
1018 GLchan
*texel
= img
->Data
+ (pos
<< 2); /* pos*4 */
1019 rgba
[k
][RCOMP
] = texel
[0];
1020 rgba
[k
][GCOMP
] = texel
[1];
1021 rgba
[k
][BCOMP
] = texel
[2];
1022 rgba
[k
][ACOMP
] = texel
[3];
1028 /**********************************************************************/
1029 /* 3-D Texture Sampling Functions */
1030 /**********************************************************************/
1033 * Given a texture image and an (i,j,k) integer texel coordinate, return the
1037 get_3d_texel( const struct gl_texture_object
*tObj
,
1038 const struct gl_texture_image
*img
,
1039 GLint i
, GLint j
, GLint k
,
1042 const GLint width
= img
->Width
; /* includes border */
1043 const GLint height
= img
->Height
; /* includes border */
1044 const GLint rectarea
= width
* height
;
1045 const GLchan
*texel
;
1048 const GLint depth
= img
->Depth
; /* includes border */
1057 switch (img
->Format
) {
1058 case GL_COLOR_INDEX
:
1060 GLint index
= img
->Data
[ rectarea
* k
+ width
* j
+ i
];
1061 palette_sample(tObj
, index
, rgba
);
1065 rgba
[ACOMP
] = img
->Data
[ rectarea
* k
+ width
* j
+ i
];
1069 rgba
[RCOMP
] = img
->Data
[ rectarea
* k
+ width
* j
+ i
];
1071 case GL_LUMINANCE_ALPHA
:
1072 texel
= img
->Data
+ ( rectarea
* k
+ width
* j
+ i
) * 2;
1073 rgba
[RCOMP
] = texel
[0];
1074 rgba
[ACOMP
] = texel
[1];
1077 texel
= img
->Data
+ (rectarea
* k
+ width
* j
+ i
) * 3;
1078 rgba
[RCOMP
] = texel
[0];
1079 rgba
[GCOMP
] = texel
[1];
1080 rgba
[BCOMP
] = texel
[2];
1083 texel
= img
->Data
+ (rectarea
* k
+ width
* j
+ i
) * 4;
1084 rgba
[RCOMP
] = texel
[0];
1085 rgba
[GCOMP
] = texel
[1];
1086 rgba
[BCOMP
] = texel
[2];
1087 rgba
[ACOMP
] = texel
[3];
1090 gl_problem(NULL
, "Bad format in get_3d_texel");
1096 * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
1099 sample_3d_nearest( const struct gl_texture_object
*tObj
,
1100 const struct gl_texture_image
*img
,
1101 GLfloat s
, GLfloat t
, GLfloat r
,
1104 const GLint imgWidth
= img
->Width
; /* includes border, if any */
1105 const GLint imgHeight
= img
->Height
; /* includes border, if any */
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 */
1109 const GLint rectarea
= imgWidth
* imgHeight
;
1110 const GLchan
*texel
;
1113 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapS
, s
, width
, i
);
1114 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapT
, t
, height
, j
);
1115 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapR
, r
, depth
, k
);
1117 switch (tObj
->Image
[0]->Format
) {
1118 case GL_COLOR_INDEX
:
1120 GLint index
= img
->Data
[ rectarea
* k
+ j
* imgWidth
+ i
];
1121 palette_sample(tObj
, index
, rgba
);
1125 rgba
[ACOMP
] = img
->Data
[ rectarea
* k
+ j
* imgWidth
+ i
];
1129 rgba
[RCOMP
] = img
->Data
[ rectarea
* k
+ j
* imgWidth
+ i
];
1131 case GL_LUMINANCE_ALPHA
:
1132 texel
= img
->Data
+ ((rectarea
* k
+ j
* imgWidth
+ i
) << 1);
1133 rgba
[RCOMP
] = texel
[0];
1134 rgba
[ACOMP
] = texel
[1];
1137 texel
= img
->Data
+ ( rectarea
* k
+ j
* imgWidth
+ i
) * 3;
1138 rgba
[RCOMP
] = texel
[0];
1139 rgba
[GCOMP
] = texel
[1];
1140 rgba
[BCOMP
] = texel
[2];
1143 texel
= img
->Data
+ ((rectarea
* k
+ j
* imgWidth
+ i
) << 2);
1144 rgba
[RCOMP
] = texel
[0];
1145 rgba
[GCOMP
] = texel
[1];
1146 rgba
[BCOMP
] = texel
[2];
1147 rgba
[ACOMP
] = texel
[3];
1150 gl_problem(NULL
, "Bad format in sample_3d_nearest");
1157 * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
1160 sample_3d_linear( const struct gl_texture_object
*tObj
,
1161 const struct gl_texture_image
*img
,
1162 GLfloat s
, GLfloat t
, GLfloat r
,
1165 const GLint width
= img
->Width2
;
1166 const GLint height
= img
->Height2
;
1167 const GLint depth
= img
->Depth2
;
1168 GLint i0
, j0
, k0
, i1
, j1
, k1
;
1169 GLuint useBorderColor
;
1172 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapS
, s
, u
, width
, i0
, i1
);
1173 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapT
, t
, v
, height
, j0
, j1
);
1174 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapR
, r
, w
, depth
, k0
, k1
);
1186 /* check if sampling texture border color */
1187 if (i0
< 0 || i0
>= width
) useBorderColor
|= I0BIT
;
1188 if (i1
< 0 || i1
>= width
) useBorderColor
|= I1BIT
;
1189 if (j0
< 0 || j0
>= height
) useBorderColor
|= J0BIT
;
1190 if (j1
< 0 || j1
>= height
) useBorderColor
|= J1BIT
;
1191 if (k0
< 0 || k0
>= depth
) useBorderColor
|= K0BIT
;
1192 if (k1
< 0 || k1
>= depth
) useBorderColor
|= K1BIT
;
1196 const GLfloat a
= FRAC(u
);
1197 const GLfloat b
= FRAC(v
);
1198 const GLfloat c
= FRAC(w
);
1199 /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
1200 GLint w000
= (GLint
) ((1.0F
-a
)*(1.0F
-b
)*(1.0F
-c
) * WEIGHT_SCALE
+ 0.5F
);
1201 GLint w100
= (GLint
) ( a
*(1.0F
-b
)*(1.0F
-c
) * WEIGHT_SCALE
+ 0.5F
);
1202 GLint w010
= (GLint
) ((1.0F
-a
)* b
*(1.0F
-c
) * WEIGHT_SCALE
+ 0.5F
);
1203 GLint w110
= (GLint
) ( a
* b
*(1.0F
-c
) * WEIGHT_SCALE
+ 0.5F
);
1204 GLint w001
= (GLint
) ((1.0F
-a
)*(1.0F
-b
)* c
* WEIGHT_SCALE
+ 0.5F
);
1205 GLint w101
= (GLint
) ( a
*(1.0F
-b
)* c
* WEIGHT_SCALE
+ 0.5F
);
1206 GLint w011
= (GLint
) ((1.0F
-a
)* b
* c
* WEIGHT_SCALE
+ 0.5F
);
1207 GLint w111
= (GLint
) ( a
* b
* c
* WEIGHT_SCALE
+ 0.5F
);
1209 GLchan t000
[4], t010
[4], t001
[4], t011
[4];
1210 GLchan t100
[4], t110
[4], t101
[4], t111
[4];
1212 if (useBorderColor
& (I0BIT
| J0BIT
| K0BIT
)) {
1213 COPY_CHAN4(t000
, tObj
->BorderColor
);
1216 get_3d_texel( tObj
, img
, i0
, j0
, k0
, t000
);
1218 if (useBorderColor
& (I1BIT
| J0BIT
| K0BIT
)) {
1219 COPY_CHAN4(t100
, tObj
->BorderColor
);
1222 get_3d_texel( tObj
, img
, i1
, j0
, k0
, t100
);
1224 if (useBorderColor
& (I0BIT
| J1BIT
| K0BIT
)) {
1225 COPY_CHAN4(t010
, tObj
->BorderColor
);
1228 get_3d_texel( tObj
, img
, i0
, j1
, k0
, t010
);
1230 if (useBorderColor
& (I1BIT
| J1BIT
| K0BIT
)) {
1231 COPY_CHAN4(t110
, tObj
->BorderColor
);
1234 get_3d_texel( tObj
, img
, i1
, j1
, k0
, t110
);
1237 if (useBorderColor
& (I0BIT
| J0BIT
| K1BIT
)) {
1238 COPY_CHAN4(t001
, tObj
->BorderColor
);
1241 get_3d_texel( tObj
, img
, i0
, j0
, k1
, t001
);
1243 if (useBorderColor
& (I1BIT
| J0BIT
| K1BIT
)) {
1244 COPY_CHAN4(t101
, tObj
->BorderColor
);
1247 get_3d_texel( tObj
, img
, i1
, j0
, k1
, t101
);
1249 if (useBorderColor
& (I0BIT
| J1BIT
| K1BIT
)) {
1250 COPY_CHAN4(t011
, tObj
->BorderColor
);
1253 get_3d_texel( tObj
, img
, i0
, j1
, k1
, t011
);
1255 if (useBorderColor
& (I1BIT
| J1BIT
| K1BIT
)) {
1256 COPY_CHAN4(t111
, tObj
->BorderColor
);
1259 get_3d_texel( tObj
, img
, i1
, j1
, k1
, t111
);
1262 rgba
[0] = (GLchan
) (
1263 (w000
*t000
[0] + w010
*t010
[0] + w001
*t001
[0] + w011
*t011
[0] +
1264 w100
*t100
[0] + w110
*t110
[0] + w101
*t101
[0] + w111
*t111
[0] )
1266 rgba
[1] = (GLchan
) (
1267 (w000
*t000
[1] + w010
*t010
[1] + w001
*t001
[1] + w011
*t011
[1] +
1268 w100
*t100
[1] + w110
*t110
[1] + w101
*t101
[1] + w111
*t111
[1] )
1270 rgba
[2] = (GLchan
) (
1271 (w000
*t000
[2] + w010
*t010
[2] + w001
*t001
[2] + w011
*t011
[2] +
1272 w100
*t100
[2] + w110
*t110
[2] + w101
*t101
[2] + w111
*t111
[2] )
1274 rgba
[3] = (GLchan
) (
1275 (w000
*t000
[3] + w010
*t010
[3] + w001
*t001
[3] + w011
*t011
[3] +
1276 w100
*t100
[3] + w110
*t110
[3] + w101
*t101
[3] + w111
*t111
[3] )
1284 sample_3d_nearest_mipmap_nearest( const struct gl_texture_object
*tObj
,
1285 GLfloat s
, GLfloat t
, GLfloat r
,
1286 GLfloat lambda
, GLchan rgba
[4] )
1289 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1290 sample_3d_nearest( tObj
, tObj
->Image
[level
], s
, t
, r
, rgba
);
1295 sample_3d_linear_mipmap_nearest( const struct gl_texture_object
*tObj
,
1296 GLfloat s
, GLfloat t
, GLfloat r
,
1297 GLfloat lambda
, GLchan rgba
[4] )
1300 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1301 sample_3d_linear( tObj
, tObj
->Image
[level
], s
, t
, r
, rgba
);
1306 sample_3d_nearest_mipmap_linear( const struct gl_texture_object
*tObj
,
1307 GLfloat s
, GLfloat t
, GLfloat r
,
1308 GLfloat lambda
, GLchan rgba
[4] )
1312 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1314 if (level
>= tObj
->_MaxLevel
) {
1315 sample_3d_nearest( tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, t
, r
, rgba
);
1318 GLchan t0
[4], t1
[4]; /* texels */
1319 const GLfloat f
= FRAC(lambda
);
1320 sample_3d_nearest( tObj
, tObj
->Image
[level
], s
, t
, r
, t0
);
1321 sample_3d_nearest( tObj
, tObj
->Image
[level
+1], s
, t
, r
, t1
);
1322 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1323 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1324 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1325 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1331 sample_3d_linear_mipmap_linear( const struct gl_texture_object
*tObj
,
1332 GLfloat s
, GLfloat t
, GLfloat r
,
1333 GLfloat lambda
, GLchan rgba
[4] )
1337 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1339 if (level
>= tObj
->_MaxLevel
) {
1340 sample_3d_linear( tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, t
, r
, rgba
);
1343 GLchan t0
[4], t1
[4]; /* texels */
1344 const GLfloat f
= FRAC(lambda
);
1345 sample_3d_linear( tObj
, tObj
->Image
[level
], s
, t
, r
, t0
);
1346 sample_3d_linear( tObj
, tObj
->Image
[level
+1], s
, t
, r
, t1
);
1347 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1348 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1349 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1350 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1356 sample_nearest_3d( GLcontext
*ctx
, GLuint texUnit
,
1357 const struct gl_texture_object
*tObj
, GLuint n
,
1358 const GLfloat s
[], const GLfloat t
[],
1359 const GLfloat u
[], const GLfloat lambda
[],
1363 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
1366 sample_3d_nearest( tObj
, image
, s
[i
], t
[i
], u
[i
], rgba
[i
] );
1373 sample_linear_3d( GLcontext
*ctx
, GLuint texUnit
,
1374 const struct gl_texture_object
*tObj
, GLuint n
,
1375 const GLfloat s
[], const GLfloat t
[],
1376 const GLfloat u
[], const GLfloat lambda
[],
1380 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
1383 sample_3d_linear( tObj
, image
, s
[i
], t
[i
], u
[i
], rgba
[i
] );
1389 * Given an (s,t,r) texture coordinate and lambda (level of detail) value,
1390 * return a texture sample.
1393 sample_lambda_3d( GLcontext
*ctx
, GLuint texUnit
,
1394 const struct gl_texture_object
*tObj
, GLuint n
,
1395 const GLfloat s
[], const GLfloat t
[],
1396 const GLfloat u
[], const GLfloat lambda
[],
1400 GLfloat MinMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
1404 if (lambda
[i
] > MinMagThresh
) {
1406 switch (tObj
->MinFilter
) {
1408 sample_3d_nearest( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], t
[i
], u
[i
], rgba
[i
] );
1411 sample_3d_linear( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], t
[i
], u
[i
], rgba
[i
] );
1413 case GL_NEAREST_MIPMAP_NEAREST
:
1414 sample_3d_nearest_mipmap_nearest( tObj
, s
[i
], t
[i
], u
[i
], lambda
[i
], rgba
[i
] );
1416 case GL_LINEAR_MIPMAP_NEAREST
:
1417 sample_3d_linear_mipmap_nearest( tObj
, s
[i
], t
[i
], u
[i
], lambda
[i
], rgba
[i
] );
1419 case GL_NEAREST_MIPMAP_LINEAR
:
1420 sample_3d_nearest_mipmap_linear( tObj
, s
[i
], t
[i
], u
[i
], lambda
[i
], rgba
[i
] );
1422 case GL_LINEAR_MIPMAP_LINEAR
:
1423 sample_3d_linear_mipmap_linear( tObj
, s
[i
], t
[i
], u
[i
], lambda
[i
], rgba
[i
] );
1426 gl_problem(NULL
, "Bad min filterin sample_3d_texture");
1431 switch (tObj
->MagFilter
) {
1433 sample_3d_nearest( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], t
[i
], u
[i
], rgba
[i
] );
1436 sample_3d_linear( tObj
, tObj
->Image
[tObj
->BaseLevel
], s
[i
], t
[i
], u
[i
], rgba
[i
] );
1439 gl_problem(NULL
, "Bad mag filter in sample_3d_texture");
1446 /**********************************************************************/
1447 /* Texture Cube Map Sampling Functions */
1448 /**********************************************************************/
1451 * Choose one of six sides of a texture cube map given the texture
1452 * coord (rx,ry,rz). Return pointer to corresponding array of texture
1455 static const struct gl_texture_image
**
1456 choose_cube_face(const struct gl_texture_object
*texObj
,
1457 GLfloat rx
, GLfloat ry
, GLfloat rz
,
1458 GLfloat
*newS
, GLfloat
*newT
)
1462 direction target sc tc ma
1463 ---------- ------------------------------- --- --- ---
1464 +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
1465 -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
1466 +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
1467 -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry
1468 +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
1469 -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
1471 const struct gl_texture_image
**imgArray
;
1472 const GLfloat arx
= ABSF(rx
), ary
= ABSF(ry
), arz
= ABSF(rz
);
1475 if (arx
> ary
&& arx
> arz
) {
1477 imgArray
= (const struct gl_texture_image
**) texObj
->Image
;
1483 imgArray
= (const struct gl_texture_image
**) texObj
->NegX
;
1489 else if (ary
> arx
&& ary
> arz
) {
1491 imgArray
= (const struct gl_texture_image
**) texObj
->PosY
;
1497 imgArray
= (const struct gl_texture_image
**) texObj
->NegY
;
1505 imgArray
= (const struct gl_texture_image
**) texObj
->PosZ
;
1511 imgArray
= (const struct gl_texture_image
**) texObj
->NegZ
;
1518 *newS
= ( sc
/ ma
+ 1.0F
) * 0.5F
;
1519 *newT
= ( tc
/ ma
+ 1.0F
) * 0.5F
;
1525 sample_nearest_cube(GLcontext
*ctx
, GLuint texUnit
,
1526 const struct gl_texture_object
*tObj
, GLuint n
,
1527 const GLfloat s
[], const GLfloat t
[],
1528 const GLfloat u
[], const GLfloat lambda
[],
1533 for (i
= 0; i
< n
; i
++) {
1534 const struct gl_texture_image
**images
;
1536 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
], &newS
, &newT
);
1537 sample_2d_nearest( tObj
, images
[tObj
->BaseLevel
], newS
, newT
, rgba
[i
] );
1543 sample_linear_cube(GLcontext
*ctx
, GLuint texUnit
,
1544 const struct gl_texture_object
*tObj
, GLuint n
,
1545 const GLfloat s
[], const GLfloat t
[],
1546 const GLfloat u
[], const GLfloat lambda
[],
1551 for (i
= 0; i
< n
; i
++) {
1552 const struct gl_texture_image
**images
;
1554 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
], &newS
, &newT
);
1555 sample_2d_linear( tObj
, images
[tObj
->BaseLevel
], newS
, newT
, rgba
[i
] );
1561 sample_cube_nearest_mipmap_nearest( const struct gl_texture_object
*tObj
,
1562 GLfloat s
, GLfloat t
, GLfloat u
,
1563 GLfloat lambda
, GLchan rgba
[4] )
1565 const struct gl_texture_image
**images
;
1569 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1571 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1572 sample_2d_nearest( tObj
, images
[level
], newS
, newT
, rgba
);
1577 sample_cube_linear_mipmap_nearest( const struct gl_texture_object
*tObj
,
1578 GLfloat s
, GLfloat t
, GLfloat u
,
1579 GLfloat lambda
, GLchan rgba
[4] )
1581 const struct gl_texture_image
**images
;
1585 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1587 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1588 sample_2d_linear( tObj
, images
[level
], newS
, newT
, rgba
);
1593 sample_cube_nearest_mipmap_linear( const struct gl_texture_object
*tObj
,
1594 GLfloat s
, GLfloat t
, GLfloat u
,
1595 GLfloat lambda
, GLchan rgba
[4] )
1597 const struct gl_texture_image
**images
;
1601 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1603 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1605 if (level
>= tObj
->_MaxLevel
) {
1606 sample_2d_nearest( tObj
, images
[tObj
->_MaxLevel
], newS
, newT
, rgba
);
1609 GLchan t0
[4], t1
[4]; /* texels */
1610 const GLfloat f
= FRAC(lambda
);
1611 sample_2d_nearest( tObj
, images
[level
], newS
, newT
, t0
);
1612 sample_2d_nearest( tObj
, images
[level
+1], newS
, newT
, t1
);
1613 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1614 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1615 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1616 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1622 sample_cube_linear_mipmap_linear( const struct gl_texture_object
*tObj
,
1623 GLfloat s
, GLfloat t
, GLfloat u
,
1624 GLfloat lambda
, GLchan rgba
[4] )
1626 const struct gl_texture_image
**images
;
1630 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1632 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1634 if (level
>= tObj
->_MaxLevel
) {
1635 sample_2d_linear( tObj
, images
[tObj
->_MaxLevel
], newS
, newT
, rgba
);
1638 GLchan t0
[4], t1
[4];
1639 const GLfloat f
= FRAC(lambda
);
1640 sample_2d_linear( tObj
, images
[level
], newS
, newT
, t0
);
1641 sample_2d_linear( tObj
, images
[level
+1], newS
, newT
, t1
);
1642 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1643 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1644 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1645 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1651 sample_lambda_cube( GLcontext
*ctx
, GLuint texUnit
,
1652 const struct gl_texture_object
*tObj
, GLuint n
,
1653 const GLfloat s
[], const GLfloat t
[],
1654 const GLfloat u
[], const GLfloat lambda
[],
1657 GLfloat MinMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
1660 for (i
= 0; i
< n
; i
++) {
1661 if (lambda
[i
] > MinMagThresh
) {
1663 switch (tObj
->MinFilter
) {
1666 const struct gl_texture_image
**images
;
1668 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
],
1670 sample_2d_nearest( tObj
, images
[tObj
->BaseLevel
],
1671 newS
, newT
, rgba
[i
] );
1676 const struct gl_texture_image
**images
;
1678 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
],
1680 sample_2d_linear( tObj
, images
[tObj
->BaseLevel
],
1681 newS
, newT
, rgba
[i
] );
1684 case GL_NEAREST_MIPMAP_NEAREST
:
1685 sample_cube_nearest_mipmap_nearest( tObj
, s
[i
], t
[i
], u
[i
],
1686 lambda
[i
], rgba
[i
] );
1688 case GL_LINEAR_MIPMAP_NEAREST
:
1689 sample_cube_linear_mipmap_nearest( tObj
, s
[i
], t
[i
], u
[i
],
1690 lambda
[i
], rgba
[i
] );
1692 case GL_NEAREST_MIPMAP_LINEAR
:
1693 sample_cube_nearest_mipmap_linear( tObj
, s
[i
], t
[i
], u
[i
],
1694 lambda
[i
], rgba
[i
] );
1696 case GL_LINEAR_MIPMAP_LINEAR
:
1697 sample_cube_linear_mipmap_linear( tObj
, s
[i
], t
[i
], u
[i
],
1698 lambda
[i
], rgba
[i
] );
1701 gl_problem(NULL
, "Bad min filter in sample_lambda_cube");
1706 const struct gl_texture_image
**images
;
1708 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
],
1710 switch (tObj
->MagFilter
) {
1712 sample_2d_nearest( tObj
, images
[tObj
->BaseLevel
],
1713 newS
, newT
, rgba
[i
] );
1716 sample_2d_linear( tObj
, images
[tObj
->BaseLevel
],
1717 newS
, newT
, rgba
[i
] );
1720 gl_problem(NULL
, "Bad mag filter in sample_lambda_cube");
1727 null_sample_func( GLcontext
*ctx
, GLuint texUnit
,
1728 const struct gl_texture_object
*tObj
, GLuint n
,
1729 const GLfloat s
[], const GLfloat t
[],
1730 const GLfloat u
[], const GLfloat lambda
[],
1735 /**********************************************************************/
1736 /* Texture Sampling Setup */
1737 /**********************************************************************/
1741 * Setup the texture sampling function for this texture object.
1744 _swrast_choose_texture_sample_func( GLcontext
*ctx
, GLuint texUnit
,
1745 const struct gl_texture_object
*t
)
1747 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1750 swrast
->TextureSample
[texUnit
] = null_sample_func
;
1753 GLboolean needLambda
= (GLboolean
) (t
->MinFilter
!= t
->MagFilter
);
1756 /* Compute min/mag filter threshold */
1757 if (t
->MagFilter
== GL_LINEAR
1758 && (t
->MinFilter
== GL_NEAREST_MIPMAP_NEAREST
||
1759 t
->MinFilter
== GL_NEAREST_MIPMAP_LINEAR
)) {
1760 swrast
->_MinMagThresh
[texUnit
] = 0.5F
;
1763 swrast
->_MinMagThresh
[texUnit
] = 0.0F
;
1767 switch (t
->Dimensions
) {
1770 swrast
->TextureSample
[texUnit
] = sample_lambda_1d
;
1772 else if (t
->MinFilter
==GL_LINEAR
) {
1773 swrast
->TextureSample
[texUnit
] = sample_linear_1d
;
1776 ASSERT(t
->MinFilter
==GL_NEAREST
);
1777 swrast
->TextureSample
[texUnit
] = sample_nearest_1d
;
1782 swrast
->TextureSample
[texUnit
] = sample_lambda_2d
;
1784 else if (t
->MinFilter
==GL_LINEAR
) {
1785 swrast
->TextureSample
[texUnit
] = sample_linear_2d
;
1788 ASSERT(t
->MinFilter
==GL_NEAREST
);
1789 if (t
->WrapS
==GL_REPEAT
&& t
->WrapT
==GL_REPEAT
1790 && t
->Image
[0]->Border
==0 && t
->Image
[0]->Format
==GL_RGB
) {
1791 swrast
->TextureSample
[texUnit
] = opt_sample_rgb_2d
;
1793 else if (t
->WrapS
==GL_REPEAT
&& t
->WrapT
==GL_REPEAT
1794 && t
->Image
[0]->Border
==0 && t
->Image
[0]->Format
==GL_RGBA
) {
1795 swrast
->TextureSample
[texUnit
] = opt_sample_rgba_2d
;
1798 swrast
->TextureSample
[texUnit
] = sample_nearest_2d
;
1803 swrast
->TextureSample
[texUnit
] = sample_lambda_3d
;
1805 else if (t
->MinFilter
==GL_LINEAR
) {
1806 swrast
->TextureSample
[texUnit
] = sample_linear_3d
;
1809 ASSERT(t
->MinFilter
==GL_NEAREST
);
1810 swrast
->TextureSample
[texUnit
] = sample_nearest_3d
;
1813 case 6: /* cube map */
1815 swrast
->TextureSample
[texUnit
] = sample_lambda_cube
;
1817 else if (t
->MinFilter
==GL_LINEAR
) {
1818 swrast
->TextureSample
[texUnit
] = sample_linear_cube
;
1821 ASSERT(t
->MinFilter
==GL_NEAREST
);
1822 swrast
->TextureSample
[texUnit
] = sample_nearest_cube
;
1826 gl_problem(NULL
, "invalid dimensions in _mesa_set_texture_sampler");
1832 #define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) )
1833 #define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) )
1836 _mesa_texture_combine(const GLcontext
*ctx
,
1837 const struct gl_texture_unit
*textureUnit
,
1839 GLchan (*primary_rgba
)[4],
1843 GLchan ccolor
[3][3*MAX_WIDTH
][4];
1844 GLchan (*argRGB
[3])[4];
1845 GLchan (*argA
[3])[4];
1847 const GLuint RGBshift
= textureUnit
->CombineScaleShiftRGB
;
1848 const GLuint Ashift
= textureUnit
->CombineScaleShiftA
;
1850 ASSERT(ctx
->Extensions
.EXT_texture_env_combine
);
1852 for (j
= 0; j
< 3; j
++) {
1853 switch (textureUnit
->CombineSourceA
[j
]) {
1857 case GL_PRIMARY_COLOR_EXT
:
1858 argA
[j
] = primary_rgba
;
1860 case GL_PREVIOUS_EXT
:
1863 case GL_CONSTANT_EXT
:
1865 GLchan alpha
, (*c
)[4] = ccolor
[j
];
1866 UNCLAMPED_FLOAT_TO_CHAN(alpha
, textureUnit
->EnvColor
[3]);
1867 for (i
= 0; i
< n
; i
++)
1868 c
[i
][ACOMP
] = alpha
;
1869 argA
[j
] = ccolor
[j
];
1873 gl_problem(NULL
, "invalid combine source");
1876 switch (textureUnit
->CombineSourceRGB
[j
]) {
1880 case GL_PRIMARY_COLOR_EXT
:
1881 argRGB
[j
] = primary_rgba
;
1883 case GL_PREVIOUS_EXT
:
1886 case GL_CONSTANT_EXT
:
1888 GLchan (*c
)[4] = ccolor
[j
];
1889 GLchan red
, green
, blue
;
1890 UNCLAMPED_FLOAT_TO_CHAN(red
, textureUnit
->EnvColor
[0]);
1891 UNCLAMPED_FLOAT_TO_CHAN(green
, textureUnit
->EnvColor
[1]);
1892 UNCLAMPED_FLOAT_TO_CHAN(blue
, textureUnit
->EnvColor
[2]);
1893 for (i
= 0; i
< n
; i
++) {
1895 c
[i
][GCOMP
] = green
;
1898 argRGB
[j
] = ccolor
[j
];
1902 gl_problem(NULL
, "invalid combine source");
1905 if (textureUnit
->CombineOperandRGB
[j
] != GL_SRC_COLOR
) {
1906 GLchan (*src
)[4] = argRGB
[j
];
1907 GLchan (*dst
)[4] = ccolor
[j
];
1909 argRGB
[j
] = ccolor
[j
];
1911 if (textureUnit
->CombineOperandRGB
[j
] == GL_ONE_MINUS_SRC_COLOR
) {
1912 for (i
= 0; i
< n
; i
++) {
1913 dst
[i
][RCOMP
] = CHAN_MAX
- src
[i
][RCOMP
];
1914 dst
[i
][GCOMP
] = CHAN_MAX
- src
[i
][GCOMP
];
1915 dst
[i
][BCOMP
] = CHAN_MAX
- src
[i
][BCOMP
];
1918 else if (textureUnit
->CombineOperandRGB
[j
] == GL_SRC_ALPHA
) {
1920 for (i
= 0; i
< n
; i
++) {
1921 dst
[i
][RCOMP
] = src
[i
][ACOMP
];
1922 dst
[i
][GCOMP
] = src
[i
][ACOMP
];
1923 dst
[i
][BCOMP
] = src
[i
][ACOMP
];
1926 else { /* GL_ONE_MINUS_SRC_ALPHA */
1928 for (i
= 0; i
< n
; i
++) {
1929 dst
[i
][RCOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
1930 dst
[i
][GCOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
1931 dst
[i
][BCOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
1936 if (textureUnit
->CombineOperandA
[j
] == GL_ONE_MINUS_SRC_ALPHA
) {
1937 GLchan (*src
)[4] = argA
[j
];
1938 GLchan (*dst
)[4] = ccolor
[j
];
1939 argA
[j
] = ccolor
[j
];
1940 for (i
= 0; i
< n
; i
++) {
1941 dst
[i
][ACOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
1945 if (textureUnit
->CombineModeRGB
== GL_REPLACE
&&
1946 textureUnit
->CombineModeA
== GL_REPLACE
) {
1947 break; /* done, we need only arg0 */
1951 textureUnit
->CombineModeRGB
!= GL_INTERPOLATE_EXT
&&
1952 textureUnit
->CombineModeA
!= GL_INTERPOLATE_EXT
) {
1953 break; /* arg0 and arg1 are done. we don't need arg2. */
1957 switch (textureUnit
->CombineModeRGB
) {
1960 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
1962 for (i
= 0; i
< n
; i
++) {
1963 GLuint r
= (GLuint
) arg0
[i
][RCOMP
] << RGBshift
;
1964 GLuint g
= (GLuint
) arg0
[i
][GCOMP
] << RGBshift
;
1965 GLuint b
= (GLuint
) arg0
[i
][BCOMP
] << RGBshift
;
1966 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
1967 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
1968 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
1972 for (i
= 0; i
< n
; i
++) {
1973 rgba
[i
][RCOMP
] = arg0
[i
][RCOMP
];
1974 rgba
[i
][GCOMP
] = arg0
[i
][GCOMP
];
1975 rgba
[i
][BCOMP
] = arg0
[i
][BCOMP
];
1982 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
1983 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
1984 const GLint shift
= 8 - RGBshift
;
1985 for (i
= 0; i
< n
; i
++) {
1986 GLuint r
= PROD(arg0
[i
][0], arg1
[i
][RCOMP
]) >> shift
;
1987 GLuint g
= PROD(arg0
[i
][1], arg1
[i
][GCOMP
]) >> shift
;
1988 GLuint b
= PROD(arg0
[i
][2], arg1
[i
][BCOMP
]) >> shift
;
1989 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
1990 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
1991 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
1997 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
1998 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
1999 for (i
= 0; i
< n
; i
++) {
2000 GLint r
= ((GLint
) arg0
[i
][RCOMP
] + (GLint
) arg1
[i
][RCOMP
]) << RGBshift
;
2001 GLint g
= ((GLint
) arg0
[i
][GCOMP
] + (GLint
) arg1
[i
][GCOMP
]) << RGBshift
;
2002 GLint b
= ((GLint
) arg0
[i
][BCOMP
] + (GLint
) arg1
[i
][BCOMP
]) << RGBshift
;
2003 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
2004 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
2005 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
2009 case GL_ADD_SIGNED_EXT
:
2011 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
2012 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
2013 for (i
= 0; i
< n
; i
++) {
2014 GLint r
= (GLint
) arg0
[i
][RCOMP
] + (GLint
) arg1
[i
][RCOMP
] - 128;
2015 GLint g
= (GLint
) arg0
[i
][GCOMP
] + (GLint
) arg1
[i
][GCOMP
] - 128;
2016 GLint b
= (GLint
) arg0
[i
][BCOMP
] + (GLint
) arg1
[i
][BCOMP
] - 128;
2017 r
= (r
< 0) ? 0 : r
<< RGBshift
;
2018 g
= (g
< 0) ? 0 : g
<< RGBshift
;
2019 b
= (b
< 0) ? 0 : b
<< RGBshift
;
2020 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
2021 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
2022 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
2026 case GL_INTERPOLATE_EXT
:
2028 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
2029 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
2030 const GLchan (*arg2
)[4] = (const GLchan (*)[4]) argRGB
[2];
2031 const GLint shift
= 8 - RGBshift
;
2032 for (i
= 0; i
< n
; i
++) {
2033 GLuint r
= (PROD(arg0
[i
][RCOMP
], arg2
[i
][RCOMP
])
2034 + PROD(arg1
[i
][RCOMP
], CHAN_MAX
- arg2
[i
][RCOMP
]))
2036 GLuint g
= (PROD(arg0
[i
][GCOMP
], arg2
[i
][GCOMP
])
2037 + PROD(arg1
[i
][GCOMP
], CHAN_MAX
- arg2
[i
][GCOMP
]))
2039 GLuint b
= (PROD(arg0
[i
][BCOMP
], arg2
[i
][BCOMP
])
2040 + PROD(arg1
[i
][BCOMP
], CHAN_MAX
- arg2
[i
][BCOMP
]))
2042 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
2043 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
2044 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
2048 case GL_DOT3_RGB_EXT
:
2049 case GL_DOT3_RGBA_EXT
:
2051 const GLubyte (*arg0
)[4] = (const GLubyte (*)[4]) argRGB
[0];
2052 const GLubyte (*arg1
)[4] = (const GLubyte (*)[4]) argRGB
[1];
2053 /* ATI's EXT extension has a constant scale by 4. The ARB
2054 * one will likely remove this restriction, and we should
2055 * drop the EXT extension in favour of the ARB one.
2057 for (i
= 0; i
< n
; i
++) {
2058 GLint dot
= (S_PROD((GLint
)arg0
[i
][RCOMP
] - 128,
2059 (GLint
)arg1
[i
][RCOMP
] - 128) +
2060 S_PROD((GLint
)arg0
[i
][GCOMP
] - 128,
2061 (GLint
)arg1
[i
][GCOMP
] - 128) +
2062 S_PROD((GLint
)arg0
[i
][BCOMP
] - 128,
2063 (GLint
)arg1
[i
][BCOMP
] - 128)) >> 6;
2064 rgba
[i
][RCOMP
] = (GLubyte
) CLAMP(dot
, 0, 255);
2065 rgba
[i
][GCOMP
] = (GLubyte
) CLAMP(dot
, 0, 255);
2066 rgba
[i
][BCOMP
] = (GLubyte
) CLAMP(dot
, 0, 255);
2071 gl_problem(NULL
, "invalid combine mode");
2074 switch (textureUnit
->CombineModeA
) {
2077 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
2079 for (i
= 0; i
< n
; i
++) {
2080 GLuint a
= (GLuint
) arg0
[i
][ACOMP
] << Ashift
;
2081 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
2085 for (i
= 0; i
< n
; i
++) {
2086 rgba
[i
][ACOMP
] = arg0
[i
][ACOMP
];
2093 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
2094 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
2095 const GLint shift
= 8 - Ashift
;
2096 for (i
= 0; i
< n
; i
++) {
2097 GLuint a
= (PROD(arg0
[i
][ACOMP
], arg1
[i
][ACOMP
]) >> shift
);
2098 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
2104 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
2105 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
2106 for (i
= 0; i
< n
; i
++) {
2107 GLint a
= ((GLint
) arg0
[i
][ACOMP
] + arg1
[i
][ACOMP
]) << Ashift
;
2108 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
2112 case GL_ADD_SIGNED_EXT
:
2114 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
2115 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
2116 for (i
= 0; i
< n
; i
++) {
2117 GLint a
= (GLint
) arg0
[i
][ACOMP
] + (GLint
) arg1
[i
][ACOMP
] - 128;
2118 a
= (a
< 0) ? 0 : a
<< Ashift
;
2119 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
2123 case GL_INTERPOLATE_EXT
:
2125 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
2126 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
2127 const GLchan (*arg2
)[4] = (const GLchan (*)[4]) argA
[2];
2128 const GLint shift
= 8 - Ashift
;
2129 for (i
=0; i
<n
; i
++) {
2130 GLuint a
= (PROD(arg0
[i
][ACOMP
], arg2
[i
][ACOMP
])
2131 + PROD(arg1
[i
][ACOMP
], CHAN_MAX
- arg2
[i
][ACOMP
]))
2133 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
2138 gl_problem(NULL
, "invalid combine mode");
2141 /* Fix the alpha component for GL_DOT3_RGBA_EXT combining.
2143 if (textureUnit
->CombineModeRGB
== GL_DOT3_RGBA_EXT
) {
2144 for (i
= 0; i
< n
; i
++) {
2145 rgba
[i
][ACOMP
] = rgba
[i
][RCOMP
];
2153 /**********************************************************************/
2154 /* Texture Application */
2155 /**********************************************************************/
2159 * Combine incoming fragment color with texel color to produce output color.
2160 * Input: textureUnit - pointer to texture unit to apply
2161 * format - base internal texture format
2162 * n - number of fragments
2163 * primary_rgba - primary colors (may be rgba for single texture)
2164 * texels - array of texel colors
2165 * InOut: rgba - incoming fragment colors modified by texel colors
2166 * according to the texture environment mode.
2169 apply_texture( const GLcontext
*ctx
,
2170 const struct gl_texture_unit
*texUnit
,
2172 GLchan primary_rgba
[][4], GLchan texel
[][4],
2177 GLint Rc
, Gc
, Bc
, Ac
;
2181 ASSERT(texUnit
->_Current
);
2183 baseLevel
= texUnit
->_Current
->BaseLevel
;
2184 ASSERT(texUnit
->_Current
->Image
[baseLevel
]);
2186 format
= texUnit
->_Current
->Image
[baseLevel
]->Format
;
2188 if (format
==GL_COLOR_INDEX
) {
2189 format
= GL_RGBA
; /* XXXX a hack! */
2192 switch (texUnit
->EnvMode
) {
2199 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
2205 GLchan Lt
= texel
[i
][RCOMP
];
2206 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = Lt
;
2210 case GL_LUMINANCE_ALPHA
:
2212 GLchan Lt
= texel
[i
][RCOMP
];
2214 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = Lt
;
2216 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
2222 GLchan It
= texel
[i
][RCOMP
];
2223 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = It
;
2225 rgba
[i
][ACOMP
] = It
;
2231 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
2232 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
2233 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
2240 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
2241 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
2242 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
2244 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
2248 gl_problem(ctx
, "Bad format (GL_REPLACE) in apply_texture");
2259 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], texel
[i
][ACOMP
] );
2265 GLchan Lt
= texel
[i
][RCOMP
];
2266 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], Lt
);
2267 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], Lt
);
2268 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], Lt
);
2272 case GL_LUMINANCE_ALPHA
:
2275 GLchan Lt
= texel
[i
][RCOMP
];
2276 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], Lt
);
2277 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], Lt
);
2278 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], Lt
);
2280 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], texel
[i
][ACOMP
] );
2286 GLchan It
= texel
[i
][RCOMP
];
2287 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], It
);
2288 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], It
);
2289 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], It
);
2291 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], It
);
2297 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], texel
[i
][RCOMP
] );
2298 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], texel
[i
][GCOMP
] );
2299 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], texel
[i
][BCOMP
] );
2306 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], texel
[i
][RCOMP
] );
2307 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], texel
[i
][GCOMP
] );
2308 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], texel
[i
][BCOMP
] );
2310 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], texel
[i
][ACOMP
] );
2314 gl_problem(ctx
, "Bad format (GL_MODULATE) in apply_texture");
2323 case GL_LUMINANCE_ALPHA
:
2330 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
2331 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
2332 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
2338 /* Cv = Cf(1-At) + CtAt */
2339 GLint t
= texel
[i
][ACOMP
], s
= CHAN_MAX
- t
;
2340 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(texel
[i
][RCOMP
],t
);
2341 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(texel
[i
][GCOMP
],t
);
2342 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(texel
[i
][BCOMP
],t
);
2347 gl_problem(ctx
, "Bad format (GL_DECAL) in apply_texture");
2353 Rc
= (GLint
) (texUnit
->EnvColor
[0] * CHAN_MAXF
);
2354 Gc
= (GLint
) (texUnit
->EnvColor
[1] * CHAN_MAXF
);
2355 Bc
= (GLint
) (texUnit
->EnvColor
[2] * CHAN_MAXF
);
2356 Ac
= (GLint
) (texUnit
->EnvColor
[3] * CHAN_MAXF
);
2362 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2367 /* Cv = Cf(1-Lt) + CcLt */
2368 GLchan Lt
= texel
[i
][RCOMP
], s
= CHAN_MAX
- Lt
;
2369 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(Rc
, Lt
);
2370 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(Gc
, Lt
);
2371 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(Bc
, Lt
);
2375 case GL_LUMINANCE_ALPHA
:
2377 /* Cv = Cf(1-Lt) + CcLt */
2378 GLchan Lt
= texel
[i
][RCOMP
], s
= CHAN_MAX
- Lt
;
2379 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(Rc
, Lt
);
2380 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(Gc
, Lt
);
2381 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(Bc
, Lt
);
2383 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
],texel
[i
][ACOMP
]);
2388 /* Cv = Cf(1-It) + CcLt */
2389 GLchan It
= texel
[i
][RCOMP
], s
= CHAN_MAX
- It
;
2390 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(Rc
, It
);
2391 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(Gc
, It
);
2392 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(Bc
, It
);
2393 /* Av = Af(1-It) + Ac*It */
2394 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], s
) + CHAN_PRODUCT(Ac
, It
);
2399 /* Cv = Cf(1-Ct) + CcCt */
2400 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], (CHAN_MAX
-texel
[i
][RCOMP
])) + CHAN_PRODUCT(Rc
,texel
[i
][RCOMP
]);
2401 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], (CHAN_MAX
-texel
[i
][GCOMP
])) + CHAN_PRODUCT(Gc
,texel
[i
][GCOMP
]);
2402 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], (CHAN_MAX
-texel
[i
][BCOMP
])) + CHAN_PRODUCT(Bc
,texel
[i
][BCOMP
]);
2408 /* Cv = Cf(1-Ct) + CcCt */
2409 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], (CHAN_MAX
-texel
[i
][RCOMP
])) + CHAN_PRODUCT(Rc
,texel
[i
][RCOMP
]);
2410 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], (CHAN_MAX
-texel
[i
][GCOMP
])) + CHAN_PRODUCT(Gc
,texel
[i
][GCOMP
]);
2411 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], (CHAN_MAX
-texel
[i
][BCOMP
])) + CHAN_PRODUCT(Bc
,texel
[i
][BCOMP
]);
2413 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
],texel
[i
][ACOMP
]);
2417 gl_problem(ctx
, "Bad format (GL_BLEND) in apply_texture");
2422 case GL_ADD
: /* GL_EXT_texture_add_env */
2429 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2434 GLuint Lt
= texel
[i
][RCOMP
];
2435 GLuint r
= rgba
[i
][RCOMP
] + Lt
;
2436 GLuint g
= rgba
[i
][GCOMP
] + Lt
;
2437 GLuint b
= rgba
[i
][BCOMP
] + Lt
;
2438 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2439 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2440 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2444 case GL_LUMINANCE_ALPHA
:
2446 GLuint Lt
= texel
[i
][RCOMP
];
2447 GLuint r
= rgba
[i
][RCOMP
] + Lt
;
2448 GLuint g
= rgba
[i
][GCOMP
] + Lt
;
2449 GLuint b
= rgba
[i
][BCOMP
] + Lt
;
2450 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2451 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2452 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2453 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2458 GLchan It
= texel
[i
][RCOMP
];
2459 GLuint r
= rgba
[i
][RCOMP
] + It
;
2460 GLuint g
= rgba
[i
][GCOMP
] + It
;
2461 GLuint b
= rgba
[i
][BCOMP
] + It
;
2462 GLuint a
= rgba
[i
][ACOMP
] + It
;
2463 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2464 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2465 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2466 rgba
[i
][ACOMP
] = MIN2(a
, CHAN_MAX
);
2471 GLuint r
= rgba
[i
][RCOMP
] + texel
[i
][RCOMP
];
2472 GLuint g
= rgba
[i
][GCOMP
] + texel
[i
][GCOMP
];
2473 GLuint b
= rgba
[i
][BCOMP
] + texel
[i
][BCOMP
];
2474 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2475 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2476 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2482 GLuint r
= rgba
[i
][RCOMP
] + texel
[i
][RCOMP
];
2483 GLuint g
= rgba
[i
][GCOMP
] + texel
[i
][GCOMP
];
2484 GLuint b
= rgba
[i
][BCOMP
] + texel
[i
][BCOMP
];
2485 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2486 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2487 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2488 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2492 gl_problem(ctx
, "Bad format (GL_ADD) in apply_texture");
2497 case GL_COMBINE_EXT
: /* GL_EXT_combine_ext; we modify texel array */
2501 texel
[i
][RCOMP
] = texel
[i
][GCOMP
] = texel
[i
][BCOMP
] = 0;
2506 GLchan Lt
= texel
[i
][RCOMP
];
2507 texel
[i
][GCOMP
] = texel
[i
][BCOMP
] = Lt
;
2509 texel
[i
][ACOMP
] = CHAN_MAX
;
2512 case GL_LUMINANCE_ALPHA
:
2514 GLchan Lt
= texel
[i
][RCOMP
];
2516 texel
[i
][GCOMP
] = texel
[i
][BCOMP
] = Lt
;
2522 GLchan It
= texel
[i
][RCOMP
];
2523 texel
[i
][GCOMP
] = texel
[i
][BCOMP
] = It
;
2525 texel
[i
][ACOMP
] = It
;
2531 texel
[i
][ACOMP
] = CHAN_MAX
;
2534 case GL_RGBA
: /* do nothing. */
2537 gl_problem(ctx
, "Bad format in apply_texture (GL_COMBINE_EXT)");
2540 _mesa_texture_combine(ctx
, texUnit
, n
, primary_rgba
, texel
, rgba
);
2544 gl_problem(ctx
, "Bad env mode in apply_texture");
2552 * Apply a unit of texture mapping to the incoming fragments.
2555 _swrast_texture_fragments( GLcontext
*ctx
, GLuint texUnit
, GLuint n
,
2556 const GLfloat s
[], const GLfloat t
[],
2557 const GLfloat r
[], GLfloat lambda
[],
2558 GLchan primary_rgba
[][4], GLchan rgba
[][4] )
2560 const GLuint mask
= TEXTURE0_ANY
<< (texUnit
* 4);
2562 if (ctx
->Texture
._ReallyEnabled
& mask
) {
2563 const struct gl_texture_unit
*textureUnit
= &ctx
->Texture
.Unit
[texUnit
];
2565 if (textureUnit
->_Current
) { /* XXX need this? */
2566 GLchan texel
[PB_SIZE
][4];
2568 if (textureUnit
->LodBias
!= 0.0F
) {
2569 /* apply LOD bias, but don't clamp yet */
2572 lambda
[i
] += textureUnit
->LodBias
;
2576 if (textureUnit
->_Current
->MinLod
!= -1000.0
2577 || textureUnit
->_Current
->MaxLod
!= 1000.0) {
2578 /* apply LOD clamping to lambda */
2579 GLfloat min
= textureUnit
->_Current
->MinLod
;
2580 GLfloat max
= textureUnit
->_Current
->MaxLod
;
2583 GLfloat l
= lambda
[i
];
2584 lambda
[i
] = CLAMP(l
, min
, max
);
2588 /* fetch texture images from device driver, if needed */
2589 if (ctx
->Driver
.GetTexImage
) {
2590 if (!_mesa_get_teximages_from_driver(ctx
, textureUnit
->_Current
)) {
2595 /* Sample the texture. */
2596 SWRAST_CONTEXT(ctx
)->TextureSample
[texUnit
]( ctx
, texUnit
,
2597 textureUnit
->_Current
,
2601 apply_texture( ctx
, textureUnit
, n
, primary_rgba
, texel
, rgba
);