2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 #include "main/glheader.h"
28 #include "main/context.h"
29 #include "main/colormac.h"
30 #include "main/image.h"
31 #include "main/imports.h"
32 #include "main/macros.h"
33 #include "main/pixel.h"
34 #include "shader/prog_instruction.h"
36 #include "s_context.h"
37 #include "s_texcombine.h"
40 #define MAX_COMBINER_TERMS 4
44 * Do texture application for GL_ARB/EXT_texture_env_combine.
45 * This function also supports GL_{EXT,ARB}_texture_env_dot3 and
46 * GL_ATI_texture_env_combine3. Since "classic" texture environments are
47 * implemented using GL_ARB_texture_env_combine-like state, this same function
48 * is used for classic texture environment application as well.
50 * \param ctx rendering context
51 * \param textureUnit the texture unit to apply
52 * \param n number of fragments to process (span width)
53 * \param primary_rgba incoming fragment color array
54 * \param texelBuffer pointer to texel colors for all texture units
56 * \param rgba incoming colors, which get modified here
59 texture_combine( const GLcontext
*ctx
, GLuint unit
, GLuint n
,
60 CONST
GLfloat (*primary_rgba
)[4],
61 CONST GLfloat
*texelBuffer
,
62 GLchan (*rgbaChan
)[4] )
64 const struct gl_texture_unit
*textureUnit
= &(ctx
->Texture
.Unit
[unit
]);
65 const struct gl_tex_env_combine_state
*combine
= textureUnit
->_CurrentCombine
;
66 const GLfloat (*argRGB
[MAX_COMBINER_TERMS
])[4];
67 const GLfloat (*argA
[MAX_COMBINER_TERMS
])[4];
68 const GLfloat RGBmult
= (GLfloat
) (1 << combine
->ScaleShiftRGB
);
69 const GLfloat Amult
= (GLfloat
) (1 << combine
->ScaleShiftA
);
70 const GLuint numColorArgs
= combine
->_NumArgsRGB
;
71 const GLuint numAlphaArgs
= combine
->_NumArgsA
;
72 GLfloat ccolor
[MAX_COMBINER_TERMS
][MAX_WIDTH
][4]; /* temp color buffers */
73 GLfloat rgba
[MAX_WIDTH
][4];
76 ASSERT(ctx
->Extensions
.EXT_texture_env_combine
||
77 ctx
->Extensions
.ARB_texture_env_combine
);
78 ASSERT(CONST_SWRAST_CONTEXT(ctx
)->_AnyTextureCombine
);
80 for (i
= 0; i
< n
; i
++) {
81 rgba
[i
][RCOMP
] = CHAN_TO_FLOAT(rgbaChan
[i
][RCOMP
]);
82 rgba
[i
][GCOMP
] = CHAN_TO_FLOAT(rgbaChan
[i
][GCOMP
]);
83 rgba
[i
][BCOMP
] = CHAN_TO_FLOAT(rgbaChan
[i
][BCOMP
]);
84 rgba
[i
][ACOMP
] = CHAN_TO_FLOAT(rgbaChan
[i
][ACOMP
]);
88 printf("modeRGB 0x%x modeA 0x%x srcRGB1 0x%x srcA1 0x%x srcRGB2 0x%x srcA2 0x%x\n",
91 combine->SourceRGB[0],
93 combine->SourceRGB[1],
98 * Do operand setup for up to 4 operands. Loop over the terms.
100 for (term
= 0; term
< numColorArgs
; term
++) {
101 const GLenum srcRGB
= combine
->SourceRGB
[term
];
102 const GLenum operandRGB
= combine
->OperandRGB
[term
];
106 argRGB
[term
] = (const GLfloat (*)[4])
107 (texelBuffer
+ unit
* (n
* 4 * sizeof(GLfloat
)));
109 case GL_PRIMARY_COLOR
:
110 argRGB
[term
] = primary_rgba
;
113 argRGB
[term
] = (const GLfloat (*)[4]) rgba
;
117 GLfloat (*c
)[4] = ccolor
[term
];
118 GLfloat red
= textureUnit
->EnvColor
[0];
119 GLfloat green
= textureUnit
->EnvColor
[1];
120 GLfloat blue
= textureUnit
->EnvColor
[2];
121 GLfloat alpha
= textureUnit
->EnvColor
[3];
122 for (i
= 0; i
< n
; i
++) {
123 ASSIGN_4V(c
[i
], red
, green
, blue
, alpha
);
125 argRGB
[term
] = (const GLfloat (*)[4]) ccolor
[term
];
128 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
132 GLfloat (*c
)[4] = ccolor
[term
];
133 for (i
= 0; i
< n
; i
++) {
134 ASSIGN_4V(c
[i
], 0.0F
, 0.0F
, 0.0F
, 0.0F
);
136 argRGB
[term
] = (const GLfloat (*)[4]) ccolor
[term
];
141 GLfloat (*c
)[4] = ccolor
[term
];
142 for (i
= 0; i
< n
; i
++) {
143 ASSIGN_4V(c
[i
], 1.0F
, 1.0F
, 1.0F
, 1.0F
);
145 argRGB
[term
] = (const GLfloat (*)[4]) ccolor
[term
];
149 /* ARB_texture_env_crossbar source */
151 const GLuint srcUnit
= srcRGB
- GL_TEXTURE0
;
152 ASSERT(srcUnit
< ctx
->Const
.MaxTextureUnits
);
153 if (!ctx
->Texture
.Unit
[srcUnit
]._ReallyEnabled
)
155 argRGB
[term
] = (const GLfloat (*)[4])
156 (texelBuffer
+ srcUnit
* (n
* 4 * sizeof(GLfloat
)));
160 if (operandRGB
!= GL_SRC_COLOR
) {
161 const GLfloat (*src
)[4] = argRGB
[term
];
162 GLfloat (*dst
)[4] = ccolor
[term
];
164 /* point to new arg[term] storage */
165 argRGB
[term
] = (const GLfloat (*)[4]) ccolor
[term
];
167 switch (operandRGB
) {
168 case GL_ONE_MINUS_SRC_COLOR
:
169 for (i
= 0; i
< n
; i
++) {
170 dst
[i
][RCOMP
] = 1.0F
- src
[i
][RCOMP
];
171 dst
[i
][GCOMP
] = 1.0F
- src
[i
][GCOMP
];
172 dst
[i
][BCOMP
] = 1.0F
- src
[i
][BCOMP
];
176 for (i
= 0; i
< n
; i
++) {
177 dst
[i
][RCOMP
] = src
[i
][ACOMP
];
178 dst
[i
][GCOMP
] = src
[i
][ACOMP
];
179 dst
[i
][BCOMP
] = src
[i
][ACOMP
];
182 case GL_ONE_MINUS_SRC_ALPHA
:
183 for (i
= 0; i
< n
; i
++) {
184 dst
[i
][RCOMP
] = 1.0F
- src
[i
][ACOMP
];
185 dst
[i
][GCOMP
] = 1.0F
- src
[i
][ACOMP
];
186 dst
[i
][BCOMP
] = 1.0F
- src
[i
][ACOMP
];
190 _mesa_problem(ctx
, "Bad operandRGB");
196 * Set up the argA[i] pointers
198 for (term
= 0; term
< numAlphaArgs
; term
++) {
199 const GLenum srcA
= combine
->SourceA
[term
];
200 const GLenum operandA
= combine
->OperandA
[term
];
204 argA
[term
] = (const GLfloat (*)[4])
205 (texelBuffer
+ unit
* (n
* 4 * sizeof(GLfloat
)));
207 case GL_PRIMARY_COLOR
:
208 argA
[term
] = primary_rgba
;
211 argA
[term
] = (const GLfloat (*)[4]) rgba
;
215 GLfloat (*c
)[4] = ccolor
[term
];
216 GLfloat alpha
= textureUnit
->EnvColor
[3];
217 for (i
= 0; i
< n
; i
++)
219 argA
[term
] = (const GLfloat (*)[4]) ccolor
[term
];
222 /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources.
226 GLfloat (*c
)[4] = ccolor
[term
];
227 for (i
= 0; i
< n
; i
++)
229 argA
[term
] = (const GLfloat (*)[4]) ccolor
[term
];
234 GLfloat (*c
)[4] = ccolor
[term
];
235 for (i
= 0; i
< n
; i
++)
237 argA
[term
] = (const GLfloat (*)[4]) ccolor
[term
];
241 /* ARB_texture_env_crossbar source */
243 const GLuint srcUnit
= srcA
- GL_TEXTURE0
;
244 ASSERT(srcUnit
< ctx
->Const
.MaxTextureUnits
);
245 if (!ctx
->Texture
.Unit
[srcUnit
]._ReallyEnabled
)
247 argA
[term
] = (const GLfloat (*)[4])
248 (texelBuffer
+ srcUnit
* (n
* 4 * sizeof(GLfloat
)));
252 if (operandA
== GL_ONE_MINUS_SRC_ALPHA
) {
253 const GLfloat (*src
)[4] = argA
[term
];
254 GLfloat (*dst
)[4] = ccolor
[term
];
255 argA
[term
] = (const GLfloat (*)[4]) ccolor
[term
];
256 for (i
= 0; i
< n
; i
++) {
257 dst
[i
][ACOMP
] = 1.0F
- src
[i
][ACOMP
];
262 /* RGB channel combine */
264 const GLfloat (*arg0
)[4] = (const GLfloat (*)[4]) argRGB
[0];
265 const GLfloat (*arg1
)[4] = (const GLfloat (*)[4]) argRGB
[1];
266 const GLfloat (*arg2
)[4] = (const GLfloat (*)[4]) argRGB
[2];
267 const GLfloat (*arg3
)[4] = (const GLfloat (*)[4]) argRGB
[3];
269 switch (combine
->ModeRGB
) {
271 for (i
= 0; i
< n
; i
++) {
272 rgba
[i
][RCOMP
] = arg0
[i
][RCOMP
] * RGBmult
;
273 rgba
[i
][GCOMP
] = arg0
[i
][GCOMP
] * RGBmult
;
274 rgba
[i
][BCOMP
] = arg0
[i
][BCOMP
] * RGBmult
;
278 for (i
= 0; i
< n
; i
++) {
279 rgba
[i
][RCOMP
] = arg0
[i
][RCOMP
] * arg1
[i
][RCOMP
] * RGBmult
;
280 rgba
[i
][GCOMP
] = arg0
[i
][GCOMP
] * arg1
[i
][GCOMP
] * RGBmult
;
281 rgba
[i
][BCOMP
] = arg0
[i
][BCOMP
] * arg1
[i
][BCOMP
] * RGBmult
;
285 if (textureUnit
->EnvMode
== GL_COMBINE4_NV
) {
286 /* (a * b) + (c * d) */
287 for (i
= 0; i
< n
; i
++) {
288 rgba
[i
][RCOMP
] = (arg0
[i
][RCOMP
] * arg1
[i
][RCOMP
] +
289 arg2
[i
][RCOMP
] * arg3
[i
][RCOMP
]) * RGBmult
;
290 rgba
[i
][GCOMP
] = (arg0
[i
][GCOMP
] * arg1
[i
][GCOMP
] +
291 arg2
[i
][GCOMP
] * arg3
[i
][GCOMP
]) * RGBmult
;
292 rgba
[i
][BCOMP
] = (arg0
[i
][BCOMP
] * arg1
[i
][BCOMP
] +
293 arg2
[i
][BCOMP
] * arg3
[i
][BCOMP
]) * RGBmult
;
297 /* 2-term addition */
298 for (i
= 0; i
< n
; i
++) {
299 rgba
[i
][RCOMP
] = (arg0
[i
][RCOMP
] + arg1
[i
][RCOMP
]) * RGBmult
;
300 rgba
[i
][GCOMP
] = (arg0
[i
][GCOMP
] + arg1
[i
][GCOMP
]) * RGBmult
;
301 rgba
[i
][BCOMP
] = (arg0
[i
][BCOMP
] + arg1
[i
][BCOMP
]) * RGBmult
;
306 if (textureUnit
->EnvMode
== GL_COMBINE4_NV
) {
307 /* (a * b) + (c * d) - 0.5 */
308 for (i
= 0; i
< n
; i
++) {
309 rgba
[i
][RCOMP
] = (arg0
[i
][RCOMP
] + arg1
[i
][RCOMP
] *
310 arg2
[i
][RCOMP
] + arg3
[i
][RCOMP
] - 0.5) * RGBmult
;
311 rgba
[i
][GCOMP
] = (arg0
[i
][GCOMP
] + arg1
[i
][GCOMP
] *
312 arg2
[i
][GCOMP
] + arg3
[i
][GCOMP
] - 0.5) * RGBmult
;
313 rgba
[i
][BCOMP
] = (arg0
[i
][BCOMP
] + arg1
[i
][BCOMP
] *
314 arg2
[i
][BCOMP
] + arg3
[i
][BCOMP
] - 0.5) * RGBmult
;
318 for (i
= 0; i
< n
; i
++) {
319 rgba
[i
][RCOMP
] = (arg0
[i
][RCOMP
] + arg1
[i
][RCOMP
] - 0.5) * RGBmult
;
320 rgba
[i
][GCOMP
] = (arg0
[i
][GCOMP
] + arg1
[i
][GCOMP
] - 0.5) * RGBmult
;
321 rgba
[i
][BCOMP
] = (arg0
[i
][BCOMP
] + arg1
[i
][BCOMP
] - 0.5) * RGBmult
;
326 for (i
= 0; i
< n
; i
++) {
327 rgba
[i
][RCOMP
] = (arg0
[i
][RCOMP
] * arg2
[i
][RCOMP
] +
328 arg1
[i
][RCOMP
] * (1.0F
- arg2
[i
][RCOMP
])) * RGBmult
;
329 rgba
[i
][GCOMP
] = (arg0
[i
][GCOMP
] * arg2
[i
][GCOMP
] +
330 arg1
[i
][GCOMP
] * (1.0F
- arg2
[i
][GCOMP
])) * RGBmult
;
331 rgba
[i
][BCOMP
] = (arg0
[i
][BCOMP
] * arg2
[i
][BCOMP
] +
332 arg1
[i
][BCOMP
] * (1.0F
- arg2
[i
][BCOMP
])) * RGBmult
;
336 for (i
= 0; i
< n
; i
++) {
337 rgba
[i
][RCOMP
] = (arg0
[i
][RCOMP
] - arg1
[i
][RCOMP
]) * RGBmult
;
338 rgba
[i
][GCOMP
] = (arg0
[i
][GCOMP
] - arg1
[i
][GCOMP
]) * RGBmult
;
339 rgba
[i
][BCOMP
] = (arg0
[i
][BCOMP
] - arg1
[i
][BCOMP
]) * RGBmult
;
342 case GL_DOT3_RGB_EXT
:
343 case GL_DOT3_RGBA_EXT
:
344 /* Do not scale the result by 1 2 or 4 */
345 for (i
= 0; i
< n
; i
++) {
346 GLfloat dot
= ((arg0
[i
][RCOMP
]-0.5F
) * (arg1
[i
][RCOMP
]-0.5F
) +
347 (arg0
[i
][GCOMP
]-0.5F
) * (arg1
[i
][GCOMP
]-0.5F
) +
348 (arg0
[i
][BCOMP
]-0.5F
) * (arg1
[i
][BCOMP
]-0.5F
))
350 dot
= CLAMP(dot
, 0.0F
, 1.0F
);
351 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = (GLfloat
) dot
;
356 /* DO scale the result by 1 2 or 4 */
357 for (i
= 0; i
< n
; i
++) {
358 GLfloat dot
= ((arg0
[i
][RCOMP
]-0.5F
) * (arg1
[i
][RCOMP
]-0.5F
) +
359 (arg0
[i
][GCOMP
]-0.5F
) * (arg1
[i
][GCOMP
]-0.5F
) +
360 (arg0
[i
][BCOMP
]-0.5F
) * (arg1
[i
][BCOMP
]-0.5F
))
362 dot
= CLAMP(dot
, 0.0, 1.0F
);
363 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = (GLfloat
) dot
;
366 case GL_MODULATE_ADD_ATI
:
367 for (i
= 0; i
< n
; i
++) {
368 rgba
[i
][RCOMP
] = ((arg0
[i
][RCOMP
] * arg2
[i
][RCOMP
]) +
369 arg1
[i
][RCOMP
]) * RGBmult
;
370 rgba
[i
][GCOMP
] = ((arg0
[i
][GCOMP
] * arg2
[i
][GCOMP
]) +
371 arg1
[i
][GCOMP
]) * RGBmult
;
372 rgba
[i
][BCOMP
] = ((arg0
[i
][BCOMP
] * arg2
[i
][BCOMP
]) +
373 arg1
[i
][BCOMP
]) * RGBmult
;
376 case GL_MODULATE_SIGNED_ADD_ATI
:
377 for (i
= 0; i
< n
; i
++) {
378 rgba
[i
][RCOMP
] = ((arg0
[i
][RCOMP
] * arg2
[i
][RCOMP
]) +
379 arg1
[i
][RCOMP
] - 0.5) * RGBmult
;
380 rgba
[i
][GCOMP
] = ((arg0
[i
][GCOMP
] * arg2
[i
][GCOMP
]) +
381 arg1
[i
][GCOMP
] - 0.5) * RGBmult
;
382 rgba
[i
][BCOMP
] = ((arg0
[i
][BCOMP
] * arg2
[i
][BCOMP
]) +
383 arg1
[i
][BCOMP
] - 0.5) * RGBmult
;
386 case GL_MODULATE_SUBTRACT_ATI
:
387 for (i
= 0; i
< n
; i
++) {
388 rgba
[i
][RCOMP
] = ((arg0
[i
][RCOMP
] * arg2
[i
][RCOMP
]) -
389 arg1
[i
][RCOMP
]) * RGBmult
;
390 rgba
[i
][GCOMP
] = ((arg0
[i
][GCOMP
] * arg2
[i
][GCOMP
]) -
391 arg1
[i
][GCOMP
]) * RGBmult
;
392 rgba
[i
][BCOMP
] = ((arg0
[i
][BCOMP
] * arg2
[i
][BCOMP
]) -
393 arg1
[i
][BCOMP
]) * RGBmult
;
396 case GL_BUMP_ENVMAP_ATI
:
398 /* this produces a fixed rgba color, and the coord calc is done elsewhere */
399 for (i
= 0; i
< n
; i
++) {
400 /* rgba result is 0,0,0,1 */
401 #if CHAN_TYPE == GL_FLOAT
402 rgba
[i
][RCOMP
] = 0.0;
403 rgba
[i
][GCOMP
] = 0.0;
404 rgba
[i
][BCOMP
] = 0.0;
405 rgba
[i
][ACOMP
] = 1.0;
410 rgba
[i
][ACOMP
] = CHAN_MAX
;
414 return; /* no alpha processing */
416 _mesa_problem(ctx
, "invalid combine mode");
420 /* Alpha channel combine */
422 const GLfloat (*arg0
)[4] = (const GLfloat (*)[4]) argA
[0];
423 const GLfloat (*arg1
)[4] = (const GLfloat (*)[4]) argA
[1];
424 const GLfloat (*arg2
)[4] = (const GLfloat (*)[4]) argA
[2];
425 const GLfloat (*arg3
)[4] = (const GLfloat (*)[4]) argA
[3];
427 switch (combine
->ModeA
) {
429 for (i
= 0; i
< n
; i
++) {
430 GLfloat a
= arg0
[i
][ACOMP
] * Amult
;
431 rgba
[i
][ACOMP
] = (GLfloat
) MIN2(a
, 1.0F
);
435 for (i
= 0; i
< n
; i
++) {
436 rgba
[i
][ACOMP
] = arg0
[i
][ACOMP
] * arg1
[i
][ACOMP
] * Amult
;
440 if (textureUnit
->EnvMode
== GL_COMBINE4_NV
) {
441 /* (a * b) + (c * d) */
442 for (i
= 0; i
< n
; i
++) {
443 rgba
[i
][ACOMP
] = (arg0
[i
][ACOMP
] * arg1
[i
][ACOMP
] +
444 arg2
[i
][ACOMP
] * arg3
[i
][ACOMP
]) * Amult
;
449 for (i
= 0; i
< n
; i
++) {
450 rgba
[i
][ACOMP
] = (arg0
[i
][ACOMP
] + arg1
[i
][ACOMP
]) * Amult
;
455 if (textureUnit
->EnvMode
== GL_COMBINE4_NV
) {
456 /* (a * b) + (c * d) - 0.5 */
457 for (i
= 0; i
< n
; i
++) {
458 rgba
[i
][ACOMP
] = (arg0
[i
][ACOMP
] * arg1
[i
][ACOMP
] +
459 arg2
[i
][ACOMP
] * arg3
[i
][ACOMP
] -
465 for (i
= 0; i
< n
; i
++) {
466 rgba
[i
][ACOMP
] = (arg0
[i
][ACOMP
] + arg1
[i
][ACOMP
] - 0.5F
) * Amult
;
471 for (i
=0; i
<n
; i
++) {
472 rgba
[i
][ACOMP
] = (arg0
[i
][ACOMP
] * arg2
[i
][ACOMP
] +
473 arg1
[i
][ACOMP
] * (1.0F
- arg2
[i
][ACOMP
]))
478 for (i
= 0; i
< n
; i
++) {
479 rgba
[i
][ACOMP
] = (arg0
[i
][ACOMP
] - arg1
[i
][ACOMP
]) * Amult
;
482 case GL_MODULATE_ADD_ATI
:
483 for (i
= 0; i
< n
; i
++) {
484 rgba
[i
][ACOMP
] = ((arg0
[i
][ACOMP
] * arg2
[i
][ACOMP
])
485 + arg1
[i
][ACOMP
]) * Amult
;
488 case GL_MODULATE_SIGNED_ADD_ATI
:
489 for (i
= 0; i
< n
; i
++) {
490 rgba
[i
][ACOMP
] = ((arg0
[i
][ACOMP
] * arg2
[i
][ACOMP
]) +
491 arg1
[i
][ACOMP
] - 0.5F
) * Amult
;
494 case GL_MODULATE_SUBTRACT_ATI
:
495 for (i
= 0; i
< n
; i
++) {
496 rgba
[i
][ACOMP
] = ((arg0
[i
][ACOMP
] * arg2
[i
][ACOMP
])
497 - arg1
[i
][ACOMP
]) * Amult
;
501 _mesa_problem(ctx
, "invalid combine mode");
505 /* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining.
506 * This is kind of a kludge. It would have been better if the spec
507 * were written such that the GL_COMBINE_ALPHA value could be set to
510 if (combine
->ModeRGB
== GL_DOT3_RGBA_EXT
||
511 combine
->ModeRGB
== GL_DOT3_RGBA
) {
512 for (i
= 0; i
< n
; i
++) {
513 rgba
[i
][ACOMP
] = rgba
[i
][RCOMP
];
517 for (i
= 0; i
< n
; i
++) {
518 UNCLAMPED_FLOAT_TO_CHAN(rgbaChan
[i
][RCOMP
], rgba
[i
][RCOMP
]);
519 UNCLAMPED_FLOAT_TO_CHAN(rgbaChan
[i
][GCOMP
], rgba
[i
][GCOMP
]);
520 UNCLAMPED_FLOAT_TO_CHAN(rgbaChan
[i
][BCOMP
], rgba
[i
][BCOMP
]);
521 UNCLAMPED_FLOAT_TO_CHAN(rgbaChan
[i
][ACOMP
], rgba
[i
][ACOMP
]);
528 * Apply X/Y/Z/W/0/1 swizzle to an array of colors/texels.
529 * See GL_EXT_texture_swizzle.
532 swizzle_texels(GLuint swizzle
, GLuint count
, GLfloat (*texels
)[4])
534 const GLuint swzR
= GET_SWZ(swizzle
, 0);
535 const GLuint swzG
= GET_SWZ(swizzle
, 1);
536 const GLuint swzB
= GET_SWZ(swizzle
, 2);
537 const GLuint swzA
= GET_SWZ(swizzle
, 3);
541 vector
[SWIZZLE_ZERO
] = 0;
542 vector
[SWIZZLE_ONE
] = 1.0F
;
544 for (i
= 0; i
< count
; i
++) {
545 vector
[SWIZZLE_X
] = texels
[i
][0];
546 vector
[SWIZZLE_Y
] = texels
[i
][1];
547 vector
[SWIZZLE_Z
] = texels
[i
][2];
548 vector
[SWIZZLE_W
] = texels
[i
][3];
549 texels
[i
][RCOMP
] = vector
[swzR
];
550 texels
[i
][GCOMP
] = vector
[swzG
];
551 texels
[i
][BCOMP
] = vector
[swzB
];
552 texels
[i
][ACOMP
] = vector
[swzA
];
558 * Apply a conventional OpenGL texture env mode (REPLACE, ADD, BLEND,
559 * MODULATE, or DECAL) to an array of fragments.
560 * Input: textureUnit - pointer to texture unit to apply
561 * format - base internal texture format
562 * n - number of fragments
563 * primary_rgba - primary colors (may alias rgba for single texture)
564 * texels - array of texel colors
565 * InOut: rgba - incoming fragment colors modified by texel colors
566 * according to the texture environment mode.
569 texture_apply( const GLcontext
*ctx
,
570 const struct gl_texture_unit
*texUnit
,
572 CONST GLfloat primary_rgba
[][4], CONST GLfloat texel
[][4],
573 GLchan rgbaChan
[][4] )
577 GLfloat Rc
, Gc
, Bc
, Ac
;
579 GLfloat rgba
[MAX_WIDTH
][4];
584 ASSERT(texUnit
->_Current
);
586 baseLevel
= texUnit
->_Current
->BaseLevel
;
587 ASSERT(texUnit
->_Current
->Image
[0][baseLevel
]);
589 format
= texUnit
->_Current
->Image
[0][baseLevel
]->_BaseFormat
;
591 if (format
== GL_COLOR_INDEX
|| format
== GL_YCBCR_MESA
) {
592 format
= GL_RGBA
; /* a bit of a hack */
594 else if (format
== GL_DEPTH_COMPONENT
|| format
== GL_DEPTH_STENCIL_EXT
) {
595 format
= texUnit
->_Current
->DepthMode
;
598 if (texUnit
->EnvMode
!= GL_REPLACE
) {
599 /* convert GLchan colors to GLfloat */
600 for (i
= 0; i
< n
; i
++) {
601 rgba
[i
][RCOMP
] = CHAN_TO_FLOAT(rgbaChan
[i
][RCOMP
]);
602 rgba
[i
][GCOMP
] = CHAN_TO_FLOAT(rgbaChan
[i
][GCOMP
]);
603 rgba
[i
][BCOMP
] = CHAN_TO_FLOAT(rgbaChan
[i
][BCOMP
]);
604 rgba
[i
][ACOMP
] = CHAN_TO_FLOAT(rgbaChan
[i
][ACOMP
]);
608 switch (texUnit
->EnvMode
) {
615 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
621 GLfloat Lt
= texel
[i
][RCOMP
];
622 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = Lt
;
626 case GL_LUMINANCE_ALPHA
:
628 GLfloat Lt
= texel
[i
][RCOMP
];
630 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = Lt
;
632 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
638 GLfloat It
= texel
[i
][RCOMP
];
639 rgba
[i
][RCOMP
] = rgba
[i
][GCOMP
] = rgba
[i
][BCOMP
] = It
;
647 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
648 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
649 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
656 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
657 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
658 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
660 rgba
[i
][ACOMP
] = texel
[i
][ACOMP
];
664 _mesa_problem(ctx
, "Bad format (GL_REPLACE) in texture_apply");
675 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * texel
[i
][ACOMP
];
681 GLfloat Lt
= texel
[i
][RCOMP
];
682 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * Lt
;
683 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * Lt
;
684 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * Lt
;
688 case GL_LUMINANCE_ALPHA
:
691 GLfloat Lt
= texel
[i
][RCOMP
];
692 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * Lt
;
693 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * Lt
;
694 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * Lt
;
696 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * texel
[i
][ACOMP
];
702 GLfloat It
= texel
[i
][RCOMP
];
703 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * It
;
704 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * It
;
705 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * It
;
707 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * It
;
713 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * texel
[i
][RCOMP
];
714 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * texel
[i
][GCOMP
];
715 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * texel
[i
][BCOMP
];
722 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * texel
[i
][RCOMP
];
723 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * texel
[i
][GCOMP
];
724 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * texel
[i
][BCOMP
];
726 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * texel
[i
][ACOMP
];
730 _mesa_problem(ctx
, "Bad format (GL_MODULATE) in texture_apply");
739 case GL_LUMINANCE_ALPHA
:
746 rgba
[i
][RCOMP
] = texel
[i
][RCOMP
];
747 rgba
[i
][GCOMP
] = texel
[i
][GCOMP
];
748 rgba
[i
][BCOMP
] = texel
[i
][BCOMP
];
754 /* Cv = Cf(1-At) + CtAt */
755 GLfloat t
= texel
[i
][ACOMP
], s
= 1.0F
- t
;
756 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * s
+ texel
[i
][RCOMP
] * t
;
757 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * s
+ texel
[i
][GCOMP
] * t
;
758 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * s
+ texel
[i
][BCOMP
] * t
;
763 _mesa_problem(ctx
, "Bad format (GL_DECAL) in texture_apply");
769 Rc
= texUnit
->EnvColor
[0];
770 Gc
= texUnit
->EnvColor
[1];
771 Bc
= texUnit
->EnvColor
[2];
772 Ac
= texUnit
->EnvColor
[3];
778 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * texel
[i
][ACOMP
];
783 /* Cv = Cf(1-Lt) + CcLt */
784 GLfloat Lt
= texel
[i
][RCOMP
], s
= 1.0F
- Lt
;
785 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * s
+ Rc
* Lt
;
786 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * s
+ Gc
* Lt
;
787 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * s
+ Bc
* Lt
;
791 case GL_LUMINANCE_ALPHA
:
793 /* Cv = Cf(1-Lt) + CcLt */
794 GLfloat Lt
= texel
[i
][RCOMP
], s
= 1.0F
- Lt
;
795 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * s
+ Rc
* Lt
;
796 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * s
+ Gc
* Lt
;
797 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * s
+ Bc
* Lt
;
799 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * texel
[i
][ACOMP
];
804 /* Cv = Cf(1-It) + CcIt */
805 GLfloat It
= texel
[i
][RCOMP
], s
= 1.0F
- It
;
806 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * s
+ Rc
* It
;
807 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * s
+ Gc
* It
;
808 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * s
+ Bc
* It
;
809 /* Av = Af(1-It) + Ac*It */
810 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * s
+ Ac
* It
;
815 /* Cv = Cf(1-Ct) + CcCt */
816 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * (1.0F
- texel
[i
][RCOMP
])
817 + Rc
* texel
[i
][RCOMP
];
818 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * (1.0F
- texel
[i
][GCOMP
])
819 + Gc
* texel
[i
][GCOMP
];
820 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * (1.0F
- texel
[i
][BCOMP
])
821 + Bc
* texel
[i
][BCOMP
];
827 /* Cv = Cf(1-Ct) + CcCt */
828 rgba
[i
][RCOMP
] = rgba
[i
][RCOMP
] * (1.0F
- texel
[i
][RCOMP
])
829 + Rc
* texel
[i
][RCOMP
];
830 rgba
[i
][GCOMP
] = rgba
[i
][GCOMP
] * (1.0F
- texel
[i
][GCOMP
])
831 + Gc
* texel
[i
][GCOMP
];
832 rgba
[i
][BCOMP
] = rgba
[i
][BCOMP
] * (1.0F
- texel
[i
][BCOMP
])
833 + Bc
* texel
[i
][BCOMP
];
835 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * texel
[i
][ACOMP
];
839 _mesa_problem(ctx
, "Bad format (GL_BLEND) in texture_apply");
844 /* XXX don't clamp results if GLfloat is float??? */
846 case GL_ADD
: /* GL_EXT_texture_add_env */
853 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * texel
[i
][ACOMP
];
858 GLfloat Lt
= texel
[i
][RCOMP
];
859 GLfloat r
= rgba
[i
][RCOMP
] + Lt
;
860 GLfloat g
= rgba
[i
][GCOMP
] + Lt
;
861 GLfloat b
= rgba
[i
][BCOMP
] + Lt
;
862 rgba
[i
][RCOMP
] = MIN2(r
, 1.0F
);
863 rgba
[i
][GCOMP
] = MIN2(g
, 1.0F
);
864 rgba
[i
][BCOMP
] = MIN2(b
, 1.0F
);
868 case GL_LUMINANCE_ALPHA
:
870 GLfloat Lt
= texel
[i
][RCOMP
];
871 GLfloat r
= rgba
[i
][RCOMP
] + Lt
;
872 GLfloat g
= rgba
[i
][GCOMP
] + Lt
;
873 GLfloat b
= rgba
[i
][BCOMP
] + Lt
;
874 rgba
[i
][RCOMP
] = MIN2(r
, 1.0F
);
875 rgba
[i
][GCOMP
] = MIN2(g
, 1.0F
);
876 rgba
[i
][BCOMP
] = MIN2(b
, 1.0F
);
877 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * texel
[i
][ACOMP
];
882 GLfloat It
= texel
[i
][RCOMP
];
883 GLfloat r
= rgba
[i
][RCOMP
] + It
;
884 GLfloat g
= rgba
[i
][GCOMP
] + It
;
885 GLfloat b
= rgba
[i
][BCOMP
] + It
;
886 GLfloat a
= rgba
[i
][ACOMP
] + It
;
887 rgba
[i
][RCOMP
] = MIN2(r
, 1.0F
);
888 rgba
[i
][GCOMP
] = MIN2(g
, 1.0F
);
889 rgba
[i
][BCOMP
] = MIN2(b
, 1.0F
);
890 rgba
[i
][ACOMP
] = MIN2(a
, 1.0F
);
895 GLfloat r
= rgba
[i
][RCOMP
] + texel
[i
][RCOMP
];
896 GLfloat g
= rgba
[i
][GCOMP
] + texel
[i
][GCOMP
];
897 GLfloat b
= rgba
[i
][BCOMP
] + texel
[i
][BCOMP
];
898 rgba
[i
][RCOMP
] = MIN2(r
, 1.0F
);
899 rgba
[i
][GCOMP
] = MIN2(g
, 1.0F
);
900 rgba
[i
][BCOMP
] = MIN2(b
, 1.0F
);
906 GLfloat r
= rgba
[i
][RCOMP
] + texel
[i
][RCOMP
];
907 GLfloat g
= rgba
[i
][GCOMP
] + texel
[i
][GCOMP
];
908 GLfloat b
= rgba
[i
][BCOMP
] + texel
[i
][BCOMP
];
909 rgba
[i
][RCOMP
] = MIN2(r
, 1.0F
);
910 rgba
[i
][GCOMP
] = MIN2(g
, 1.0F
);
911 rgba
[i
][BCOMP
] = MIN2(b
, 1.0F
);
912 rgba
[i
][ACOMP
] = rgba
[i
][ACOMP
] * texel
[i
][ACOMP
];
916 _mesa_problem(ctx
, "Bad format (GL_ADD) in texture_apply");
922 _mesa_problem(ctx
, "Bad env mode in texture_apply");
926 /* convert GLfloat colors to GLchan */
927 for (i
= 0; i
< n
; i
++) {
928 CLAMPED_FLOAT_TO_CHAN(rgbaChan
[i
][RCOMP
], rgba
[i
][RCOMP
]);
929 CLAMPED_FLOAT_TO_CHAN(rgbaChan
[i
][GCOMP
], rgba
[i
][GCOMP
]);
930 CLAMPED_FLOAT_TO_CHAN(rgbaChan
[i
][BCOMP
], rgba
[i
][BCOMP
]);
931 CLAMPED_FLOAT_TO_CHAN(rgbaChan
[i
][ACOMP
], rgba
[i
][ACOMP
]);
938 * Apply texture mapping to a span of fragments.
941 _swrast_texture_span( GLcontext
*ctx
, SWspan
*span
)
943 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
944 GLfloat primary_rgba
[MAX_WIDTH
][4];
947 ASSERT(span
->end
< MAX_WIDTH
);
950 * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
952 if (swrast
->_AnyTextureCombine
) {
954 for (i
= 0; i
< span
->end
; i
++) {
955 primary_rgba
[i
][RCOMP
] = CHAN_TO_FLOAT(span
->array
->rgba
[i
][RCOMP
]);
956 primary_rgba
[i
][GCOMP
] = CHAN_TO_FLOAT(span
->array
->rgba
[i
][GCOMP
]);
957 primary_rgba
[i
][BCOMP
] = CHAN_TO_FLOAT(span
->array
->rgba
[i
][BCOMP
]);
958 primary_rgba
[i
][ACOMP
] = CHAN_TO_FLOAT(span
->array
->rgba
[i
][ACOMP
]);
962 /* First must sample all bump maps */
963 for (unit
= 0; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
964 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
&&
965 ctx
->Texture
.Unit
[unit
]._CurrentCombine
->ModeRGB
== GL_BUMP_ENVMAP_ATI
) {
966 const GLfloat (*texcoords
)[4]
967 = (const GLfloat (*)[4])
968 span
->array
->attribs
[FRAG_ATTRIB_TEX0
+ unit
];
969 GLfloat (*targetcoords
)[4]
971 span
->array
->attribs
[FRAG_ATTRIB_TEX0
+
972 ctx
->Texture
.Unit
[unit
].BumpTarget
- GL_TEXTURE0
];
974 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
975 const struct gl_texture_object
*curObj
= texUnit
->_Current
;
976 GLfloat
*lambda
= span
->array
->lambda
[unit
];
977 GLchan (*texels
)[4] = (GLchan (*)[4])
978 (swrast
->TexelBuffer
+ unit
* (span
->end
* 4 * sizeof(GLchan
)));
980 GLfloat rotMatrix00
= ctx
->Texture
.Unit
[unit
].RotMatrix
[0];
981 GLfloat rotMatrix01
= ctx
->Texture
.Unit
[unit
].RotMatrix
[1];
982 GLfloat rotMatrix10
= ctx
->Texture
.Unit
[unit
].RotMatrix
[2];
983 GLfloat rotMatrix11
= ctx
->Texture
.Unit
[unit
].RotMatrix
[3];
985 /* adjust texture lod (lambda) */
986 if (span
->arrayMask
& SPAN_LAMBDA
) {
987 if (texUnit
->LodBias
+ curObj
->LodBias
!= 0.0F
) {
988 /* apply LOD bias, but don't clamp yet */
989 const GLfloat bias
= CLAMP(texUnit
->LodBias
+ curObj
->LodBias
,
990 -ctx
->Const
.MaxTextureLodBias
,
991 ctx
->Const
.MaxTextureLodBias
);
993 for (i
= 0; i
< span
->end
; i
++) {
998 if (curObj
->MinLod
!= -1000.0 || curObj
->MaxLod
!= 1000.0) {
999 /* apply LOD clamping to lambda */
1000 const GLfloat min
= curObj
->MinLod
;
1001 const GLfloat max
= curObj
->MaxLod
;
1003 for (i
= 0; i
< span
->end
; i
++) {
1004 GLfloat l
= lambda
[i
];
1005 lambda
[i
] = CLAMP(l
, min
, max
);
1010 /* Sample the texture (span->end = number of fragments) */
1011 swrast
->TextureSample
[unit
]( ctx
, texUnit
->_Current
, span
->end
,
1012 texcoords
, lambda
, texels
);
1014 /* manipulate the span values of the bump target
1015 not sure this can work correctly even ignoring
1016 the problem that channel is unsigned */
1017 for (i
= 0; i
< span
->end
; i
++) {
1018 #if CHAN_TYPE == GL_FLOAT
1019 targetcoords
[i
][0] += (texels
[i
][0] * rotMatrix00
+ texels
[i
][1] *
1020 rotMatrix01
) / targetcoords
[i
][3];
1021 targetcoords
[i
][1] += (texels
[i
][0] * rotMatrix10
+ texels
[i
][1] *
1022 rotMatrix11
) / targetcoords
[i
][3];
1024 targetcoords
[i
][0] += (CHAN_TO_FLOAT(texels
[i
][1]) * rotMatrix00
+
1025 CHAN_TO_FLOAT(texels
[i
][1]) * rotMatrix01
) /
1027 targetcoords
[i
][1] += (CHAN_TO_FLOAT(texels
[i
][0]) * rotMatrix10
+
1028 CHAN_TO_FLOAT(texels
[i
][1]) * rotMatrix11
) /
1036 * Must do all texture sampling before combining in order to
1037 * accomodate GL_ARB_texture_env_crossbar.
1039 for (unit
= 0; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
1040 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
&&
1041 ctx
->Texture
.Unit
[unit
]._CurrentCombine
->ModeRGB
!= GL_BUMP_ENVMAP_ATI
) {
1042 const GLfloat (*texcoords
)[4]
1043 = (const GLfloat (*)[4])
1044 span
->array
->attribs
[FRAG_ATTRIB_TEX0
+ unit
];
1045 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1046 const struct gl_texture_object
*curObj
= texUnit
->_Current
;
1047 GLfloat
*lambda
= span
->array
->lambda
[unit
];
1048 GLfloat (*texels
)[4] = (GLfloat (*)[4])
1049 (swrast
->TexelBuffer
+ unit
* (span
->end
* 4 * sizeof(GLfloat
)));
1051 /* adjust texture lod (lambda) */
1052 if (span
->arrayMask
& SPAN_LAMBDA
) {
1053 if (texUnit
->LodBias
+ curObj
->LodBias
!= 0.0F
) {
1054 /* apply LOD bias, but don't clamp yet */
1055 const GLfloat bias
= CLAMP(texUnit
->LodBias
+ curObj
->LodBias
,
1056 -ctx
->Const
.MaxTextureLodBias
,
1057 ctx
->Const
.MaxTextureLodBias
);
1059 for (i
= 0; i
< span
->end
; i
++) {
1064 if (curObj
->MinLod
!= -1000.0 || curObj
->MaxLod
!= 1000.0) {
1065 /* apply LOD clamping to lambda */
1066 const GLfloat min
= curObj
->MinLod
;
1067 const GLfloat max
= curObj
->MaxLod
;
1069 for (i
= 0; i
< span
->end
; i
++) {
1070 GLfloat l
= lambda
[i
];
1071 lambda
[i
] = CLAMP(l
, min
, max
);
1076 /* Sample the texture (span->end = number of fragments) */
1077 swrast
->TextureSample
[unit
]( ctx
, texUnit
->_Current
, span
->end
,
1078 texcoords
, lambda
, texels
);
1080 /* GL_SGI_texture_color_table */
1081 if (texUnit
->ColorTableEnabled
) {
1082 _mesa_lookup_rgba_float(&texUnit
->ColorTable
, span
->end
, texels
);
1085 /* GL_EXT_texture_swizzle */
1086 if (curObj
->_Swizzle
!= SWIZZLE_NOOP
) {
1087 swizzle_texels(curObj
->_Swizzle
, span
->end
, texels
);
1094 * OK, now apply the texture (aka texture combine/blend).
1095 * We modify the span->color.rgba values.
1097 for (unit
= 0; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
1098 if (ctx
->Texture
.Unit
[unit
]._ReallyEnabled
) {
1099 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1100 if (texUnit
->_CurrentCombine
!= &texUnit
->_EnvMode
) {
1101 texture_combine( ctx
, unit
, span
->end
,
1102 (CONST
GLfloat (*)[4]) primary_rgba
,
1103 swrast
->TexelBuffer
,
1104 span
->array
->rgba
);
1107 /* conventional texture blend */
1108 const GLfloat (*texels
)[4] = (const GLfloat (*)[4])
1109 (swrast
->TexelBuffer
+ unit
*
1110 (span
->end
* 4 * sizeof(GLfloat
)));
1113 texture_apply( ctx
, texUnit
, span
->end
,
1114 (CONST
GLfloat (*)[4]) primary_rgba
, texels
,
1115 span
->array
->rgba
);