3520fd506ac6a1a9812c490dd7f3d3219f2a39f0
1 /* $Id: s_zoom.c,v 1.1 2000/10/31 18:00:05 keithw 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.
31 #include "s_stencil.h"
37 * Write a span of pixels to the frame buffer while applying a pixel zoom.
38 * This is only used by glDrawPixels and glCopyPixels.
39 * Input: n - number of pixels in input row
40 * x, y - destination of the span
41 * z - depth values for the span
42 * red, green, blue, alpha - array of colors
43 * y0 - location of first row in the image we're drawing.
46 gl_write_zoomed_rgba_span( GLcontext
*ctx
,
47 GLuint n
, GLint x
, GLint y
, const GLdepth z
[],
49 CONST GLchan rgba
[][4], GLint y0
)
54 GLchan zrgba
[MAX_WIDTH
][4]; /* zoomed pixel colors */
55 GLdepth zdepth
[MAX_WIDTH
]; /* zoomed depth values */
56 GLfixed zfog
[MAX_WIDTH
]; /* zoomed fog values */
57 GLint maxwidth
= MIN2( ctx
->DrawBuffer
->Width
, MAX_WIDTH
);
58 const GLuint
*srcRGBA32
= (const GLuint
*) rgba
;
59 GLuint
*dstRGBA32
= (GLuint
*) zrgba
;
61 /* compute width of output row */
62 m
= (GLint
) ABSF( n
* ctx
->Pixel
.ZoomX
);
66 if (ctx
->Pixel
.ZoomX
<0.0) {
67 /* adjust x coordinate for left/right mirroring */
71 /* compute which rows to draw */
73 r0
= y0
+ (GLint
) (row
* ctx
->Pixel
.ZoomY
);
74 r1
= y0
+ (GLint
) ((row
+1) * ctx
->Pixel
.ZoomY
);
84 /* return early if r0...r1 is above or below window */
89 if (r0
>=ctx
->DrawBuffer
->Height
&& r1
>=ctx
->DrawBuffer
->Height
) {
94 /* check if left edge is outside window */
100 /* make sure span isn't too long or short */
108 assert( m
<= MAX_WIDTH
);
110 /* zoom the span horizontally */
111 if (ctx
->Pixel
.ZoomX
==-1.0F
) {
114 i
= n
- (j
+skipcol
) - 1;
115 dstRGBA32
[j
] = srcRGBA32
[i
];
118 if (fog
&& ctx
->Fog
.Enabled
) {
120 i
= n
- (j
+skipcol
) - 1;
126 GLfloat xscale
= 1.0F
/ ctx
->Pixel
.ZoomX
;
128 i
= (GLint
) ((j
+skipcol
) * xscale
);
129 if (i
<0) i
= n
+ i
- 1;
130 dstRGBA32
[j
] = srcRGBA32
[i
];
133 if (fog
&& ctx
->Fog
.Enabled
) {
135 i
= (GLint
) ((j
+skipcol
) * xscale
);
136 if (i
<0) i
= n
+ i
- 1;
143 for (r
=r0
; r
<r1
; r
++) {
144 gl_write_rgba_span( ctx
, m
, x
+skipcol
, r
, zdepth
,
153 gl_write_zoomed_rgb_span( GLcontext
*ctx
,
154 GLuint n
, GLint x
, GLint y
, const GLdepth z
[],
156 CONST GLchan rgb
[][3], GLint y0
)
159 GLint r0
, r1
, row
, r
;
161 GLchan zrgba
[MAX_WIDTH
][4]; /* zoomed pixel colors */
162 GLdepth zdepth
[MAX_WIDTH
]; /* zoomed depth values */
163 GLfixed zfog
[MAX_WIDTH
]; /* zoomed fog values */
164 GLint maxwidth
= MIN2( ctx
->DrawBuffer
->Width
, MAX_WIDTH
);
166 /* compute width of output row */
167 m
= (GLint
) ABSF( n
* ctx
->Pixel
.ZoomX
);
171 if (ctx
->Pixel
.ZoomX
<0.0) {
172 /* adjust x coordinate for left/right mirroring */
176 /* compute which rows to draw */
178 r0
= y0
+ (GLint
) (row
* ctx
->Pixel
.ZoomY
);
179 r1
= y0
+ (GLint
) ((row
+1) * ctx
->Pixel
.ZoomY
);
189 /* return early if r0...r1 is above or below window */
194 if (r0
>=ctx
->DrawBuffer
->Height
&& r1
>=ctx
->DrawBuffer
->Height
) {
199 /* check if left edge is outside window */
205 /* make sure span isn't too long or short */
213 assert( m
<= MAX_WIDTH
);
215 /* zoom the span horizontally */
216 if (ctx
->Pixel
.ZoomX
==-1.0F
) {
219 i
= n
- (j
+skipcol
) - 1;
220 zrgba
[j
][0] = rgb
[i
][0];
221 zrgba
[j
][1] = rgb
[i
][1];
222 zrgba
[j
][2] = rgb
[i
][2];
223 zrgba
[j
][3] = CHAN_MAX
;
226 if (fog
&& ctx
->Fog
.Enabled
) {
228 i
= n
- (j
+skipcol
) - 1;
234 GLfloat xscale
= 1.0F
/ ctx
->Pixel
.ZoomX
;
236 i
= (GLint
) ((j
+skipcol
) * xscale
);
237 if (i
<0) i
= n
+ i
- 1;
238 zrgba
[j
][0] = rgb
[i
][0];
239 zrgba
[j
][1] = rgb
[i
][1];
240 zrgba
[j
][2] = rgb
[i
][2];
241 zrgba
[j
][3] = CHAN_MAX
;
244 if (fog
&& ctx
->Fog
.Enabled
) {
246 i
= (GLint
) ((j
+skipcol
) * xscale
);
247 if (i
<0) i
= n
+ i
- 1;
254 for (r
=r0
; r
<r1
; r
++) {
255 gl_write_rgba_span( ctx
, m
, x
+skipcol
, r
, zdepth
,
256 (fog
? zfog
: 0), zrgba
, GL_BITMAP
);
263 * As above, but write CI pixels.
266 gl_write_zoomed_index_span( GLcontext
*ctx
,
267 GLuint n
, GLint x
, GLint y
, const GLdepth z
[],
269 const GLuint indexes
[], GLint y0
)
272 GLint r0
, r1
, row
, r
;
274 GLuint zindexes
[MAX_WIDTH
]; /* zoomed color indexes */
275 GLdepth zdepth
[MAX_WIDTH
]; /* zoomed depth values */
276 GLfixed zfog
[MAX_WIDTH
]; /* zoomed fog values */
277 GLint maxwidth
= MIN2( ctx
->DrawBuffer
->Width
, MAX_WIDTH
);
279 /* compute width of output row */
280 m
= (GLint
) ABSF( n
* ctx
->Pixel
.ZoomX
);
284 if (ctx
->Pixel
.ZoomX
<0.0) {
285 /* adjust x coordinate for left/right mirroring */
289 /* compute which rows to draw */
291 r0
= y0
+ (GLint
) (row
* ctx
->Pixel
.ZoomY
);
292 r1
= y0
+ (GLint
) ((row
+1) * ctx
->Pixel
.ZoomY
);
302 /* return early if r0...r1 is above or below window */
307 if (r0
>=ctx
->DrawBuffer
->Height
&& r1
>=ctx
->DrawBuffer
->Height
) {
312 /* check if left edge is outside window */
318 /* make sure span isn't too long or short */
326 assert( m
<= MAX_WIDTH
);
328 /* zoom the span horizontally */
329 if (ctx
->Pixel
.ZoomX
==-1.0F
) {
332 i
= n
- (j
+skipcol
) - 1;
333 zindexes
[j
] = indexes
[i
];
336 if (fog
&& ctx
->Fog
.Enabled
) {
338 i
= n
- (j
+skipcol
) - 1;
344 GLfloat xscale
= 1.0F
/ ctx
->Pixel
.ZoomX
;
346 i
= (GLint
) ((j
+skipcol
) * xscale
);
347 if (i
<0) i
= n
+ i
- 1;
348 zindexes
[j
] = indexes
[i
];
351 if (fog
&& ctx
->Fog
.Enabled
) {
353 i
= (GLint
) ((j
+skipcol
) * xscale
);
354 if (i
<0) i
= n
+ i
- 1;
361 for (r
=r0
; r
<r1
; r
++) {
362 gl_write_index_span( ctx
, m
, x
+skipcol
, r
, zdepth
,
363 (fog
? zfog
: 0), zindexes
, GL_BITMAP
);
370 * As above, but write stencil values.
373 gl_write_zoomed_stencil_span( GLcontext
*ctx
,
374 GLuint n
, GLint x
, GLint y
,
375 const GLstencil stencil
[], GLint y0
)
378 GLint r0
, r1
, row
, r
;
380 GLstencil zstencil
[MAX_WIDTH
]; /* zoomed stencil values */
381 GLint maxwidth
= MIN2( ctx
->DrawBuffer
->Width
, MAX_WIDTH
);
383 /* compute width of output row */
384 m
= (GLint
) ABSF( n
* ctx
->Pixel
.ZoomX
);
388 if (ctx
->Pixel
.ZoomX
<0.0) {
389 /* adjust x coordinate for left/right mirroring */
393 /* compute which rows to draw */
395 r0
= y0
+ (GLint
) (row
* ctx
->Pixel
.ZoomY
);
396 r1
= y0
+ (GLint
) ((row
+1) * ctx
->Pixel
.ZoomY
);
406 /* return early if r0...r1 is above or below window */
411 if (r0
>=ctx
->DrawBuffer
->Height
&& r1
>=ctx
->DrawBuffer
->Height
) {
416 /* check if left edge is outside window */
422 /* make sure span isn't too long or short */
430 assert( m
<= MAX_WIDTH
);
432 /* zoom the span horizontally */
433 if (ctx
->Pixel
.ZoomX
==-1.0F
) {
436 i
= n
- (j
+skipcol
) - 1;
437 zstencil
[j
] = stencil
[i
];
441 GLfloat xscale
= 1.0F
/ ctx
->Pixel
.ZoomX
;
443 i
= (GLint
) ((j
+skipcol
) * xscale
);
444 if (i
<0) i
= n
+ i
- 1;
445 zstencil
[j
] = stencil
[i
];
450 for (r
=r0
; r
<r1
; r
++) {
451 _mesa_write_stencil_span( ctx
, m
, x
+skipcol
, r
, zstencil
);