ReactOS  0.4.14-dev-50-g13bb5e2
texture.c
Go to the documentation of this file.
1 /* $Id: texture.c,v 1.36 1997/11/17 02:04:06 brianp Exp $ */
2 
3 /*
4  * Mesa 3-D graphics library
5  * Version: 2.5
6  * Copyright (C) 1995-1997 Brian Paul
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 
24 /*
25  * $Log: texture.c,v $
26  * Revision 1.36 1997/11/17 02:04:06 brianp
27  * fixed a typo in texture code
28  *
29  * Revision 1.35 1997/11/13 02:17:32 brianp
30  * added a few const keywords
31  *
32  * Revision 1.34 1997/10/16 01:59:08 brianp
33  * added GL_EXT_shared_texture_palette extension
34  *
35  * Revision 1.33 1997/09/27 00:14:39 brianp
36  * added GL_EXT_paletted_texture extension
37  *
38  * Revision 1.32 1997/08/14 01:03:12 brianp
39  * fixed small bug in GL_SPHERE_MAP texgen (Petri Nordlund)
40  *
41  * Revision 1.31 1997/07/24 01:25:34 brianp
42  * changed precompiled header symbol from PCH to PC_HEADER
43  *
44  * Revision 1.30 1997/07/22 01:23:48 brianp
45  * fixed negative texture coord sampling problem (Magnus Lundin)
46  *
47  * Revision 1.29 1997/07/09 00:32:26 brianp
48  * fixed bug involving sampling and incomplete texture objects
49  *
50  * Revision 1.28 1997/05/28 03:26:49 brianp
51  * added precompiled header (PCH) support
52  *
53  * Revision 1.27 1997/05/17 03:51:10 brianp
54  * fixed bug in PROD macro (Waldemar Celes)
55  *
56  * Revision 1.26 1997/05/03 00:53:56 brianp
57  * all-new texture sampling via gl_texture_object's SampleFunc pointer
58  *
59  * Revision 1.25 1997/05/01 01:40:14 brianp
60  * replaced sqrt() with GL_SQRT, use NORMALIZE_3FV instead of NORMALIZE_3V
61  *
62  * Revision 1.24 1997/04/28 02:04:18 brianp
63  * GL_SPHERE_MAP texgen was wrong (Eamon O'Dea)
64  *
65  * Revision 1.23 1997/04/20 20:29:11 brianp
66  * replaced abort() with gl_problem()
67  *
68  * Revision 1.22 1997/04/16 23:56:41 brianp
69  * added a few #include files
70  *
71  * Revision 1.21 1997/04/14 02:02:39 brianp
72  * moved many functions into new texstate.c file
73  *
74  * Revision 1.20 1997/04/01 04:19:14 brianp
75  * call gl_analyze_modelview_matrix instead of gl_compute_modelview_inverse
76  *
77  * Revision 1.19 1997/03/04 19:55:58 brianp
78  * small texture sampling optimizations. better comments.
79  *
80  * Revision 1.18 1997/03/04 19:19:20 brianp
81  * fixed a number of problems with texture borders
82  *
83  * Revision 1.17 1997/02/27 19:58:08 brianp
84  * call gl_problem() instead of gl_warning()
85  *
86  * Revision 1.16 1997/02/09 19:53:43 brianp
87  * now use TEXTURE_xD enable constants
88  *
89  * Revision 1.15 1997/02/09 18:53:14 brianp
90  * added GL_EXT_texture3D support
91  *
92  * Revision 1.14 1997/01/30 21:06:03 brianp
93  * added some missing glGetTexLevelParameter() GLenums
94  *
95  * Revision 1.13 1997/01/16 03:36:01 brianp
96  * added calls to device driver TexParameter() and TexEnv() functions
97  *
98  * Revision 1.12 1997/01/09 19:48:30 brianp
99  * better error checking
100  * added gl_texturing_enabled()
101  *
102  * Revision 1.11 1996/12/20 20:22:30 brianp
103  * linear interpolation between mipmap levels was reverse weighted
104  * max mipmap level was incorrectly tested for
105  *
106  * Revision 1.10 1996/12/12 22:33:05 brianp
107  * minor changes to gl_texgen()
108  *
109  * Revision 1.9 1996/12/07 10:35:41 brianp
110  * implmented glGetTexGen*() functions
111  *
112  * Revision 1.8 1996/11/14 01:03:09 brianp
113  * removed const's from gl_texgen() function to avoid VMS compiler warning
114  *
115  * Revision 1.7 1996/11/08 02:19:52 brianp
116  * gl_do_texgen() replaced with gl_texgen()
117  *
118  * Revision 1.6 1996/10/26 17:17:30 brianp
119  * glTexGen GL_EYE_PLANE vector now transformed by inverse modelview matrix
120  *
121  * Revision 1.5 1996/10/11 03:42:38 brianp
122  * replaced old _EXT symbols
123  *
124  * Revision 1.4 1996/09/27 01:30:24 brianp
125  * added missing default cases to switches
126  *
127  * Revision 1.3 1996/09/15 14:18:55 brianp
128  * now use GLframebuffer and GLvisual
129  *
130  * Revision 1.2 1996/09/15 01:48:58 brianp
131  * removed #define NULL 0
132  *
133  * Revision 1.1 1996/09/13 01:38:16 brianp
134  * Initial revision
135  *
136  */
137 
138 
139 #ifdef PC_HEADER
140 #include "all.h"
141 #else
142 #include <math.h>
143 #include <stdlib.h>
144 #include "context.h"
145 #include "macros.h"
146 #include "mmath.h"
147 #include "pb.h"
148 #include "texture.h"
149 #include "types.h"
150 #endif
151 
152 
153 
154 /*
155  * Perform automatic texture coordinate generation.
156  * Input: ctx - the context
157  * n - number of texture coordinates to generate
158  * obj - array of vertexes in object coordinate system
159  * eye - array of vertexes in eye coordinate system
160  * normal - array of normal vectores in eye coordinate system
161  * Output: texcoord - array of resuling texture coordinates
162  */
164  GLfloat obj[][4], GLfloat eye[][4],
165  GLfloat normal[][3], GLfloat texcoord[][4] )
166 {
167  /* special case: S and T sphere mapping */
168  if (ctx->Texture.TexGenEnabled==(S_BIT|T_BIT)
169  && ctx->Texture.GenModeS==GL_SPHERE_MAP
170  && ctx->Texture.GenModeT==GL_SPHERE_MAP) {
171  GLint i;
172  for (i=0;i<n;i++) {
173  GLfloat u[3], two_nu, m, fx, fy, fz;
174  COPY_3V( u, eye[i] );
175  NORMALIZE_3FV( u );
176  two_nu = 2.0F * DOT3(normal[i],u);
177  fx = u[0] - normal[i][0] * two_nu;
178  fy = u[1] - normal[i][1] * two_nu;
179  fz = u[2] - normal[i][2] * two_nu;
180  m = 2.0F * GL_SQRT( fx*fx + fy*fy + (fz+1.0F)*(fz+1.0F) );
181  if (m==0.0F) {
182  texcoord[i][0] = 0.5F;
183  texcoord[i][1] = 0.5F;
184  }
185  else {
186  GLfloat mInv = 1.0F / m;
187  texcoord[i][0] = fx * mInv + 0.5F;
188  texcoord[i][1] = fy * mInv + 0.5F;
189  }
190  }
191  return;
192  }
193 
194  /* general solution */
195  if (ctx->Texture.TexGenEnabled & S_BIT) {
196  GLint i;
197  switch (ctx->Texture.GenModeS) {
198  case GL_OBJECT_LINEAR:
199  for (i=0;i<n;i++) {
200  texcoord[i][0] = DOT4( obj[i], ctx->Texture.ObjectPlaneS );
201  }
202  break;
203  case GL_EYE_LINEAR:
204  for (i=0;i<n;i++) {
205  texcoord[i][0] = DOT4( eye[i], ctx->Texture.EyePlaneS );
206  }
207  break;
208  case GL_SPHERE_MAP:
209  for (i=0;i<n;i++) {
210  GLfloat u[3], two_nu, m, fx, fy, fz;
211  COPY_3V( u, eye[i] );
212  NORMALIZE_3FV( u );
213  two_nu = 2.0*DOT3(normal[i],u);
214  fx = u[0] - normal[i][0] * two_nu;
215  fy = u[1] - normal[i][1] * two_nu;
216  fz = u[2] - normal[i][2] * two_nu;
217  m = 2.0F * GL_SQRT( fx*fx + fy*fy + (fz+1.0)*(fz+1.0) );
218  if (m==0.0F) {
219  texcoord[i][0] = 0.5F;
220  }
221  else {
222  texcoord[i][0] = fx / m + 0.5F;
223  }
224  }
225  break;
226  default:
227  gl_problem(ctx, "Bad S texgen");
228  return;
229  }
230  }
231 
232  if (ctx->Texture.TexGenEnabled & T_BIT) {
233  GLint i;
234  switch (ctx->Texture.GenModeT) {
235  case GL_OBJECT_LINEAR:
236  for (i=0;i<n;i++) {
237  texcoord[i][1] = DOT4( obj[i], ctx->Texture.ObjectPlaneT );
238  }
239  break;
240  case GL_EYE_LINEAR:
241  for (i=0;i<n;i++) {
242  texcoord[i][1] = DOT4( eye[i], ctx->Texture.EyePlaneT );
243  }
244  break;
245  case GL_SPHERE_MAP:
246  for (i=0;i<n;i++) {
247  GLfloat u[3], two_nu, m, fx, fy, fz;
248  COPY_3V( u, eye[i] );
249  NORMALIZE_3FV( u );
250  two_nu = 2.0*DOT3(normal[i],u);
251  fx = u[0] - normal[i][0] * two_nu;
252  fy = u[1] - normal[i][1] * two_nu;
253  fz = u[2] - normal[i][2] * two_nu;
254  m = 2.0F * GL_SQRT( fx*fx + fy*fy + (fz+1.0)*(fz+1.0) );
255  if (m==0.0F) {
256  texcoord[i][1] = 0.5F;
257  }
258  else {
259  texcoord[i][1] = fy / m + 0.5F;
260  }
261  }
262  break;
263  default:
264  gl_problem(ctx, "Bad T texgen");
265  return;
266  }
267  }
268 
269  if (ctx->Texture.TexGenEnabled & R_BIT) {
270  GLint i;
271  switch (ctx->Texture.GenModeR) {
272  case GL_OBJECT_LINEAR:
273  for (i=0;i<n;i++) {
274  texcoord[i][2] = DOT4( obj[i], ctx->Texture.ObjectPlaneR );
275  }
276  break;
277  case GL_EYE_LINEAR:
278  for (i=0;i<n;i++) {
279  texcoord[i][2] = DOT4( eye[i], ctx->Texture.EyePlaneR );
280  }
281  break;
282  default:
283  gl_problem(ctx, "Bad R texgen");
284  return;
285  }
286  }
287 
288  if (ctx->Texture.TexGenEnabled & Q_BIT) {
289  GLint i;
290  switch (ctx->Texture.GenModeQ) {
291  case GL_OBJECT_LINEAR:
292  for (i=0;i<n;i++) {
293  texcoord[i][3] = DOT4( obj[i], ctx->Texture.ObjectPlaneQ );
294  }
295  break;
296  case GL_EYE_LINEAR:
297  for (i=0;i<n;i++) {
298  texcoord[i][3] = DOT4( eye[i], ctx->Texture.EyePlaneQ );
299  }
300  break;
301  default:
302  gl_problem(ctx, "Bad Q texgen");
303  return;
304  }
305  }
306 }
307 
308 
309 
310 /*
311  * Paletted texture sampling.
312  * Input: tObj - the texture object
313  * index - the palette index (8-bit only)
314  * Output: red, green, blue, alpha - the texel color
315  */
316 static void palette_sample(const struct gl_texture_object *tObj,
319 {
320  GLint i = index;
321  const GLubyte *palette;
322 
323  palette = tObj->Palette;
324 
325  switch (tObj->PaletteFormat) {
326  case GL_ALPHA:
327  *alpha = tObj->Palette[index];
328  return;
329  case GL_LUMINANCE:
330  case GL_INTENSITY:
331  *red = palette[index];
332  return;
333  case GL_LUMINANCE_ALPHA:
334  *red = palette[(index << 1) + 0];
335  *alpha = palette[(index << 1) + 1];
336  return;
337  case GL_RGB:
338  *red = palette[index * 3 + 0];
339  *green = palette[index * 3 + 1];
340  *blue = palette[index * 3 + 2];
341  return;
342  case GL_RGBA:
343  *red = palette[(i << 2) + 0];
344  *green = palette[(i << 2) + 1];
345  *blue = palette[(i << 2) + 2];
346  *alpha = palette[(i << 2) + 3];
347  return;
348  default:
349  gl_problem(NULL, "Bad palette format in palette_sample");
350  }
351 }
352 
353 
354 
355 
356 /**********************************************************************/
357 /* 1-D Texture Sampling Functions */
358 /**********************************************************************/
359 
360 
361 /*
362  * Return the fractional part of x.
363  */
364 #define frac(x) ((GLfloat)(x)-floor((GLfloat)x))
365 
366 
367 
368 /*
369  * Given 1-D texture image and an (i) texel column coordinate, return the
370  * texel color.
371  */
372 static void get_1d_texel( const struct gl_texture_object *tObj,
373  const struct gl_texture_image *img, GLint i,
375  GLubyte *alpha )
376 {
377  GLubyte *texel;
378 
379 #ifdef DEBUG
380  GLint width = img->Width;
381  if (i<0 || i>=width) abort();
382 #endif
383 
384  switch (img->Format) {
385  case GL_COLOR_INDEX:
386  {
387  GLubyte index = img->Data[i];
388  palette_sample(tObj, index, red, green, blue, alpha);
389  return;
390  }
391  return;
392  case GL_ALPHA:
393  *alpha = img->Data[ i ];
394  return;
395  case GL_LUMINANCE:
396  case GL_INTENSITY:
397  *red = img->Data[ i ];
398  return;
399  case GL_LUMINANCE_ALPHA:
400  texel = img->Data + i * 2;
401  *red = texel[0];
402  *alpha = texel[1];
403  return;
404  case GL_RGB:
405  texel = img->Data + i * 3;
406  *red = texel[0];
407  *green = texel[1];
408  *blue = texel[2];
409  return;
410  case GL_RGBA:
411  texel = img->Data + i * 4;
412  *red = texel[0];
413  *green = texel[1];
414  *blue = texel[2];
415  *alpha = texel[3];
416  return;
417  default:
418  gl_problem(NULL, "Bad format in get_1d_texel");
419  return;
420  }
421 }
422 
423 
424 
425 /*
426  * Return the texture sample for coordinate (s) using GL_NEAREST filter.
427  */
428 static void sample_1d_nearest( const struct gl_texture_object *tObj,
429  const struct gl_texture_image *img,
430  GLfloat s,
433 {
434  GLint width = img->Width2; /* without border, power of two */
435  GLint i;
436  GLubyte *texel;
437 
438  /* Clamp/Repeat S and convert to integer texel coordinate */
439  if (tObj->WrapS==GL_REPEAT) {
440  /* s limited to [0,1) */
441  /* i limited to [0,width-1] */
442  i = (GLint) (s * width);
443  if (s<0.0F) i -= 1;
444  i &= (width-1);
445  }
446  else {
447  /* s limited to [0,1] */
448  /* i limited to [0,width-1] */
449  if (s<0.0F) i = 0;
450  else if (s>1.0F) i = width-1;
451  else i = (GLint) (s * width);
452  }
453 
454  /* skip over the border, if any */
455  i += img->Border;
456 
457  /* Get the texel */
458  switch (img->Format) {
459  case GL_COLOR_INDEX:
460  {
461  GLubyte index = img->Data[i];
462  palette_sample(tObj, index, red, green, blue, alpha);
463  return;
464  }
465  case GL_ALPHA:
466  *alpha = img->Data[i];
467  return;
468  case GL_LUMINANCE:
469  case GL_INTENSITY:
470  *red = img->Data[i];
471  return;
472  case GL_LUMINANCE_ALPHA:
473  texel = img->Data + i * 2;
474  *red = texel[0];
475  *alpha = texel[1];
476  return;
477  case GL_RGB:
478  texel = img->Data + i * 3;
479  *red = texel[0];
480  *green = texel[1];
481  *blue = texel[2];
482  return;
483  case GL_RGBA:
484  texel = img->Data + i * 4;
485  *red = texel[0];
486  *green = texel[1];
487  *blue = texel[2];
488  *alpha = texel[3];
489  return;
490  default:
491  gl_problem(NULL, "Bad format in sample_1d_nearest");
492  }
493 }
494 
495 
496 
497 /*
498  * Return the texture sample for coordinate (s) using GL_LINEAR filter.
499  */
500 static void sample_1d_linear( const struct gl_texture_object *tObj,
501  const struct gl_texture_image *img,
502  GLfloat s,
505 {
506  GLint width = img->Width2;
507  GLint i0, i1;
508  GLfloat u;
509  GLint i0border, i1border;
510 
511  u = s * width;
512  if (tObj->WrapS==GL_REPEAT) {
513  i0 = ((GLint) floor(u - 0.5F)) % width;
514  i1 = (i0 + 1) & (width-1);
515  i0border = i1border = 0;
516  }
517  else {
518  i0 = (GLint) floor(u - 0.5F);
519  i1 = i0 + 1;
520  i0border = (i0<0) | (i0>=width);
521  i1border = (i1<0) | (i1>=width);
522  }
523 
524  if (img->Border) {
525  i0 += img->Border;
526  i1 += img->Border;
527  i0border = i1border = 0;
528  }
529  else {
530  i0 &= (width-1);
531  }
532 
533  {
534  GLfloat a = frac(u - 0.5F);
535 
536  GLint w0 = (GLint) ((1.0F-a) * 256.0F);
537  GLint w1 = (GLint) ( a * 256.0F);
538 
539  GLubyte red0, green0, blue0, alpha0;
540  GLubyte red1, green1, blue1, alpha1;
541 
542  if (i0border) {
543  red0 = tObj->BorderColor[0];
544  green0 = tObj->BorderColor[1];
545  blue0 = tObj->BorderColor[2];
546  alpha0 = tObj->BorderColor[3];
547  }
548  else {
549  get_1d_texel( tObj, img, i0, &red0, &green0, &blue0, &alpha0 );
550  }
551  if (i1border) {
552  red1 = tObj->BorderColor[0];
553  green1 = tObj->BorderColor[1];
554  blue1 = tObj->BorderColor[2];
555  alpha1 = tObj->BorderColor[3];
556  }
557  else {
558  get_1d_texel( tObj, img, i1, &red1, &green1, &blue1, &alpha1 );
559  }
560 
561  *red = (w0*red0 + w1*red1) >> 8;
562  *green = (w0*green0 + w1*green1) >> 8;
563  *blue = (w0*blue0 + w1*blue1) >> 8;
564  *alpha = (w0*alpha0 + w1*alpha1) >> 8;
565  }
566 }
567 
568 
569 static void
571  GLfloat s, GLfloat lambda,
574 {
575  GLint level;
576  if (lambda<=0.5F) {
577  level = 0;
578  }
579  else {
580  GLint widthlog2 = tObj->Image[0]->WidthLog2;
581  level = (GLint) (lambda + 0.499999F);
582  if (level>widthlog2 ) {
583  level = widthlog2;
584  }
585  }
586  sample_1d_nearest( tObj, tObj->Image[level],
587  s, red, green, blue, alpha );
588 }
589 
590 
591 static void
593  GLfloat s, GLfloat lambda,
596 {
597  GLint level;
598  if (lambda<=0.5F) {
599  level = 0;
600  }
601  else {
602  GLint widthlog2 = tObj->Image[0]->WidthLog2;
603  level = (GLint) (lambda + 0.499999F);
604  if (level>widthlog2 ) {
605  level = widthlog2;
606  }
607  }
608  sample_1d_linear( tObj, tObj->Image[level],
609  s, red, green, blue, alpha );
610 }
611 
612 
613 
614 static void
616  GLfloat s, GLfloat lambda,
619 {
620  GLint max = tObj->Image[0]->MaxLog2;
621 
622  if (lambda>=max) {
623  sample_1d_nearest( tObj, tObj->Image[max],
624  s, red, green, blue, alpha );
625  }
626  else {
627  GLubyte red0, green0, blue0, alpha0;
628  GLubyte red1, green1, blue1, alpha1;
629  GLfloat f = frac(lambda);
630  GLint level = (GLint) (lambda + 1.0F);
631  level = CLAMP( level, 1, max );
632  sample_1d_nearest( tObj, tObj->Image[level-1],
633  s, &red0, &green0, &blue0, &alpha0 );
634  sample_1d_nearest( tObj, tObj->Image[level],
635  s, &red1, &green1, &blue1, &alpha1 );
636  *red = (1.0F-f)*red0 + f*red1;
637  *green = (1.0F-f)*green0 + f*green1;
638  *blue = (1.0F-f)*blue0 + f*blue1;
639  *alpha = (1.0F-f)*alpha0 + f*alpha1;
640  }
641 }
642 
643 
644 
645 static void
647  GLfloat s, GLfloat lambda,
650 {
651  GLint max = tObj->Image[0]->MaxLog2;
652 
653  if (lambda>=max) {
654  sample_1d_linear( tObj, tObj->Image[max],
655  s, red, green, blue, alpha );
656  }
657  else {
658  GLubyte red0, green0, blue0, alpha0;
659  GLubyte red1, green1, blue1, alpha1;
660  GLfloat f = frac(lambda);
661  GLint level = (GLint) (lambda + 1.0F);
662  level = CLAMP( level, 1, max );
663  sample_1d_linear( tObj, tObj->Image[level-1],
664  s, &red0, &green0, &blue0, &alpha0 );
665  sample_1d_linear( tObj, tObj->Image[level],
666  s, &red1, &green1, &blue1, &alpha1 );
667  *red = (1.0F-f)*red0 + f*red1;
668  *green = (1.0F-f)*green0 + f*green1;
669  *blue = (1.0F-f)*blue0 + f*blue1;
670  *alpha = (1.0F-f)*alpha0 + f*alpha1;
671  }
672 }
673 
674 
675 
676 static void sample_nearest_1d( const struct gl_texture_object *tObj, GLuint n,
677  const GLfloat s[], const GLfloat t[],
678  const GLfloat u[], const GLfloat lambda[],
680  GLubyte alpha[] )
681 {
682  GLuint i;
683  for (i=0;i<n;i++) {
684  sample_1d_nearest( tObj, tObj->Image[0], s[i],
685  &red[i], &green[i], &blue[i], &alpha[i]);
686  }
687 }
688 
689 
690 
691 static void sample_linear_1d( const struct gl_texture_object *tObj, GLuint n,
692  const GLfloat s[], const GLfloat t[],
693  const GLfloat u[], const GLfloat lambda[],
695  GLubyte alpha[] )
696 {
697  GLuint i;
698  for (i=0;i<n;i++) {
699  sample_1d_linear( tObj, tObj->Image[0], s[i],
700  &red[i], &green[i], &blue[i], &alpha[i]);
701  }
702 }
703 
704 
705 /*
706  * Given an (s) texture coordinate and lambda (level of detail) value,
707  * return a texture sample.
708  *
709  */
710 static void sample_lambda_1d( const struct gl_texture_object *tObj, GLuint n,
711  const GLfloat s[], const GLfloat t[],
712  const GLfloat u[], const GLfloat lambda[],
714  GLubyte alpha[] )
715 {
716  GLuint i;
717 
718  for (i=0;i<n;i++) {
719  if (lambda[i] > tObj->MinMagThresh) {
720  /* minification */
721  switch (tObj->MinFilter) {
722  case GL_NEAREST:
723  sample_1d_nearest( tObj, tObj->Image[0], s[i],
724  &red[i], &green[i], &blue[i], &alpha[i] );
725  break;
726  case GL_LINEAR:
727  sample_1d_linear( tObj, tObj->Image[0], s[i],
728  &red[i], &green[i], &blue[i], &alpha[i] );
729  break;
731  sample_1d_nearest_mipmap_nearest( tObj, lambda[i], s[i],
732  &red[i], &green[i], &blue[i], &alpha[i] );
733  break;
735  sample_1d_linear_mipmap_nearest( tObj, s[i], lambda[i],
736  &red[i], &green[i], &blue[i], &alpha[i] );
737  break;
739  sample_1d_nearest_mipmap_linear( tObj, s[i], lambda[i],
740  &red[i], &green[i], &blue[i], &alpha[i] );
741  break;
743  sample_1d_linear_mipmap_linear( tObj, s[i], lambda[i],
744  &red[i], &green[i], &blue[i], &alpha[i] );
745  break;
746  default:
747  gl_problem(NULL, "Bad min filter in sample_1d_texture");
748  return;
749  }
750  }
751  else {
752  /* magnification */
753  switch (tObj->MagFilter) {
754  case GL_NEAREST:
755  sample_1d_nearest( tObj, tObj->Image[0], s[i],
756  &red[i], &green[i], &blue[i], &alpha[i] );
757  break;
758  case GL_LINEAR:
759  sample_1d_linear( tObj, tObj->Image[0], s[i],
760  &red[i], &green[i], &blue[i], &alpha[i] );
761  break;
762  default:
763  gl_problem(NULL, "Bad mag filter in sample_1d_texture");
764  return;
765  }
766  }
767  }
768 }
769 
770 
771 
772 
773 /**********************************************************************/
774 /* 2-D Texture Sampling Functions */
775 /**********************************************************************/
776 
777 
778 /*
779  * Given a texture image and an (i,j) integer texel coordinate, return the
780  * texel color.
781  */
782 static void get_2d_texel( const struct gl_texture_object *tObj,
783  const struct gl_texture_image *img, GLint i, GLint j,
785  GLubyte *alpha )
786 {
787  GLint width = img->Width; /* includes border */
788  GLubyte *texel;
789 
790 #ifdef DEBUG
791  GLint height = img->Height; /* includes border */
792  if (i<0 || i>=width) abort();
793  if (j<0 || j>=height) abort();
794 #endif
795 
796  switch (img->Format) {
797  case GL_COLOR_INDEX:
798  {
799  GLubyte index = img->Data[ width *j + i ];
800  palette_sample(tObj, index, red, green, blue, alpha);
801  return;
802  }
803  case GL_ALPHA:
804  *alpha = img->Data[ width * j + i ];
805  return;
806  case GL_LUMINANCE:
807  case GL_INTENSITY:
808  *red = img->Data[ width * j + i ];
809  return;
810  case GL_LUMINANCE_ALPHA:
811  texel = img->Data + (width * j + i) * 2;
812  *red = texel[0];
813  *alpha = texel[1];
814  return;
815  case GL_RGB:
816  texel = img->Data + (width * j + i) * 3;
817  *red = texel[0];
818  *green = texel[1];
819  *blue = texel[2];
820  return;
821  case GL_RGBA:
822  texel = img->Data + (width * j + i) * 4;
823  *red = texel[0];
824  *green = texel[1];
825  *blue = texel[2];
826  *alpha = texel[3];
827  return;
828  default:
829  gl_problem(NULL, "Bad format in get_2d_texel");
830  }
831 }
832 
833 
834 
835 /*
836  * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
837  */
838 static void sample_2d_nearest( const struct gl_texture_object *tObj,
839  const struct gl_texture_image *img,
840  GLfloat s, GLfloat t,
843 {
844  GLint imgWidth = img->Width; /* includes border */
845  GLint width = img->Width2; /* without border, power of two */
846  GLint height = img->Height2; /* without border, power of two */
847  GLint i, j;
848  GLubyte *texel;
849 
850  /* Clamp/Repeat S and convert to integer texel coordinate */
851  if (tObj->WrapS==GL_REPEAT) {
852  /* s limited to [0,1) */
853  /* i limited to [0,width-1] */
854  i = (GLint) (s * width);
855  if (s<0.0F) i -= 1;
856  i &= (width-1);
857  }
858  else {
859  /* s limited to [0,1] */
860  /* i limited to [0,width-1] */
861  if (s<=0.0F) i = 0;
862  else if (s>1.0F) i = width-1;
863  else i = (GLint) (s * width);
864  }
865 
866  /* Clamp/Repeat T and convert to integer texel coordinate */
867  if (tObj->WrapT==GL_REPEAT) {
868  /* t limited to [0,1) */
869  /* j limited to [0,height-1] */
870  j = (GLint) (t * height);
871  if (t<0.0F) j -= 1;
872  j &= (height-1);
873  }
874  else {
875  /* t limited to [0,1] */
876  /* j limited to [0,height-1] */
877  if (t<=0.0F) j = 0;
878  else if (t>1.0F) j = height-1;
879  else j = (GLint) (t * height);
880  }
881 
882  /* skip over the border, if any */
883  i += img->Border;
884  j += img->Border;
885 
886  switch (img->Format) {
887  case GL_COLOR_INDEX:
888  {
889  GLubyte index = img->Data[ j * imgWidth + i ];
890  palette_sample(tObj, index, red, green, blue, alpha);
891  return;
892  }
893  case GL_ALPHA:
894  *alpha = img->Data[ j * imgWidth + i ];
895  return;
896  case GL_LUMINANCE:
897  case GL_INTENSITY:
898  *red = img->Data[ j * imgWidth + i ];
899  return;
900  case GL_LUMINANCE_ALPHA:
901  texel = img->Data + ((j * imgWidth + i) << 1);
902  *red = texel[0];
903  *alpha = texel[1];
904  return;
905  case GL_RGB:
906  texel = img->Data + (j * imgWidth + i) * 3;
907  *red = texel[0];
908  *green = texel[1];
909  *blue = texel[2];
910  return;
911  case GL_RGBA:
912  texel = img->Data + ((j * imgWidth + i) << 2);
913  *red = texel[0];
914  *green = texel[1];
915  *blue = texel[2];
916  *alpha = texel[3];
917  return;
918  default:
919  gl_problem(NULL, "Bad format in sample_2d_nearest");
920  }
921 }
922 
923 
924 
925 /*
926  * Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
927  */
928 static void sample_2d_linear( const struct gl_texture_object *tObj,
929  const struct gl_texture_image *img,
930  GLfloat s, GLfloat t,
933 {
934  GLint width = img->Width2;
935  GLint height = img->Height2;
936  GLint i0, j0, i1, j1;
937  GLint i0border, j0border, i1border, j1border;
938  GLfloat u, v;
939 
940  u = s * width;
941  if (tObj->WrapS==GL_REPEAT) {
942  i0 = ((GLint) floor(u - 0.5F)) % width;
943  i1 = (i0 + 1) & (width-1);
944  i0border = i1border = 0;
945  }
946  else {
947  i0 = (GLint) floor(u - 0.5F);
948  i1 = i0 + 1;
949  i0border = (i0<0) | (i0>=width);
950  i1border = (i1<0) | (i1>=width);
951  }
952 
953  v = t * height;
954  if (tObj->WrapT==GL_REPEAT) {
955  j0 = ((GLint) floor(v - 0.5F)) % height;
956  j1 = (j0 + 1) & (height-1);
957  j0border = j1border = 0;
958  }
959  else {
960  j0 = (GLint) floor(v - 0.5F );
961  j1 = j0 + 1;
962  j0border = (j0<0) | (j0>=height);
963  j1border = (j1<0) | (j1>=height);
964  }
965 
966  if (img->Border) {
967  i0 += img->Border;
968  i1 += img->Border;
969  j0 += img->Border;
970  j1 += img->Border;
971  i0border = i1border = 0;
972  j0border = j1border = 0;
973  }
974  else {
975  i0 &= (width-1);
976  j0 &= (height-1);
977  }
978 
979  {
980  GLfloat a = frac(u - 0.5F);
981  GLfloat b = frac(v - 0.5F);
982 
983  GLint w00 = (GLint) ((1.0F-a)*(1.0F-b) * 256.0F);
984  GLint w10 = (GLint) ( a *(1.0F-b) * 256.0F);
985  GLint w01 = (GLint) ((1.0F-a)* b * 256.0F);
986  GLint w11 = (GLint) ( a * b * 256.0F);
987 
988  GLubyte red00, green00, blue00, alpha00;
989  GLubyte red10, green10, blue10, alpha10;
990  GLubyte red01, green01, blue01, alpha01;
991  GLubyte red11, green11, blue11, alpha11;
992 
993  if (i0border | j0border) {
994  red00 = tObj->BorderColor[0];
995  green00 = tObj->BorderColor[1];
996  blue00 = tObj->BorderColor[2];
997  alpha00 = tObj->BorderColor[3];
998  }
999  else {
1000  get_2d_texel( tObj, img, i0, j0, &red00, &green00, &blue00, &alpha00);
1001  }
1002  if (i1border | j0border) {
1003  red10 = tObj->BorderColor[0];
1004  green10 = tObj->BorderColor[1];
1005  blue10 = tObj->BorderColor[2];
1006  alpha10 = tObj->BorderColor[3];
1007  }
1008  else {
1009  get_2d_texel( tObj, img, i1, j0, &red10, &green10, &blue10, &alpha10);
1010  }
1011  if (i0border | j1border) {
1012  red01 = tObj->BorderColor[0];
1013  green01 = tObj->BorderColor[1];
1014  blue01 = tObj->BorderColor[2];
1015  alpha01 = tObj->BorderColor[3];
1016  }
1017  else {
1018  get_2d_texel( tObj, img, i0, j1, &red01, &green01, &blue01, &alpha01);
1019  }
1020  if (i1border | j1border) {
1021  red11 = tObj->BorderColor[0];
1022  green11 = tObj->BorderColor[1];
1023  blue11 = tObj->BorderColor[2];
1024  alpha11 = tObj->BorderColor[3];
1025  }
1026  else {
1027  get_2d_texel( tObj, img, i1, j1, &red11, &green11, &blue11, &alpha11);
1028  }
1029 
1030  *red = (w00*red00 + w10*red10 + w01*red01 + w11*red11 ) >> 8;
1031  *green = (w00*green00 + w10*green10 + w01*green01 + w11*green11) >> 8;
1032  *blue = (w00*blue00 + w10*blue10 + w01*blue01 + w11*blue11 ) >> 8;
1033  *alpha = (w00*alpha00 + w10*alpha10 + w01*alpha01 + w11*alpha11) >> 8;
1034  }
1035 }
1036 
1037 
1038 
1039 static void
1041  GLfloat s, GLfloat t, GLfloat lambda,
1042  GLubyte *red, GLubyte *green,
1043  GLubyte *blue, GLubyte *alpha )
1044 {
1045  GLint level;
1046  if (lambda<=0.5F) {
1047  level = 0;
1048  }
1049  else {
1050  GLint max = tObj->Image[0]->MaxLog2;
1051  level = (GLint) (lambda + 0.499999F);
1052  if (level>max) {
1053  level = max;
1054  }
1055  }
1056  sample_2d_nearest( tObj, tObj->Image[level],
1057  s, t, red, green, blue, alpha );
1058 }
1059 
1060 
1061 
1062 static void
1064  GLfloat s, GLfloat t, GLfloat lambda,
1065  GLubyte *red, GLubyte *green,
1066  GLubyte *blue, GLubyte *alpha )
1067 {
1068  GLint level;
1069  if (lambda<=0.5F) {
1070  level = 0;
1071  }
1072  else {
1073  GLint max = tObj->Image[0]->MaxLog2;
1074  level = (GLint) (lambda + 0.499999F);
1075  if (level>max) {
1076  level = max;
1077  }
1078  }
1079  sample_2d_linear( tObj, tObj->Image[level],
1080  s, t, red, green, blue, alpha );
1081 }
1082 
1083 
1084 
1085 static void
1087  GLfloat s, GLfloat t, GLfloat lambda,
1088  GLubyte *red, GLubyte *green,
1089  GLubyte *blue, GLubyte *alpha )
1090 {
1091  GLint max = tObj->Image[0]->MaxLog2;
1092 
1093  if (lambda>=max) {
1094  sample_2d_nearest( tObj, tObj->Image[max],
1095  s, t, red, green, blue, alpha );
1096  }
1097  else {
1098  GLubyte red0, green0, blue0, alpha0;
1099  GLubyte red1, green1, blue1, alpha1;
1100  GLfloat f = frac(lambda);
1101  GLint level = (GLint) (lambda + 1.0F);
1102  level = CLAMP( level, 1, max );
1103  sample_2d_nearest( tObj, tObj->Image[level-1], s, t,
1104  &red0, &green0, &blue0, &alpha0 );
1105  sample_2d_nearest( tObj, tObj->Image[level], s, t,
1106  &red1, &green1, &blue1, &alpha1 );
1107  *red = (1.0F-f)*red0 + f*red1;
1108  *green = (1.0F-f)*green0 + f*green1;
1109  *blue = (1.0F-f)*blue0 + f*blue1;
1110  *alpha = (1.0F-f)*alpha0 + f*alpha1;
1111  }
1112 }
1113 
1114 
1115 
1116 static void
1118  GLfloat s, GLfloat t, GLfloat lambda,
1119  GLubyte *red, GLubyte *green,
1120  GLubyte *blue, GLubyte *alpha )
1121 {
1122  GLint max = tObj->Image[0]->MaxLog2;
1123 
1124  if (lambda>=max) {
1125  sample_2d_linear( tObj, tObj->Image[max],
1126  s, t, red, green, blue, alpha );
1127  }
1128  else {
1129  GLubyte red0, green0, blue0, alpha0;
1130  GLubyte red1, green1, blue1, alpha1;
1131  GLfloat f = frac(lambda);
1132  GLint level = (GLint) (lambda + 1.0F);
1133  level = CLAMP( level, 1, max );
1134  sample_2d_linear( tObj, tObj->Image[level-1], s, t,
1135  &red0, &green0, &blue0, &alpha0 );
1136  sample_2d_linear( tObj, tObj->Image[level], s, t,
1137  &red1, &green1, &blue1, &alpha1 );
1138  *red = (1.0F-f)*red0 + f*red1;
1139  *green = (1.0F-f)*green0 + f*green1;
1140  *blue = (1.0F-f)*blue0 + f*blue1;
1141  *alpha = (1.0F-f)*alpha0 + f*alpha1;
1142  }
1143 }
1144 
1145 
1146 
1147 static void sample_nearest_2d( const struct gl_texture_object *tObj, GLuint n,
1148  const GLfloat s[], const GLfloat t[],
1149  const GLfloat u[], const GLfloat lambda[],
1150  GLubyte red[], GLubyte green[], GLubyte blue[],
1151  GLubyte alpha[] )
1152 {
1153  GLuint i;
1154  for (i=0;i<n;i++) {
1155  sample_2d_nearest( tObj, tObj->Image[0], s[i], t[i],
1156  &red[i], &green[i], &blue[i], &alpha[i]);
1157  }
1158 }
1159 
1160 
1161 
1162 static void sample_linear_2d( const struct gl_texture_object *tObj, GLuint n,
1163  const GLfloat s[], const GLfloat t[],
1164  const GLfloat u[], const GLfloat lambda[],
1165  GLubyte red[], GLubyte green[], GLubyte blue[],
1166  GLubyte alpha[] )
1167 {
1168  GLuint i;
1169  for (i=0;i<n;i++) {
1170  sample_2d_linear( tObj, tObj->Image[0], s[i], t[i],
1171  &red[i], &green[i], &blue[i], &alpha[i]);
1172  }
1173 }
1174 
1175 
1176 /*
1177  * Given an (s,t) texture coordinate and lambda (level of detail) value,
1178  * return a texture sample.
1179  */
1180 static void sample_lambda_2d( const struct gl_texture_object *tObj,
1181  GLuint n,
1182  const GLfloat s[], const GLfloat t[],
1183  const GLfloat u[], const GLfloat lambda[],
1184  GLubyte red[], GLubyte green[], GLubyte blue[],
1185  GLubyte alpha[] )
1186 {
1187  GLuint i;
1188  for (i=0;i<n;i++) {
1189  if (lambda[i] > tObj->MinMagThresh) {
1190  /* minification */
1191  switch (tObj->MinFilter) {
1192  case GL_NEAREST:
1193  sample_2d_nearest( tObj, tObj->Image[0], s[i], t[i],
1194  &red[i], &green[i], &blue[i], &alpha[i] );
1195  break;
1196  case GL_LINEAR:
1197  sample_2d_linear( tObj, tObj->Image[0], s[i], t[i],
1198  &red[i], &green[i], &blue[i], &alpha[i] );
1199  break;
1201  sample_2d_nearest_mipmap_nearest( tObj, s[i], t[i], lambda[i],
1202  &red[i], &green[i], &blue[i], &alpha[i] );
1203  break;
1205  sample_2d_linear_mipmap_nearest( tObj, s[i], t[i], lambda[i],
1206  &red[i], &green[i], &blue[i], &alpha[i] );
1207  break;
1209  sample_2d_nearest_mipmap_linear( tObj, s[i], t[i], lambda[i],
1210  &red[i], &green[i], &blue[i], &alpha[i] );
1211  break;
1213  sample_2d_linear_mipmap_linear( tObj, s[i], t[i], lambda[i],
1214  &red[i], &green[i], &blue[i], &alpha[i] );
1215  break;
1216  default:
1217  gl_problem(NULL, "Bad min filter in sample_2d_texture");
1218  return;
1219  }
1220  }
1221  else {
1222  /* magnification */
1223  switch (tObj->MagFilter) {
1224  case GL_NEAREST:
1225  sample_2d_nearest( tObj, tObj->Image[0], s[i], t[i],
1226  &red[i], &green[i], &blue[i], &alpha[i] );
1227  break;
1228  case GL_LINEAR:
1229  sample_2d_linear( tObj, tObj->Image[0], s[i], t[i],
1230  &red[i], &green[i], &blue[i], &alpha[i] );
1231  break;
1232  default:
1233  gl_problem(NULL, "Bad mag filter in sample_2d_texture");
1234  }
1235  }
1236  }
1237 }
1238 
1239 
1240 /*
1241  * Optimized 2-D texture sampling:
1242  * S and T wrap mode == GL_REPEAT
1243  * No border
1244  * Format = GL_RGB
1245  */
1246 static void opt_sample_rgb_2d( const struct gl_texture_object *tObj,
1247  GLuint n, const GLfloat s[], const GLfloat t[],
1248  const GLfloat u[], const GLfloat lamda[],
1249  GLubyte red[], GLubyte green[],
1250  GLubyte blue[], GLubyte alpha[] )
1251 {
1252  const struct gl_texture_image *img = tObj->Image[0];
1253  GLfloat width = img->Width, height = img->Height;
1254  GLint colMask = img->Width-1, rowMask = img->Height-1;
1255  GLint shift = img->WidthLog2;
1256  GLuint k;
1257 
1258  ASSERT(tObj->WrapS==GL_REPEAT);
1259  ASSERT(tObj->WrapT==GL_REPEAT);
1260  ASSERT(img->Border==0);
1261  ASSERT(img->Format==GL_RGB);
1262 
1263  for (k=0;k<n;k++) {
1264  GLint i = (GLint) (s[k] * width) & colMask;
1265  GLint j = (GLint) (t[k] * height) & rowMask;
1266  GLint pos = (j << shift) | i;
1267  GLubyte *texel = img->Data + pos + pos + pos; /* pos*3 */
1268  red[k] = texel[0];
1269  green[k] = texel[1];
1270  blue[k] = texel[2];
1271  }
1272 }
1273 
1274 
1275 /*
1276  * Optimized 2-D texture sampling:
1277  * S and T wrap mode == GL_REPEAT
1278  * No border
1279  * Format = GL_RGBA
1280  */
1281 static void opt_sample_rgba_2d( const struct gl_texture_object *tObj,
1282  GLuint n, const GLfloat s[], const GLfloat t[],
1283  const GLfloat u[], const GLfloat lamda[],
1284  GLubyte red[], GLubyte green[],
1285  GLubyte blue[], GLubyte alpha[] )
1286 {
1287  const struct gl_texture_image *img = tObj->Image[0];
1288  GLfloat width = img->Width, height = img->Height;
1289  GLint colMask = img->Width-1, rowMask = img->Height-1;
1290  GLint shift = img->WidthLog2;
1291  GLuint k;
1292 
1293  ASSERT(tObj->WrapS==GL_REPEAT);
1294  ASSERT(tObj->WrapT==GL_REPEAT);
1295  ASSERT(img->Border==0);
1296  ASSERT(img->Format==GL_RGBA);
1297 
1298  for (k=0;k<n;k++) {
1299  GLint i = (GLint) (s[k] * width) & colMask;
1300  GLint j = (GLint) (t[k] * height) & rowMask;
1301  GLint pos = (j << shift) | i;
1302  GLubyte *texel = img->Data + (pos << 2); /* pos*4 */
1303  red[k] = texel[0];
1304  green[k] = texel[1];
1305  blue[k] = texel[2];
1306  alpha[k] = texel[3];
1307  }
1308 }
1309 
1310 
1311 /**********************************************************************/
1312 /* Texture Sampling Setup */
1313 /**********************************************************************/
1314 
1315 
1316 /*
1317  * Setup the texture sampling function for this texture object.
1318  */
1320 {
1321  if (!t->Complete) {
1322  t->SampleFunc = NULL;
1323  }
1324  else {
1325  GLboolean needLambda = (t->MinFilter != t->MagFilter);
1326 
1327  if (needLambda) {
1328  /* Compute min/mag filter threshold */
1329  if (t->MagFilter==GL_LINEAR
1330  && (t->MinFilter==GL_NEAREST_MIPMAP_NEAREST ||
1331  t->MinFilter==GL_LINEAR_MIPMAP_NEAREST)) {
1332  t->MinMagThresh = 0.5F;
1333  }
1334  else {
1335  t->MinMagThresh = 0.0F;
1336  }
1337  }
1338 
1339  switch (t->Dimensions) {
1340  case 1:
1341  if (needLambda) {
1342  t->SampleFunc = sample_lambda_1d;
1343  }
1344  else if (t->MinFilter==GL_LINEAR) {
1345  t->SampleFunc = sample_linear_1d;
1346  }
1347  else {
1348  ASSERT(t->MinFilter==GL_NEAREST);
1349  t->SampleFunc = sample_nearest_1d;
1350  }
1351  break;
1352  case 2:
1353  if (needLambda) {
1354  t->SampleFunc = sample_lambda_2d;
1355  }
1356  else if (t->MinFilter==GL_LINEAR) {
1357  t->SampleFunc = sample_linear_2d;
1358  }
1359  else {
1360  ASSERT(t->MinFilter==GL_NEAREST);
1361  if (t->WrapS==GL_REPEAT && t->WrapT==GL_REPEAT
1362  && t->Image[0]->Border==0 && t->Image[0]->Format==GL_RGB) {
1363  t->SampleFunc = opt_sample_rgb_2d;
1364  }
1365  else if (t->WrapS==GL_REPEAT && t->WrapT==GL_REPEAT
1366  && t->Image[0]->Border==0 && t->Image[0]->Format==GL_RGBA) {
1367  t->SampleFunc = opt_sample_rgba_2d;
1368  }
1369  else
1370  t->SampleFunc = sample_nearest_2d;
1371  }
1372  break;
1373  default:
1374  gl_problem(NULL, "invalid dimensions in gl_set_texture_sampler");
1375  }
1376  }
1377 }
1378 
1379 
1380 
1381 /**********************************************************************/
1382 /* Texture Application */
1383 /**********************************************************************/
1384 
1385 
1386 /*
1387  * Combine incoming fragment color with texel color to produce output color.
1388  * Input: n - number of fragments
1389  * format - base internal texture format
1390  * env_mode - texture environment mode
1391  * Rt, Gt, Bt, At - array of texel colors
1392  * InOut: red, green, blue, alpha - incoming fragment colors modified
1393  * by texel colors according to the
1394  * texture environment mode.
1395  */
1396 static void apply_texture( GLcontext *ctx,
1397  GLuint n, GLint format, GLenum env_mode,
1399  GLubyte Rt[], GLubyte Gt[], GLubyte Bt[], GLubyte At[] )
1400 {
1401  GLuint i;
1402  GLint Rc, Gc, Bc, Ac;
1403 
1404  if (!ctx->Visual->EightBitColor) {
1405  /* This is a hack! Rescale input colors from [0,scale] to [0,255]. */
1406  GLfloat rscale = 255.0 * ctx->Visual->InvRedScale;
1407  GLfloat gscale = 255.0 * ctx->Visual->InvGreenScale;
1408  GLfloat bscale = 255.0 * ctx->Visual->InvBlueScale;
1409  GLfloat ascale = 255.0 * ctx->Visual->InvAlphaScale;
1410  for (i=0;i<n;i++) {
1411  red[i] = (GLint) (red[i] * rscale);
1412  green[i] = (GLint) (green[i] * gscale);
1413  blue[i] = (GLint) (blue[i] * bscale);
1414  alpha[i] = (GLint) (alpha[i] * ascale);
1415  }
1416  }
1417 
1418 /*
1419  * Use (A*(B+1)) >> 8 as a fast approximation of (A*B)/255 for A
1420  * and B in [0,255]
1421  */
1422 #define PROD(A,B) (((GLint)(A) * ((GLint)(B)+1)) >> 8)
1423 
1424  if (format==GL_COLOR_INDEX) {
1425  format = GL_RGBA; /* XXXX a hack! */
1426  }
1427 
1428  switch (env_mode) {
1429  case GL_REPLACE:
1430  switch (format) {
1431  case GL_ALPHA:
1432  for (i=0;i<n;i++) {
1433  /* Cv = Cf */
1434  /* Av = At */
1435  alpha[i] = At[i];
1436  }
1437  break;
1438  case GL_LUMINANCE:
1439  for (i=0;i<n;i++) {
1440  /* Cv = Lt */
1441  GLint Lt = Rt[i];
1442  red[i] = green[i] = blue[i] = Lt;
1443  /* Av = Af */
1444  }
1445  break;
1446  case GL_LUMINANCE_ALPHA:
1447  for (i=0;i<n;i++) {
1448  GLint Lt = Rt[i];
1449  /* Cv = Lt */
1450  red[i] = green[i] = blue[i] = Lt;
1451  /* Av = At */
1452  alpha[i] = At[i];
1453  }
1454  break;
1455  case GL_INTENSITY:
1456  for (i=0;i<n;i++) {
1457  /* Cv = It */
1458  GLint It = Rt[i];
1459  red[i] = green[i] = blue[i] = It;
1460  /* Av = It */
1461  alpha[i] = It;
1462  }
1463  break;
1464  case GL_RGB:
1465  for (i=0;i<n;i++) {
1466  /* Cv = Ct */
1467  red[i] = Rt[i];
1468  green[i] = Gt[i];
1469  blue[i] = Bt[i];
1470  /* Av = Af */
1471  }
1472  break;
1473  case GL_RGBA:
1474  for (i=0;i<n;i++) {
1475  /* Cv = Ct */
1476  red[i] = Rt[i];
1477  green[i] = Gt[i];
1478  blue[i] = Bt[i];
1479  /* Av = At */
1480  alpha[i] = At[i];
1481  }
1482  break;
1483  default:
1484  gl_problem(ctx, "Bad format in apply_texture");
1485  return;
1486  }
1487  break;
1488 
1489  case GL_MODULATE:
1490  switch (format) {
1491  case GL_ALPHA:
1492  for (i=0;i<n;i++) {
1493  /* Cv = Cf */
1494  /* Av = AfAt */
1495  alpha[i] = PROD( alpha[i], At[i] );
1496  }
1497  break;
1498  case GL_LUMINANCE:
1499  for (i=0;i<n;i++) {
1500  /* Cv = LtCf */
1501  GLint Lt = Rt[i];
1502  red[i] = PROD( red[i], Lt );
1503  green[i] = PROD( green[i], Lt );
1504  blue[i] = PROD( blue[i], Lt );
1505  /* Av = Af */
1506  }
1507  break;
1508  case GL_LUMINANCE_ALPHA:
1509  for (i=0;i<n;i++) {
1510  /* Cv = CfLt */
1511  GLint Lt = Rt[i];
1512  red[i] = PROD( red[i], Lt );
1513  green[i] = PROD( green[i], Lt );
1514  blue[i] = PROD( blue[i], Lt );
1515  /* Av = AfAt */
1516  alpha[i] = PROD( alpha[i], At[i] );
1517  }
1518  break;
1519  case GL_INTENSITY:
1520  for (i=0;i<n;i++) {
1521  /* Cv = CfIt */
1522  GLint It = Rt[i];
1523  red[i] = PROD( red[i], It );
1524  green[i] = PROD( green[i], It );
1525  blue[i] = PROD( blue[i], It );
1526  /* Av = AfIt */
1527  alpha[i] = PROD( alpha[i], It );
1528  }
1529  break;
1530  case GL_RGB:
1531  for (i=0;i<n;i++) {
1532  /* Cv = CfCt */
1533  red[i] = PROD( red[i], Rt[i] );
1534  green[i] = PROD( green[i], Gt[i] );
1535  blue[i] = PROD( blue[i], Bt[i] );
1536  /* Av = Af */
1537  }
1538  break;
1539  case GL_RGBA:
1540  for (i=0;i<n;i++) {
1541  /* Cv = CfCt */
1542  red[i] = PROD( red[i], Rt[i] );
1543  green[i] = PROD( green[i], Gt[i] );
1544  blue[i] = PROD( blue[i], Bt[i] );
1545  /* Av = AfAt */
1546  alpha[i] = PROD( alpha[i], At[i] );
1547  }
1548  break;
1549  default:
1550  gl_problem(ctx, "Bad format (2) in apply_texture");
1551  return;
1552  }
1553  break;
1554 
1555  case GL_DECAL:
1556  switch (format) {
1557  case GL_ALPHA:
1558  case GL_LUMINANCE:
1559  case GL_LUMINANCE_ALPHA:
1560  case GL_INTENSITY:
1561  /* undefined */
1562  break;
1563  case GL_RGB:
1564  for (i=0;i<n;i++) {
1565  /* Cv = Ct */
1566  red[i] = Rt[i];
1567  green[i] = Gt[i];
1568  blue[i] = Bt[i];
1569  /* Av = Af */
1570  }
1571  break;
1572  case GL_RGBA:
1573  for (i=0;i<n;i++) {
1574  /* Cv = Cf(1-At) + CtAt */
1575  GLint t = At[i], s = 255 - t;
1576  red[i] = PROD(red[i], s) + PROD(Rt[i],t);
1577  green[i] = PROD(green[i],s) + PROD(Gt[i],t);
1578  blue[i] = PROD(blue[i], s) + PROD(Bt[i],t);
1579  /* Av = Af */
1580  }
1581  break;
1582  default:
1583  gl_problem(ctx, "Bad format (3) in apply_texture");
1584  return;
1585  }
1586  break;
1587 
1588  case GL_BLEND:
1589  Rc = (GLint) (ctx->Texture.EnvColor[0] * 255.0F);
1590  Gc = (GLint) (ctx->Texture.EnvColor[1] * 255.0F);
1591  Bc = (GLint) (ctx->Texture.EnvColor[2] * 255.0F);
1592  Ac = (GLint) (ctx->Texture.EnvColor[3] * 255.0F);
1593  switch (format) {
1594  case GL_ALPHA:
1595  for (i=0;i<n;i++) {
1596  /* Cv = Cf */
1597  /* Av = AfAt */
1598  alpha[i] = PROD(alpha[i], At[i]);
1599  }
1600  break;
1601  case GL_LUMINANCE:
1602  for (i=0;i<n;i++) {
1603  /* Cv = Cf(1-Lt) + CcLt */
1604  GLint Lt = Rt[i], s = 255 - Lt;
1605  red[i] = PROD(red[i], s) + PROD(Rc, Lt);
1606  green[i] = PROD(green[i],s) + PROD(Gc,Lt);
1607  blue[i] = PROD(blue[i], s) + PROD(Bc, Lt);
1608  /* Av = Af */
1609  }
1610  break;
1611  case GL_LUMINANCE_ALPHA:
1612  for (i=0;i<n;i++) {
1613  /* Cv = Cf(1-Lt) + CcLt */
1614  GLint Lt = Rt[i], s = 255 - Lt;
1615  red[i] = PROD(red[i], s) + PROD(Rc, Lt);
1616  green[i] = PROD(green[i],s) + PROD(Gc,Lt);
1617  blue[i] = PROD(blue[i], s) + PROD(Bc, Lt);
1618  /* Av = AfAt */
1619  alpha[i] = PROD(alpha[i],At[i]);
1620  }
1621  break;
1622  case GL_INTENSITY:
1623  for (i=0;i<n;i++) {
1624  /* Cv = Cf(1-It) + CcLt */
1625  GLint It = Rt[i], s = 255 - It;
1626  red[i] = PROD(red[i], s) + PROD(Rc,It);
1627  green[i] = PROD(green[i],s) + PROD(Gc,It);
1628  blue[i] = PROD(blue[i], s) + PROD(Bc,It);
1629  /* Av = Af(1-It) + Ac*It */
1630  alpha[i] = PROD(alpha[i],s) + PROD(Ac,It);
1631  }
1632  break;
1633  case GL_RGB:
1634  for (i=0;i<n;i++) {
1635  /* Cv = Cf(1-Ct) + CcCt */
1636  red[i] = PROD(red[i], (255-Rt[i])) + PROD(Rc,Rt[i]);
1637  green[i] = PROD(green[i],(255-Gt[i])) + PROD(Gc,Gt[i]);
1638  blue[i] = PROD(blue[i], (255-Bt[i])) + PROD(Bc,Bt[i]);
1639  /* Av = Af */
1640  }
1641  break;
1642  case GL_RGBA:
1643  for (i=0;i<n;i++) {
1644  /* Cv = Cf(1-Ct) + CcCt */
1645  red[i] = PROD(red[i], (255-Rt[i])) + PROD(Rc,Rt[i]);
1646  green[i] = PROD(green[i],(255-Gt[i])) + PROD(Gc,Gt[i]);
1647  blue[i] = PROD(blue[i], (255-Bt[i])) + PROD(Bc,Bt[i]);
1648  /* Av = AfAt */
1649  alpha[i] = PROD(alpha[i],At[i]);
1650  }
1651  break;
1652  }
1653  break;
1654 
1655  default:
1656  gl_problem(ctx, "Bad env mode in apply_texture");
1657  return;
1658  }
1659 #undef PROD
1660 
1661  if (!ctx->Visual->EightBitColor) {
1662  /* This is a hack! Rescale input colors from [0,255] to [0,scale]. */
1663  GLfloat rscale = ctx->Visual->RedScale * (1.0F/ 255.0F);
1664  GLfloat gscale = ctx->Visual->GreenScale * (1.0F/ 255.0F);
1665  GLfloat bscale = ctx->Visual->BlueScale * (1.0F/ 255.0F);
1666  GLfloat ascale = ctx->Visual->AlphaScale * (1.0F/ 255.0F);
1667  for (i=0;i<n;i++) {
1668  red[i] = (GLint) (red[i] * rscale);
1669  green[i] = (GLint) (green[i] * gscale);
1670  blue[i] = (GLint) (blue[i] * bscale);
1671  alpha[i] = (GLint) (alpha[i] * ascale);
1672  }
1673  }
1674 }
1675 
1676 
1677 
1679  const GLfloat s[], const GLfloat t[],
1680  const GLfloat r[], const GLfloat lambda[],
1681  GLubyte red[], GLubyte green[],
1682  GLubyte blue[], GLubyte alpha[] )
1683 {
1684  GLubyte tred[PB_SIZE];
1685  GLubyte tgreen[PB_SIZE];
1686  GLubyte tblue[PB_SIZE];
1687  GLubyte talpha[PB_SIZE];
1688 
1689  if (!ctx->Texture.Current || !ctx->Texture.Current->SampleFunc)
1690  return;
1691 
1692  /* Sample the texture. */
1693  (*ctx->Texture.Current->SampleFunc)( ctx->Texture.Current, n,
1694  s, t, r, lambda,
1695  tred, tgreen, tblue, talpha );
1696 
1697  apply_texture( ctx, n,
1698  ctx->Texture.Current->Image[0]->Format,
1699  ctx->Texture.EnvMode,
1700  red, green, blue, alpha,
1701  tred, tgreen, tblue, talpha );
1702 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
struct gl_texture_image * Image[MAX_TEXTURE_LEVELS]
Definition: types.h:1100
GLint level
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
#define PROD(A, B)
GLubyte Palette[MAX_TEXTURE_PALETTE_SIZE *4]
Definition: types.h:1103
#define max(a, b)
Definition: svc.c:63
static void sample_2d_linear_mipmap_nearest(const struct gl_texture_object *tObj, GLfloat s, GLfloat t, GLfloat lambda, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:1063
#define frac(x)
Definition: texture.c:364
#define shift
Definition: input.c:1668
#define GL_MODULATE
Definition: gl.h:677
GLint BorderColor[4]
Definition: types.h:1093
static void sample_2d_linear(const struct gl_texture_object *tObj, const struct gl_texture_image *img, GLfloat s, GLfloat t, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:928
#define GL_BLEND
Definition: gl.h:371
static void apply_texture(GLcontext *ctx, GLuint n, GLint format, GLenum env_mode, GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[], GLubyte Rt[], GLubyte Gt[], GLubyte Bt[], GLubyte At[])
Definition: texture.c:1396
unsigned char GLubyte
Definition: gl.h:157
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static void sample_2d_nearest_mipmap_nearest(const struct gl_texture_object *tObj, GLfloat s, GLfloat t, GLfloat lambda, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:1040
static void sample_2d_nearest(const struct gl_texture_object *tObj, const struct gl_texture_image *img, GLfloat s, GLfloat t, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:838
GLfloat MinMagThresh
Definition: types.h:1099
#define GL_NEAREST
Definition: gl.h:678
#define GL_ALPHA
Definition: gl.h:483
#define GL_NEAREST_MIPMAP_NEAREST
Definition: gl.h:667
#define GL_REPEAT
Definition: gl.h:679
GLdouble n
Definition: glext.h:7729
GLdouble GLdouble t
Definition: gl.h:2047
#define GL_DECAL
Definition: gl.h:676
GLenum WrapT
Definition: types.h:1095
GLvisual * Visual
Definition: types.h:1272
GLenum MagFilter
Definition: types.h:1098
static void palette_sample(const struct gl_texture_object *tObj, GLubyte index, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:316
GLenum WrapS
Definition: types.h:1094
const GLfloat * m
Definition: glext.h:10848
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static void sample_1d_linear(const struct gl_texture_object *tObj, const struct gl_texture_image *img, GLfloat s, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:500
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static void sample_linear_1d(const struct gl_texture_object *tObj, GLuint n, const GLfloat s[], const GLfloat t[], const GLfloat u[], const GLfloat lambda[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: texture.c:691
static void sample_lambda_1d(const struct gl_texture_object *tObj, GLuint n, const GLfloat s[], const GLfloat t[], const GLfloat u[], const GLfloat lambda[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: texture.c:710
#define GL_NEAREST_MIPMAP_LINEAR
Definition: gl.h:668
#define CLAMP(f, min, max)
Definition: tif_color.c:177
unsigned char GLboolean
Definition: gl.h:151
#define S_BIT
Definition: types.h:891
static void sample_2d_linear_mipmap_linear(const struct gl_texture_object *tObj, GLfloat s, GLfloat t, GLfloat lambda, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:1117
smooth NULL
Definition: ftsmooth.c:416
GLfloat AlphaScale
Definition: types.h:1143
#define GL_EYE_LINEAR
Definition: gl.h:673
GLfloat BlueScale
Definition: types.h:1142
GLuint index
Definition: glext.h:6031
GLclampf GLclampf blue
Definition: gl.h:1740
#define b
Definition: ke_i.h:79
GLfloat GreenScale
Definition: types.h:1141
#define COPY_3V(DST, SRC)
Definition: macros.h:98
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static void sample_1d_nearest_mipmap_linear(const struct gl_texture_object *tObj, GLfloat s, GLfloat lambda, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:615
static void sample_nearest_1d(const struct gl_texture_object *tObj, GLuint n, const GLfloat s[], const GLfloat t[], const GLfloat u[], const GLfloat lambda[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: texture.c:676
#define R_BIT
Definition: types.h:890
struct gl_texture_attrib Texture
Definition: types.h:1334
static void opt_sample_rgb_2d(const struct gl_texture_object *tObj, GLuint n, const GLfloat s[], const GLfloat t[], const GLfloat u[], const GLfloat lamda[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: texture.c:1246
GLfloat f
Definition: glext.h:7540
GLfloat InvRedScale
Definition: types.h:1148
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLint GLvoid * img
Definition: gl.h:1956
#define GL_LUMINANCE_ALPHA
Definition: gl.h:485
#define GL_SQRT(X)
Definition: mmath.h:63
static void sample_lambda_2d(const struct gl_texture_object *tObj, GLuint n, const GLfloat s[], const GLfloat t[], const GLfloat u[], const GLfloat lambda[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: texture.c:1180
GLclampf green
Definition: gl.h:1740
static void sample_1d_linear_mipmap_nearest(const struct gl_texture_object *tObj, GLfloat s, GLfloat lambda, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:592
GLboolean EightBitColor
Definition: types.h:1146
GLenum MinFilter
Definition: types.h:1097
#define red
Definition: linetest.c:67
GLenum PaletteFormat
Definition: types.h:1106
#define GL_LINEAR
Definition: gl.h:421
#define GL_RGB
Definition: gl.h:502
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static void sample_2d_nearest_mipmap_linear(const struct gl_texture_object *tObj, GLfloat s, GLfloat t, GLfloat lambda, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:1086
#define NORMALIZE_3FV(V)
Definition: mmath.h:68
static void sample_nearest_2d(const struct gl_texture_object *tObj, GLuint n, const GLfloat s[], const GLfloat t[], const GLfloat u[], const GLfloat lambda[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: texture.c:1147
#define T_BIT
Definition: types.h:892
#define index(s, c)
Definition: various.h:29
#define GL_REPLACE
Definition: gl.h:460
#define DOT3(a, b)
Definition: macros.h:167
GLfixed fx
Definition: tritemp.h:482
GLdouble s
Definition: gl.h:2039
static void sample_1d_nearest_mipmap_nearest(const struct gl_texture_object *tObj, GLfloat s, GLfloat lambda, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:570
unsigned int GLenum
Definition: gl.h:150
void gl_problem(const GLcontext *ctx, const char *s)
Definition: context.c:1394
static HPALETTE palette
Definition: clipboard.c:1345
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
#define GL_OBJECT_LINEAR
Definition: gl.h:671
#define GL_LUMINANCE
Definition: gl.h:484
static void sample_linear_2d(const struct gl_texture_object *tObj, GLuint n, const GLfloat s[], const GLfloat t[], const GLfloat u[], const GLfloat lambda[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: texture.c:1162
const GLdouble * v
Definition: gl.h:2040
unsigned int GLuint
Definition: gl.h:159
#define GL_COLOR_INDEX
Definition: gl.h:479
GLfloat RedScale
Definition: types.h:1140
#define f
Definition: ke_i.h:83
static void get_1d_texel(const struct gl_texture_object *tObj, const struct gl_texture_image *img, GLint i, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:372
static void opt_sample_rgba_2d(const struct gl_texture_object *tObj, GLuint n, const GLfloat s[], const GLfloat t[], const GLfloat u[], const GLfloat lamda[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: texture.c:1281
#define abort()
Definition: i386-dis.c:35
GLfloat InvBlueScale
Definition: types.h:1150
#define GL_LINEAR_MIPMAP_LINEAR
Definition: gl.h:670
#define GL_LINEAR_MIPMAP_NEAREST
Definition: gl.h:669
float GLfloat
Definition: gl.h:161
void gl_texture_pixels(GLcontext *ctx, GLuint n, const GLfloat s[], const GLfloat t[], const GLfloat r[], const GLfloat lambda[], GLubyte red[], GLubyte green[], GLubyte blue[], GLubyte alpha[])
Definition: texture.c:1678
GLfloat InvGreenScale
Definition: types.h:1149
void gl_texgen(GLcontext *ctx, GLint n, GLfloat obj[][4], GLfloat eye[][4], GLfloat normal[][3], GLfloat texcoord[][4])
Definition: texture.c:163
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
int GLint
Definition: gl.h:156
#define GL_RGBA
Definition: gl.h:503
GLfixed fy
Definition: tritemp.h:490
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
_Check_return_ _CRTIMP double __cdecl floor(_In_ double x)
GLfloat InvAlphaScale
Definition: types.h:1151
static void get_2d_texel(const struct gl_texture_object *tObj, const struct gl_texture_image *img, GLint i, GLint j, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:782
#define GL_INTENSITY
Definition: gl.h:747
static void sample_1d_nearest(const struct gl_texture_object *tObj, const struct gl_texture_image *img, GLfloat s, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:428
int k
Definition: mpi.c:3369
#define GL_SPHERE_MAP
Definition: gl.h:675
#define PB_SIZE
Definition: pb.h:52
#define F(x, y, z)
Definition: md5.c:51
#define DOT4(a, b)
Definition: macros.h:171
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
Definition: glext.h:8308
static void sample_1d_linear_mipmap_linear(const struct gl_texture_object *tObj, GLfloat s, GLfloat lambda, GLubyte *red, GLubyte *green, GLubyte *blue, GLubyte *alpha)
Definition: texture.c:646
void gl_set_texture_sampler(struct gl_texture_object *t)
Definition: texture.c:1319
#define Q_BIT
Definition: types.h:889