1 /* $Id: drawpix.c,v 1.22 2000/05/04 13:48:49 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52 * Given the dest position, size and skipPixels and skipRows values
53 * for a glDrawPixels command, perform clipping of the image bounds
54 * so the result lies withing the context's buffer bounds.
55 * Return: GL_TRUE if image is ready for drawing
56 * GL_FALSE if image was completely clipped away (draw nothing)
59 _mesa_clip_pixelrect(const GLcontext
*ctx
,
60 GLint
*destX
, GLint
*destY
,
61 GLsizei
*width
, GLsizei
*height
,
62 GLint
*skipPixels
, GLint
*skipRows
)
64 const GLframebuffer
*buffer
= ctx
->DrawBuffer
;
67 if (*destX
< buffer
->Xmin
) {
68 *skipPixels
+= (buffer
->Xmin
- *destX
);
69 *width
-= (buffer
->Xmin
- *destX
);
70 *destX
= buffer
->Xmin
;
73 if (*destX
+ *width
> buffer
->Xmax
)
74 *width
-= (*destX
+ *width
- buffer
->Xmax
- 1);
80 if (*destY
< buffer
->Ymin
) {
81 *skipRows
+= (buffer
->Ymin
- *destY
);
82 *height
-= (buffer
->Ymin
- *destY
);
83 *destY
= buffer
->Ymin
;
86 if (*destY
+ *height
> buffer
->Ymax
)
87 *height
-= (*destY
+ *height
- buffer
->Ymax
- 1);
98 * Try to do a fast and simple RGB(a) glDrawPixels.
99 * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead
102 simple_DrawPixels( GLcontext
*ctx
, GLint x
, GLint y
,
103 GLsizei width
, GLsizei height
, GLenum format
, GLenum type
,
104 const GLvoid
*pixels
)
106 const struct gl_pixelstore_attrib
*unpack
= &ctx
->Unpack
;
107 GLubyte rgb
[MAX_WIDTH
][3];
108 GLubyte rgba
[MAX_WIDTH
][4];
110 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx
, "glDrawPixels",
114 if (!ctx
->Current
.RasterPosValid
) {
119 if ((ctx
->RasterMask
&(~(SCISSOR_BIT
|WINCLIP_BIT
)))==0
120 && !ctx
->Pixel
.ScaleOrBiasRGBA
121 && !ctx
->Pixel
.ScaleOrBiasRGBApcm
122 && ctx
->ColorMatrix
.type
== MATRIX_IDENTITY
123 && !ctx
->Pixel
.ColorTableEnabled
124 && !ctx
->Pixel
.PostColorMatrixColorTableEnabled
125 && !ctx
->Pixel
.MinMaxEnabled
126 && !ctx
->Pixel
.HistogramEnabled
127 && ctx
->Pixel
.IndexShift
==0 && ctx
->Pixel
.IndexOffset
==0
128 && ctx
->Pixel
.MapColorFlag
==0
129 && ctx
->Texture
.ReallyEnabled
== 0
130 && unpack
->Alignment
==1
131 && !unpack
->SwapBytes
132 && !unpack
->LsbFirst
) {
136 GLint drawWidth
= width
; /* actual width drawn */
137 GLint drawHeight
= height
; /* actual height drawn */
138 GLint skipPixels
= unpack
->SkipPixels
;
139 GLint skipRows
= unpack
->SkipRows
;
141 GLdepth zSpan
[MAX_WIDTH
]; /* only used when zooming */
144 if (unpack
->RowLength
> 0)
145 rowLength
= unpack
->RowLength
;
149 /* If we're not using pixel zoom then do all clipping calculations
150 * now. Otherwise, we'll let the gl_write_zoomed_*_span() functions
151 * handle the clipping.
153 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
154 /* horizontal clipping */
155 if (destX
< ctx
->DrawBuffer
->Xmin
) {
156 skipPixels
+= (ctx
->DrawBuffer
->Xmin
- destX
);
157 drawWidth
-= (ctx
->DrawBuffer
->Xmin
- destX
);
158 destX
= ctx
->DrawBuffer
->Xmin
;
160 if (destX
+ drawWidth
> ctx
->DrawBuffer
->Xmax
)
161 drawWidth
-= (destX
+ drawWidth
- ctx
->DrawBuffer
->Xmax
- 1);
165 /* vertical clipping */
166 if (destY
< ctx
->DrawBuffer
->Ymin
) {
167 skipRows
+= (ctx
->DrawBuffer
->Ymin
- destY
);
168 drawHeight
-= (ctx
->DrawBuffer
->Ymin
- destY
);
169 destY
= ctx
->DrawBuffer
->Ymin
;
171 if (destY
+ drawHeight
> ctx
->DrawBuffer
->Ymax
)
172 drawHeight
-= (destY
+ drawHeight
- ctx
->DrawBuffer
->Ymax
- 1);
176 zoomY0
= 0; /* not used - silence compiler warning */
179 /* setup array of fragment Z value to pass to zoom function */
180 GLdepth z
= (GLdepth
) (ctx
->Current
.RasterPos
[2] * ctx
->Visual
->DepthMaxF
);
182 assert(drawWidth
< MAX_WIDTH
);
183 for (i
=0; i
<drawWidth
; i
++)
186 /* save Y value of first row */
187 zoomY0
= (GLint
) (ctx
->Current
.RasterPos
[1] + 0.5F
);
193 * The window region at (destX, destY) of size (drawWidth, drawHeight)
194 * will be written to.
195 * We'll take pixel data from buffer pointed to by "pixels" but we'll
196 * skip "skipRows" rows and skip "skipPixels" pixels/row.
199 if (format
==GL_RGBA
&& type
==GL_UNSIGNED_BYTE
) {
200 if (ctx
->Visual
->RGBAflag
) {
201 GLubyte
*src
= (GLubyte
*) pixels
202 + (skipRows
* rowLength
+ skipPixels
) * 4;
203 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
206 for (row
=0; row
<drawHeight
; row
++) {
207 (*ctx
->Driver
.WriteRGBASpan
)(ctx
, drawWidth
, destX
, destY
,
209 src
+= rowLength
* 4;
216 for (row
=0; row
<drawHeight
; row
++) {
217 gl_write_zoomed_rgba_span(ctx
, drawWidth
, destX
, destY
,
218 zSpan
, (void *) src
, zoomY0
);
219 src
+= rowLength
* 4;
226 else if (format
==GL_RGB
&& type
==GL_UNSIGNED_BYTE
) {
227 if (ctx
->Visual
->RGBAflag
) {
228 GLubyte
*src
= (GLubyte
*) pixels
229 + (skipRows
* rowLength
+ skipPixels
) * 3;
230 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
232 for (row
=0; row
<drawHeight
; row
++) {
233 (*ctx
->Driver
.WriteRGBSpan
)(ctx
, drawWidth
, destX
, destY
,
235 src
+= rowLength
* 3;
242 for (row
=0; row
<drawHeight
; row
++) {
243 gl_write_zoomed_rgb_span(ctx
, drawWidth
, destX
, destY
,
244 zSpan
, (void *) src
, zoomY0
);
245 src
+= rowLength
* 3;
252 else if (format
==GL_LUMINANCE
&& type
==GL_UNSIGNED_BYTE
) {
253 if (ctx
->Visual
->RGBAflag
) {
254 GLubyte
*src
= (GLubyte
*) pixels
255 + (skipRows
* rowLength
+ skipPixels
);
256 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
259 assert(drawWidth
< MAX_WIDTH
);
260 for (row
=0; row
<drawHeight
; row
++) {
262 for (i
=0;i
<drawWidth
;i
++) {
267 (*ctx
->Driver
.WriteRGBSpan
)(ctx
, drawWidth
, destX
, destY
,
276 assert(drawWidth
< MAX_WIDTH
);
277 for (row
=0; row
<drawHeight
; row
++) {
279 for (i
=0;i
<drawWidth
;i
++) {
284 gl_write_zoomed_rgb_span(ctx
, drawWidth
, destX
, destY
,
285 zSpan
, (void *) rgb
, zoomY0
);
293 else if (format
==GL_LUMINANCE_ALPHA
&& type
==GL_UNSIGNED_BYTE
) {
294 if (ctx
->Visual
->RGBAflag
) {
295 GLubyte
*src
= (GLubyte
*) pixels
296 + (skipRows
* rowLength
+ skipPixels
)*2;
297 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
300 assert(drawWidth
< MAX_WIDTH
);
301 for (row
=0; row
<drawHeight
; row
++) {
304 for (i
=0;i
<drawWidth
;i
++) {
310 (*ctx
->Driver
.WriteRGBASpan
)(ctx
, drawWidth
, destX
, destY
,
311 (void *) rgba
, NULL
);
319 assert(drawWidth
< MAX_WIDTH
);
320 for (row
=0; row
<drawHeight
; row
++) {
323 for (i
=0;i
<drawWidth
;i
++) {
329 gl_write_zoomed_rgba_span(ctx
, drawWidth
, destX
, destY
,
330 zSpan
, (void *) rgba
, zoomY0
);
338 else if (format
==GL_COLOR_INDEX
&& type
==GL_UNSIGNED_BYTE
) {
339 GLubyte
*src
= (GLubyte
*) pixels
+ skipRows
* rowLength
+ skipPixels
;
340 if (ctx
->Visual
->RGBAflag
) {
341 /* convert CI data to RGBA */
342 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
345 for (row
=0; row
<drawHeight
; row
++) {
346 assert(drawWidth
< MAX_WIDTH
);
347 _mesa_map_ci8_to_rgba(ctx
, drawWidth
, src
, rgba
);
348 (*ctx
->Driver
.WriteRGBASpan
)(ctx
, drawWidth
, destX
, destY
,
349 (const GLubyte (*)[4])rgba
,
359 for (row
=0; row
<drawHeight
; row
++) {
360 assert(drawWidth
< MAX_WIDTH
);
361 _mesa_map_ci8_to_rgba(ctx
, drawWidth
, src
, rgba
);
362 gl_write_zoomed_rgba_span(ctx
, drawWidth
, destX
, destY
,
363 zSpan
, (void *) rgba
, zoomY0
);
371 /* write CI data to CI frame buffer */
373 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
375 for (row
=0; row
<drawHeight
; row
++) {
376 (*ctx
->Driver
.WriteCI8Span
)(ctx
, drawWidth
, destX
, destY
,
390 /* can't handle this pixel format and/or data type here */
395 /* can't do a simple draw, have to use slow path */
402 * Do glDrawPixels of index pixels.
405 draw_index_pixels( GLcontext
*ctx
, GLint x
, GLint y
,
406 GLsizei width
, GLsizei height
,
407 GLenum type
, const GLvoid
*pixels
)
409 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!=1.0 || ctx
->Pixel
.ZoomY
!=1.0;
410 const GLint desty
= y
;
411 GLint row
, drawWidth
;
412 GLdepth zspan
[MAX_WIDTH
];
414 drawWidth
= (width
> MAX_WIDTH
) ? MAX_WIDTH
: width
;
416 /* Fragment depth values */
417 if (ctx
->Depth
.Test
|| ctx
->Fog
.Enabled
) {
418 GLdepth zval
= (GLdepth
) (ctx
->Current
.RasterPos
[2] * ctx
->Visual
->DepthMaxF
);
420 for (i
= 0; i
< drawWidth
; i
++) {
428 for (row
= 0; row
< height
; row
++, y
++) {
429 GLuint indexes
[MAX_WIDTH
];
430 const GLvoid
*source
= _mesa_image_address(&ctx
->Unpack
,
431 pixels
, width
, height
, GL_COLOR_INDEX
, type
, 0, row
, 0);
432 _mesa_unpack_index_span(ctx
, drawWidth
, GL_UNSIGNED_INT
, indexes
,
433 type
, source
, &ctx
->Unpack
, GL_TRUE
);
435 gl_write_zoomed_index_span(ctx
, drawWidth
, x
, y
, zspan
, indexes
, desty
);
438 gl_write_index_span(ctx
, drawWidth
, x
, y
, zspan
, indexes
, GL_BITMAP
);
446 * Do glDrawPixels of stencil image. The image datatype may either
447 * be GLubyte or GLbitmap.
450 draw_stencil_pixels( GLcontext
*ctx
, GLint x
, GLint y
,
451 GLsizei width
, GLsizei height
,
452 GLenum type
, const GLvoid
*pixels
)
454 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!=1.0 || ctx
->Pixel
.ZoomY
!=1.0;
455 const GLboolean shift_or_offset
= ctx
->Pixel
.IndexShift
|| ctx
->Pixel
.IndexOffset
;
456 const GLint desty
= y
;
457 GLint row
, drawWidth
;
459 if (type
!= GL_BYTE
&&
460 type
!= GL_UNSIGNED_BYTE
&&
462 type
!= GL_UNSIGNED_SHORT
&&
464 type
!= GL_UNSIGNED_INT
&&
467 gl_error( ctx
, GL_INVALID_ENUM
, "glDrawPixels(stencil type)");
471 drawWidth
= (width
> MAX_WIDTH
) ? MAX_WIDTH
: width
;
473 for (row
= 0; row
< height
; row
++, y
++) {
474 GLstencil values
[MAX_WIDTH
];
475 GLenum destType
= (sizeof(GLstencil
) == sizeof(GLubyte
))
476 ? GL_UNSIGNED_BYTE
: GL_UNSIGNED_SHORT
;
477 const GLvoid
*source
= _mesa_image_address(&ctx
->Unpack
,
478 pixels
, width
, height
, GL_COLOR_INDEX
, type
, 0, row
, 0);
479 _mesa_unpack_index_span(ctx
, drawWidth
, destType
, values
,
480 type
, source
, &ctx
->Unpack
, GL_FALSE
);
481 if (shift_or_offset
) {
482 _mesa_shift_and_offset_stencil( ctx
, drawWidth
, values
);
484 if (ctx
->Pixel
.MapStencilFlag
) {
485 _mesa_map_stencil( ctx
, drawWidth
, values
);
489 gl_write_zoomed_stencil_span( ctx
, (GLuint
) drawWidth
, x
, y
,
493 _mesa_write_stencil_span( ctx
, (GLuint
) drawWidth
, x
, y
, values
);
501 * Do a glDrawPixels of depth values.
504 draw_depth_pixels( GLcontext
*ctx
, GLint x
, GLint y
,
505 GLsizei width
, GLsizei height
,
506 GLenum type
, const GLvoid
*pixels
)
508 const GLboolean bias_or_scale
= ctx
->Pixel
.DepthBias
!=0.0 || ctx
->Pixel
.DepthScale
!=1.0;
509 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!=1.0 || ctx
->Pixel
.ZoomY
!=1.0;
510 const GLint desty
= y
;
511 GLubyte rgba
[MAX_WIDTH
][4];
512 GLuint ispan
[MAX_WIDTH
];
513 GLint drawWidth
= (width
> MAX_WIDTH
) ? MAX_WIDTH
: width
;
515 if (type
!= GL_UNSIGNED_BYTE
516 && type
!= GL_UNSIGNED_BYTE
517 && type
!= GL_UNSIGNED_SHORT
518 && type
!= GL_UNSIGNED_SHORT
519 && type
!= GL_UNSIGNED_INT
520 && type
!= GL_UNSIGNED_INT
521 && type
!= GL_FLOAT
) {
522 gl_error(ctx
, GL_INVALID_ENUM
, "glDrawPixels(type)");
526 /* Colors or indexes */
527 if (ctx
->Visual
->RGBAflag
) {
528 GLint r
= (GLint
) (ctx
->Current
.RasterColor
[0] * 255.0F
);
529 GLint g
= (GLint
) (ctx
->Current
.RasterColor
[1] * 255.0F
);
530 GLint b
= (GLint
) (ctx
->Current
.RasterColor
[2] * 255.0F
);
531 GLint a
= (GLint
) (ctx
->Current
.RasterColor
[3] * 255.0F
);
533 for (i
= 0; i
< drawWidth
; i
++) {
542 for (i
= 0; i
< drawWidth
; i
++) {
543 ispan
[i
] = ctx
->Current
.RasterIndex
;
547 if (type
==GL_UNSIGNED_SHORT
&& sizeof(GLdepth
)==sizeof(GLushort
)
548 && !bias_or_scale
&& !zoom
&& ctx
->Visual
->RGBAflag
) {
549 /* Special case: directly write 16-bit depth values */
551 for (row
= 0; row
< height
; row
++, y
++) {
552 GLdepth zspan
[MAX_WIDTH
];
553 const GLushort
*zptr
= _mesa_image_address(&ctx
->Unpack
,
554 pixels
, width
, height
, GL_DEPTH_COMPONENT
, type
, 0, row
, 0);
556 for (i
= 0; i
< width
; i
++)
558 gl_write_rgba_span( ctx
, width
, x
, y
, zspan
, rgba
, GL_BITMAP
);
561 else if (type
==GL_UNSIGNED_INT
&& ctx
->Visual
->DepthBits
== 32
562 && !bias_or_scale
&& !zoom
&& ctx
->Visual
->RGBAflag
) {
563 /* Special case: directly write 32-bit depth values */
565 for (row
= 0; row
< height
; row
++, y
++) {
566 const GLuint
*zptr
= _mesa_image_address(&ctx
->Unpack
,
567 pixels
, width
, height
, GL_DEPTH_COMPONENT
, type
, 0, row
, 0);
568 gl_write_rgba_span( ctx
, width
, x
, y
, zptr
, rgba
, GL_BITMAP
);
574 for (row
= 0; row
< height
; row
++, y
++) {
575 GLdepth zspan
[MAX_WIDTH
];
576 const GLvoid
*src
= _mesa_image_address(&ctx
->Unpack
,
577 pixels
, width
, height
, GL_DEPTH_COMPONENT
, type
, 0, row
, 0);
578 _mesa_unpack_depth_span( ctx
, drawWidth
, zspan
, type
, src
,
579 &ctx
->Unpack
, GL_TRUE
);
580 if (ctx
->Visual
->RGBAflag
) {
582 gl_write_zoomed_rgba_span(ctx
, width
, x
, y
, zspan
,
583 (const GLubyte (*)[4])rgba
, desty
);
586 gl_write_rgba_span(ctx
, width
, x
, y
, zspan
, rgba
, GL_BITMAP
);
591 gl_write_zoomed_index_span(ctx
, width
, x
, y
, zspan
,
595 gl_write_index_span(ctx
, width
, x
, y
, zspan
, ispan
, GL_BITMAP
);
605 * Do glDrawPixels of RGBA pixels.
608 draw_rgba_pixels( GLcontext
*ctx
, GLint x
, GLint y
,
609 GLsizei width
, GLsizei height
,
610 GLenum format
, GLenum type
, const GLvoid
*pixels
)
612 const struct gl_pixelstore_attrib
*unpack
= &ctx
->Unpack
;
613 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!=1.0 || ctx
->Pixel
.ZoomY
!=1.0;
614 const GLint desty
= y
;
615 GLdepth zspan
[MAX_WIDTH
];
618 /* Try an optimized glDrawPixels first */
619 if (simple_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, pixels
))
622 /* Fragment depth values */
623 if (ctx
->Depth
.Test
|| ctx
->Fog
.Enabled
) {
624 /* fill in array of z values */
625 GLdepth z
= (GLdepth
) (ctx
->Current
.RasterPos
[2] * ctx
->Visual
->DepthMaxF
);
627 for (i
=0;i
<width
;i
++) {
633 if (ctx
->RasterMask
== 0 && !zoom
635 && x
+ width
<= ctx
->DrawBuffer
->Width
636 && y
+ height
<= ctx
->DrawBuffer
->Height
) {
640 quickDraw
= GL_FALSE
;
647 GLubyte rgba
[MAX_WIDTH
][4];
649 if (width
> MAX_WIDTH
)
651 for (row
= 0; row
< height
; row
++, y
++) {
652 const GLvoid
*source
= _mesa_image_address(unpack
,
653 pixels
, width
, height
, format
, type
, 0, row
, 0);
654 _mesa_unpack_ubyte_color_span(ctx
, width
, GL_RGBA
, (void*) rgba
,
655 format
, type
, source
, unpack
, GL_TRUE
);
656 if (ctx
->Pixel
.MinMaxEnabled
&& ctx
->MinMax
.Sink
)
659 if (ctx
->Texture
.ReallyEnabled
&& ctx
->Pixel
.PixelTextureEnabled
) {
660 GLfloat s
[MAX_WIDTH
], t
[MAX_WIDTH
], r
[MAX_WIDTH
], q
[MAX_WIDTH
];
662 /* XXX not sure how multitexture is supposed to work here */
663 for (unit
= 0; unit
< MAX_TEXTURE_UNITS
; unit
++) {
664 _mesa_pixeltexgen(ctx
, width
, (const GLubyte (*)[4]) rgba
,
666 gl_texture_pixels(ctx
, unit
, width
, s
, t
, r
, NULL
, rgba
);
671 (*ctx
->Driver
.WriteRGBASpan
)( ctx
, width
, x
, y
,
672 (CONST
GLubyte (*)[]) rgba
, NULL
);
675 gl_write_zoomed_rgba_span( ctx
, width
, x
, y
, zspan
,
676 (CONST
GLubyte (*)[]) rgba
, desty
);
679 gl_write_rgba_span( ctx
, (GLuint
) width
, x
, y
, zspan
, rgba
, GL_BITMAP
);
688 * Execute glDrawPixels
691 _mesa_DrawPixels( GLsizei width
, GLsizei height
,
692 GLenum format
, GLenum type
, const GLvoid
*pixels
)
694 GET_CURRENT_CONTEXT(ctx
);
695 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glDrawPixels");
697 if (ctx
->RenderMode
==GL_RENDER
) {
699 if (!pixels
|| !ctx
->Current
.RasterPosValid
) {
704 gl_update_state(ctx
);
707 x
= (GLint
) (ctx
->Current
.RasterPos
[0] + 0.5F
);
708 y
= (GLint
) (ctx
->Current
.RasterPos
[1] + 0.5F
);
710 ctx
->OcclusionResult
= GL_TRUE
;
712 /* see if device driver can do the drawpix */
713 if (ctx
->Driver
.DrawPixels
714 && (*ctx
->Driver
.DrawPixels
)(ctx
, x
, y
, width
, height
, format
, type
,
715 &ctx
->Unpack
, pixels
)) {
720 case GL_STENCIL_INDEX
:
721 draw_stencil_pixels( ctx
, x
, y
, width
, height
, type
, pixels
);
723 case GL_DEPTH_COMPONENT
:
724 draw_depth_pixels( ctx
, x
, y
, width
, height
, type
, pixels
);
727 if (ctx
->Visual
->RGBAflag
)
728 draw_rgba_pixels(ctx
, x
,y
, width
, height
, format
, type
, pixels
);
730 draw_index_pixels(ctx
, x
, y
, width
, height
, type
, pixels
);
737 case GL_LUMINANCE_ALPHA
:
743 draw_rgba_pixels(ctx
, x
, y
, width
, height
, format
, type
, pixels
);
746 gl_error( ctx
, GL_INVALID_ENUM
, "glDrawPixels(format)" );
750 else if (ctx
->RenderMode
==GL_FEEDBACK
) {
751 if (ctx
->Current
.RasterPosValid
) {
753 GLfloat texcoord
[4], invq
;
754 UBYTE_RGBA_TO_FLOAT_RGBA(color
, ctx
->Current
.ByteColor
);
755 invq
= 1.0F
/ ctx
->Current
.Texcoord
[0][3];
756 texcoord
[0] = ctx
->Current
.Texcoord
[0][0] * invq
;
757 texcoord
[1] = ctx
->Current
.Texcoord
[0][1] * invq
;
758 texcoord
[2] = ctx
->Current
.Texcoord
[0][2] * invq
;
759 texcoord
[3] = ctx
->Current
.Texcoord
[0][3];
760 FEEDBACK_TOKEN( ctx
, (GLfloat
) (GLint
) GL_DRAW_PIXEL_TOKEN
);
761 gl_feedback_vertex( ctx
,
762 ctx
->Current
.RasterPos
,
763 color
, ctx
->Current
.Index
, texcoord
);
766 else if (ctx
->RenderMode
==GL_SELECT
) {
767 if (ctx
->Current
.RasterPosValid
) {
768 gl_update_hitflag( ctx
, ctx
->Current
.RasterPos
[2] );