1 /* $Id: teximage.c,v 1.2 1999/10/08 09:27:11 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 /* $XFree86: xc/lib/GL/mesa/src/teximage.c,v 1.3 1999/04/04 00:20:32 dawes Exp $ */
39 #include "GL/xf86glx.h"
50 #include "GL/xf86glx.h"
58 * The internal texture storage convension is an array of N GLubytes
59 * where N = width * height * components. There is no padding.
66 * Compute log base 2 of n.
67 * If n isn't an exact power of two return -1.
70 static int logbase2( int n
)
94 * Given an internal texture format enum or 1, 2, 3, 4 return the
95 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
96 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return -1 if
99 static GLint
decode_internal_format( GLint format
)
116 case GL_LUMINANCE_ALPHA
:
117 case GL_LUMINANCE4_ALPHA4
:
118 case GL_LUMINANCE6_ALPHA2
:
119 case GL_LUMINANCE8_ALPHA8
:
120 case GL_LUMINANCE12_ALPHA4
:
121 case GL_LUMINANCE12_ALPHA12
:
122 case GL_LUMINANCE16_ALPHA16
:
123 return GL_LUMINANCE_ALPHA
;
151 case GL_COLOR_INDEX1_EXT
:
152 case GL_COLOR_INDEX2_EXT
:
153 case GL_COLOR_INDEX4_EXT
:
154 case GL_COLOR_INDEX8_EXT
:
155 case GL_COLOR_INDEX12_EXT
:
156 case GL_COLOR_INDEX16_EXT
:
157 return GL_COLOR_INDEX
;
159 return -1; /* error */
166 * Given an internal texture format enum or 1, 2, 3, 4 return the
167 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
168 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the
169 * number of components for the format. Return -1 if invalid enum.
171 static GLint
components_in_intformat( GLint format
)
188 case GL_LUMINANCE_ALPHA
:
189 case GL_LUMINANCE4_ALPHA4
:
190 case GL_LUMINANCE6_ALPHA2
:
191 case GL_LUMINANCE8_ALPHA8
:
192 case GL_LUMINANCE12_ALPHA4
:
193 case GL_LUMINANCE12_ALPHA12
:
194 case GL_LUMINANCE16_ALPHA16
:
223 case GL_COLOR_INDEX1_EXT
:
224 case GL_COLOR_INDEX2_EXT
:
225 case GL_COLOR_INDEX4_EXT
:
226 case GL_COLOR_INDEX8_EXT
:
227 case GL_COLOR_INDEX12_EXT
:
228 case GL_COLOR_INDEX16_EXT
:
231 return -1; /* error */
237 struct gl_texture_image
*gl_alloc_texture_image( void )
239 return (struct gl_texture_image
*) calloc( 1, sizeof(struct gl_texture_image
) );
244 void gl_free_texture_image( struct gl_texture_image
*teximage
)
246 if (teximage
->Data
) {
247 free( teximage
->Data
);
255 * Examine the texImage->Format field and set the Red, Green, Blue, etc
256 * texel component sizes to default values.
257 * These fields are set only here by core Mesa but device drivers may
258 * overwritting these fields to indicate true texel resolution.
260 static void set_teximage_component_sizes( struct gl_texture_image
*texImage
)
262 switch (texImage
->Format
) {
264 texImage
->RedBits
= 0;
265 texImage
->GreenBits
= 0;
266 texImage
->BlueBits
= 0;
267 texImage
->AlphaBits
= 8;
268 texImage
->IntensityBits
= 0;
269 texImage
->LuminanceBits
= 0;
270 texImage
->IndexBits
= 0;
273 texImage
->RedBits
= 0;
274 texImage
->GreenBits
= 0;
275 texImage
->BlueBits
= 0;
276 texImage
->AlphaBits
= 0;
277 texImage
->IntensityBits
= 0;
278 texImage
->LuminanceBits
= 8;
279 texImage
->IndexBits
= 0;
281 case GL_LUMINANCE_ALPHA
:
282 texImage
->RedBits
= 0;
283 texImage
->GreenBits
= 0;
284 texImage
->BlueBits
= 0;
285 texImage
->AlphaBits
= 8;
286 texImage
->IntensityBits
= 0;
287 texImage
->LuminanceBits
= 8;
288 texImage
->IndexBits
= 0;
291 texImage
->RedBits
= 0;
292 texImage
->GreenBits
= 0;
293 texImage
->BlueBits
= 0;
294 texImage
->AlphaBits
= 0;
295 texImage
->IntensityBits
= 8;
296 texImage
->LuminanceBits
= 0;
297 texImage
->IndexBits
= 0;
300 texImage
->RedBits
= 8;
301 texImage
->GreenBits
= 8;
302 texImage
->BlueBits
= 8;
303 texImage
->AlphaBits
= 0;
304 texImage
->IntensityBits
= 0;
305 texImage
->LuminanceBits
= 0;
306 texImage
->IndexBits
= 0;
309 texImage
->RedBits
= 8;
310 texImage
->GreenBits
= 8;
311 texImage
->BlueBits
= 8;
312 texImage
->AlphaBits
= 8;
313 texImage
->IntensityBits
= 0;
314 texImage
->LuminanceBits
= 0;
315 texImage
->IndexBits
= 0;
318 texImage
->RedBits
= 0;
319 texImage
->GreenBits
= 0;
320 texImage
->BlueBits
= 0;
321 texImage
->AlphaBits
= 0;
322 texImage
->IntensityBits
= 0;
323 texImage
->LuminanceBits
= 0;
324 texImage
->IndexBits
= 8;
327 gl_problem(NULL
, "unexpected format in set_teximage_component_sizes");
332 /* Need this to prevent an out-of-bounds memory access when using
333 * X86 optimized code.
336 # define EXTRA_BYTE 1
338 # define EXTRA_BYTE 0
343 * Given a gl_image, apply the pixel transfer scale, bias, and mapping
344 * to produce a gl_texture_image. Convert image data to GLubytes.
345 * Input: image - the incoming gl_image
346 * internalFormat - desired format of resultant texture
347 * border - texture border width (0 or 1)
348 * Return: pointer to a gl_texture_image or NULL if an error occurs.
350 static struct gl_texture_image
*
351 image_to_texture( GLcontext
*ctx
, const struct gl_image
*image
,
352 GLint internalFormat
, GLint border
)
355 struct gl_texture_image
*texImage
;
356 GLint numPixels
, pixel
;
357 GLboolean scaleOrBias
;
360 assert(image
->Width
>0);
361 assert(image
->Height
>0);
362 assert(image
->Depth
>0);
364 /* internalFormat = decode_internal_format(internalFormat);*/
365 components
= components_in_intformat(internalFormat
);
366 numPixels
= image
->Width
* image
->Height
* image
->Depth
;
368 texImage
= gl_alloc_texture_image();
372 texImage
->Format
= (GLenum
) decode_internal_format(internalFormat
);
373 set_teximage_component_sizes( texImage
);
374 texImage
->IntFormat
= (GLenum
) internalFormat
;
375 texImage
->Border
= border
;
376 texImage
->Width
= image
->Width
;
377 texImage
->Height
= image
->Height
;
378 texImage
->Depth
= image
->Depth
;
379 texImage
->WidthLog2
= logbase2(image
->Width
- 2*border
);
380 if (image
->Height
==1) /* 1-D texture */
381 texImage
->HeightLog2
= 0;
383 texImage
->HeightLog2
= logbase2(image
->Height
- 2*border
);
384 if (image
->Depth
==1) /* 2-D texture */
385 texImage
->DepthLog2
= 0;
387 texImage
->DepthLog2
= logbase2(image
->Depth
- 2*border
);
388 texImage
->Width2
= 1 << texImage
->WidthLog2
;
389 texImage
->Height2
= 1 << texImage
->HeightLog2
;
390 texImage
->Depth2
= 1 << texImage
->DepthLog2
;
391 texImage
->MaxLog2
= MAX2( texImage
->WidthLog2
, texImage
->HeightLog2
);
392 texImage
->Data
= (GLubyte
*) malloc( numPixels
* components
+ EXTRA_BYTE
);
394 if (!texImage
->Data
) {
396 gl_free_texture_image( texImage
);
400 /* Determine if scaling and/or biasing is needed */
401 if (ctx
->Pixel
.RedScale
!=1.0F
|| ctx
->Pixel
.RedBias
!=0.0F
||
402 ctx
->Pixel
.GreenScale
!=1.0F
|| ctx
->Pixel
.GreenBias
!=0.0F
||
403 ctx
->Pixel
.BlueScale
!=1.0F
|| ctx
->Pixel
.BlueBias
!=0.0F
||
404 ctx
->Pixel
.AlphaScale
!=1.0F
|| ctx
->Pixel
.AlphaBias
!=0.0F
) {
405 scaleOrBias
= GL_TRUE
;
408 scaleOrBias
= GL_FALSE
;
411 switch (image
->Type
) {
414 GLint shift
= ctx
->Pixel
.IndexShift
;
415 GLint offset
= ctx
->Pixel
.IndexOffset
;
416 /* MapIto[RGBA]Size must be powers of two */
417 GLint rMask
= ctx
->Pixel
.MapItoRsize
-1;
418 GLint gMask
= ctx
->Pixel
.MapItoGsize
-1;
419 GLint bMask
= ctx
->Pixel
.MapItoBsize
-1;
420 GLint aMask
= ctx
->Pixel
.MapItoAsize
-1;
422 GLubyte
*srcPtr
= (GLubyte
*) image
->Data
;
424 assert( image
->Format
==GL_COLOR_INDEX
);
426 for (j
=0; j
<image
->Height
; j
++) {
427 GLubyte bitMask
= 128;
428 for (i
=0; i
<image
->Width
; i
++) {
430 GLubyte red
, green
, blue
, alpha
;
432 /* Fetch image color index */
433 index
= (*srcPtr
& bitMask
) ? 1 : 0;
434 bitMask
= bitMask
>> 1;
439 /* apply index shift and offset */
441 index
= (index
<< shift
) + offset
;
444 index
= (index
>> -shift
) + offset
;
446 /* convert index to RGBA */
447 red
= (GLint
) (ctx
->Pixel
.MapItoR
[index
& rMask
] * 255.0F
);
448 green
= (GLint
) (ctx
->Pixel
.MapItoG
[index
& gMask
] * 255.0F
);
449 blue
= (GLint
) (ctx
->Pixel
.MapItoB
[index
& bMask
] * 255.0F
);
450 alpha
= (GLint
) (ctx
->Pixel
.MapItoA
[index
& aMask
] * 255.0F
);
452 /* store texel (components are GLubytes in [0,255]) */
453 pixel
= j
* image
->Width
+ i
;
454 switch (texImage
->Format
) {
456 texImage
->Data
[pixel
] = alpha
;
459 texImage
->Data
[pixel
] = red
;
461 case GL_LUMINANCE_ALPHA
:
462 texImage
->Data
[pixel
*2+0] = red
;
463 texImage
->Data
[pixel
*2+1] = alpha
;
466 texImage
->Data
[pixel
] = red
;
469 texImage
->Data
[pixel
*3+0] = red
;
470 texImage
->Data
[pixel
*3+1] = green
;
471 texImage
->Data
[pixel
*3+2] = blue
;
474 texImage
->Data
[pixel
*4+0] = red
;
475 texImage
->Data
[pixel
*4+1] = green
;
476 texImage
->Data
[pixel
*4+2] = blue
;
477 texImage
->Data
[pixel
*4+3] = alpha
;
480 gl_problem(ctx
,"Bad format in image_to_texture");
491 case GL_UNSIGNED_BYTE
:
492 if (image
->Format
== texImage
->Format
&& !scaleOrBias
&& !ctx
->Pixel
.MapColorFlag
) {
493 switch (image
->Format
) {
495 if (decode_internal_format(internalFormat
)!=GL_COLOR_INDEX
) {
496 /* convert color index to RGBA */
497 for (pixel
=0; pixel
<numPixels
; pixel
++) {
498 GLint index
= ((GLubyte
*)image
->Data
)[pixel
];
499 index
= (GLint
) (255.0F
* ctx
->Pixel
.MapItoR
[index
]);
500 texImage
->Data
[pixel
] = index
;
508 MEMCPY(texImage
->Data
, image
->Data
, numPixels
* 1);
511 case GL_LUMINANCE_ALPHA
:
512 MEMCPY(texImage
->Data
, image
->Data
, numPixels
* 2);
516 MEMCPY(texImage
->Data
, image
->Data
, numPixels
* 3);
520 MEMCPY(texImage
->Data
, image
->Data
, numPixels
* 4);
527 for (pixel
=0; pixel
<numPixels
; pixel
++) {
528 GLubyte red
, green
, blue
, alpha
;
529 switch (image
->Format
) {
531 if (decode_internal_format(internalFormat
)==GL_COLOR_INDEX
) {
532 /* a paletted texture */
533 GLint index
= ((GLubyte
*)image
->Data
)[pixel
];
537 /* convert color index to RGBA */
538 GLint index
= ((GLubyte
*)image
->Data
)[pixel
];
539 red
= (GLint
) (255.0F
* ctx
->Pixel
.MapItoR
[index
]);
540 green
= (GLint
) (255.0F
* ctx
->Pixel
.MapItoG
[index
]);
541 blue
= (GLint
) (255.0F
* ctx
->Pixel
.MapItoB
[index
]);
542 alpha
= (GLint
) (255.0F
* ctx
->Pixel
.MapItoA
[index
]);
546 /* Fetch image RGBA values */
547 red
= ((GLubyte
*) image
->Data
)[pixel
*3+0];
548 green
= ((GLubyte
*) image
->Data
)[pixel
*3+1];
549 blue
= ((GLubyte
*) image
->Data
)[pixel
*3+2];
553 red
= ((GLubyte
*) image
->Data
)[pixel
*4+0];
554 green
= ((GLubyte
*) image
->Data
)[pixel
*4+1];
555 blue
= ((GLubyte
*) image
->Data
)[pixel
*4+2];
556 alpha
= ((GLubyte
*) image
->Data
)[pixel
*4+3];
559 red
= ((GLubyte
*) image
->Data
)[pixel
];
566 green
= ((GLubyte
*) image
->Data
)[pixel
];
573 blue
= ((GLubyte
*) image
->Data
)[pixel
];
580 alpha
= ((GLubyte
*) image
->Data
)[pixel
];
583 red
= ((GLubyte
*) image
->Data
)[pixel
];
588 case GL_LUMINANCE_ALPHA
:
589 red
= ((GLubyte
*) image
->Data
)[pixel
*2+0];
592 alpha
= ((GLubyte
*) image
->Data
)[pixel
*2+1];
595 gl_problem(ctx
,"Bad format (2) in image_to_texture");
599 if (scaleOrBias
|| ctx
->Pixel
.MapColorFlag
) {
600 /* Apply RGBA scale and bias */
601 GLfloat r
= UBYTE_COLOR_TO_FLOAT_COLOR(red
);
602 GLfloat g
= UBYTE_COLOR_TO_FLOAT_COLOR(green
);
603 GLfloat b
= UBYTE_COLOR_TO_FLOAT_COLOR(blue
);
604 GLfloat a
= UBYTE_COLOR_TO_FLOAT_COLOR(alpha
);
606 /* r,g,b,a now in [0,1] */
607 r
= r
* ctx
->Pixel
.RedScale
+ ctx
->Pixel
.RedBias
;
608 g
= g
* ctx
->Pixel
.GreenScale
+ ctx
->Pixel
.GreenBias
;
609 b
= b
* ctx
->Pixel
.BlueScale
+ ctx
->Pixel
.BlueBias
;
610 a
= a
* ctx
->Pixel
.AlphaScale
+ ctx
->Pixel
.AlphaBias
;
611 r
= CLAMP( r
, 0.0F
, 1.0F
);
612 g
= CLAMP( g
, 0.0F
, 1.0F
);
613 b
= CLAMP( b
, 0.0F
, 1.0F
);
614 a
= CLAMP( a
, 0.0F
, 1.0F
);
616 /* Apply pixel maps */
617 if (ctx
->Pixel
.MapColorFlag
) {
618 GLint ir
= (GLint
) (r
*ctx
->Pixel
.MapRtoRsize
);
619 GLint ig
= (GLint
) (g
*ctx
->Pixel
.MapGtoGsize
);
620 GLint ib
= (GLint
) (b
*ctx
->Pixel
.MapBtoBsize
);
621 GLint ia
= (GLint
) (a
*ctx
->Pixel
.MapAtoAsize
);
622 r
= ctx
->Pixel
.MapRtoR
[ir
];
623 g
= ctx
->Pixel
.MapGtoG
[ig
];
624 b
= ctx
->Pixel
.MapBtoB
[ib
];
625 a
= ctx
->Pixel
.MapAtoA
[ia
];
627 red
= (GLint
) (r
* 255.0F
);
628 green
= (GLint
) (g
* 255.0F
);
629 blue
= (GLint
) (b
* 255.0F
);
630 alpha
= (GLint
) (a
* 255.0F
);
633 /* store texel (components are GLubytes in [0,255]) */
634 switch (texImage
->Format
) {
636 texImage
->Data
[pixel
] = red
; /* really an index */
639 texImage
->Data
[pixel
] = alpha
;
642 texImage
->Data
[pixel
] = red
;
644 case GL_LUMINANCE_ALPHA
:
645 texImage
->Data
[pixel
*2+0] = red
;
646 texImage
->Data
[pixel
*2+1] = alpha
;
649 texImage
->Data
[pixel
] = red
;
652 texImage
->Data
[pixel
*3+0] = red
;
653 texImage
->Data
[pixel
*3+1] = green
;
654 texImage
->Data
[pixel
*3+2] = blue
;
657 texImage
->Data
[pixel
*4+0] = red
;
658 texImage
->Data
[pixel
*4+1] = green
;
659 texImage
->Data
[pixel
*4+2] = blue
;
660 texImage
->Data
[pixel
*4+3] = alpha
;
663 gl_problem(ctx
,"Bad format (3) in image_to_texture");
670 for (pixel
=0; pixel
<numPixels
; pixel
++) {
671 GLfloat red
, green
, blue
, alpha
;
672 switch (image
->Format
) {
674 if (decode_internal_format(internalFormat
)==GL_COLOR_INDEX
) {
675 /* a paletted texture */
676 GLint index
= (GLint
) ((GLfloat
*) image
->Data
)[pixel
];
680 GLint shift
= ctx
->Pixel
.IndexShift
;
681 GLint offset
= ctx
->Pixel
.IndexOffset
;
682 /* MapIto[RGBA]Size must be powers of two */
683 GLint rMask
= ctx
->Pixel
.MapItoRsize
-1;
684 GLint gMask
= ctx
->Pixel
.MapItoGsize
-1;
685 GLint bMask
= ctx
->Pixel
.MapItoBsize
-1;
686 GLint aMask
= ctx
->Pixel
.MapItoAsize
-1;
687 /* Fetch image color index */
688 GLint index
= (GLint
) ((GLfloat
*) image
->Data
)[pixel
];
689 /* apply index shift and offset */
691 index
= (index
<< shift
) + offset
;
694 index
= (index
>> -shift
) + offset
;
696 /* convert index to RGBA */
697 red
= ctx
->Pixel
.MapItoR
[index
& rMask
];
698 green
= ctx
->Pixel
.MapItoG
[index
& gMask
];
699 blue
= ctx
->Pixel
.MapItoB
[index
& bMask
];
700 alpha
= ctx
->Pixel
.MapItoA
[index
& aMask
];
704 /* Fetch image RGBA values */
705 red
= ((GLfloat
*) image
->Data
)[pixel
*3+0];
706 green
= ((GLfloat
*) image
->Data
)[pixel
*3+1];
707 blue
= ((GLfloat
*) image
->Data
)[pixel
*3+2];
711 red
= ((GLfloat
*) image
->Data
)[pixel
*4+0];
712 green
= ((GLfloat
*) image
->Data
)[pixel
*4+1];
713 blue
= ((GLfloat
*) image
->Data
)[pixel
*4+2];
714 alpha
= ((GLfloat
*) image
->Data
)[pixel
*4+3];
717 red
= ((GLfloat
*) image
->Data
)[pixel
];
724 green
= ((GLfloat
*) image
->Data
)[pixel
];
731 blue
= ((GLfloat
*) image
->Data
)[pixel
];
738 alpha
= ((GLfloat
*) image
->Data
)[pixel
];
741 red
= ((GLfloat
*) image
->Data
)[pixel
];
746 case GL_LUMINANCE_ALPHA
:
747 red
= ((GLfloat
*) image
->Data
)[pixel
*2+0];
750 alpha
= ((GLfloat
*) image
->Data
)[pixel
*2+1];
753 gl_problem(ctx
,"Bad format (4) in image_to_texture");
757 if (image
->Format
!=GL_COLOR_INDEX
) {
758 /* Apply RGBA scale and bias */
760 red
= red
* ctx
->Pixel
.RedScale
+ ctx
->Pixel
.RedBias
;
761 green
= green
* ctx
->Pixel
.GreenScale
+ ctx
->Pixel
.GreenBias
;
762 blue
= blue
* ctx
->Pixel
.BlueScale
+ ctx
->Pixel
.BlueBias
;
763 alpha
= alpha
* ctx
->Pixel
.AlphaScale
+ ctx
->Pixel
.AlphaBias
;
764 red
= CLAMP( red
, 0.0F
, 1.0F
);
765 green
= CLAMP( green
, 0.0F
, 1.0F
);
766 blue
= CLAMP( blue
, 0.0F
, 1.0F
);
767 alpha
= CLAMP( alpha
, 0.0F
, 1.0F
);
769 /* Apply pixel maps */
770 if (ctx
->Pixel
.MapColorFlag
) {
771 GLint ir
= (GLint
) (red
*ctx
->Pixel
.MapRtoRsize
);
772 GLint ig
= (GLint
) (green
*ctx
->Pixel
.MapGtoGsize
);
773 GLint ib
= (GLint
) (blue
*ctx
->Pixel
.MapBtoBsize
);
774 GLint ia
= (GLint
) (alpha
*ctx
->Pixel
.MapAtoAsize
);
775 red
= ctx
->Pixel
.MapRtoR
[ir
];
776 green
= ctx
->Pixel
.MapGtoG
[ig
];
777 blue
= ctx
->Pixel
.MapBtoB
[ib
];
778 alpha
= ctx
->Pixel
.MapAtoA
[ia
];
782 /* store texel (components are GLubytes in [0,255]) */
783 switch (texImage
->Format
) {
785 /* a paletted texture */
786 texImage
->Data
[pixel
] = (GLint
) (red
* 255.0F
);
789 texImage
->Data
[pixel
] = (GLint
) (alpha
* 255.0F
);
792 texImage
->Data
[pixel
] = (GLint
) (red
* 255.0F
);
794 case GL_LUMINANCE_ALPHA
:
795 texImage
->Data
[pixel
*2+0] = (GLint
) (red
* 255.0F
);
796 texImage
->Data
[pixel
*2+1] = (GLint
) (alpha
* 255.0F
);
799 texImage
->Data
[pixel
] = (GLint
) (red
* 255.0F
);
802 texImage
->Data
[pixel
*3+0] = (GLint
) (red
* 255.0F
);
803 texImage
->Data
[pixel
*3+1] = (GLint
) (green
* 255.0F
);
804 texImage
->Data
[pixel
*3+2] = (GLint
) (blue
* 255.0F
);
807 texImage
->Data
[pixel
*4+0] = (GLint
) (red
* 255.0F
);
808 texImage
->Data
[pixel
*4+1] = (GLint
) (green
* 255.0F
);
809 texImage
->Data
[pixel
*4+2] = (GLint
) (blue
* 255.0F
);
810 texImage
->Data
[pixel
*4+3] = (GLint
) (alpha
* 255.0F
);
813 gl_problem(ctx
,"Bad format (5) in image_to_texture");
820 gl_problem(ctx
, "Bad image type in image_to_texture");
830 * glTexImage[123]D can accept a NULL image pointer. In this case we
831 * create a texture image with unspecified image contents per the OpenGL
834 static struct gl_texture_image
*
835 make_null_texture( GLcontext
*ctx
, GLenum internalFormat
,
836 GLsizei width
, GLsizei height
, GLsizei depth
, GLint border
)
839 struct gl_texture_image
*texImage
;
843 /*internalFormat = decode_internal_format(internalFormat);*/
844 components
= components_in_intformat(internalFormat
);
845 numPixels
= width
* height
* depth
;
847 texImage
= gl_alloc_texture_image();
851 texImage
->Format
= (GLenum
) decode_internal_format(internalFormat
);
852 set_teximage_component_sizes( texImage
);
853 texImage
->IntFormat
= internalFormat
;
854 texImage
->Border
= border
;
855 texImage
->Width
= width
;
856 texImage
->Height
= height
;
857 texImage
->Depth
= depth
;
858 texImage
->WidthLog2
= logbase2(width
- 2*border
);
859 if (height
==1) /* 1-D texture */
860 texImage
->HeightLog2
= 0;
862 texImage
->HeightLog2
= logbase2(height
- 2*border
);
863 if (depth
==1) /* 2-D texture */
864 texImage
->DepthLog2
= 0;
866 texImage
->DepthLog2
= logbase2(depth
- 2*border
);
867 texImage
->Width2
= 1 << texImage
->WidthLog2
;
868 texImage
->Height2
= 1 << texImage
->HeightLog2
;
869 texImage
->Depth2
= 1 << texImage
->DepthLog2
;
870 texImage
->MaxLog2
= MAX2( texImage
->WidthLog2
, texImage
->HeightLog2
);
872 /* XXX should we really allocate memory for the image or let it be NULL? */
873 /*texImage->Data = NULL;*/
875 texImage
->Data
= (GLubyte
*) malloc( numPixels
* components
+ EXTRA_BYTE
);
878 * Let's see if anyone finds this. If glTexImage2D() is called with
879 * a NULL image pointer then load the texture image with something
880 * interesting instead of leaving it indeterminate.
882 if (texImage
->Data
) {
883 char message
[8][32] = {
887 " X X XXXX XXX XXXXX ",
890 " X X XXXXX XXX X X ",
894 GLubyte
*imgPtr
= texImage
->Data
;
896 for (i
=0;i
<height
;i
++) {
897 GLint srcRow
= 7 - i
% 8;
898 for (j
=0;j
<width
;j
++) {
899 GLint srcCol
= j
% 32;
900 GLubyte texel
= (message
[srcRow
][srcCol
]=='X') ? 255 : 70;
901 for (k
=0;k
<components
;k
++) {
914 * Test glTexImage() parameters for errors.
916 * dimensions - must be 1 or 2 or 3
917 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors
919 static GLboolean
texture_error_check( GLcontext
*ctx
, GLenum target
,
920 GLint level
, GLint internalFormat
,
921 GLenum format
, GLenum type
,
923 GLint width
, GLint height
,
924 GLint depth
, GLint border
)
929 if (dimensions
== 1) {
930 isProxy
= (target
== GL_PROXY_TEXTURE_1D
);
931 if (target
!= GL_TEXTURE_1D
&& !isProxy
) {
932 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
936 else if (dimensions
== 2) {
937 isProxy
= (target
== GL_PROXY_TEXTURE_2D
);
938 if (target
!= GL_TEXTURE_2D
&& !isProxy
) {
939 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
943 else if (dimensions
== 3) {
944 isProxy
= (target
== GL_PROXY_TEXTURE_3D
);
945 if (target
!= GL_TEXTURE_3D
&& !isProxy
) {
946 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(target)" );
951 gl_problem( ctx
, "bad dims in texture_error_check" );
956 if (border
!=0 && border
!=1) {
959 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage1D(border)" );
960 else if (dimensions
== 2)
961 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage2D(border)" );
962 else if (dimensions
== 3)
963 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(border)" );
969 if (width
< 2 * border
|| width
> 2 + ctx
->Const
.MaxTextureSize
970 || logbase2( width
- 2 * border
) < 0) {
973 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage1D(width)" );
974 else if (dimensions
== 2)
975 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage2D(width)" );
976 else if (dimensions
== 3)
977 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(width)" );
983 if (dimensions
>= 2) {
984 if (height
< 2 * border
|| height
> 2 + ctx
->Const
.MaxTextureSize
985 || logbase2( height
- 2 * border
) < 0) {
988 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage2D(height)" );
989 else if (dimensions
== 3)
990 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(height)" );
997 if (dimensions
>= 3) {
998 if (depth
< 2 * border
|| depth
> 2 + ctx
->Const
.MaxTextureSize
999 || logbase2( depth
- 2 * border
) < 0) {
1001 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(depth)" );
1008 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
1009 if (dimensions
== 1)
1010 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage1D(level)" );
1011 else if (dimensions
== 2)
1012 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage2D(level)" );
1013 else if (dimensions
== 3)
1014 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(level)" );
1018 iformat
= decode_internal_format( internalFormat
);
1020 if (dimensions
== 1)
1021 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage1D(internalFormat)" );
1022 else if (dimensions
== 2)
1023 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage2D(internalFormat)" );
1024 else if (dimensions
== 3)
1025 gl_error( ctx
, GL_INVALID_VALUE
, "glTexImage3D(internalFormat)" );
1029 if (!gl_is_legal_format_and_type( format
, type
)) {
1030 if (dimensions
== 1)
1031 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(format or type)");
1032 else if (dimensions
== 2)
1033 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(format or type)");
1034 else if (dimensions
== 3)
1035 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3D(format or type)");
1039 /* if we get here, the parameters are OK */
1046 * Called from the API. Note that width includes the border.
1048 void gl_TexImage1D( GLcontext
*ctx
,
1049 GLenum target
, GLint level
, GLint internalformat
,
1050 GLsizei width
, GLint border
, GLenum format
,
1051 GLenum type
, struct gl_image
*image
)
1053 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1054 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage1D");
1056 if (target
==GL_TEXTURE_1D
) {
1057 struct gl_texture_image
*teximage
;
1058 if (texture_error_check( ctx
, target
, level
, internalformat
,
1059 format
, type
, 1, width
, 1, 1, border
)) {
1060 /* error in texture image was detected */
1064 /* free current texture image, if any */
1065 if (texUnit
->CurrentD
[1]->Image
[level
]) {
1066 gl_free_texture_image( texUnit
->CurrentD
[1]->Image
[level
] );
1069 /* make new texture from source image */
1071 teximage
= image_to_texture(ctx
, image
, internalformat
, border
);
1074 teximage
= make_null_texture(ctx
, (GLenum
) internalformat
,
1075 width
, 1, 1, border
);
1078 /* install new texture image */
1080 texUnit
->CurrentD
[1]->Image
[level
] = teximage
;
1081 gl_put_texobj_on_dirty_list( ctx
, texUnit
->CurrentD
[1] );
1082 ctx
->NewState
|= NEW_TEXTURING
;
1084 /* free the source image */
1085 if (image
&& image
->RefCount
==0) {
1086 /* if RefCount>0 then image must be in a display list */
1087 gl_free_image(image
);
1090 /* tell driver about change */
1091 if (ctx
->Driver
.TexImage
) {
1092 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_1D
,
1093 texUnit
->CurrentD
[1],
1094 level
, internalformat
, teximage
);
1097 else if (target
==GL_PROXY_TEXTURE_1D
) {
1098 /* Proxy texture: check for errors and update proxy state */
1099 if (texture_error_check( ctx
, target
, level
, internalformat
,
1100 format
, type
, 1, width
, 1, 1, border
)) {
1101 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1102 MEMSET( ctx
->Texture
.Proxy1D
->Image
[level
], 0,
1103 sizeof(struct gl_texture_image
) );
1107 ctx
->Texture
.Proxy1D
->Image
[level
]->Format
= (GLenum
) format
;
1108 set_teximage_component_sizes( ctx
->Texture
.Proxy1D
->Image
[level
] );
1109 ctx
->Texture
.Proxy1D
->Image
[level
]->IntFormat
= (GLenum
) internalformat
;
1110 ctx
->Texture
.Proxy1D
->Image
[level
]->Border
= border
;
1111 ctx
->Texture
.Proxy1D
->Image
[level
]->Width
= width
;
1112 ctx
->Texture
.Proxy1D
->Image
[level
]->Height
= 1;
1113 ctx
->Texture
.Proxy1D
->Image
[level
]->Depth
= 1;
1115 if (image
&& image
->RefCount
==0) {
1116 /* if RefCount>0 then image must be in a display list */
1117 gl_free_image(image
);
1121 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage1D(target)" );
1130 * Called by the API or display list executor.
1131 * Note that width and height include the border.
1133 void gl_TexImage2D( GLcontext
*ctx
,
1134 GLenum target
, GLint level
, GLint internalformat
,
1135 GLsizei width
, GLsizei height
, GLint border
,
1136 GLenum format
, GLenum type
,
1137 struct gl_image
*image
)
1139 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1140 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage2D");
1142 if (target
==GL_TEXTURE_2D
) {
1143 struct gl_texture_image
*teximage
;
1144 if (texture_error_check( ctx
, target
, level
, internalformat
,
1145 format
, type
, 2, width
, height
, 1, border
)) {
1146 /* error in texture image was detected */
1150 /* free current texture image, if any */
1151 if (texUnit
->CurrentD
[2]->Image
[level
]) {
1152 gl_free_texture_image( texUnit
->CurrentD
[2]->Image
[level
] );
1155 /* make new texture from source image */
1157 teximage
= image_to_texture(ctx
, image
, internalformat
, border
);
1160 teximage
= make_null_texture(ctx
, (GLenum
) internalformat
,
1161 width
, height
, 1, border
);
1164 /* install new texture image */
1165 texUnit
->CurrentD
[2]->Image
[level
] = teximage
;
1166 gl_put_texobj_on_dirty_list( ctx
, texUnit
->CurrentD
[2] );
1167 ctx
->NewState
|= NEW_TEXTURING
;
1169 /* free the source image */
1170 if (image
&& image
->RefCount
==0) {
1171 /* if RefCount>0 then image must be in a display list */
1172 gl_free_image(image
);
1175 /* tell driver about change */
1176 if (ctx
->Driver
.TexImage
) {
1177 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_2D
,
1178 texUnit
->CurrentD
[2],
1179 level
, internalformat
, teximage
);
1182 else if (target
==GL_PROXY_TEXTURE_2D
) {
1183 /* Proxy texture: check for errors and update proxy state */
1184 if (texture_error_check( ctx
, target
, level
, internalformat
,
1185 format
, type
, 2, width
, height
, 1, border
)) {
1186 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1187 MEMSET( ctx
->Texture
.Proxy2D
->Image
[level
], 0,
1188 sizeof(struct gl_texture_image
) );
1192 ctx
->Texture
.Proxy2D
->Image
[level
]->Format
= (GLenum
) format
;
1193 set_teximage_component_sizes( ctx
->Texture
.Proxy2D
->Image
[level
] );
1194 ctx
->Texture
.Proxy2D
->Image
[level
]->IntFormat
= (GLenum
) internalformat
;
1195 ctx
->Texture
.Proxy2D
->Image
[level
]->Border
= border
;
1196 ctx
->Texture
.Proxy2D
->Image
[level
]->Width
= width
;
1197 ctx
->Texture
.Proxy2D
->Image
[level
]->Height
= height
;
1198 ctx
->Texture
.Proxy2D
->Image
[level
]->Depth
= 1;
1200 if (image
&& image
->RefCount
==0) {
1201 /* if RefCount>0 then image must be in a display list */
1202 gl_free_image(image
);
1206 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage2D(target)" );
1214 * Called by the API or display list executor.
1215 * Note that width and height include the border.
1217 void gl_TexImage3DEXT( GLcontext
*ctx
,
1218 GLenum target
, GLint level
, GLint internalformat
,
1219 GLsizei width
, GLsizei height
, GLsizei depth
,
1220 GLint border
, GLenum format
, GLenum type
,
1221 struct gl_image
*image
)
1223 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1224 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glTexImage3DEXT");
1226 if (target
==GL_TEXTURE_3D_EXT
) {
1227 struct gl_texture_image
*teximage
;
1228 if (texture_error_check( ctx
, target
, level
, internalformat
,
1229 format
, type
, 3, width
, height
, depth
,
1231 /* error in texture image was detected */
1235 /* free current texture image, if any */
1236 if (texUnit
->CurrentD
[3]->Image
[level
]) {
1237 gl_free_texture_image( texUnit
->CurrentD
[3]->Image
[level
] );
1240 /* make new texture from source image */
1242 teximage
= image_to_texture(ctx
, image
, internalformat
, border
);
1245 teximage
= make_null_texture(ctx
, (GLenum
) internalformat
,
1246 width
, height
, depth
, border
);
1249 /* install new texture image */
1250 texUnit
->CurrentD
[3]->Image
[level
] = teximage
;
1251 gl_put_texobj_on_dirty_list( ctx
, texUnit
->CurrentD
[3] );
1252 ctx
->NewState
|= NEW_TEXTURING
;
1254 /* free the source image */
1255 if (image
&& image
->RefCount
==0) {
1256 /* if RefCount>0 then image must be in a display list */
1257 gl_free_image(image
);
1260 /* tell driver about change */
1261 if (ctx
->Driver
.TexImage
) {
1262 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_3D_EXT
,
1263 texUnit
->CurrentD
[3],
1264 level
, internalformat
, teximage
);
1267 else if (target
==GL_PROXY_TEXTURE_3D_EXT
) {
1268 /* Proxy texture: check for errors and update proxy state */
1269 if (texture_error_check( ctx
, target
, level
, internalformat
,
1270 format
, type
, 3, width
, height
, depth
,
1272 if (level
>=0 && level
<ctx
->Const
.MaxTextureLevels
) {
1273 MEMSET( ctx
->Texture
.Proxy3D
->Image
[level
], 0,
1274 sizeof(struct gl_texture_image
) );
1278 ctx
->Texture
.Proxy3D
->Image
[level
]->Format
= (GLenum
) format
;
1279 set_teximage_component_sizes( ctx
->Texture
.Proxy3D
->Image
[level
] );
1280 ctx
->Texture
.Proxy3D
->Image
[level
]->IntFormat
= (GLenum
) internalformat
;
1281 ctx
->Texture
.Proxy3D
->Image
[level
]->Border
= border
;
1282 ctx
->Texture
.Proxy3D
->Image
[level
]->Width
= width
;
1283 ctx
->Texture
.Proxy3D
->Image
[level
]->Height
= height
;
1284 ctx
->Texture
.Proxy3D
->Image
[level
]->Depth
= depth
;
1286 if (image
&& image
->RefCount
==0) {
1287 /* if RefCount>0 then image must be in a display list */
1288 gl_free_image(image
);
1292 gl_error( ctx
, GL_INVALID_ENUM
, "glTexImage3DEXT(target)" );
1299 void gl_GetTexImage( GLcontext
*ctx
, GLenum target
, GLint level
, GLenum format
,
1300 GLenum type
, GLvoid
*pixels
)
1302 const struct gl_texture_object
*texObj
;
1304 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glGetTexImage");
1306 if (level
< 0 || level
>= ctx
->Const
.MaxTextureLevels
) {
1307 gl_error( ctx
, GL_INVALID_VALUE
, "glGetTexImage(level)" );
1311 if (gl_sizeof_type(type
) <= 0) {
1312 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(type)" );
1316 if (gl_components_in_format(format
) <= 0) {
1317 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(format)" );
1322 return; /* XXX generate an error??? */
1326 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[1];
1329 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[2];
1332 texObj
= ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
].CurrentD
[3];
1335 gl_error( ctx
, GL_INVALID_ENUM
, "glGetTexImage(target)" );
1339 if (texObj
->Image
[level
] && texObj
->Image
[level
]->Data
) {
1340 const struct gl_texture_image
*texImage
= texObj
->Image
[level
];
1341 GLint width
= texImage
->Width
;
1342 GLint height
= texImage
->Height
;
1345 for (row
= 0; row
< height
; row
++) {
1346 /* compute destination address in client memory */
1347 GLvoid
*dest
= gl_pixel_addr_in_image( &ctx
->Unpack
, pixels
,
1349 format
, type
, 0, row
, 0);
1352 if (texImage
->Format
== GL_RGBA
) {
1353 const GLubyte
*src
= texImage
->Data
+ row
* width
* 4 * sizeof(GLubyte
);
1354 gl_pack_rgba_span( ctx
, width
, (void *) src
, format
, type
, dest
,
1355 &ctx
->Pack
, GL_TRUE
);
1358 /* fetch RGBA row from texture image then pack it in client mem */
1359 GLubyte rgba
[MAX_WIDTH
][4];
1362 switch (texImage
->Format
) {
1364 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1365 for (i
= 0; i
< width
; i
++) {
1366 rgba
[i
][RCOMP
] = 255;
1367 rgba
[i
][GCOMP
] = 255;
1368 rgba
[i
][BCOMP
] = 255;
1369 rgba
[i
][ACOMP
] = src
[i
];
1373 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1374 for (i
= 0; i
< width
; i
++) {
1375 rgba
[i
][RCOMP
] = src
[i
];
1376 rgba
[i
][GCOMP
] = src
[i
];
1377 rgba
[i
][BCOMP
] = src
[i
];
1378 rgba
[i
][ACOMP
] = 255;
1381 case GL_LUMINANCE_ALPHA
:
1382 src
= texImage
->Data
+ row
* 2 * width
* sizeof(GLubyte
);
1383 for (i
= 0; i
< width
; i
++) {
1384 rgba
[i
][RCOMP
] = src
[i
*2+0];
1385 rgba
[i
][GCOMP
] = src
[i
*2+0];
1386 rgba
[i
][BCOMP
] = src
[i
*2+0];
1387 rgba
[i
][ACOMP
] = src
[i
*2+1];
1391 src
= texImage
->Data
+ row
* width
* sizeof(GLubyte
);
1392 for (i
= 0; i
< width
; i
++) {
1393 rgba
[i
][RCOMP
] = src
[i
];
1394 rgba
[i
][GCOMP
] = src
[i
];
1395 rgba
[i
][BCOMP
] = src
[i
];
1396 rgba
[i
][ACOMP
] = 255;
1400 src
= texImage
->Data
+ row
* 3 * width
* sizeof(GLubyte
);
1401 for (i
= 0; i
< width
; i
++) {
1402 rgba
[i
][RCOMP
] = src
[i
*3+0];
1403 rgba
[i
][GCOMP
] = src
[i
*3+1];
1404 rgba
[i
][BCOMP
] = src
[i
*3+2];
1405 rgba
[i
][ACOMP
] = 255;
1409 /* this special case should have been handled above! */
1410 gl_problem( ctx
, "error 1 in gl_GetTexImage" );
1412 case GL_COLOR_INDEX
:
1413 gl_problem( ctx
, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
1416 gl_problem( ctx
, "bad format in gl_GetTexImage" );
1418 gl_pack_rgba_span( ctx
, width
, (const GLubyte (*)[4])rgba
,
1419 format
, type
, dest
, &ctx
->Pack
, GL_TRUE
);
1428 * Unpack the image data given to glTexSubImage[12]D.
1429 * This function is just a wrapper for gl_unpack_image() but it does
1430 * some extra error checking.
1433 gl_unpack_texsubimage( GLcontext
*ctx
, GLint width
, GLint height
,
1434 GLenum format
, GLenum type
, const GLvoid
*pixels
)
1436 if (type
==GL_BITMAP
&& format
!=GL_COLOR_INDEX
) {
1440 if (format
==GL_STENCIL_INDEX
|| format
==GL_DEPTH_COMPONENT
){
1444 if (gl_sizeof_type(type
)<=0) {
1448 return gl_unpack_image3D( ctx
, width
, height
, 1, format
, type
, pixels
, &ctx
->Unpack
);
1453 * Unpack the image data given to glTexSubImage3D.
1454 * This function is just a wrapper for gl_unpack_image() but it does
1455 * some extra error checking.
1458 gl_unpack_texsubimage3D( GLcontext
*ctx
, GLint width
, GLint height
,
1459 GLint depth
, GLenum format
, GLenum type
,
1460 const GLvoid
*pixels
)
1462 if (type
==GL_BITMAP
&& format
!=GL_COLOR_INDEX
) {
1466 if (format
==GL_STENCIL_INDEX
|| format
==GL_DEPTH_COMPONENT
){
1470 if (gl_sizeof_type(type
)<=0) {
1474 return gl_unpack_image3D( ctx
, width
, height
, depth
, format
, type
, pixels
,
1480 void gl_TexSubImage1D( GLcontext
*ctx
,
1481 GLenum target
, GLint level
, GLint xoffset
,
1482 GLsizei width
, GLenum format
, GLenum type
,
1483 struct gl_image
*image
)
1485 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1486 struct gl_texture_image
*destTex
;
1488 if (target
!=GL_TEXTURE_1D
) {
1489 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(target)" );
1492 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
1493 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(level)" );
1497 destTex
= texUnit
->CurrentD
[1]->Image
[level
];
1499 gl_error( ctx
, GL_INVALID_OPERATION
, "glTexSubImage1D" );
1503 if (xoffset
< -((GLint
)destTex
->Border
)) {
1504 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage1D(xoffset)" );
1507 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1508 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage1D(xoffset+width)" );
1513 /* unpacking must have been error-free */
1514 GLint texcomponents
= components_in_intformat(destTex
->Format
);
1516 if (image
->Type
==GL_UNSIGNED_BYTE
&& texcomponents
==image
->Components
) {
1517 /* Simple case, just byte copy image data into texture image */
1519 GLubyte
*dst
= destTex
->Data
+ texcomponents
* xoffset
;
1520 GLubyte
*src
= (GLubyte
*) image
->Data
;
1521 MEMCPY( dst
, src
, width
* texcomponents
);
1524 /* General case, convert image pixels into texels, scale, bias, etc */
1525 struct gl_texture_image
*subTexImg
= image_to_texture(ctx
, image
,
1526 destTex
->IntFormat
, destTex
->Border
);
1527 GLubyte
*dst
= destTex
->Data
+ texcomponents
* xoffset
;
1528 GLubyte
*src
= subTexImg
->Data
;
1529 MEMCPY( dst
, src
, width
* texcomponents
);
1530 gl_free_texture_image(subTexImg
);
1533 /* if the image's reference count is zero, delete it now */
1534 if (image
->RefCount
==0) {
1535 gl_free_image(image
);
1538 gl_put_texobj_on_dirty_list( ctx
, texUnit
->CurrentD
[1] );
1540 /* tell driver about change */
1541 if (ctx
->Driver
.TexSubImage
) {
1542 (*ctx
->Driver
.TexSubImage
)( ctx
, GL_TEXTURE_1D
,
1543 texUnit
->CurrentD
[1], level
,
1545 texUnit
->CurrentD
[1]->Image
[level
]->IntFormat
,
1549 if (ctx
->Driver
.TexImage
) {
1550 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_1D
, texUnit
->CurrentD
[1], level
,
1551 texUnit
->CurrentD
[1]->Image
[level
]->IntFormat
,
1557 /* if no image, an error must have occured, do more testing now */
1558 GLint components
, size
;
1561 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage1D(width)" );
1564 if (type
==GL_BITMAP
&& format
!=GL_COLOR_INDEX
) {
1565 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(format)" );
1568 components
= components_in_intformat( format
);
1569 if (components
<0 || format
==GL_STENCIL_INDEX
1570 || format
==GL_DEPTH_COMPONENT
){
1571 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(format)" );
1574 size
= gl_sizeof_type( type
);
1576 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(type)" );
1579 /* if we get here, probably ran out of memory during unpacking */
1580 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D" );
1586 void gl_TexSubImage2D( GLcontext
*ctx
,
1587 GLenum target
, GLint level
,
1588 GLint xoffset
, GLint yoffset
,
1589 GLsizei width
, GLsizei height
,
1590 GLenum format
, GLenum type
,
1591 struct gl_image
*image
)
1593 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1594 struct gl_texture_image
*destTex
;
1596 if (target
!=GL_TEXTURE_2D
) {
1597 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(target)" );
1600 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
1601 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(level)" );
1605 destTex
= texUnit
->CurrentD
[2]->Image
[level
];
1607 gl_error( ctx
, GL_INVALID_OPERATION
, "glTexSubImage2D" );
1611 if (xoffset
< -((GLint
)destTex
->Border
)) {
1612 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage2D(xoffset)" );
1615 if (yoffset
< -((GLint
)destTex
->Border
)) {
1616 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage2D(yoffset)" );
1619 if (xoffset
+ width
> (GLint
) (destTex
->Width
+ destTex
->Border
)) {
1620 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage2D(xoffset+width)" );
1623 if (yoffset
+ height
> (GLint
) (destTex
->Height
+ destTex
->Border
)) {
1624 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage2D(yoffset+height)" );
1629 /* unpacking must have been error-free */
1630 GLint texcomponents
= components_in_intformat(destTex
->Format
);
1632 if (image
->Type
==GL_UNSIGNED_BYTE
&& texcomponents
==image
->Components
) {
1633 /* Simple case, just byte copy image data into texture image */
1635 GLubyte
*dst
= destTex
->Data
1636 + (yoffset
* destTex
->Width
+ xoffset
) * texcomponents
;
1637 GLubyte
*src
= (GLubyte
*) image
->Data
;
1639 for (j
=0;j
<height
;j
++) {
1640 MEMCPY( dst
, src
, width
* texcomponents
);
1641 dst
+= destTex
->Width
* texcomponents
* sizeof(GLubyte
);
1642 src
+= width
* texcomponents
* sizeof(GLubyte
);
1646 /* General case, convert image pixels into texels, scale, bias, etc */
1647 struct gl_texture_image
*subTexImg
= image_to_texture(ctx
, image
,
1648 destTex
->IntFormat
, destTex
->Border
);
1649 GLubyte
*dst
= destTex
->Data
1650 + (yoffset
* destTex
->Width
+ xoffset
) * texcomponents
;
1651 GLubyte
*src
= subTexImg
->Data
;
1653 for (j
=0;j
<height
;j
++) {
1654 MEMCPY( dst
, src
, width
* texcomponents
);
1655 dst
+= destTex
->Width
* texcomponents
* sizeof(GLubyte
);
1656 src
+= width
* texcomponents
* sizeof(GLubyte
);
1658 gl_free_texture_image(subTexImg
);
1661 /* if the image's reference count is zero, delete it now */
1662 if (image
->RefCount
==0) {
1663 gl_free_image(image
);
1666 gl_put_texobj_on_dirty_list( ctx
, texUnit
->CurrentD
[2] );
1668 /* tell driver about change */
1669 if (ctx
->Driver
.TexSubImage
) {
1670 (*ctx
->Driver
.TexSubImage
)( ctx
, GL_TEXTURE_2D
, texUnit
->CurrentD
[2], level
,
1671 xoffset
, yoffset
, width
, height
,
1672 texUnit
->CurrentD
[2]->Image
[level
]->IntFormat
,
1676 if (ctx
->Driver
.TexImage
) {
1677 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_2D
, texUnit
->CurrentD
[2], level
,
1678 texUnit
->CurrentD
[2]->Image
[level
]->IntFormat
,
1684 /* if no image, an error must have occured, do more testing now */
1685 GLint components
, size
;
1688 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage2D(width)" );
1692 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage2D(height)" );
1695 if (type
==GL_BITMAP
&& format
!=GL_COLOR_INDEX
) {
1696 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage1D(format)" );
1699 components
= gl_components_in_format( format
);
1700 if (components
<0 || format
==GL_STENCIL_INDEX
1701 || format
==GL_DEPTH_COMPONENT
){
1702 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(format)" );
1705 size
= gl_sizeof_packed_type( type
);
1707 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage2D(type)" );
1710 /* if we get here, probably ran out of memory during unpacking */
1711 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D" );
1717 void gl_TexSubImage3DEXT( GLcontext
*ctx
,
1718 GLenum target
, GLint level
,
1719 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1720 GLsizei width
, GLsizei height
, GLsizei depth
,
1721 GLenum format
, GLenum type
,
1722 struct gl_image
*image
)
1724 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
1725 struct gl_texture_image
*destTex
;
1727 if (target
!=GL_TEXTURE_3D_EXT
) {
1728 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3DEXT(target)" );
1731 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
1732 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3DEXT(level)" );
1736 destTex
= texUnit
->CurrentD
[3]->Image
[level
];
1738 gl_error( ctx
, GL_INVALID_OPERATION
, "glTexSubImage3DEXT" );
1742 if (xoffset
< -((GLint
)destTex
->Border
)) {
1743 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage3DEXT(xoffset)" );
1746 if (yoffset
< -((GLint
)destTex
->Border
)) {
1747 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage3DEXT(yoffset)" );
1750 if (zoffset
< -((GLint
)destTex
->Border
)) {
1751 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage3DEXT(zoffset)" );
1754 if (xoffset
+ width
> (GLint
) (destTex
->Width
+destTex
->Border
)) {
1755 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage3DEXT(xoffset+width)" );
1758 if (yoffset
+ height
> (GLint
) (destTex
->Height
+destTex
->Border
)) {
1759 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage3DEXT(yoffset+height)" );
1762 if (zoffset
+ depth
> (GLint
) (destTex
->Depth
+destTex
->Border
)) {
1763 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage3DEXT(zoffset+depth)" );
1768 /* unpacking must have been error-free */
1769 GLint texcomponents
= components_in_intformat(destTex
->Format
);
1770 GLint dstRectArea
= destTex
->Width
* destTex
->Height
;
1771 GLint srcRectArea
= width
* height
;
1773 if (image
->Type
==GL_UNSIGNED_BYTE
&& texcomponents
==image
->Components
) {
1774 /* Simple case, just byte copy image data into texture image */
1776 GLubyte
*dst
= destTex
->Data
1777 + (zoffset
* dstRectArea
+ yoffset
* destTex
->Width
+ xoffset
)
1779 GLubyte
*src
= (GLubyte
*) image
->Data
;
1781 for(k
=0;k
<depth
; k
++) {
1782 for (j
=0;j
<height
;j
++) {
1783 MEMCPY( dst
, src
, width
* texcomponents
);
1784 dst
+= destTex
->Width
* texcomponents
;
1785 src
+= width
* texcomponents
;
1787 dst
+= dstRectArea
* texcomponents
* sizeof(GLubyte
);
1788 src
+= srcRectArea
* texcomponents
* sizeof(GLubyte
);
1792 /* General case, convert image pixels into texels, scale, bias, etc */
1793 struct gl_texture_image
*subTexImg
= image_to_texture(ctx
, image
,
1794 destTex
->IntFormat
, destTex
->Border
);
1795 GLubyte
*dst
= destTex
->Data
1796 + (zoffset
* dstRectArea
+ yoffset
* destTex
->Width
+ xoffset
)
1798 GLubyte
*src
= subTexImg
->Data
;
1800 for(k
=0;k
<depth
; k
++) {
1801 for (j
=0;j
<height
;j
++) {
1802 MEMCPY( dst
, src
, width
* texcomponents
);
1803 dst
+= destTex
->Width
* texcomponents
;
1804 src
+= width
* texcomponents
;
1806 dst
+= dstRectArea
* texcomponents
* sizeof(GLubyte
);
1807 src
+= srcRectArea
* texcomponents
* sizeof(GLubyte
);
1809 gl_free_texture_image(subTexImg
);
1811 /* if the image's reference count is zero, delete it now */
1812 if (image
->RefCount
==0) {
1813 gl_free_image(image
);
1816 gl_put_texobj_on_dirty_list( ctx
, texUnit
->CurrentD
[3] );
1818 /* tell driver about change */
1819 if (ctx
->Driver
.TexImage
) {
1820 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_3D_EXT
, texUnit
->CurrentD
[3],
1821 level
, texUnit
->CurrentD
[3]->Image
[level
]->IntFormat
,
1826 /* if no image, an error must have occured, do more testing now */
1827 GLint components
, size
;
1830 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage3DEXT(width)" );
1834 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage3DEXT(height)" );
1838 gl_error( ctx
, GL_INVALID_VALUE
, "glTexSubImage3DEXT(depth)" );
1841 if (type
==GL_BITMAP
&& format
!=GL_COLOR_INDEX
) {
1842 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3DEXT(format)" );
1845 components
= components_in_intformat( format
);
1846 if (components
<0 || format
==GL_STENCIL_INDEX
1847 || format
==GL_DEPTH_COMPONENT
){
1848 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3DEXT(format)" );
1851 size
= gl_sizeof_type( type
);
1853 gl_error( ctx
, GL_INVALID_ENUM
, "glTexSubImage3DEXT(type)" );
1856 /* if we get here, probably ran out of memory during unpacking */
1857 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3DEXT" );
1864 * Read an RGBA image from the frame buffer.
1865 * Input: ctx - the context
1866 * x, y - lower left corner
1867 * width, height - size of region to read
1868 * format - one of GL_RED, GL_RGB, GL_LUMINANCE, etc.
1869 * Return: gl_image pointer or NULL if out of memory
1871 static struct gl_image
*read_color_image( GLcontext
*ctx
, GLint x
, GLint y
,
1872 GLsizei width
, GLsizei height
,
1875 struct gl_image
*image
;
1880 components
= components_in_intformat( format
);
1883 * Allocate image struct and image data buffer
1885 image
= (struct gl_image
*) malloc( sizeof(struct gl_image
) );
1887 image
->Width
= width
;
1888 image
->Height
= height
;
1890 image
->Components
= components
;
1891 image
->Format
= format
;
1892 image
->Type
= GL_UNSIGNED_BYTE
;
1893 image
->RefCount
= 0;
1894 image
->Data
= (GLubyte
*) malloc( width
* height
* components
);
1904 imgptr
= (GLubyte
*) image
->Data
;
1906 /* Select buffer to read from */
1907 (void) (*ctx
->Driver
.SetBuffer
)( ctx
, ctx
->Pixel
.DriverReadBuffer
);
1909 for (j
=0;j
<height
;j
++) {
1910 GLubyte rgba
[MAX_WIDTH
][4];
1911 gl_read_rgba_span( ctx
, width
, x
, y
+j
, rgba
);
1915 for (i
=0;i
<width
;i
++) {
1916 *imgptr
++ = rgba
[i
][ACOMP
];
1920 for (i
=0;i
<width
;i
++) {
1921 *imgptr
++ = rgba
[i
][RCOMP
];
1924 case GL_LUMINANCE_ALPHA
:
1925 for (i
=0;i
<width
;i
++) {
1926 *imgptr
++ = rgba
[i
][RCOMP
];
1927 *imgptr
++ = rgba
[i
][ACOMP
];
1931 for (i
=0;i
<width
;i
++) {
1932 *imgptr
++ = rgba
[i
][RCOMP
];
1936 for (i
=0;i
<width
;i
++) {
1937 *imgptr
++ = rgba
[i
][RCOMP
];
1938 *imgptr
++ = rgba
[i
][GCOMP
];
1939 *imgptr
++ = rgba
[i
][BCOMP
];
1943 for (i
=0;i
<width
;i
++) {
1944 *imgptr
++ = rgba
[i
][RCOMP
];
1945 *imgptr
++ = rgba
[i
][GCOMP
];
1946 *imgptr
++ = rgba
[i
][BCOMP
];
1947 *imgptr
++ = rgba
[i
][ACOMP
];
1951 gl_problem(ctx
, "Bad format in read_color_image");
1957 /* Restore drawing buffer */
1958 (void) (*ctx
->Driver
.SetBuffer
)( ctx
, ctx
->Color
.DriverDrawBuffer
);
1966 void gl_CopyTexImage1D( GLcontext
*ctx
,
1967 GLenum target
, GLint level
,
1968 GLenum internalformat
,
1970 GLsizei width
, GLint border
)
1973 struct gl_image
*teximage
;
1975 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage1D");
1976 if (target
!=GL_TEXTURE_1D
) {
1977 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage1D(target)" );
1980 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
1981 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexImage1D(level)" );
1984 if (border
!=0 && border
!=1) {
1985 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexImage1D(border)" );
1988 if (width
< 2*border
|| width
> 2 + ctx
->Const
.MaxTextureSize
|| width
<0) {
1989 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexImage1D(width)" );
1992 format
= decode_internal_format( internalformat
);
1993 if (format
<0 || (internalformat
>=1 && internalformat
<=4)) {
1994 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexImage1D(format)" );
1998 teximage
= read_color_image( ctx
, x
, y
, width
, 1, (GLenum
) format
);
2000 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage1D" );
2004 gl_TexImage1D( ctx
, target
, level
, internalformat
, width
,
2005 border
, GL_RGBA
, GL_UNSIGNED_BYTE
, teximage
);
2007 /* teximage was freed in gl_TexImage1D */
2012 void gl_CopyTexImage2D( GLcontext
*ctx
,
2013 GLenum target
, GLint level
, GLenum internalformat
,
2014 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
2018 struct gl_image
*teximage
;
2020 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexImage2D");
2021 if (target
!=GL_TEXTURE_2D
) {
2022 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexImage2D(target)" );
2025 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
2026 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(level)" );
2029 if (border
!=0 && border
!=1) {
2030 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(border)" );
2033 if (width
<2*border
|| width
>2+ctx
->Const
.MaxTextureSize
|| width
<0) {
2034 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(width)" );
2037 if (height
<2*border
|| height
>2+ctx
->Const
.MaxTextureSize
|| height
<0) {
2038 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(height)" );
2041 format
= decode_internal_format( internalformat
);
2042 if (format
<0 || (internalformat
>=1 && internalformat
<=4)) {
2043 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexImage2D(format)" );
2047 teximage
= read_color_image( ctx
, x
, y
, width
, height
, (GLenum
) format
);
2049 gl_error( ctx
, GL_OUT_OF_MEMORY
, "glCopyTexImage2D" );
2053 gl_TexImage2D( ctx
, target
, level
, internalformat
, width
, height
,
2054 border
, GL_RGBA
, GL_UNSIGNED_BYTE
, teximage
);
2056 /* teximage was freed in gl_TexImage2D */
2063 * Do the work of glCopyTexSubImage[123]D.
2064 * TODO: apply pixel bias scale and mapping.
2066 static void copy_tex_sub_image( GLcontext
*ctx
, struct gl_texture_image
*dest
,
2067 GLint width
, GLint height
,
2068 GLint srcx
, GLint srcy
,
2069 GLint dstx
, GLint dsty
, GLint zoffset
)
2072 GLint format
, components
, rectarea
;
2073 GLint texwidth
, texheight
;
2075 texwidth
= dest
->Width
;
2076 texheight
= dest
->Height
;
2077 rectarea
= texwidth
* texheight
;
2078 zoffset
*= rectarea
;
2079 format
= dest
->Format
;
2080 components
= components_in_intformat( format
);
2082 /* Select buffer to read from */
2083 (void) (*ctx
->Driver
.SetBuffer
)( ctx
, ctx
->Pixel
.DriverReadBuffer
);
2085 for (j
=0;j
<height
;j
++) {
2086 GLubyte rgba
[MAX_WIDTH
][4];
2089 gl_read_rgba_span( ctx
, width
, srcx
, srcy
+j
, rgba
);
2091 texptr
= dest
->Data
+ ( zoffset
+ (dsty
+j
) * texwidth
+ dstx
) * components
;
2095 for (i
=0;i
<width
;i
++) {
2096 *texptr
++ = rgba
[i
][ACOMP
];
2100 for (i
=0;i
<width
;i
++) {
2101 *texptr
++ = rgba
[i
][RCOMP
];
2104 case GL_LUMINANCE_ALPHA
:
2105 for (i
=0;i
<width
;i
++) {
2106 *texptr
++ = rgba
[i
][RCOMP
];
2107 *texptr
++ = rgba
[i
][ACOMP
];
2111 for (i
=0;i
<width
;i
++) {
2112 *texptr
++ = rgba
[i
][RCOMP
];
2116 for (i
=0;i
<width
;i
++) {
2117 *texptr
++ = rgba
[i
][RCOMP
];
2118 *texptr
++ = rgba
[i
][GCOMP
];
2119 *texptr
++ = rgba
[i
][BCOMP
];
2123 for (i
=0;i
<width
;i
++) {
2124 *texptr
++ = rgba
[i
][RCOMP
];
2125 *texptr
++ = rgba
[i
][GCOMP
];
2126 *texptr
++ = rgba
[i
][BCOMP
];
2127 *texptr
++ = rgba
[i
][ACOMP
];
2134 /* Restore drawing buffer */
2135 (void) (*ctx
->Driver
.SetBuffer
)( ctx
, ctx
->Color
.DriverDrawBuffer
);
2141 void gl_CopyTexSubImage1D( GLcontext
*ctx
,
2142 GLenum target
, GLint level
,
2143 GLint xoffset
, GLint x
, GLint y
, GLsizei width
)
2145 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2146 struct gl_texture_image
*teximage
;
2148 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage1D");
2149 if (target
!=GL_TEXTURE_1D
) {
2150 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage1D(target)" );
2153 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
2154 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage1D(level)" );
2158 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage1D(width)" );
2162 teximage
= texUnit
->CurrentD
[1]->Image
[level
];
2165 if (xoffset
< -((GLint
)teximage
->Border
)) {
2166 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage1D(xoffset)" );
2169 /* NOTE: we're adding the border here, not subtracting! */
2170 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
2171 gl_error( ctx
, GL_INVALID_VALUE
,
2172 "glCopyTexSubImage1D(xoffset+width)" );
2175 if (teximage
->Data
) {
2176 copy_tex_sub_image( ctx
, teximage
, width
, 1, x
, y
, xoffset
, 0, 0 );
2178 /* tell driver about change */
2179 if (ctx
->Driver
.TexSubImage
) {
2180 (*ctx
->Driver
.TexSubImage
)( ctx
, GL_TEXTURE_1D
,
2181 texUnit
->CurrentD
[1], level
,
2183 teximage
->IntFormat
,
2187 if (ctx
->Driver
.TexImage
) {
2188 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_1D
, texUnit
->CurrentD
[1], level
,
2189 teximage
->IntFormat
,
2196 gl_error( ctx
, GL_INVALID_OPERATION
, "glCopyTexSubImage1D" );
2202 void gl_CopyTexSubImage2D( GLcontext
*ctx
,
2203 GLenum target
, GLint level
,
2204 GLint xoffset
, GLint yoffset
,
2205 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2207 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2208 struct gl_texture_image
*teximage
;
2210 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage2D");
2211 if (target
!=GL_TEXTURE_2D
) {
2212 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage2D(target)" );
2215 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
2216 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage2D(level)" );
2220 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage2D(width)" );
2224 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage2D(height)" );
2228 teximage
= texUnit
->CurrentD
[2]->Image
[level
];
2231 if (xoffset
< -((GLint
)teximage
->Border
)) {
2232 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage2D(xoffset)" );
2235 if (yoffset
< -((GLint
)teximage
->Border
)) {
2236 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage2D(yoffset)" );
2239 /* NOTE: we're adding the border here, not subtracting! */
2240 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
2241 gl_error( ctx
, GL_INVALID_VALUE
,
2242 "glCopyTexSubImage2D(xoffset+width)" );
2245 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
2246 gl_error( ctx
, GL_INVALID_VALUE
,
2247 "glCopyTexSubImage2D(yoffset+height)" );
2251 if (teximage
->Data
) {
2252 copy_tex_sub_image( ctx
, teximage
, width
, height
,
2253 x
, y
, xoffset
, yoffset
, 0 );
2254 /* tell driver about change */
2255 if (ctx
->Driver
.TexSubImage
) {
2256 (*ctx
->Driver
.TexSubImage
)( ctx
, GL_TEXTURE_2D
, texUnit
->CurrentD
[2], level
,
2257 xoffset
, yoffset
, width
, height
,
2258 teximage
->IntFormat
,
2262 if (ctx
->Driver
.TexImage
) {
2263 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_2D
, texUnit
->CurrentD
[2], level
,
2264 teximage
->IntFormat
,
2271 gl_error( ctx
, GL_INVALID_OPERATION
, "glCopyTexSubImage2D" );
2277 void gl_CopyTexSubImage3DEXT( GLcontext
*ctx
,
2278 GLenum target
, GLint level
,
2279 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2280 GLint x
, GLint y
, GLsizei width
, GLsizei height
)
2282 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
];
2283 struct gl_texture_image
*teximage
;
2285 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glCopyTexSubImage3DEXT");
2286 if (target
!=GL_TEXTURE_2D
) {
2287 gl_error( ctx
, GL_INVALID_ENUM
, "glCopyTexSubImage3DEXT(target)" );
2290 if (level
<0 || level
>=ctx
->Const
.MaxTextureLevels
) {
2291 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage3DEXT(level)" );
2295 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage3DEXT(width)" );
2299 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage3DEXT(height)" );
2303 teximage
= texUnit
->CurrentD
[3]->Image
[level
];
2305 if (xoffset
< -((GLint
)teximage
->Border
)) {
2306 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage3DEXT(xoffset)" );
2309 if (yoffset
< -((GLint
)teximage
->Border
)) {
2310 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage3DEXT(yoffset)" );
2313 if (zoffset
< -((GLint
)teximage
->Border
)) {
2314 gl_error( ctx
, GL_INVALID_VALUE
, "glCopyTexSubImage3DEXT(zoffset)" );
2317 /* NOTE: we're adding the border here, not subtracting! */
2318 if (xoffset
+width
> (GLint
) (teximage
->Width
+teximage
->Border
)) {
2319 gl_error( ctx
, GL_INVALID_VALUE
,
2320 "glCopyTexSubImage3DEXT(xoffset+width)" );
2323 if (yoffset
+height
> (GLint
) (teximage
->Height
+teximage
->Border
)) {
2324 gl_error( ctx
, GL_INVALID_VALUE
,
2325 "glCopyTexSubImage3DEXT(yoffset+height)" );
2328 if (zoffset
> (GLint
) (teximage
->Depth
+teximage
->Border
)) {
2329 gl_error( ctx
, GL_INVALID_VALUE
,
2330 "glCopyTexSubImage3DEXT(zoffset+depth)" );
2334 if (teximage
->Data
) {
2335 copy_tex_sub_image( ctx
, teximage
, width
, height
,
2336 x
, y
, xoffset
, yoffset
, zoffset
);
2338 /* tell driver about change */
2339 if (ctx
->Driver
.TexImage
) {
2340 (*ctx
->Driver
.TexImage
)( ctx
, GL_TEXTURE_3D_EXT
, texUnit
->CurrentD
[3],
2341 level
, teximage
->IntFormat
,
2347 gl_error( ctx
, GL_INVALID_OPERATION
, "glCopyTexSubImage3DEXT" );