1 /* $Id: s_texture.c,v 1.14 2001/03/03 20:33:30 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.
36 #include "s_context.h"
38 #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 or GL_CLAMP_TO_EDGE
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); \
76 if (wrapMode == GL_CLAMP_TO_EDGE) { \
87 * Used to compute texel location for nearest sampling.
89 #define COMPUTE_NEAREST_TEXEL_LOCATION(wrapMode, S, SIZE, I) \
91 if (wrapMode == GL_REPEAT) { \
92 /* s limited to [0,1) */ \
93 /* i limited to [0,width-1] */ \
94 I = (GLint) (S * SIZE); \
99 else if (wrapMode == GL_CLAMP_TO_EDGE) { \
100 const GLfloat min = 1.0F / (2.0F * SIZE); \
101 const GLfloat max = 1.0F - min; \
107 I = (GLint) (S * SIZE); \
110 ASSERT(wrapMode == GL_CLAMP); \
111 /* s limited to [0,1] */ \
112 /* i limited to [0,width-1] */ \
115 else if (S >= 1.0F) \
118 I = (GLint) (S * SIZE); \
124 * Compute linear mipmap levels for given lambda.
126 #define COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level) \
130 else if (lambda > tObj->_MaxLambda) \
131 lambda = tObj->_MaxLambda; \
132 level = (GLint) (tObj->BaseLevel + lambda); \
137 * Compute nearest mipmap level for given lambda.
139 #define COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level) \
141 if (lambda <= 0.5F) \
143 else if (lambda > tObj->_MaxLambda + 0.4999F) \
144 lambda = tObj->_MaxLambda + 0.4999F; \
145 level = (GLint) (tObj->BaseLevel + lambda + 0.5F); \
146 if (level > tObj->_MaxLevel) \
147 level = tObj->_MaxLevel; \
154 * Bitflags for texture border color sampling.
166 * Get texture palette entry.
169 palette_sample(const GLcontext
*ctx
,
170 const struct gl_texture_object
*tObj
,
171 GLint index
, GLchan rgba
[4] )
173 const GLchan
*palette
;
176 if (ctx
->Texture
.SharedPalette
) {
177 ASSERT(!ctx
->Texture
.Palette
.FloatTable
);
178 palette
= (const GLchan
*) ctx
->Texture
.Palette
.Table
;
179 format
= ctx
->Texture
.Palette
.Format
;
182 ASSERT(!tObj
->Palette
.FloatTable
);
183 palette
= (const GLchan
*) tObj
->Palette
.Table
;
184 format
= tObj
->Palette
.Format
;
189 rgba
[ACOMP
] = palette
[index
];
193 rgba
[RCOMP
] = palette
[index
];
195 case GL_LUMINANCE_ALPHA
:
196 rgba
[RCOMP
] = palette
[(index
<< 1) + 0];
197 rgba
[ACOMP
] = palette
[(index
<< 1) + 1];
200 rgba
[RCOMP
] = palette
[index
* 3 + 0];
201 rgba
[GCOMP
] = palette
[index
* 3 + 1];
202 rgba
[BCOMP
] = palette
[index
* 3 + 2];
205 rgba
[RCOMP
] = palette
[(index
<< 2) + 0];
206 rgba
[GCOMP
] = palette
[(index
<< 2) + 1];
207 rgba
[BCOMP
] = palette
[(index
<< 2) + 2];
208 rgba
[ACOMP
] = palette
[(index
<< 2) + 3];
211 _mesa_problem(ctx
, "Bad palette format in palette_sample");
217 /**********************************************************************/
218 /* 1-D Texture Sampling Functions */
219 /**********************************************************************/
222 * Return the texture sample for coordinate (s) using GL_NEAREST filter.
225 sample_1d_nearest(GLcontext
*ctx
,
226 const struct gl_texture_object
*tObj
,
227 const struct gl_texture_image
*img
,
228 GLfloat s
, GLchan rgba
[4])
230 const GLint width
= img
->Width2
; /* without border, power of two */
233 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapS
, s
, width
, i
);
235 /* skip over the border, if any */
238 (*img
->FetchTexel
)(img
, i
, 0, 0, (GLvoid
*) rgba
);
239 if (img
->Format
== GL_COLOR_INDEX
) {
240 palette_sample(ctx
, tObj
, rgba
[0], rgba
);
247 * Return the texture sample for coordinate (s) using GL_LINEAR filter.
250 sample_1d_linear(GLcontext
*ctx
,
251 const struct gl_texture_object
*tObj
,
252 const struct gl_texture_image
*img
,
253 GLfloat s
, GLchan rgba
[4])
255 const GLint width
= img
->Width2
;
258 GLuint useBorderColor
;
260 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapS
, s
, u
, width
, i0
, i1
);
268 if (i0
< 0 || i0
>= width
) useBorderColor
|= I0BIT
;
269 if (i1
< 0 || i1
>= width
) useBorderColor
|= I1BIT
;
273 const GLfloat a
= FRAC(u
);
274 /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
275 const GLint w0
= (GLint
) ((1.0F
-a
) * WEIGHT_SCALE
+ 0.5F
);
276 const GLint w1
= (GLint
) ( a
* WEIGHT_SCALE
+ 0.5F
);
278 GLchan t0
[4], t1
[4]; /* texels */
280 if (useBorderColor
& I0BIT
) {
281 COPY_CHAN4(t0
, tObj
->BorderColor
);
284 (*img
->FetchTexel
)(img
, i0
, 0, 0, (GLvoid
*) t0
);
285 if (img
->Format
== GL_COLOR_INDEX
) {
286 palette_sample(ctx
, tObj
, t0
[0], t0
);
289 if (useBorderColor
& I1BIT
) {
290 COPY_CHAN4(t1
, tObj
->BorderColor
);
293 (*img
->FetchTexel
)(img
, i1
, 0, 0, (GLvoid
*) t1
);
294 if (img
->Format
== GL_COLOR_INDEX
) {
295 palette_sample(ctx
, tObj
, t1
[0], t1
);
299 rgba
[0] = (GLchan
) ((w0
* t0
[0] + w1
* t1
[0]) >> WEIGHT_SHIFT
);
300 rgba
[1] = (GLchan
) ((w0
* t0
[1] + w1
* t1
[1]) >> WEIGHT_SHIFT
);
301 rgba
[2] = (GLchan
) ((w0
* t0
[2] + w1
* t1
[2]) >> WEIGHT_SHIFT
);
302 rgba
[3] = (GLchan
) ((w0
* t0
[3] + w1
* t1
[3]) >> WEIGHT_SHIFT
);
308 sample_1d_nearest_mipmap_nearest(GLcontext
*ctx
,
309 const struct gl_texture_object
*tObj
,
310 GLfloat s
, GLfloat lambda
,
314 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
315 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, rgba
);
320 sample_1d_linear_mipmap_nearest(GLcontext
*ctx
,
321 const struct gl_texture_object
*tObj
,
322 GLfloat s
, GLfloat lambda
,
326 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
327 sample_1d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, rgba
);
333 sample_1d_nearest_mipmap_linear(GLcontext
*ctx
,
334 const struct gl_texture_object
*tObj
,
335 GLfloat s
, GLfloat lambda
,
340 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
342 if (level
>= tObj
->_MaxLevel
) {
343 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, rgba
);
347 const GLfloat f
= FRAC(lambda
);
348 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, t0
);
349 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[level
+1], s
, t1
);
350 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
351 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
352 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
353 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
360 sample_1d_linear_mipmap_linear(GLcontext
*ctx
,
361 const struct gl_texture_object
*tObj
,
362 GLfloat s
, GLfloat lambda
,
367 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
369 if (level
>= tObj
->_MaxLevel
) {
370 sample_1d_linear(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, rgba
);
374 const GLfloat f
= FRAC(lambda
);
375 sample_1d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, t0
);
376 sample_1d_linear(ctx
, tObj
, tObj
->Image
[level
+1], s
, t1
);
377 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
378 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
379 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
380 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
387 sample_nearest_1d( GLcontext
*ctx
, GLuint texUnit
,
388 const struct gl_texture_object
*tObj
, GLuint n
,
389 const GLfloat s
[], const GLfloat t
[],
390 const GLfloat u
[], const GLfloat lambda
[],
394 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
399 sample_1d_nearest(ctx
, tObj
, image
, s
[i
], rgba
[i
]);
406 sample_linear_1d( GLcontext
*ctx
, GLuint texUnit
,
407 const struct gl_texture_object
*tObj
, GLuint n
,
408 const GLfloat s
[], const GLfloat t
[],
409 const GLfloat u
[], const GLfloat lambda
[],
413 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
418 sample_1d_linear(ctx
, tObj
, image
, s
[i
], rgba
[i
]);
424 * Given an (s) texture coordinate and lambda (level of detail) value,
425 * return a texture sample.
429 sample_lambda_1d( GLcontext
*ctx
, GLuint texUnit
,
430 const struct gl_texture_object
*tObj
, GLuint n
,
431 const GLfloat s
[], const GLfloat t
[],
432 const GLfloat u
[], const GLfloat lambda
[],
435 GLfloat MinMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
442 if (lambda
[i
] > MinMagThresh
) {
444 switch (tObj
->MinFilter
) {
446 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
450 sample_1d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
453 case GL_NEAREST_MIPMAP_NEAREST
:
454 sample_1d_nearest_mipmap_nearest(ctx
, tObj
, lambda
[i
], s
[i
],
457 case GL_LINEAR_MIPMAP_NEAREST
:
458 sample_1d_linear_mipmap_nearest(ctx
, tObj
, s
[i
], lambda
[i
],
461 case GL_NEAREST_MIPMAP_LINEAR
:
462 sample_1d_nearest_mipmap_linear(ctx
, tObj
, s
[i
], lambda
[i
],
465 case GL_LINEAR_MIPMAP_LINEAR
:
466 sample_1d_linear_mipmap_linear(ctx
, tObj
, s
[i
], lambda
[i
],
470 _mesa_problem(NULL
, "Bad min filter in sample_1d_texture");
476 switch (tObj
->MagFilter
) {
478 sample_1d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
482 sample_1d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
486 _mesa_problem(NULL
, "Bad mag filter in sample_1d_texture");
496 /**********************************************************************/
497 /* 2-D Texture Sampling Functions */
498 /**********************************************************************/
502 * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
505 sample_2d_nearest(GLcontext
*ctx
,
506 const struct gl_texture_object
*tObj
,
507 const struct gl_texture_image
*img
,
508 GLfloat s
, GLfloat t
,
511 const GLint width
= img
->Width2
; /* without border, power of two */
512 const GLint height
= img
->Height2
; /* without border, power of two */
515 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapS
, s
, width
, i
);
516 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapT
, t
, height
, j
);
518 /* skip over the border, if any */
522 (*img
->FetchTexel
)(img
, i
, j
, 0, (GLvoid
*) rgba
);
523 if (img
->Format
== GL_COLOR_INDEX
) {
524 palette_sample(ctx
, tObj
, rgba
[0], rgba
);
531 * Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
532 * New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
535 sample_2d_linear(GLcontext
*ctx
,
536 const struct gl_texture_object
*tObj
,
537 const struct gl_texture_image
*img
,
538 GLfloat s
, GLfloat t
,
541 const GLint width
= img
->Width2
;
542 const GLint height
= img
->Height2
;
543 GLint i0
, j0
, i1
, j1
;
544 GLuint useBorderColor
;
547 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapS
, s
, u
, width
, i0
, i1
);
548 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapT
, t
, v
, height
, j0
, j1
);
558 if (i0
< 0 || i0
>= width
) useBorderColor
|= I0BIT
;
559 if (i1
< 0 || i1
>= width
) useBorderColor
|= I1BIT
;
560 if (j0
< 0 || j0
>= height
) useBorderColor
|= J0BIT
;
561 if (j1
< 0 || j1
>= height
) useBorderColor
|= J1BIT
;
565 const GLfloat a
= FRAC(u
);
566 const GLfloat b
= FRAC(v
);
567 /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
568 const GLint w00
= (GLint
) ((1.0F
-a
)*(1.0F
-b
) * WEIGHT_SCALE
+ 0.5F
);
569 const GLint w10
= (GLint
) ( a
*(1.0F
-b
) * WEIGHT_SCALE
+ 0.5F
);
570 const GLint w01
= (GLint
) ((1.0F
-a
)* b
* WEIGHT_SCALE
+ 0.5F
);
571 const GLint w11
= (GLint
) ( a
* b
* WEIGHT_SCALE
+ 0.5F
);
577 if (useBorderColor
& (I0BIT
| J0BIT
)) {
578 COPY_CHAN4(t00
, tObj
->BorderColor
);
581 (*img
->FetchTexel
)(img
, i0
, j0
, 0, (GLvoid
*) t00
);
582 if (img
->Format
== GL_COLOR_INDEX
) {
583 palette_sample(ctx
, tObj
, t00
[0], t00
);
586 if (useBorderColor
& (I1BIT
| J0BIT
)) {
587 COPY_CHAN4(t10
, tObj
->BorderColor
);
590 (*img
->FetchTexel
)(img
, i1
, j0
, 0, (GLvoid
*) t10
);
591 if (img
->Format
== GL_COLOR_INDEX
) {
592 palette_sample(ctx
, tObj
, t10
[0], t10
);
595 if (useBorderColor
& (I0BIT
| J1BIT
)) {
596 COPY_CHAN4(t01
, tObj
->BorderColor
);
599 (*img
->FetchTexel
)(img
, i0
, j1
, 0, (GLvoid
*) t01
);
600 if (img
->Format
== GL_COLOR_INDEX
) {
601 palette_sample(ctx
, tObj
, t01
[0], t01
);
604 if (useBorderColor
& (I1BIT
| J1BIT
)) {
605 COPY_CHAN4(t11
, tObj
->BorderColor
);
608 (*img
->FetchTexel
)(img
, i1
, j1
, 0, (GLvoid
*) t11
);
609 if (img
->Format
== GL_COLOR_INDEX
) {
610 palette_sample(ctx
, tObj
, t11
[0], t11
);
614 rgba
[0] = (GLchan
) ((w00
* t00
[0] + w10
* t10
[0] + w01
* t01
[0] + w11
* t11
[0]) >> WEIGHT_SHIFT
);
615 rgba
[1] = (GLchan
) ((w00
* t00
[1] + w10
* t10
[1] + w01
* t01
[1] + w11
* t11
[1]) >> WEIGHT_SHIFT
);
616 rgba
[2] = (GLchan
) ((w00
* t00
[2] + w10
* t10
[2] + w01
* t01
[2] + w11
* t11
[2]) >> WEIGHT_SHIFT
);
617 rgba
[3] = (GLchan
) ((w00
* t00
[3] + w10
* t10
[3] + w01
* t01
[3] + w11
* t11
[3]) >> WEIGHT_SHIFT
);
625 sample_2d_nearest_mipmap_nearest(GLcontext
*ctx
,
626 const struct gl_texture_object
*tObj
,
627 GLfloat s
, GLfloat t
, GLfloat lambda
,
631 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
632 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, t
, rgba
);
638 sample_2d_linear_mipmap_nearest(GLcontext
*ctx
,
639 const struct gl_texture_object
*tObj
,
640 GLfloat s
, GLfloat t
, GLfloat lambda
,
644 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
645 sample_2d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, t
, rgba
);
651 sample_2d_nearest_mipmap_linear(GLcontext
*ctx
,
652 const struct gl_texture_object
*tObj
,
653 GLfloat s
, GLfloat t
, GLfloat lambda
,
658 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
660 if (level
>= tObj
->_MaxLevel
) {
661 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, t
, rgba
);
664 GLchan t0
[4], t1
[4]; /* texels */
665 const GLfloat f
= FRAC(lambda
);
666 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, t
, t0
);
667 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[level
+1], s
, t
, t1
);
668 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
669 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
670 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
671 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
678 sample_2d_linear_mipmap_linear(GLcontext
*ctx
,
679 const struct gl_texture_object
*tObj
,
680 GLfloat s
, GLfloat t
, GLfloat lambda
,
685 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
687 if (level
>= tObj
->_MaxLevel
) {
688 sample_2d_linear(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, t
, rgba
);
691 GLchan t0
[4], t1
[4]; /* texels */
692 const GLfloat f
= FRAC(lambda
);
693 sample_2d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, t
, t0
);
694 sample_2d_linear(ctx
, tObj
, tObj
->Image
[level
+1], s
, t
, t1
);
695 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
696 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
697 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
698 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
705 sample_nearest_2d( GLcontext
*ctx
, GLuint texUnit
,
706 const struct gl_texture_object
*tObj
, GLuint n
,
707 const GLfloat s
[], const GLfloat t
[],
708 const GLfloat u
[], const GLfloat lambda
[],
712 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
716 sample_2d_nearest(ctx
, tObj
, image
, s
[i
], t
[i
], rgba
[i
]);
723 sample_linear_2d( GLcontext
*ctx
, GLuint texUnit
,
724 const struct gl_texture_object
*tObj
, GLuint n
,
725 const GLfloat s
[], const GLfloat t
[],
726 const GLfloat u
[], const GLfloat lambda
[],
730 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
734 sample_2d_linear(ctx
, tObj
, image
, s
[i
], t
[i
], rgba
[i
]);
740 * Given an array of (s,t) texture coordinate and lambda (level of detail)
741 * values, return an array of texture sample.
744 sample_lambda_2d( GLcontext
*ctx
, GLuint texUnit
,
745 const struct gl_texture_object
*tObj
,
747 const GLfloat s
[], const GLfloat t
[],
748 const GLfloat u
[], const GLfloat lambda
[],
751 const GLfloat minMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
755 /* check if lambda is monotonous-array */
756 if (lambda
[0] <= minMagThresh
&& lambda
[n
-1] <= minMagThresh
) {
758 switch (tObj
->MagFilter
) {
760 for (i
= 0; i
< n
; i
++)
761 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
762 s
[i
], t
[i
], rgba
[i
] );
765 for (i
= 0; i
< n
; i
++)
766 sample_2d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
767 s
[i
], t
[i
], rgba
[i
] );
770 _mesa_problem(NULL
, "Bad mag filter in sample_2d_texture");
774 for (i
= 0; i
< n
; i
++) {
775 if (lambda
[i
] > minMagThresh
) {
777 switch (tObj
->MinFilter
) {
779 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
780 s
[i
], t
[i
], rgba
[i
]);
783 sample_2d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
784 s
[i
], t
[i
], rgba
[i
]);
786 case GL_NEAREST_MIPMAP_NEAREST
:
787 sample_2d_nearest_mipmap_nearest(ctx
, tObj
, s
[i
], t
[i
],
790 case GL_LINEAR_MIPMAP_NEAREST
:
791 sample_2d_linear_mipmap_nearest(ctx
,tObj
, s
[i
], t
[i
],
794 case GL_NEAREST_MIPMAP_LINEAR
:
795 sample_2d_nearest_mipmap_linear(ctx
,tObj
, s
[i
], t
[i
],
798 case GL_LINEAR_MIPMAP_LINEAR
:
799 sample_2d_linear_mipmap_linear(ctx
,tObj
, s
[i
], t
[i
],
800 lambda
[i
], rgba
[i
] );
803 _mesa_problem(NULL
, "Bad min filter in sample_2d_texture");
809 switch (tObj
->MagFilter
) {
811 sample_2d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
812 s
[i
], t
[i
], rgba
[i
]);
815 sample_2d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
816 s
[i
], t
[i
], rgba
[i
] );
819 _mesa_problem(NULL
, "Bad mag filter in sample_2d_texture");
828 * Optimized 2-D texture sampling:
829 * S and T wrap mode == GL_REPEAT
830 * GL_NEAREST min/mag filter
835 opt_sample_rgb_2d( GLcontext
*ctx
, GLuint texUnit
,
836 const struct gl_texture_object
*tObj
,
837 GLuint n
, const GLfloat s
[], const GLfloat t
[],
838 const GLfloat u
[], const GLfloat lambda
[],
841 const struct gl_texture_image
*img
= tObj
->Image
[tObj
->BaseLevel
];
842 const GLfloat width
= (GLfloat
) img
->Width
;
843 const GLfloat height
= (GLfloat
) img
->Height
;
844 const GLint colMask
= img
->Width
- 1;
845 const GLint rowMask
= img
->Height
- 1;
846 const GLint shift
= img
->WidthLog2
;
850 ASSERT(tObj
->WrapS
==GL_REPEAT
);
851 ASSERT(tObj
->WrapT
==GL_REPEAT
);
852 ASSERT(tObj
->MinFilter
==GL_NEAREST
);
853 ASSERT(tObj
->MagFilter
==GL_NEAREST
);
854 ASSERT(img
->Border
==0);
855 ASSERT(img
->Format
==GL_RGB
);
857 /* NOTE: negative float->int doesn't floor, add 10000 as to work-around */
859 GLint i
= (GLint
) ((s
[k
] + 10000.0) * width
) & colMask
;
860 GLint j
= (GLint
) ((t
[k
] + 10000.0) * height
) & rowMask
;
861 GLint pos
= (j
<< shift
) | i
;
862 GLchan
*texel
= ((GLchan
*) img
->Data
) + pos
+ pos
+ pos
; /* pos*3 */
863 rgba
[k
][RCOMP
] = texel
[0];
864 rgba
[k
][GCOMP
] = texel
[1];
865 rgba
[k
][BCOMP
] = texel
[2];
871 * Optimized 2-D texture sampling:
872 * S and T wrap mode == GL_REPEAT
873 * GL_NEAREST min/mag filter
878 opt_sample_rgba_2d( GLcontext
*ctx
, GLuint texUnit
,
879 const struct gl_texture_object
*tObj
,
880 GLuint n
, const GLfloat s
[], const GLfloat t
[],
881 const GLfloat u
[], const GLfloat lambda
[],
884 const struct gl_texture_image
*img
= tObj
->Image
[tObj
->BaseLevel
];
885 const GLfloat width
= (GLfloat
) img
->Width
;
886 const GLfloat height
= (GLfloat
) img
->Height
;
887 const GLint colMask
= img
->Width
- 1;
888 const GLint rowMask
= img
->Height
- 1;
889 const GLint shift
= img
->WidthLog2
;
893 ASSERT(tObj
->WrapS
==GL_REPEAT
);
894 ASSERT(tObj
->WrapT
==GL_REPEAT
);
895 ASSERT(tObj
->MinFilter
==GL_NEAREST
);
896 ASSERT(tObj
->MagFilter
==GL_NEAREST
);
897 ASSERT(img
->Border
==0);
898 ASSERT(img
->Format
==GL_RGBA
);
900 /* NOTE: negative float->int doesn't floor, add 10000 as to work-around */
902 GLint i
= (GLint
) ((s
[k
] + 10000.0) * width
) & colMask
;
903 GLint j
= (GLint
) ((t
[k
] + 10000.0) * height
) & rowMask
;
904 GLint pos
= (j
<< shift
) | i
;
905 GLchan
*texel
= ((GLchan
*) img
->Data
) + (pos
<< 2); /* pos*4 */
906 rgba
[k
][RCOMP
] = texel
[0];
907 rgba
[k
][GCOMP
] = texel
[1];
908 rgba
[k
][BCOMP
] = texel
[2];
909 rgba
[k
][ACOMP
] = texel
[3];
915 /**********************************************************************/
916 /* 3-D Texture Sampling Functions */
917 /**********************************************************************/
920 * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
923 sample_3d_nearest(GLcontext
*ctx
,
924 const struct gl_texture_object
*tObj
,
925 const struct gl_texture_image
*img
,
926 GLfloat s
, GLfloat t
, GLfloat r
,
929 const GLint width
= img
->Width2
; /* without border, power of two */
930 const GLint height
= img
->Height2
; /* without border, power of two */
931 const GLint depth
= img
->Depth2
; /* without border, power of two */
934 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapS
, s
, width
, i
);
935 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapT
, t
, height
, j
);
936 COMPUTE_NEAREST_TEXEL_LOCATION(tObj
->WrapR
, r
, depth
, k
);
938 (*img
->FetchTexel
)(img
, i
, j
, k
, (GLvoid
*) rgba
);
939 if (img
->Format
== GL_COLOR_INDEX
) {
940 palette_sample(ctx
, tObj
, rgba
[0], rgba
);
947 * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
950 sample_3d_linear(GLcontext
*ctx
,
951 const struct gl_texture_object
*tObj
,
952 const struct gl_texture_image
*img
,
953 GLfloat s
, GLfloat t
, GLfloat r
,
956 const GLint width
= img
->Width2
;
957 const GLint height
= img
->Height2
;
958 const GLint depth
= img
->Depth2
;
959 GLint i0
, j0
, k0
, i1
, j1
, k1
;
960 GLuint useBorderColor
;
963 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapS
, s
, u
, width
, i0
, i1
);
964 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapT
, t
, v
, height
, j0
, j1
);
965 COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj
->WrapR
, r
, w
, depth
, k0
, k1
);
977 /* check if sampling texture border color */
978 if (i0
< 0 || i0
>= width
) useBorderColor
|= I0BIT
;
979 if (i1
< 0 || i1
>= width
) useBorderColor
|= I1BIT
;
980 if (j0
< 0 || j0
>= height
) useBorderColor
|= J0BIT
;
981 if (j1
< 0 || j1
>= height
) useBorderColor
|= J1BIT
;
982 if (k0
< 0 || k0
>= depth
) useBorderColor
|= K0BIT
;
983 if (k1
< 0 || k1
>= depth
) useBorderColor
|= K1BIT
;
987 const GLfloat a
= FRAC(u
);
988 const GLfloat b
= FRAC(v
);
989 const GLfloat c
= FRAC(w
);
990 /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
991 GLint w000
= (GLint
) ((1.0F
-a
)*(1.0F
-b
)*(1.0F
-c
) * WEIGHT_SCALE
+ 0.5F
);
992 GLint w100
= (GLint
) ( a
*(1.0F
-b
)*(1.0F
-c
) * WEIGHT_SCALE
+ 0.5F
);
993 GLint w010
= (GLint
) ((1.0F
-a
)* b
*(1.0F
-c
) * WEIGHT_SCALE
+ 0.5F
);
994 GLint w110
= (GLint
) ( a
* b
*(1.0F
-c
) * WEIGHT_SCALE
+ 0.5F
);
995 GLint w001
= (GLint
) ((1.0F
-a
)*(1.0F
-b
)* c
* WEIGHT_SCALE
+ 0.5F
);
996 GLint w101
= (GLint
) ( a
*(1.0F
-b
)* c
* WEIGHT_SCALE
+ 0.5F
);
997 GLint w011
= (GLint
) ((1.0F
-a
)* b
* c
* WEIGHT_SCALE
+ 0.5F
);
998 GLint w111
= (GLint
) ( a
* b
* c
* WEIGHT_SCALE
+ 0.5F
);
1000 GLchan t000
[4], t010
[4], t001
[4], t011
[4];
1001 GLchan t100
[4], t110
[4], t101
[4], t111
[4];
1003 if (useBorderColor
& (I0BIT
| J0BIT
| K0BIT
)) {
1004 COPY_CHAN4(t000
, tObj
->BorderColor
);
1007 (*img
->FetchTexel
)(img
, i0
, j0
, k0
, (GLvoid
*) t000
);
1008 if (img
->Format
== GL_COLOR_INDEX
) {
1009 palette_sample(ctx
, tObj
, t000
[0], t000
);
1012 if (useBorderColor
& (I1BIT
| J0BIT
| K0BIT
)) {
1013 COPY_CHAN4(t100
, tObj
->BorderColor
);
1016 (*img
->FetchTexel
)(img
, i1
, j0
, k0
, (GLvoid
*) t100
);
1017 if (img
->Format
== GL_COLOR_INDEX
) {
1018 palette_sample(ctx
, tObj
, t100
[0], t100
);
1021 if (useBorderColor
& (I0BIT
| J1BIT
| K0BIT
)) {
1022 COPY_CHAN4(t010
, tObj
->BorderColor
);
1025 (*img
->FetchTexel
)(img
, i0
, j1
, k0
, (GLvoid
*) t010
);
1026 if (img
->Format
== GL_COLOR_INDEX
) {
1027 palette_sample(ctx
, tObj
, t010
[0], t010
);
1030 if (useBorderColor
& (I1BIT
| J1BIT
| K0BIT
)) {
1031 COPY_CHAN4(t110
, tObj
->BorderColor
);
1034 (*img
->FetchTexel
)(img
, i1
, j1
, k0
, (GLvoid
*) t110
);
1035 if (img
->Format
== GL_COLOR_INDEX
) {
1036 palette_sample(ctx
, tObj
, t110
[0], t110
);
1040 if (useBorderColor
& (I0BIT
| J0BIT
| K1BIT
)) {
1041 COPY_CHAN4(t001
, tObj
->BorderColor
);
1044 (*img
->FetchTexel
)(img
, i0
, j0
, k1
, (GLvoid
*) t001
);
1045 if (img
->Format
== GL_COLOR_INDEX
) {
1046 palette_sample(ctx
, tObj
, t001
[0], t001
);
1049 if (useBorderColor
& (I1BIT
| J0BIT
| K1BIT
)) {
1050 COPY_CHAN4(t101
, tObj
->BorderColor
);
1053 (*img
->FetchTexel
)(img
, i1
, j0
, k1
, (GLvoid
*) t101
);
1054 if (img
->Format
== GL_COLOR_INDEX
) {
1055 palette_sample(ctx
, tObj
, t101
[0], t101
);
1058 if (useBorderColor
& (I0BIT
| J1BIT
| K1BIT
)) {
1059 COPY_CHAN4(t011
, tObj
->BorderColor
);
1062 (*img
->FetchTexel
)(img
, i0
, j1
, k1
, (GLvoid
*) t011
);
1063 if (img
->Format
== GL_COLOR_INDEX
) {
1064 palette_sample(ctx
, tObj
, t011
[0], t011
);
1067 if (useBorderColor
& (I1BIT
| J1BIT
| K1BIT
)) {
1068 COPY_CHAN4(t111
, tObj
->BorderColor
);
1071 (*img
->FetchTexel
)(img
, i1
, j1
, k1
, (GLvoid
*) t111
);
1072 if (img
->Format
== GL_COLOR_INDEX
) {
1073 palette_sample(ctx
, tObj
, t111
[0], t111
);
1077 rgba
[0] = (GLchan
) (
1078 (w000
*t000
[0] + w010
*t010
[0] + w001
*t001
[0] + w011
*t011
[0] +
1079 w100
*t100
[0] + w110
*t110
[0] + w101
*t101
[0] + w111
*t111
[0] )
1081 rgba
[1] = (GLchan
) (
1082 (w000
*t000
[1] + w010
*t010
[1] + w001
*t001
[1] + w011
*t011
[1] +
1083 w100
*t100
[1] + w110
*t110
[1] + w101
*t101
[1] + w111
*t111
[1] )
1085 rgba
[2] = (GLchan
) (
1086 (w000
*t000
[2] + w010
*t010
[2] + w001
*t001
[2] + w011
*t011
[2] +
1087 w100
*t100
[2] + w110
*t110
[2] + w101
*t101
[2] + w111
*t111
[2] )
1089 rgba
[3] = (GLchan
) (
1090 (w000
*t000
[3] + w010
*t010
[3] + w001
*t001
[3] + w011
*t011
[3] +
1091 w100
*t100
[3] + w110
*t110
[3] + w101
*t101
[3] + w111
*t111
[3] )
1099 sample_3d_nearest_mipmap_nearest(GLcontext
*ctx
,
1100 const struct gl_texture_object
*tObj
,
1101 GLfloat s
, GLfloat t
, GLfloat r
,
1102 GLfloat lambda
, GLchan rgba
[4] )
1105 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1106 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, t
, r
, rgba
);
1111 sample_3d_linear_mipmap_nearest(GLcontext
*ctx
,
1112 const struct gl_texture_object
*tObj
,
1113 GLfloat s
, GLfloat t
, GLfloat r
,
1114 GLfloat lambda
, GLchan rgba
[4])
1117 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1118 sample_3d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, t
, r
, rgba
);
1123 sample_3d_nearest_mipmap_linear(GLcontext
*ctx
,
1124 const struct gl_texture_object
*tObj
,
1125 GLfloat s
, GLfloat t
, GLfloat r
,
1126 GLfloat lambda
, GLchan rgba
[4])
1130 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1132 if (level
>= tObj
->_MaxLevel
) {
1133 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
],
1137 GLchan t0
[4], t1
[4]; /* texels */
1138 const GLfloat f
= FRAC(lambda
);
1139 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[level
], s
, t
, r
, t0
);
1140 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[level
+1], s
, t
, r
, t1
);
1141 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1142 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1143 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1144 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1150 sample_3d_linear_mipmap_linear(GLcontext
*ctx
,
1151 const struct gl_texture_object
*tObj
,
1152 GLfloat s
, GLfloat t
, GLfloat r
,
1153 GLfloat lambda
, GLchan rgba
[4] )
1157 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1159 if (level
>= tObj
->_MaxLevel
) {
1160 sample_3d_linear(ctx
, tObj
, tObj
->Image
[tObj
->_MaxLevel
], s
, t
, r
, rgba
);
1163 GLchan t0
[4], t1
[4]; /* texels */
1164 const GLfloat f
= FRAC(lambda
);
1165 sample_3d_linear(ctx
, tObj
, tObj
->Image
[level
], s
, t
, r
, t0
);
1166 sample_3d_linear(ctx
, tObj
, tObj
->Image
[level
+1], s
, t
, r
, t1
);
1167 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1168 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1169 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1170 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1176 sample_nearest_3d(GLcontext
*ctx
, GLuint texUnit
,
1177 const struct gl_texture_object
*tObj
, GLuint n
,
1178 const GLfloat s
[], const GLfloat t
[],
1179 const GLfloat u
[], const GLfloat lambda
[],
1183 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
1186 sample_3d_nearest(ctx
, tObj
, image
, s
[i
], t
[i
], u
[i
], rgba
[i
]);
1193 sample_linear_3d( GLcontext
*ctx
, GLuint texUnit
,
1194 const struct gl_texture_object
*tObj
, GLuint n
,
1195 const GLfloat s
[], const GLfloat t
[],
1196 const GLfloat u
[], const GLfloat lambda
[],
1200 struct gl_texture_image
*image
= tObj
->Image
[tObj
->BaseLevel
];
1203 sample_3d_linear(ctx
, tObj
, image
, s
[i
], t
[i
], u
[i
], rgba
[i
]);
1209 * Given an (s,t,r) texture coordinate and lambda (level of detail) value,
1210 * return a texture sample.
1213 sample_lambda_3d( GLcontext
*ctx
, GLuint texUnit
,
1214 const struct gl_texture_object
*tObj
, GLuint n
,
1215 const GLfloat s
[], const GLfloat t
[],
1216 const GLfloat u
[], const GLfloat lambda
[],
1220 GLfloat MinMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
1224 if (lambda
[i
] > MinMagThresh
) {
1226 switch (tObj
->MinFilter
) {
1228 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1229 s
[i
], t
[i
], u
[i
], rgba
[i
]);
1232 sample_3d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1233 s
[i
], t
[i
], u
[i
], rgba
[i
]);
1235 case GL_NEAREST_MIPMAP_NEAREST
:
1236 sample_3d_nearest_mipmap_nearest(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1237 lambda
[i
], rgba
[i
]);
1239 case GL_LINEAR_MIPMAP_NEAREST
:
1240 sample_3d_linear_mipmap_nearest(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1241 lambda
[i
], rgba
[i
]);
1243 case GL_NEAREST_MIPMAP_LINEAR
:
1244 sample_3d_nearest_mipmap_linear(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1245 lambda
[i
], rgba
[i
]);
1247 case GL_LINEAR_MIPMAP_LINEAR
:
1248 sample_3d_linear_mipmap_linear(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1249 lambda
[i
], rgba
[i
]);
1252 _mesa_problem(NULL
, "Bad min filterin sample_3d_texture");
1257 switch (tObj
->MagFilter
) {
1259 sample_3d_nearest(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1260 s
[i
], t
[i
], u
[i
], rgba
[i
]);
1263 sample_3d_linear(ctx
, tObj
, tObj
->Image
[tObj
->BaseLevel
],
1264 s
[i
], t
[i
], u
[i
], rgba
[i
]);
1267 _mesa_problem(NULL
, "Bad mag filter in sample_3d_texture");
1274 /**********************************************************************/
1275 /* Texture Cube Map Sampling Functions */
1276 /**********************************************************************/
1279 * Choose one of six sides of a texture cube map given the texture
1280 * coord (rx,ry,rz). Return pointer to corresponding array of texture
1283 static const struct gl_texture_image
**
1284 choose_cube_face(const struct gl_texture_object
*texObj
,
1285 GLfloat rx
, GLfloat ry
, GLfloat rz
,
1286 GLfloat
*newS
, GLfloat
*newT
)
1290 direction target sc tc ma
1291 ---------- ------------------------------- --- --- ---
1292 +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
1293 -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
1294 +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
1295 -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry
1296 +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
1297 -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
1299 const struct gl_texture_image
**imgArray
;
1300 const GLfloat arx
= ABSF(rx
), ary
= ABSF(ry
), arz
= ABSF(rz
);
1303 if (arx
> ary
&& arx
> arz
) {
1305 imgArray
= (const struct gl_texture_image
**) texObj
->Image
;
1311 imgArray
= (const struct gl_texture_image
**) texObj
->NegX
;
1317 else if (ary
> arx
&& ary
> arz
) {
1319 imgArray
= (const struct gl_texture_image
**) texObj
->PosY
;
1325 imgArray
= (const struct gl_texture_image
**) texObj
->NegY
;
1333 imgArray
= (const struct gl_texture_image
**) texObj
->PosZ
;
1339 imgArray
= (const struct gl_texture_image
**) texObj
->NegZ
;
1346 *newS
= ( sc
/ ma
+ 1.0F
) * 0.5F
;
1347 *newT
= ( tc
/ ma
+ 1.0F
) * 0.5F
;
1353 sample_nearest_cube(GLcontext
*ctx
, GLuint texUnit
,
1354 const struct gl_texture_object
*tObj
, GLuint n
,
1355 const GLfloat s
[], const GLfloat t
[],
1356 const GLfloat u
[], const GLfloat lambda
[],
1361 for (i
= 0; i
< n
; i
++) {
1362 const struct gl_texture_image
**images
;
1364 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
], &newS
, &newT
);
1365 sample_2d_nearest(ctx
, tObj
, images
[tObj
->BaseLevel
],
1366 newS
, newT
, rgba
[i
]);
1372 sample_linear_cube(GLcontext
*ctx
, GLuint texUnit
,
1373 const struct gl_texture_object
*tObj
, GLuint n
,
1374 const GLfloat s
[], const GLfloat t
[],
1375 const GLfloat u
[], const GLfloat lambda
[],
1380 for (i
= 0; i
< n
; i
++) {
1381 const struct gl_texture_image
**images
;
1383 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
], &newS
, &newT
);
1384 sample_2d_linear(ctx
, tObj
, images
[tObj
->BaseLevel
],
1385 newS
, newT
, rgba
[i
]);
1391 sample_cube_nearest_mipmap_nearest(GLcontext
*ctx
,
1392 const struct gl_texture_object
*tObj
,
1393 GLfloat s
, GLfloat t
, GLfloat u
,
1394 GLfloat lambda
, GLchan rgba
[4])
1396 const struct gl_texture_image
**images
;
1400 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1402 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1403 sample_2d_nearest(ctx
, tObj
, images
[level
], newS
, newT
, rgba
);
1408 sample_cube_linear_mipmap_nearest(GLcontext
*ctx
,
1409 const struct gl_texture_object
*tObj
,
1410 GLfloat s
, GLfloat t
, GLfloat u
,
1411 GLfloat lambda
, GLchan rgba
[4])
1413 const struct gl_texture_image
**images
;
1417 COMPUTE_NEAREST_MIPMAP_LEVEL(tObj
, lambda
, level
);
1419 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1420 sample_2d_linear(ctx
, tObj
, images
[level
], newS
, newT
, rgba
);
1425 sample_cube_nearest_mipmap_linear(GLcontext
*ctx
,
1426 const struct gl_texture_object
*tObj
,
1427 GLfloat s
, GLfloat t
, GLfloat u
,
1428 GLfloat lambda
, GLchan rgba
[4])
1430 const struct gl_texture_image
**images
;
1434 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1436 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1438 if (level
>= tObj
->_MaxLevel
) {
1439 sample_2d_nearest(ctx
, tObj
, images
[tObj
->_MaxLevel
], newS
, newT
, rgba
);
1442 GLchan t0
[4], t1
[4]; /* texels */
1443 const GLfloat f
= FRAC(lambda
);
1444 sample_2d_nearest(ctx
, tObj
, images
[level
], newS
, newT
, t0
);
1445 sample_2d_nearest(ctx
, tObj
, images
[level
+1], newS
, newT
, t1
);
1446 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1447 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1448 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1449 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1455 sample_cube_linear_mipmap_linear(GLcontext
*ctx
,
1456 const struct gl_texture_object
*tObj
,
1457 GLfloat s
, GLfloat t
, GLfloat u
,
1458 GLfloat lambda
, GLchan rgba
[4])
1460 const struct gl_texture_image
**images
;
1464 COMPUTE_LINEAR_MIPMAP_LEVEL(tObj
, lambda
, level
);
1466 images
= choose_cube_face(tObj
, s
, t
, u
, &newS
, &newT
);
1468 if (level
>= tObj
->_MaxLevel
) {
1469 sample_2d_linear(ctx
, tObj
, images
[tObj
->_MaxLevel
], newS
, newT
, rgba
);
1472 GLchan t0
[4], t1
[4];
1473 const GLfloat f
= FRAC(lambda
);
1474 sample_2d_linear(ctx
, tObj
, images
[level
], newS
, newT
, t0
);
1475 sample_2d_linear(ctx
, tObj
, images
[level
+1], newS
, newT
, t1
);
1476 rgba
[RCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[RCOMP
] + f
* t1
[RCOMP
]);
1477 rgba
[GCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[GCOMP
] + f
* t1
[GCOMP
]);
1478 rgba
[BCOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[BCOMP
] + f
* t1
[BCOMP
]);
1479 rgba
[ACOMP
] = (GLchan
) (GLint
) ((1.0F
-f
) * t0
[ACOMP
] + f
* t1
[ACOMP
]);
1485 sample_lambda_cube( GLcontext
*ctx
, GLuint texUnit
,
1486 const struct gl_texture_object
*tObj
, GLuint n
,
1487 const GLfloat s
[], const GLfloat t
[],
1488 const GLfloat u
[], const GLfloat lambda
[],
1491 GLfloat MinMagThresh
= SWRAST_CONTEXT(ctx
)->_MinMagThresh
[texUnit
];
1494 for (i
= 0; i
< n
; i
++) {
1495 if (lambda
[i
] > MinMagThresh
) {
1497 switch (tObj
->MinFilter
) {
1500 const struct gl_texture_image
**images
;
1502 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
],
1504 sample_2d_nearest(ctx
, tObj
, images
[tObj
->BaseLevel
],
1505 newS
, newT
, rgba
[i
]);
1510 const struct gl_texture_image
**images
;
1512 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
],
1514 sample_2d_linear(ctx
, tObj
, images
[tObj
->BaseLevel
],
1515 newS
, newT
, rgba
[i
]);
1518 case GL_NEAREST_MIPMAP_NEAREST
:
1519 sample_cube_nearest_mipmap_nearest(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1520 lambda
[i
], rgba
[i
]);
1522 case GL_LINEAR_MIPMAP_NEAREST
:
1523 sample_cube_linear_mipmap_nearest(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1524 lambda
[i
], rgba
[i
]);
1526 case GL_NEAREST_MIPMAP_LINEAR
:
1527 sample_cube_nearest_mipmap_linear(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1528 lambda
[i
], rgba
[i
]);
1530 case GL_LINEAR_MIPMAP_LINEAR
:
1531 sample_cube_linear_mipmap_linear(ctx
, tObj
, s
[i
], t
[i
], u
[i
],
1532 lambda
[i
], rgba
[i
]);
1535 _mesa_problem(NULL
, "Bad min filter in sample_lambda_cube");
1540 const struct gl_texture_image
**images
;
1542 images
= choose_cube_face(tObj
, s
[i
], t
[i
], u
[i
],
1544 switch (tObj
->MagFilter
) {
1546 sample_2d_nearest(ctx
, tObj
, images
[tObj
->BaseLevel
],
1547 newS
, newT
, rgba
[i
]);
1550 sample_2d_linear(ctx
, tObj
, images
[tObj
->BaseLevel
],
1551 newS
, newT
, rgba
[i
]);
1554 _mesa_problem(NULL
, "Bad mag filter in sample_lambda_cube");
1561 null_sample_func( GLcontext
*ctx
, GLuint texUnit
,
1562 const struct gl_texture_object
*tObj
, GLuint n
,
1563 const GLfloat s
[], const GLfloat t
[],
1564 const GLfloat u
[], const GLfloat lambda
[],
1569 /**********************************************************************/
1570 /* Texture Sampling Setup */
1571 /**********************************************************************/
1575 * Setup the texture sampling function for this texture object.
1578 _swrast_choose_texture_sample_func( GLcontext
*ctx
, GLuint texUnit
,
1579 const struct gl_texture_object
*t
)
1581 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
1584 swrast
->TextureSample
[texUnit
] = null_sample_func
;
1587 GLboolean needLambda
= (GLboolean
) (t
->MinFilter
!= t
->MagFilter
);
1590 /* Compute min/mag filter threshold */
1591 if (t
->MagFilter
== GL_LINEAR
1592 && (t
->MinFilter
== GL_NEAREST_MIPMAP_NEAREST
||
1593 t
->MinFilter
== GL_NEAREST_MIPMAP_LINEAR
)) {
1594 swrast
->_MinMagThresh
[texUnit
] = 0.5F
;
1597 swrast
->_MinMagThresh
[texUnit
] = 0.0F
;
1601 switch (t
->Dimensions
) {
1604 swrast
->TextureSample
[texUnit
] = sample_lambda_1d
;
1606 else if (t
->MinFilter
==GL_LINEAR
) {
1607 swrast
->TextureSample
[texUnit
] = sample_linear_1d
;
1610 ASSERT(t
->MinFilter
==GL_NEAREST
);
1611 swrast
->TextureSample
[texUnit
] = sample_nearest_1d
;
1616 swrast
->TextureSample
[texUnit
] = sample_lambda_2d
;
1618 else if (t
->MinFilter
==GL_LINEAR
) {
1619 swrast
->TextureSample
[texUnit
] = sample_linear_2d
;
1622 GLint baseLevel
= t
->BaseLevel
;
1623 ASSERT(t
->MinFilter
==GL_NEAREST
);
1624 if (t
->WrapS
== GL_REPEAT
&&
1625 t
->WrapT
== GL_REPEAT
&&
1626 t
->Image
[baseLevel
]->Border
== 0 &&
1627 t
->Image
[baseLevel
]->Format
== GL_RGB
&&
1628 t
->Image
[baseLevel
]->Type
== CHAN_TYPE
) {
1629 swrast
->TextureSample
[texUnit
] = opt_sample_rgb_2d
;
1631 else if (t
->WrapS
== GL_REPEAT
&&
1632 t
->WrapT
== GL_REPEAT
&&
1633 t
->Image
[baseLevel
]->Border
== 0 &&
1634 t
->Image
[baseLevel
]->Format
==GL_RGBA
&&
1635 t
->Image
[baseLevel
]->Type
== CHAN_TYPE
) {
1636 swrast
->TextureSample
[texUnit
] = opt_sample_rgba_2d
;
1639 swrast
->TextureSample
[texUnit
] = sample_nearest_2d
;
1644 swrast
->TextureSample
[texUnit
] = sample_lambda_3d
;
1646 else if (t
->MinFilter
==GL_LINEAR
) {
1647 swrast
->TextureSample
[texUnit
] = sample_linear_3d
;
1650 ASSERT(t
->MinFilter
==GL_NEAREST
);
1651 swrast
->TextureSample
[texUnit
] = sample_nearest_3d
;
1654 case 6: /* cube map */
1656 swrast
->TextureSample
[texUnit
] = sample_lambda_cube
;
1658 else if (t
->MinFilter
==GL_LINEAR
) {
1659 swrast
->TextureSample
[texUnit
] = sample_linear_cube
;
1662 ASSERT(t
->MinFilter
==GL_NEAREST
);
1663 swrast
->TextureSample
[texUnit
] = sample_nearest_cube
;
1667 _mesa_problem(NULL
, "invalid dimensions in _mesa_set_texture_sampler");
1673 #define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) )
1674 #define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) )
1677 texture_combine(const GLcontext
*ctx
,
1678 const struct gl_texture_unit
*textureUnit
,
1680 CONST
GLchan (*primary_rgba
)[4],
1681 CONST
GLchan (*texel
)[4],
1684 GLchan ccolor
[3][3*MAX_WIDTH
][4];
1685 const GLchan (*argRGB
[3])[4];
1686 const GLchan (*argA
[3])[4];
1688 const GLuint RGBshift
= textureUnit
->CombineScaleShiftRGB
;
1689 const GLuint Ashift
= textureUnit
->CombineScaleShiftA
;
1691 ASSERT(ctx
->Extensions
.EXT_texture_env_combine
);
1693 for (j
= 0; j
< 3; j
++) {
1694 switch (textureUnit
->CombineSourceA
[j
]) {
1698 case GL_PRIMARY_COLOR_EXT
:
1699 argA
[j
] = primary_rgba
;
1701 case GL_PREVIOUS_EXT
:
1702 argA
[j
] = (const GLchan (*)[4]) rgba
;
1704 case GL_CONSTANT_EXT
:
1706 GLchan alpha
, (*c
)[4] = ccolor
[j
];
1707 UNCLAMPED_FLOAT_TO_CHAN(alpha
, textureUnit
->EnvColor
[3]);
1708 for (i
= 0; i
< n
; i
++)
1709 c
[i
][ACOMP
] = alpha
;
1710 argA
[j
] = (const GLchan (*)[4]) ccolor
[j
];
1714 _mesa_problem(NULL
, "invalid combine source");
1717 switch (textureUnit
->CombineSourceRGB
[j
]) {
1721 case GL_PRIMARY_COLOR_EXT
:
1722 argRGB
[j
] = primary_rgba
;
1724 case GL_PREVIOUS_EXT
:
1725 argRGB
[j
] = (const GLchan (*)[4]) rgba
;
1727 case GL_CONSTANT_EXT
:
1729 GLchan (*c
)[4] = ccolor
[j
];
1730 GLchan red
, green
, blue
;
1731 UNCLAMPED_FLOAT_TO_CHAN(red
, textureUnit
->EnvColor
[0]);
1732 UNCLAMPED_FLOAT_TO_CHAN(green
, textureUnit
->EnvColor
[1]);
1733 UNCLAMPED_FLOAT_TO_CHAN(blue
, textureUnit
->EnvColor
[2]);
1734 for (i
= 0; i
< n
; i
++) {
1736 c
[i
][GCOMP
] = green
;
1739 argRGB
[j
] = (const GLchan (*)[4]) ccolor
[j
];
1743 _mesa_problem(NULL
, "invalid combine source");
1746 if (textureUnit
->CombineOperandRGB
[j
] != GL_SRC_COLOR
) {
1747 const GLchan (*src
)[4] = argRGB
[j
];
1748 GLchan (*dst
)[4] = ccolor
[j
];
1750 argRGB
[j
] = (const GLchan (*)[4]) ccolor
[j
];
1752 if (textureUnit
->CombineOperandRGB
[j
] == GL_ONE_MINUS_SRC_COLOR
) {
1753 for (i
= 0; i
< n
; i
++) {
1754 dst
[i
][RCOMP
] = CHAN_MAX
- src
[i
][RCOMP
];
1755 dst
[i
][GCOMP
] = CHAN_MAX
- src
[i
][GCOMP
];
1756 dst
[i
][BCOMP
] = CHAN_MAX
- src
[i
][BCOMP
];
1759 else if (textureUnit
->CombineOperandRGB
[j
] == GL_SRC_ALPHA
) {
1760 src
= (const GLchan (*)[4]) argA
[j
];
1761 for (i
= 0; i
< n
; i
++) {
1762 dst
[i
][RCOMP
] = src
[i
][ACOMP
];
1763 dst
[i
][GCOMP
] = src
[i
][ACOMP
];
1764 dst
[i
][BCOMP
] = src
[i
][ACOMP
];
1767 else { /* GL_ONE_MINUS_SRC_ALPHA */
1768 src
= (const GLchan (*)[4]) argA
[j
];
1769 for (i
= 0; i
< n
; i
++) {
1770 dst
[i
][RCOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
1771 dst
[i
][GCOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
1772 dst
[i
][BCOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
1777 if (textureUnit
->CombineOperandA
[j
] == GL_ONE_MINUS_SRC_ALPHA
) {
1778 const GLchan (*src
)[4] = argA
[j
];
1779 GLchan (*dst
)[4] = ccolor
[j
];
1780 argA
[j
] = (const GLchan (*)[4]) ccolor
[j
];
1781 for (i
= 0; i
< n
; i
++) {
1782 dst
[i
][ACOMP
] = CHAN_MAX
- src
[i
][ACOMP
];
1786 if (textureUnit
->CombineModeRGB
== GL_REPLACE
&&
1787 textureUnit
->CombineModeA
== GL_REPLACE
) {
1788 break; /* done, we need only arg0 */
1792 textureUnit
->CombineModeRGB
!= GL_INTERPOLATE_EXT
&&
1793 textureUnit
->CombineModeA
!= GL_INTERPOLATE_EXT
) {
1794 break; /* arg0 and arg1 are done. we don't need arg2. */
1798 switch (textureUnit
->CombineModeRGB
) {
1801 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
1803 for (i
= 0; i
< n
; i
++) {
1804 GLuint r
= (GLuint
) arg0
[i
][RCOMP
] << RGBshift
;
1805 GLuint g
= (GLuint
) arg0
[i
][GCOMP
] << RGBshift
;
1806 GLuint b
= (GLuint
) arg0
[i
][BCOMP
] << RGBshift
;
1807 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
1808 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
1809 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
1813 for (i
= 0; i
< n
; i
++) {
1814 rgba
[i
][RCOMP
] = arg0
[i
][RCOMP
];
1815 rgba
[i
][GCOMP
] = arg0
[i
][GCOMP
];
1816 rgba
[i
][BCOMP
] = arg0
[i
][BCOMP
];
1823 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
1824 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
1825 const GLint shift
= 8 - RGBshift
;
1826 for (i
= 0; i
< n
; i
++) {
1827 GLuint r
= PROD(arg0
[i
][0], arg1
[i
][RCOMP
]) >> shift
;
1828 GLuint g
= PROD(arg0
[i
][1], arg1
[i
][GCOMP
]) >> shift
;
1829 GLuint b
= PROD(arg0
[i
][2], arg1
[i
][BCOMP
]) >> shift
;
1830 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
1831 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
1832 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
1838 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
1839 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
1840 for (i
= 0; i
< n
; i
++) {
1841 GLint r
= ((GLint
) arg0
[i
][RCOMP
] + (GLint
) arg1
[i
][RCOMP
]) << RGBshift
;
1842 GLint g
= ((GLint
) arg0
[i
][GCOMP
] + (GLint
) arg1
[i
][GCOMP
]) << RGBshift
;
1843 GLint b
= ((GLint
) arg0
[i
][BCOMP
] + (GLint
) arg1
[i
][BCOMP
]) << RGBshift
;
1844 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
1845 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
1846 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
1850 case GL_ADD_SIGNED_EXT
:
1852 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
1853 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
1854 for (i
= 0; i
< n
; i
++) {
1855 GLint r
= (GLint
) arg0
[i
][RCOMP
] + (GLint
) arg1
[i
][RCOMP
] - 128;
1856 GLint g
= (GLint
) arg0
[i
][GCOMP
] + (GLint
) arg1
[i
][GCOMP
] - 128;
1857 GLint b
= (GLint
) arg0
[i
][BCOMP
] + (GLint
) arg1
[i
][BCOMP
] - 128;
1858 r
= (r
< 0) ? 0 : r
<< RGBshift
;
1859 g
= (g
< 0) ? 0 : g
<< RGBshift
;
1860 b
= (b
< 0) ? 0 : b
<< RGBshift
;
1861 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
1862 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
1863 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
1867 case GL_INTERPOLATE_EXT
:
1869 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argRGB
[0];
1870 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argRGB
[1];
1871 const GLchan (*arg2
)[4] = (const GLchan (*)[4]) argRGB
[2];
1872 const GLint shift
= 8 - RGBshift
;
1873 for (i
= 0; i
< n
; i
++) {
1874 GLuint r
= (PROD(arg0
[i
][RCOMP
], arg2
[i
][RCOMP
])
1875 + PROD(arg1
[i
][RCOMP
], CHAN_MAX
- arg2
[i
][RCOMP
]))
1877 GLuint g
= (PROD(arg0
[i
][GCOMP
], arg2
[i
][GCOMP
])
1878 + PROD(arg1
[i
][GCOMP
], CHAN_MAX
- arg2
[i
][GCOMP
]))
1880 GLuint b
= (PROD(arg0
[i
][BCOMP
], arg2
[i
][BCOMP
])
1881 + PROD(arg1
[i
][BCOMP
], CHAN_MAX
- arg2
[i
][BCOMP
]))
1883 rgba
[i
][RCOMP
] = (GLchan
) MIN2(r
, CHAN_MAX
);
1884 rgba
[i
][GCOMP
] = (GLchan
) MIN2(g
, CHAN_MAX
);
1885 rgba
[i
][BCOMP
] = (GLchan
) MIN2(b
, CHAN_MAX
);
1889 case GL_DOT3_RGB_EXT
:
1890 case GL_DOT3_RGBA_EXT
:
1892 const GLubyte (*arg0
)[4] = (const GLubyte (*)[4]) argRGB
[0];
1893 const GLubyte (*arg1
)[4] = (const GLubyte (*)[4]) argRGB
[1];
1894 /* ATI's EXT extension has a constant scale by 4. The ARB
1895 * one will likely remove this restriction, and we should
1896 * drop the EXT extension in favour of the ARB one.
1898 for (i
= 0; i
< n
; i
++) {
1899 GLint dot
= (S_PROD((GLint
)arg0
[i
][RCOMP
] - 128,
1900 (GLint
)arg1
[i
][RCOMP
] - 128) +
1901 S_PROD((GLint
)arg0
[i
][GCOMP
] - 128,
1902 (GLint
)arg1
[i
][GCOMP
] - 128) +
1903 S_PROD((GLint
)arg0
[i
][BCOMP
] - 128,
1904 (GLint
)arg1
[i
][BCOMP
] - 128)) >> 6;
1905 rgba
[i
][RCOMP
] = (GLubyte
) CLAMP(dot
, 0, 255);
1906 rgba
[i
][GCOMP
] = (GLubyte
) CLAMP(dot
, 0, 255);
1907 rgba
[i
][BCOMP
] = (GLubyte
) CLAMP(dot
, 0, 255);
1912 _mesa_problem(NULL
, "invalid combine mode");
1915 switch (textureUnit
->CombineModeA
) {
1918 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
1920 for (i
= 0; i
< n
; i
++) {
1921 GLuint a
= (GLuint
) arg0
[i
][ACOMP
] << Ashift
;
1922 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
1926 for (i
= 0; i
< n
; i
++) {
1927 rgba
[i
][ACOMP
] = arg0
[i
][ACOMP
];
1934 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
1935 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
1936 const GLint shift
= 8 - Ashift
;
1937 for (i
= 0; i
< n
; i
++) {
1938 GLuint a
= (PROD(arg0
[i
][ACOMP
], arg1
[i
][ACOMP
]) >> shift
);
1939 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
1945 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
1946 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
1947 for (i
= 0; i
< n
; i
++) {
1948 GLint a
= ((GLint
) arg0
[i
][ACOMP
] + arg1
[i
][ACOMP
]) << Ashift
;
1949 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
1953 case GL_ADD_SIGNED_EXT
:
1955 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
1956 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
1957 for (i
= 0; i
< n
; i
++) {
1958 GLint a
= (GLint
) arg0
[i
][ACOMP
] + (GLint
) arg1
[i
][ACOMP
] - 128;
1959 a
= (a
< 0) ? 0 : a
<< Ashift
;
1960 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
1964 case GL_INTERPOLATE_EXT
:
1966 const GLchan (*arg0
)[4] = (const GLchan (*)[4]) argA
[0];
1967 const GLchan (*arg1
)[4] = (const GLchan (*)[4]) argA
[1];
1968 const GLchan (*arg2
)[4] = (const GLchan (*)[4]) argA
[2];
1969 const GLint shift
= 8 - Ashift
;
1970 for (i
=0; i
<n
; i
++) {
1971 GLuint a
= (PROD(arg0
[i
][ACOMP
], arg2
[i
][ACOMP
])
1972 + PROD(arg1
[i
][ACOMP
], CHAN_MAX
- arg2
[i
][ACOMP
]))
1974 rgba
[i
][ACOMP
] = (GLchan
) MIN2(a
, CHAN_MAX
);
1979 _mesa_problem(NULL
, "invalid combine mode");
1982 /* Fix the alpha component for GL_DOT3_RGBA_EXT combining.
1984 if (textureUnit
->CombineModeRGB
== GL_DOT3_RGBA_EXT
) {
1985 for (i
= 0; i
< n
; i
++) {
1986 rgba
[i
][ACOMP
] = rgba
[i
][RCOMP
];
1994 /**********************************************************************/
1995 /* Texture Application */
1996 /**********************************************************************/
2000 * Combine incoming fragment color with texel color to produce output color.
2001 * Input: textureUnit - pointer to texture unit to apply
2002 * format - base internal texture format
2003 * n - number of fragments
2004 * primary_rgba - primary colors (may alias rgba for single texture)
2005 * texels - array of texel colors
2006 * InOut: rgba - incoming fragment colors modified by texel colors
2007 * according to the texture environment mode.
2010 apply_texture( const GLcontext
*ctx
,
2011 const struct gl_texture_unit
*texUnit
,
2013 CONST GLchan primary_rgba
[][4], CONST GLchan texel
[][4],
2018 GLint Rc
, Gc
, Bc
, Ac
;
2022 ASSERT(texUnit
->_Current
);
2024 baseLevel
= texUnit
->_Current
->BaseLevel
;
2025 ASSERT(texUnit
->_Current
->Image
[baseLevel
]);
2027 format
= texUnit
->_Current
->Image
[baseLevel
]->Format
;
2029 if (format
==GL_COLOR_INDEX
|| format
==GL_DEPTH_COMPONENT
) {
2030 format
= GL_RGBA
; /* XXXX a hack! */
2033 switch (texUnit
->EnvMode
) {
2040 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
2046 GLchan Lt
= texel
[i
][RCOMP
];
2047 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = Lt
;
2051 case GL_LUMINANCE_ALPHA
:
2053 GLchan Lt
= texel
[i
][RCOMP
];
2055 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = Lt
;
2057 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
2063 GLchan It
= texel
[i
][RCOMP
];
2064 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = It
;
2066 rgba
[i
][ACOMP
] = It
;
2072 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
2073 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
2074 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
2081 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
2082 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
2083 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
2085 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
2089 _mesa_problem(ctx
, "Bad format (GL_REPLACE) in apply_texture");
2100 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], texel
[i
][ACOMP
] );
2106 GLchan Lt
= texel
[i
][RCOMP
];
2107 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], Lt
);
2108 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], Lt
);
2109 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], Lt
);
2113 case GL_LUMINANCE_ALPHA
:
2116 GLchan Lt
= texel
[i
][RCOMP
];
2117 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], Lt
);
2118 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], Lt
);
2119 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], Lt
);
2121 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], texel
[i
][ACOMP
] );
2127 GLchan It
= texel
[i
][RCOMP
];
2128 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], It
);
2129 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], It
);
2130 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], It
);
2132 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], It
);
2138 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], texel
[i
][RCOMP
] );
2139 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], texel
[i
][GCOMP
] );
2140 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], texel
[i
][BCOMP
] );
2147 rgba
[i
][RCOMP
] = CHAN_PRODUCT( rgba
[i
][RCOMP
], texel
[i
][RCOMP
] );
2148 rgba
[i
][GCOMP
] = CHAN_PRODUCT( rgba
[i
][GCOMP
], texel
[i
][GCOMP
] );
2149 rgba
[i
][BCOMP
] = CHAN_PRODUCT( rgba
[i
][BCOMP
], texel
[i
][BCOMP
] );
2151 rgba
[i
][ACOMP
] = CHAN_PRODUCT( rgba
[i
][ACOMP
], texel
[i
][ACOMP
] );
2155 _mesa_problem(ctx
, "Bad format (GL_MODULATE) in apply_texture");
2164 case GL_LUMINANCE_ALPHA
:
2171 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
2172 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
2173 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
2179 /* Cv = Cf(1-At) + CtAt */
2180 GLint t
= texel
[i
][ACOMP
], s
= CHAN_MAX
- t
;
2181 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(texel
[i
][RCOMP
],t
);
2182 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(texel
[i
][GCOMP
],t
);
2183 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(texel
[i
][BCOMP
],t
);
2188 _mesa_problem(ctx
, "Bad format (GL_DECAL) in apply_texture");
2194 Rc
= (GLint
) (texUnit
->EnvColor
[0] * CHAN_MAXF
);
2195 Gc
= (GLint
) (texUnit
->EnvColor
[1] * CHAN_MAXF
);
2196 Bc
= (GLint
) (texUnit
->EnvColor
[2] * CHAN_MAXF
);
2197 Ac
= (GLint
) (texUnit
->EnvColor
[3] * CHAN_MAXF
);
2203 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2208 /* Cv = Cf(1-Lt) + CcLt */
2209 GLchan Lt
= texel
[i
][RCOMP
], s
= CHAN_MAX
- Lt
;
2210 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(Rc
, Lt
);
2211 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(Gc
, Lt
);
2212 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(Bc
, Lt
);
2216 case GL_LUMINANCE_ALPHA
:
2218 /* Cv = Cf(1-Lt) + CcLt */
2219 GLchan Lt
= texel
[i
][RCOMP
], s
= CHAN_MAX
- Lt
;
2220 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(Rc
, Lt
);
2221 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(Gc
, Lt
);
2222 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(Bc
, Lt
);
2224 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
],texel
[i
][ACOMP
]);
2229 /* Cv = Cf(1-It) + CcLt */
2230 GLchan It
= texel
[i
][RCOMP
], s
= CHAN_MAX
- It
;
2231 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], s
) + CHAN_PRODUCT(Rc
, It
);
2232 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], s
) + CHAN_PRODUCT(Gc
, It
);
2233 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], s
) + CHAN_PRODUCT(Bc
, It
);
2234 /* Av = Af(1-It) + Ac*It */
2235 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], s
) + CHAN_PRODUCT(Ac
, It
);
2240 /* Cv = Cf(1-Ct) + CcCt */
2241 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], (CHAN_MAX
-texel
[i
][RCOMP
])) + CHAN_PRODUCT(Rc
,texel
[i
][RCOMP
]);
2242 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], (CHAN_MAX
-texel
[i
][GCOMP
])) + CHAN_PRODUCT(Gc
,texel
[i
][GCOMP
]);
2243 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], (CHAN_MAX
-texel
[i
][BCOMP
])) + CHAN_PRODUCT(Bc
,texel
[i
][BCOMP
]);
2249 /* Cv = Cf(1-Ct) + CcCt */
2250 rgba
[i
][RCOMP
] = CHAN_PRODUCT(rgba
[i
][RCOMP
], (CHAN_MAX
-texel
[i
][RCOMP
])) + CHAN_PRODUCT(Rc
,texel
[i
][RCOMP
]);
2251 rgba
[i
][GCOMP
] = CHAN_PRODUCT(rgba
[i
][GCOMP
], (CHAN_MAX
-texel
[i
][GCOMP
])) + CHAN_PRODUCT(Gc
,texel
[i
][GCOMP
]);
2252 rgba
[i
][BCOMP
] = CHAN_PRODUCT(rgba
[i
][BCOMP
], (CHAN_MAX
-texel
[i
][BCOMP
])) + CHAN_PRODUCT(Bc
,texel
[i
][BCOMP
]);
2254 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
],texel
[i
][ACOMP
]);
2258 _mesa_problem(ctx
, "Bad format (GL_BLEND) in apply_texture");
2263 case GL_ADD
: /* GL_EXT_texture_add_env */
2270 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2275 GLuint Lt
= texel
[i
][RCOMP
];
2276 GLuint r
= rgba
[i
][RCOMP
] + Lt
;
2277 GLuint g
= rgba
[i
][GCOMP
] + Lt
;
2278 GLuint b
= rgba
[i
][BCOMP
] + Lt
;
2279 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2280 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2281 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2285 case GL_LUMINANCE_ALPHA
:
2287 GLuint Lt
= texel
[i
][RCOMP
];
2288 GLuint r
= rgba
[i
][RCOMP
] + Lt
;
2289 GLuint g
= rgba
[i
][GCOMP
] + Lt
;
2290 GLuint b
= rgba
[i
][BCOMP
] + Lt
;
2291 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2292 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2293 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2294 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2299 GLchan It
= texel
[i
][RCOMP
];
2300 GLuint r
= rgba
[i
][RCOMP
] + It
;
2301 GLuint g
= rgba
[i
][GCOMP
] + It
;
2302 GLuint b
= rgba
[i
][BCOMP
] + It
;
2303 GLuint a
= rgba
[i
][ACOMP
] + It
;
2304 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2305 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2306 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2307 rgba
[i
][ACOMP
] = MIN2(a
, CHAN_MAX
);
2312 GLuint r
= rgba
[i
][RCOMP
] + texel
[i
][RCOMP
];
2313 GLuint g
= rgba
[i
][GCOMP
] + texel
[i
][GCOMP
];
2314 GLuint b
= rgba
[i
][BCOMP
] + texel
[i
][BCOMP
];
2315 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2316 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2317 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2323 GLuint r
= rgba
[i
][RCOMP
] + texel
[i
][RCOMP
];
2324 GLuint g
= rgba
[i
][GCOMP
] + texel
[i
][GCOMP
];
2325 GLuint b
= rgba
[i
][BCOMP
] + texel
[i
][BCOMP
];
2326 rgba
[i
][RCOMP
] = MIN2(r
, CHAN_MAX
);
2327 rgba
[i
][GCOMP
] = MIN2(g
, CHAN_MAX
);
2328 rgba
[i
][BCOMP
] = MIN2(b
, CHAN_MAX
);
2329 rgba
[i
][ACOMP
] = CHAN_PRODUCT(rgba
[i
][ACOMP
], texel
[i
][ACOMP
]);
2333 _mesa_problem(ctx
, "Bad format (GL_ADD) in apply_texture");
2338 case GL_COMBINE_EXT
:
2339 texture_combine(ctx
, texUnit
, n
, primary_rgba
, texel
, rgba
);
2343 _mesa_problem(ctx
, "Bad env mode in apply_texture");
2351 * Sample a shadow/depth texture.
2352 * Input: ctx - context
2353 * texUnit - the texture unit
2354 * n - number of samples
2355 * s,t,r - array [n] of texture coordinates
2356 * In/Out: rgba - array [n] of texel colors.
2359 sample_depth_texture(const GLcontext
*ctx
,
2360 const struct gl_texture_unit
*texUnit
,
2362 const GLfloat s
[], const GLfloat t
[], const GLfloat r
[],
2365 const struct gl_texture_object
*texObj
= texUnit
->_Current
;
2366 const GLint baseLevel
= texObj
->BaseLevel
;
2367 const struct gl_texture_image
*texImage
= texObj
->Image
[baseLevel
];
2368 const GLuint width
= texImage
->Width
;
2369 const GLuint height
= texImage
->Height
;
2370 const GLchan ambient
= texObj
->ShadowAmbient
;
2371 GLboolean lequal
, gequal
;
2373 if (texObj
->Dimensions
!= 2) {
2374 _mesa_problem(ctx
, "only 2-D depth textures supported at this time");
2378 if (texObj
->MinFilter
!= texObj
->MagFilter
) {
2379 _mesa_problem(ctx
, "mipmapped depth textures not supported at this time");
2383 /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if
2384 * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object
2385 * isn't a depth texture.
2387 if (texImage
->Format
!= GL_DEPTH_COMPONENT
) {
2388 _mesa_problem(ctx
,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture");
2392 if (texObj
->CompareOperator
== GL_TEXTURE_LEQUAL_R_SGIX
) {
2401 if (texObj
->MagFilter
== GL_NEAREST
) {
2403 for (i
= 0; i
< n
; i
++) {
2404 GLfloat depthSample
;
2406 COMPUTE_NEAREST_TEXEL_LOCATION(texObj
->WrapS
, s
[i
], width
, col
);
2407 COMPUTE_NEAREST_TEXEL_LOCATION(texObj
->WrapT
, t
[i
], height
, row
);
2408 depthSample
= *((const GLfloat
*) texImage
->Data
+ row
* width
+ col
);
2409 if ((depthSample
<= r
[i
] && lequal
) ||
2410 (depthSample
>= r
[i
] && gequal
)) {
2411 texel
[i
][RCOMP
] = ambient
;
2412 texel
[i
][GCOMP
] = ambient
;
2413 texel
[i
][BCOMP
] = ambient
;
2414 texel
[i
][ACOMP
] = CHAN_MAX
;
2417 texel
[i
][RCOMP
] = CHAN_MAX
;
2418 texel
[i
][GCOMP
] = CHAN_MAX
;
2419 texel
[i
][BCOMP
] = CHAN_MAX
;
2420 texel
[i
][ACOMP
] = CHAN_MAX
;
2426 ASSERT(texObj
->MagFilter
== GL_LINEAR
);
2427 for (i
= 0; i
< n
; i
++) {
2428 GLfloat depth00
, depth01
, depth10
, depth11
;
2429 GLint i0
, i1
, j0
, j1
;
2431 GLuint useBorderTexel
;
2433 COMPUTE_LINEAR_TEXEL_LOCATIONS(texObj
->WrapS
, s
[i
], u
, width
, i0
, i1
);
2434 COMPUTE_LINEAR_TEXEL_LOCATIONS(texObj
->WrapT
, t
[i
], v
, height
,j0
, j1
);
2437 if (texImage
->Border
) {
2438 i0
+= texImage
->Border
;
2439 i1
+= texImage
->Border
;
2440 j0
+= texImage
->Border
;
2441 j1
+= texImage
->Border
;
2444 if (i0
< 0 || i0
>= width
) useBorderTexel
|= I0BIT
;
2445 if (i1
< 0 || i1
>= width
) useBorderTexel
|= I1BIT
;
2446 if (j0
< 0 || j0
>= height
) useBorderTexel
|= J0BIT
;
2447 if (j1
< 0 || j1
>= height
) useBorderTexel
|= J1BIT
;
2450 /* get four depth samples from the texture */
2451 if (useBorderTexel
& (I0BIT
| J0BIT
)) {
2455 depth00
= *((const GLfloat
*) texImage
->Data
+ j0
* width
+ i0
);
2457 if (useBorderTexel
& (I1BIT
| J0BIT
)) {
2461 depth10
= *((const GLfloat
*) texImage
->Data
+ j0
* width
+ i1
);
2463 if (useBorderTexel
& (I0BIT
| J1BIT
)) {
2467 depth01
= *((const GLfloat
*) texImage
->Data
+ j1
* width
+ i0
);
2469 if (useBorderTexel
& (I1BIT
| J1BIT
)) {
2473 depth11
= *((const GLfloat
*) texImage
->Data
+ j1
* width
+ i1
);
2477 /* compute a single weighted depth sample and do one comparison */
2478 const GLfloat a
= FRAC(u
);
2479 const GLfloat b
= FRAC(v
);
2480 const GLfloat w00
= (1.0F
- a
) * (1.0F
- b
);
2481 const GLfloat w10
= ( a
) * (1.0F
- b
);
2482 const GLfloat w01
= (1.0F
- a
) * ( b
);
2483 const GLfloat w11
= ( a
) * ( b
);
2484 const GLfloat depthSample
= w00
* depth00
+ w10
* depth10
2485 + w01
* depth01
+ w11
* depth11
;
2486 if ((depthSample
<= r
[i
] && lequal
) ||
2487 (depthSample
>= r
[i
] && gequal
)) {
2488 texel
[i
][RCOMP
] = ambient
;
2489 texel
[i
][GCOMP
] = ambient
;
2490 texel
[i
][BCOMP
] = ambient
;
2491 texel
[i
][ACOMP
] = CHAN_MAX
;
2494 texel
[i
][RCOMP
] = CHAN_MAX
;
2495 texel
[i
][GCOMP
] = CHAN_MAX
;
2496 texel
[i
][BCOMP
] = CHAN_MAX
;
2497 texel
[i
][ACOMP
] = CHAN_MAX
;
2501 /* Do four depth/R comparisons and compute a weighted result.
2502 * If this touches on somebody's I.P., I'll remove this code
2505 const GLfloat d
= (CHAN_MAXF
- (GLfloat
) ambient
) * 0.25F
;
2506 GLfloat luminance
= CHAN_MAXF
;
2509 if (depth00
<= r
[i
]) luminance
-= d
;
2510 if (depth01
<= r
[i
]) luminance
-= d
;
2511 if (depth10
<= r
[i
]) luminance
-= d
;
2512 if (depth11
<= r
[i
]) luminance
-= d
;
2515 if (depth00
>= r
[i
]) luminance
-= d
;
2516 if (depth01
>= r
[i
]) luminance
-= d
;
2517 if (depth10
>= r
[i
]) luminance
-= d
;
2518 if (depth11
>= r
[i
]) luminance
-= d
;
2520 lum
= (GLchan
) luminance
;
2521 texel
[i
][RCOMP
] = lum
;
2522 texel
[i
][GCOMP
] = lum
;
2523 texel
[i
][BCOMP
] = lum
;
2524 texel
[i
][ACOMP
] = CHAN_MAX
;
2533 * Experimental depth texture sampling function.
2536 sample_depth_texture2(const GLcontext
*ctx
,
2537 const struct gl_texture_unit
*texUnit
,
2539 const GLfloat s
[], const GLfloat t
[], const GLfloat r
[],
2542 const struct gl_texture_object
*texObj
= texUnit
->_Current
;
2543 const GLint baseLevel
= texObj
->BaseLevel
;
2544 const struct gl_texture_image
*texImage
= texObj
->Image
[baseLevel
];
2545 const GLuint width
= texImage
->Width
;
2546 const GLuint height
= texImage
->Height
;
2547 const GLchan ambient
= texObj
->ShadowAmbient
;
2548 GLboolean lequal
, gequal
;
2550 if (texObj
->Dimensions
!= 2) {
2551 _mesa_problem(ctx
, "only 2-D depth textures supported at this time");
2555 if (texObj
->MinFilter
!= texObj
->MagFilter
) {
2556 _mesa_problem(ctx
, "mipmapped depth textures not supported at this time");
2560 /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if
2561 * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object
2562 * isn't a depth texture.
2564 if (texImage
->Format
!= GL_DEPTH_COMPONENT
) {
2565 _mesa_problem(ctx
,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture");
2569 if (texObj
->CompareOperator
== GL_TEXTURE_LEQUAL_R_SGIX
) {
2580 for (i
= 0; i
< n
; i
++) {
2582 GLint col
, row
, ii
, jj
, imin
, imax
, jmin
, jmax
, samples
, count
;
2585 COMPUTE_NEAREST_TEXEL_LOCATION(texObj
->WrapS
, s
[i
], width
, col
);
2586 COMPUTE_NEAREST_TEXEL_LOCATION(texObj
->WrapT
, t
[i
], height
, row
);
2593 if (imin
< 0) imin
= 0;
2594 if (imax
>= width
) imax
= width
- 1;
2595 if (jmin
< 0) jmin
= 0;
2596 if (jmax
>= height
) jmax
= height
- 1;
2598 samples
= (imax
- imin
+ 1) * (jmax
- jmin
+ 1);
2600 for (jj
= jmin
; jj
<= jmax
; jj
++) {
2601 for (ii
= imin
; ii
<= imax
; ii
++) {
2602 GLfloat depthSample
= *((const GLfloat
*) texImage
->Data
2604 if ((depthSample
<= r
[i
] && lequal
) ||
2605 (depthSample
>= r
[i
] && gequal
)) {
2611 w
= (GLfloat
) count
/ (GLfloat
) samples
;
2612 w
= CHAN_MAXF
- w
* (CHAN_MAXF
- (GLfloat
) ambient
);
2615 texel
[i
][RCOMP
] = lum
;
2616 texel
[i
][GCOMP
] = lum
;
2617 texel
[i
][BCOMP
] = lum
;
2618 texel
[i
][ACOMP
] = CHAN_MAX
;
2626 * Apply a unit of texture mapping to the incoming fragments.
2629 _swrast_texture_fragments( GLcontext
*ctx
, GLuint texUnit
, GLuint n
,
2630 const GLfloat s
[], const GLfloat t
[],
2631 const GLfloat r
[], GLfloat lambda
[],
2632 CONST GLchan primary_rgba
[][4], GLchan rgba
[][4] )
2634 const GLuint mask
= TEXTURE0_ANY
<< (texUnit
* 4);
2636 if (ctx
->Texture
._ReallyEnabled
& mask
) {
2637 const struct gl_texture_unit
*textureUnit
= &ctx
->Texture
.Unit
[texUnit
];
2639 if (textureUnit
->_Current
) { /* XXX need this? */
2640 GLchan texel
[PB_SIZE
][4];
2642 if (textureUnit
->LodBias
!= 0.0F
) {
2643 /* apply LOD bias, but don't clamp yet */
2646 lambda
[i
] += textureUnit
->LodBias
;
2650 if (textureUnit
->_Current
->MinLod
!= -1000.0
2651 || textureUnit
->_Current
->MaxLod
!= 1000.0) {
2652 /* apply LOD clamping to lambda */
2653 const GLfloat min
= textureUnit
->_Current
->MinLod
;
2654 const GLfloat max
= textureUnit
->_Current
->MaxLod
;
2657 GLfloat l
= lambda
[i
];
2658 lambda
[i
] = CLAMP(l
, min
, max
);
2662 /* Sample the texture. */
2663 if (textureUnit
->_Current
->CompareFlag
) {
2665 sample_depth_texture(ctx
, textureUnit
, n
, s
, t
, r
, texel
);
2669 SWRAST_CONTEXT(ctx
)->TextureSample
[texUnit
]( ctx
, texUnit
,
2670 textureUnit
->_Current
,
2674 apply_texture( ctx
, textureUnit
, n
, primary_rgba
,
2675 (const GLchan (*)[4]) texel
, rgba
);