38de1a0434a49edf42b9ba9e0b0419f48fc4368f
1 /* $Id: drawpix.c,v 1.12 2000/02/08 23:42:14 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.
49 * Given the dest position, size and skipPixels and skipRows values
50 * for a glDrawPixels command, perform clipping of the image bounds
51 * so the result lies withing the context's buffer bounds.
52 * Return: GL_TRUE if image is ready for drawing
53 * GL_FALSE if image was completely clipped away (draw nothing)
56 _mesa_clip_pixelrect(const GLcontext
*ctx
,
57 GLint
*destX
, GLint
*destY
,
58 GLsizei
*width
, GLsizei
*height
,
59 GLint
*skipPixels
, GLint
*skipRows
)
61 const GLframebuffer
*buffer
= ctx
->DrawBuffer
;
64 if (*destX
< buffer
->Xmin
) {
65 *skipPixels
+= (buffer
->Xmin
- *destX
);
66 *width
-= (buffer
->Xmin
- *destX
);
67 *destX
= buffer
->Xmin
;
70 if (*destX
+ *width
> buffer
->Xmax
)
71 *width
-= (*destX
+ *width
- buffer
->Xmax
- 1);
77 if (*destY
< buffer
->Ymin
) {
78 *skipRows
+= (buffer
->Ymin
- *destY
);
79 *height
-= (buffer
->Ymin
- *destY
);
80 *destY
= buffer
->Ymin
;
83 if (*destY
+ *height
> buffer
->Ymax
)
84 *height
-= (*destY
+ *height
- buffer
->Ymax
- 1);
95 * Try to do a fast and simple RGB(a) glDrawPixels.
96 * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead
99 simple_DrawPixels( GLcontext
*ctx
, GLint x
, GLint y
,
100 GLsizei width
, GLsizei height
, GLenum format
, GLenum type
,
101 const GLvoid
*pixels
)
103 const struct gl_pixelstore_attrib
*unpack
= &ctx
->Unpack
;
104 GLubyte rgb
[MAX_WIDTH
][3];
105 GLubyte rgba
[MAX_WIDTH
][4];
107 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx
, "glDrawPixels",
111 if (!ctx
->Current
.RasterPosValid
) {
117 gl_update_state(ctx
);
120 /* see if device driver can do the drawpix */
121 if (ctx
->Driver
.DrawPixels
122 && (*ctx
->Driver
.DrawPixels
)(ctx
, x
, y
, width
, height
, format
, type
,
127 if ((ctx
->RasterMask
&(~(SCISSOR_BIT
|WINCLIP_BIT
)))==0
128 && ctx
->Pixel
.RedBias
==0.0 && ctx
->Pixel
.RedScale
==1.0
129 && ctx
->Pixel
.GreenBias
==0.0 && ctx
->Pixel
.GreenScale
==1.0
130 && ctx
->Pixel
.BlueBias
==0.0 && ctx
->Pixel
.BlueScale
==1.0
131 && ctx
->Pixel
.AlphaBias
==0.0 && ctx
->Pixel
.AlphaScale
==1.0
132 && ctx
->Pixel
.IndexShift
==0 && ctx
->Pixel
.IndexOffset
==0
133 && ctx
->Pixel
.MapColorFlag
==0
134 && unpack
->Alignment
==1
135 && !unpack
->SwapBytes
136 && !unpack
->LsbFirst
) {
140 GLint drawWidth
= width
; /* actual width drawn */
141 GLint drawHeight
= height
; /* actual height drawn */
142 GLint skipPixels
= unpack
->SkipPixels
;
143 GLint skipRows
= unpack
->SkipRows
;
145 GLdepth zSpan
[MAX_WIDTH
]; /* only used when zooming */
148 if (unpack
->RowLength
> 0)
149 rowLength
= unpack
->RowLength
;
153 /* If we're not using pixel zoom then do all clipping calculations
154 * now. Otherwise, we'll let the gl_write_zoomed_*_span() functions
155 * handle the clipping.
157 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
158 /* horizontal clipping */
159 if (destX
< ctx
->DrawBuffer
->Xmin
) {
160 skipPixels
+= (ctx
->DrawBuffer
->Xmin
- destX
);
161 drawWidth
-= (ctx
->DrawBuffer
->Xmin
- destX
);
162 destX
= ctx
->DrawBuffer
->Xmin
;
164 if (destX
+ drawWidth
> ctx
->DrawBuffer
->Xmax
)
165 drawWidth
-= (destX
+ drawWidth
- ctx
->DrawBuffer
->Xmax
- 1);
169 /* vertical clipping */
170 if (destY
< ctx
->DrawBuffer
->Ymin
) {
171 skipRows
+= (ctx
->DrawBuffer
->Ymin
- destY
);
172 drawHeight
-= (ctx
->DrawBuffer
->Ymin
- destY
);
173 destY
= ctx
->DrawBuffer
->Ymin
;
175 if (destY
+ drawHeight
> ctx
->DrawBuffer
->Ymax
)
176 drawHeight
-= (destY
+ drawHeight
- ctx
->DrawBuffer
->Ymax
- 1);
180 zoomY0
= 0; /* not used - silence compiler warning */
183 /* setup array of fragment Z value to pass to zoom function */
184 GLdepth z
= (GLdepth
) (ctx
->Current
.RasterPos
[2] * DEPTH_SCALE
);
186 assert(drawWidth
< MAX_WIDTH
);
187 for (i
=0; i
<drawWidth
; i
++)
190 /* save Y value of first row */
191 zoomY0
= (GLint
) (ctx
->Current
.RasterPos
[1] + 0.5F
);
197 * The window region at (destX, destY) of size (drawWidth, drawHeight)
198 * will be written to.
199 * We'll take pixel data from buffer pointed to by "pixels" but we'll
200 * skip "skipRows" rows and skip "skipPixels" pixels/row.
203 if (format
==GL_RGBA
&& type
==GL_UNSIGNED_BYTE
) {
204 if (ctx
->Visual
->RGBAflag
) {
205 GLubyte
*src
= (GLubyte
*) pixels
206 + (skipRows
* rowLength
+ skipPixels
) * 4;
207 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
210 for (row
=0; row
<drawHeight
; row
++) {
211 (*ctx
->Driver
.WriteRGBASpan
)(ctx
, drawWidth
, destX
, destY
,
213 src
+= rowLength
* 4;
220 for (row
=0; row
<drawHeight
; row
++) {
221 gl_write_zoomed_rgba_span(ctx
, drawWidth
, destX
, destY
,
222 zSpan
, (void *) src
, zoomY0
);
223 src
+= rowLength
* 4;
230 else if (format
==GL_RGB
&& type
==GL_UNSIGNED_BYTE
) {
231 if (ctx
->Visual
->RGBAflag
) {
232 GLubyte
*src
= (GLubyte
*) pixels
233 + (skipRows
* rowLength
+ skipPixels
) * 3;
234 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
236 for (row
=0; row
<drawHeight
; row
++) {
237 (*ctx
->Driver
.WriteRGBSpan
)(ctx
, drawWidth
, destX
, destY
,
239 src
+= rowLength
* 3;
246 for (row
=0; row
<drawHeight
; row
++) {
247 gl_write_zoomed_rgb_span(ctx
, drawWidth
, destX
, destY
,
248 zSpan
, (void *) src
, zoomY0
);
249 src
+= rowLength
* 3;
256 else if (format
==GL_LUMINANCE
&& type
==GL_UNSIGNED_BYTE
) {
257 if (ctx
->Visual
->RGBAflag
) {
258 GLubyte
*src
= (GLubyte
*) pixels
259 + (skipRows
* rowLength
+ skipPixels
);
260 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
263 assert(drawWidth
< MAX_WIDTH
);
264 for (row
=0; row
<drawHeight
; row
++) {
266 for (i
=0;i
<drawWidth
;i
++) {
271 (*ctx
->Driver
.WriteRGBSpan
)(ctx
, drawWidth
, destX
, destY
,
280 assert(drawWidth
< MAX_WIDTH
);
281 for (row
=0; row
<drawHeight
; row
++) {
283 for (i
=0;i
<drawWidth
;i
++) {
288 gl_write_zoomed_rgb_span(ctx
, drawWidth
, destX
, destY
,
289 zSpan
, (void *) rgb
, zoomY0
);
297 else if (format
==GL_LUMINANCE_ALPHA
&& type
==GL_UNSIGNED_BYTE
) {
298 if (ctx
->Visual
->RGBAflag
) {
299 GLubyte
*src
= (GLubyte
*) pixels
300 + (skipRows
* rowLength
+ skipPixels
)*2;
301 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
304 assert(drawWidth
< MAX_WIDTH
);
305 for (row
=0; row
<drawHeight
; row
++) {
308 for (i
=0;i
<drawWidth
;i
++) {
314 (*ctx
->Driver
.WriteRGBASpan
)(ctx
, drawWidth
, destX
, destY
,
315 (void *) rgba
, NULL
);
323 assert(drawWidth
< MAX_WIDTH
);
324 for (row
=0; row
<drawHeight
; row
++) {
327 for (i
=0;i
<drawWidth
;i
++) {
333 gl_write_zoomed_rgba_span(ctx
, drawWidth
, destX
, destY
,
334 zSpan
, (void *) rgba
, zoomY0
);
342 else if (format
==GL_COLOR_INDEX
&& type
==GL_UNSIGNED_BYTE
) {
343 GLubyte
*src
= (GLubyte
*) pixels
+ skipRows
* rowLength
+ skipPixels
;
344 if (ctx
->Visual
->RGBAflag
) {
345 /* convert CI data to RGBA */
346 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
349 for (row
=0; row
<drawHeight
; row
++) {
350 assert(drawWidth
< MAX_WIDTH
);
351 gl_map_ci8_to_rgba(ctx
, drawWidth
, src
, rgba
);
352 (*ctx
->Driver
.WriteRGBASpan
)(ctx
, drawWidth
, destX
, destY
,
353 (const GLubyte (*)[4])rgba
,
363 for (row
=0; row
<drawHeight
; row
++) {
364 assert(drawWidth
< MAX_WIDTH
);
365 gl_map_ci8_to_rgba(ctx
, drawWidth
, src
, rgba
);
366 gl_write_zoomed_rgba_span(ctx
, drawWidth
, destX
, destY
,
367 zSpan
, (void *) rgba
, zoomY0
);
375 /* write CI data to CI frame buffer */
377 if (ctx
->Pixel
.ZoomX
==1.0F
&& ctx
->Pixel
.ZoomY
==1.0F
) {
379 for (row
=0; row
<drawHeight
; row
++) {
380 (*ctx
->Driver
.WriteCI8Span
)(ctx
, drawWidth
, destX
, destY
,
394 /* can't handle this pixel format and/or data type here */
399 /* can't do a simple draw, have to use slow path */
406 * Do glDrawPixels of index pixels.
409 draw_index_pixels( GLcontext
*ctx
, GLint x
, GLint y
,
410 GLsizei width
, GLsizei height
,
411 GLenum type
, const GLvoid
*pixels
)
413 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!=1.0 || ctx
->Pixel
.ZoomY
!=1.0;
414 const GLint desty
= y
;
415 GLint row
, drawWidth
;
416 GLdepth zspan
[MAX_WIDTH
];
418 drawWidth
= (width
> MAX_WIDTH
) ? MAX_WIDTH
: width
;
420 /* Fragment depth values */
421 if (ctx
->Depth
.Test
|| ctx
->Fog
.Enabled
) {
422 GLdepth zval
= (GLdepth
) (ctx
->Current
.RasterPos
[2] * DEPTH_SCALE
);
424 for (i
= 0; i
< drawWidth
; i
++) {
432 for (row
= 0; row
< height
; row
++, y
++) {
433 GLuint indexes
[MAX_WIDTH
];
434 const GLvoid
*source
= gl_pixel_addr_in_image(&ctx
->Unpack
,
435 pixels
, width
, height
, GL_COLOR_INDEX
, type
, 0, row
, 0);
436 _mesa_unpack_index_span(ctx
, drawWidth
, GL_UNSIGNED_INT
, indexes
,
437 type
, source
, &ctx
->Unpack
, GL_TRUE
);
439 gl_write_zoomed_index_span(ctx
, drawWidth
, x
, y
, zspan
, indexes
, desty
);
442 gl_write_index_span(ctx
, drawWidth
, x
, y
, zspan
, indexes
, GL_BITMAP
);
450 * Do glDrawPixels of stencil image. The image datatype may either
451 * be GLubyte or GLbitmap.
454 draw_stencil_pixels( GLcontext
*ctx
, GLint x
, GLint y
,
455 GLsizei width
, GLsizei height
,
456 GLenum type
, const GLvoid
*pixels
)
458 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!=1.0 || ctx
->Pixel
.ZoomY
!=1.0;
459 const GLint desty
= y
;
460 GLint row
, drawWidth
;
462 if (type
!= GL_BYTE
&&
463 type
!= GL_UNSIGNED_BYTE
&&
465 type
!= GL_UNSIGNED_SHORT
&&
467 type
!= GL_UNSIGNED_INT
&&
470 gl_error( ctx
, GL_INVALID_ENUM
, "glDrawPixels(stencil type)");
474 drawWidth
= (width
> MAX_WIDTH
) ? MAX_WIDTH
: width
;
476 for (row
= 0; row
< height
; row
++, y
++) {
477 GLstencil values
[MAX_WIDTH
];
478 GLenum destType
= (sizeof(GLstencil
) == sizeof(GLubyte
))
479 ? GL_UNSIGNED_BYTE
: GL_UNSIGNED_SHORT
;
480 const GLvoid
*source
= gl_pixel_addr_in_image(&ctx
->Unpack
,
481 pixels
, width
, height
, GL_COLOR_INDEX
, type
, 0, row
, 0);
482 _mesa_unpack_index_span(ctx
, drawWidth
, destType
, values
,
483 type
, source
, &ctx
->Unpack
, GL_TRUE
);
486 gl_write_zoomed_stencil_span( ctx
, (GLuint
) drawWidth
, x
, y
,
490 gl_write_stencil_span( ctx
, (GLuint
) drawWidth
, x
, y
, values
);
498 * Do a glDrawPixels of depth values.
501 draw_depth_pixels( GLcontext
*ctx
, GLint x
, GLint y
,
502 GLsizei width
, GLsizei height
,
503 GLenum type
, const GLvoid
*pixels
)
505 const GLboolean bias_or_scale
= ctx
->Pixel
.DepthBias
!=0.0 || ctx
->Pixel
.DepthScale
!=1.0;
506 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!=1.0 || ctx
->Pixel
.ZoomY
!=1.0;
507 const GLint desty
= y
;
508 GLubyte rgba
[MAX_WIDTH
][4];
509 GLuint ispan
[MAX_WIDTH
];
510 GLint drawWidth
= (width
> MAX_WIDTH
) ? MAX_WIDTH
: width
;
512 if (type
!= GL_UNSIGNED_BYTE
513 && type
!= GL_UNSIGNED_BYTE
514 && type
!= GL_UNSIGNED_SHORT
515 && type
!= GL_UNSIGNED_SHORT
516 && type
!= GL_UNSIGNED_INT
517 && type
!= GL_UNSIGNED_INT
518 && type
!= GL_FLOAT
) {
519 gl_error(ctx
, GL_INVALID_ENUM
, "glDrawPixels(type)");
523 /* Colors or indexes */
524 if (ctx
->Visual
->RGBAflag
) {
525 GLint r
= (GLint
) (ctx
->Current
.RasterColor
[0] * 255.0F
);
526 GLint g
= (GLint
) (ctx
->Current
.RasterColor
[1] * 255.0F
);
527 GLint b
= (GLint
) (ctx
->Current
.RasterColor
[2] * 255.0F
);
528 GLint a
= (GLint
) (ctx
->Current
.RasterColor
[3] * 255.0F
);
530 for (i
= 0; i
< drawWidth
; i
++) {
539 for (i
= 0; i
< drawWidth
; i
++) {
540 ispan
[i
] = ctx
->Current
.RasterIndex
;
544 if (type
==GL_UNSIGNED_SHORT
&& sizeof(GLdepth
)==sizeof(GLushort
)
545 && !bias_or_scale
&& !zoom
&& ctx
->Visual
->RGBAflag
) {
546 /* Special case: directly write 16-bit depth values */
548 for (row
= 0; row
< height
; row
++, y
++) {
549 const GLdepth
*zptr
= gl_pixel_addr_in_image(&ctx
->Unpack
,
550 pixels
, width
, height
, GL_DEPTH_COMPONENT
, type
, 0, row
, 0);
551 gl_write_rgba_span( ctx
, width
, x
, y
, zptr
, rgba
, GL_BITMAP
);
554 else if (type
==GL_UNSIGNED_INT
&& sizeof(GLdepth
)==sizeof(GLuint
)
555 && !bias_or_scale
&& !zoom
&& ctx
->Visual
->RGBAflag
) {
556 /* Special case: directly write 32-bit depth values */
558 /* Compute shift value to scale 32-bit uints down to depth values. */
560 GLuint max
= MAX_DEPTH
;
561 while ((max
& 0x80000000) == 0) {
565 for (row
= 0; row
< height
; row
++, y
++) {
566 GLdepth zspan
[MAX_WIDTH
];
567 const GLdepth
*zptr
= gl_pixel_addr_in_image(&ctx
->Unpack
,
568 pixels
, width
, height
, GL_DEPTH_COMPONENT
, type
, 0, row
, 0);
569 for (i
=0;i
<width
;i
++) {
570 zspan
[i
] = zptr
[i
] >> shift
;
572 gl_write_rgba_span( ctx
, width
, x
, y
, zspan
, rgba
, GL_BITMAP
);
578 for (row
= 0; row
< height
; row
++, y
++) {
579 GLdepth zspan
[MAX_WIDTH
];
580 const GLvoid
*src
= gl_pixel_addr_in_image(&ctx
->Unpack
,
581 pixels
, width
, height
, GL_DEPTH_COMPONENT
, type
, 0, row
, 0);
582 _mesa_unpack_depth_span( ctx
, drawWidth
, zspan
, type
, src
,
583 &ctx
->Unpack
, GL_TRUE
);
584 if (ctx
->Visual
->RGBAflag
) {
586 gl_write_zoomed_rgba_span(ctx
, width
, x
, y
, zspan
,
587 (const GLubyte (*)[4])rgba
, desty
);
590 gl_write_rgba_span(ctx
, width
, x
, y
, zspan
, rgba
, GL_BITMAP
);
595 gl_write_zoomed_index_span(ctx
, width
, x
, y
, zspan
,
599 gl_write_index_span(ctx
, width
, x
, y
, zspan
, ispan
, GL_BITMAP
);
609 * Do glDrawPixels of RGBA pixels.
612 draw_rgba_pixels( GLcontext
*ctx
, GLint x
, GLint y
,
613 GLsizei width
, GLsizei height
,
614 GLenum format
, GLenum type
, const GLvoid
*pixels
)
616 const struct gl_pixelstore_attrib
*unpack
= &ctx
->Unpack
;
617 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!=1.0 || ctx
->Pixel
.ZoomY
!=1.0;
618 const GLint desty
= y
;
619 GLdepth zspan
[MAX_WIDTH
];
622 /* Try an optimized glDrawPixels first */
623 if (simple_DrawPixels(ctx
, x
, y
, width
, height
, format
, type
, pixels
))
626 /* Fragment depth values */
627 if (ctx
->Depth
.Test
|| ctx
->Fog
.Enabled
) {
628 /* fill in array of z values */
629 GLdepth z
= (GLdepth
) (ctx
->Current
.RasterPos
[2] * DEPTH_SCALE
);
631 for (i
=0;i
<width
;i
++) {
637 if (ctx
->RasterMask
== 0 && !zoom
639 && x
+ width
<= ctx
->DrawBuffer
->Width
640 && y
+ height
<= ctx
->DrawBuffer
->Height
) {
644 quickDraw
= GL_FALSE
;
651 GLubyte rgba
[MAX_WIDTH
][4];
653 if (width
> MAX_WIDTH
)
655 for (row
= 0; row
< height
; row
++, y
++) {
656 const GLvoid
*source
= gl_pixel_addr_in_image(unpack
,
657 pixels
, width
, height
, format
, type
, 0, row
, 0);
658 _mesa_unpack_ubyte_color_span(ctx
, width
, GL_RGBA
, (void*) rgba
,
659 format
, type
, source
, unpack
, GL_TRUE
);
662 (*ctx
->Driver
.WriteRGBASpan
)( ctx
, width
, x
, y
,
663 (CONST
GLubyte (*)[]) rgba
, NULL
);
666 gl_write_zoomed_rgba_span( ctx
, width
, x
, y
, zspan
,
667 (CONST
GLubyte (*)[]) rgba
, desty
);
670 gl_write_rgba_span( ctx
, (GLuint
) width
, x
, y
, zspan
, rgba
, GL_BITMAP
);
679 * Execute glDrawPixels
682 _mesa_DrawPixels( GLsizei width
, GLsizei height
,
683 GLenum format
, GLenum type
, const GLvoid
*pixels
)
685 GET_CURRENT_CONTEXT(ctx
);
686 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glDrawPixels");
688 if (ctx
->RenderMode
==GL_RENDER
) {
690 if (!pixels
|| !ctx
->Current
.RasterPosValid
) {
694 x
= (GLint
) (ctx
->Current
.RasterPos
[0] + 0.5F
);
695 y
= (GLint
) (ctx
->Current
.RasterPos
[1] + 0.5F
);
698 case GL_STENCIL_INDEX
:
699 draw_stencil_pixels( ctx
, x
, y
, width
, height
, type
, pixels
);
701 case GL_DEPTH_COMPONENT
:
702 draw_depth_pixels( ctx
, x
, y
, width
, height
, type
, pixels
);
705 if (ctx
->Visual
->RGBAflag
)
706 draw_rgba_pixels(ctx
, x
,y
, width
, height
, format
, type
, pixels
);
708 draw_index_pixels(ctx
, x
, y
, width
, height
, type
, pixels
);
715 case GL_LUMINANCE_ALPHA
:
721 draw_rgba_pixels(ctx
, x
, y
, width
, height
, format
, type
, pixels
);
724 gl_error( ctx
, GL_INVALID_ENUM
, "glDrawPixels(format)" );
728 else if (ctx
->RenderMode
==GL_FEEDBACK
) {
729 if (ctx
->Current
.RasterPosValid
) {
731 GLfloat texcoord
[4], invq
;
732 UBYTE_RGBA_TO_FLOAT_RGBA(color
, ctx
->Current
.ByteColor
);
733 invq
= 1.0F
/ ctx
->Current
.Texcoord
[0][3];
734 texcoord
[0] = ctx
->Current
.Texcoord
[0][0] * invq
;
735 texcoord
[1] = ctx
->Current
.Texcoord
[0][1] * invq
;
736 texcoord
[2] = ctx
->Current
.Texcoord
[0][2] * invq
;
737 texcoord
[3] = ctx
->Current
.Texcoord
[0][3];
738 FEEDBACK_TOKEN( ctx
, (GLfloat
) (GLint
) GL_DRAW_PIXEL_TOKEN
);
739 gl_feedback_vertex( ctx
,
740 ctx
->Current
.RasterPos
,
741 color
, ctx
->Current
.Index
, texcoord
);
744 else if (ctx
->RenderMode
==GL_SELECT
) {
745 if (ctx
->Current
.RasterPosValid
) {
746 gl_update_hitflag( ctx
, ctx
->Current
.RasterPos
[2] );