source: trunk/src/opengl/mesa/zoom.c@ 3721

Last change on this file since 3721 was 3598, checked in by jeroen, 25 years ago

* empty log message *

File size: 9.9 KB
Line 
1/* $Id: zoom.c,v 1.2 2000-05-23 20:41:08 jeroen Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 */
26
27
28
29
30
31#ifdef PC_HEADER
32#include "all.h"
33#else
34#include "glheader.h"
35#include "macros.h"
36#include "span.h"
37#include "stencil.h"
38#include "zoom.h"
39#endif
40
41
42
43/*
44 * Write a span of pixels to the frame buffer while applying a pixel zoom.
45 * This is only used by glDrawPixels and glCopyPixels.
46 * Input: n - number of pixels in input row
47 * x, y - destination of the span
48 * z - depth values for the span
49 * red, green, blue, alpha - array of colors
50 * y0 - location of first row in the image we're drawing.
51 */
52void
53gl_write_zoomed_rgba_span( GLcontext *ctx,
54 GLuint n, GLint x, GLint y, const GLdepth z[],
55 CONST GLubyte rgba[][4], GLint y0 )
56{
57 GLint m;
58 GLint r0, r1, row, r;
59 GLint i, j, skipcol;
60 GLubyte zrgba[MAX_WIDTH][4]; /* zoomed pixel colors */
61 GLdepth zdepth[MAX_WIDTH]; /* zoomed depth values */
62 GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
63 const GLuint *srcRGBA32 = (const GLuint *) rgba;
64 GLuint *dstRGBA32 = (GLuint *) zrgba;
65
66 /* compute width of output row */
67 m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
68 if (m==0) {
69 return;
70 }
71 if (ctx->Pixel.ZoomX<0.0) {
72 /* adjust x coordinate for left/right mirroring */
73 x = x - m;
74 }
75
76 /* compute which rows to draw */
77 row = y-y0;
78 r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
79 r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
80 if (r0==r1) {
81 return;
82 }
83 else if (r1<r0) {
84 GLint rtmp = r1;
85 r1 = r0;
86 r0 = rtmp;
87 }
88
89 /* return early if r0...r1 is above or below window */
90 if (r0<0 && r1<0) {
91 /* below window */
92 return;
93 }
94 if (r0>=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) {
95 /* above window */
96 return;
97 }
98
99 /* check if left edge is outside window */
100 skipcol = 0;
101 if (x<0) {
102 skipcol = -x;
103 m += x;
104 }
105 /* make sure span isn't too long or short */
106 if (m>maxwidth) {
107 m = maxwidth;
108 }
109 else if (m<=0) {
110 return;
111 }
112
113 ASSERT( m <= MAX_WIDTH );
114
115 /* zoom the span horizontally */
116 if (ctx->Pixel.ZoomX==-1.0F) {
117 /* n==m */
118 for (j=0;j<m;j++) {
119 i = n - (j+skipcol) - 1;
120 dstRGBA32[j] = srcRGBA32[i];
121 zdepth[j] = z[i];
122 }
123 }
124 else {
125 GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
126 for (j=0;j<m;j++) {
127 i = (GLint) ((j+skipcol) * xscale);
128 if (i<0) i = n + i - 1;
129 dstRGBA32[j] = srcRGBA32[i];
130 zdepth[j] = z[i];
131 }
132 }
133
134 /* write the span */
135 for (r=r0; r<r1; r++) {
136 gl_write_rgba_span( ctx, m, x+skipcol, r, zdepth, zrgba, GL_BITMAP );
137 }
138}
139
140
141
142void
143gl_write_zoomed_rgb_span( GLcontext *ctx,
144 GLuint n, GLint x, GLint y, const GLdepth z[],
145 CONST GLubyte rgb[][3], GLint y0 )
146{
147 GLint m;
148 GLint r0, r1, row, r;
149 GLint i, j, skipcol;
150 GLubyte zrgba[MAX_WIDTH][4]; /* zoomed pixel colors */
151 GLdepth zdepth[MAX_WIDTH]; /* zoomed depth values */
152 GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
153
154 /* compute width of output row */
155 m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
156 if (m==0) {
157 return;
158 }
159 if (ctx->Pixel.ZoomX<0.0) {
160 /* adjust x coordinate for left/right mirroring */
161 x = x - m;
162 }
163
164 /* compute which rows to draw */
165 row = y-y0;
166 r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
167 r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
168 if (r0==r1) {
169 return;
170 }
171 else if (r1<r0) {
172 GLint rtmp = r1;
173 r1 = r0;
174 r0 = rtmp;
175 }
176
177 /* return early if r0...r1 is above or below window */
178 if (r0<0 && r1<0) {
179 /* below window */
180 return;
181 }
182 if (r0>=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) {
183 /* above window */
184 return;
185 }
186
187 /* check if left edge is outside window */
188 skipcol = 0;
189 if (x<0) {
190 skipcol = -x;
191 m += x;
192 }
193 /* make sure span isn't too long or short */
194 if (m>maxwidth) {
195 m = maxwidth;
196 }
197 else if (m<=0) {
198 return;
199 }
200
201 ASSERT( m <= MAX_WIDTH );
202
203 /* zoom the span horizontally */
204 if (ctx->Pixel.ZoomX==-1.0F) {
205 /* n==m */
206 for (j=0;j<m;j++) {
207 i = n - (j+skipcol) - 1;
208 zrgba[j][0] = rgb[i][0];
209 zrgba[j][1] = rgb[i][1];
210 zrgba[j][2] = rgb[i][2];
211 zrgba[j][3] = 255;
212 zdepth[j] = z[i];
213 }
214 }
215 else {
216 GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
217 for (j=0;j<m;j++) {
218 i = (GLint) ((j+skipcol) * xscale);
219 if (i<0) i = n + i - 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] = 255;
224 zdepth[j] = z[i];
225 }
226 }
227
228 /* write the span */
229 for (r=r0; r<r1; r++) {
230 gl_write_rgba_span( ctx, m, x+skipcol, r, zdepth, zrgba, GL_BITMAP );
231 }
232}
233
234
235
236/*
237 * As above, but write CI pixels.
238 */
239void
240gl_write_zoomed_index_span( GLcontext *ctx,
241 GLuint n, GLint x, GLint y, const GLdepth z[],
242 const GLuint indexes[], GLint y0 )
243{
244 GLint m;
245 GLint r0, r1, row, r;
246 GLint i, j, skipcol;
247 GLuint zindexes[MAX_WIDTH]; /* zoomed color indexes */
248 GLdepth zdepth[MAX_WIDTH]; /* zoomed depth values */
249 GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
250
251 /* compute width of output row */
252 m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
253 if (m==0) {
254 return;
255 }
256 if (ctx->Pixel.ZoomX<0.0) {
257 /* adjust x coordinate for left/right mirroring */
258 x = x - m;
259 }
260
261 /* compute which rows to draw */
262 row = y-y0;
263 r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
264 r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
265 if (r0==r1) {
266 return;
267 }
268 else if (r1<r0) {
269 GLint rtmp = r1;
270 r1 = r0;
271 r0 = rtmp;
272 }
273
274 /* return early if r0...r1 is above or below window */
275 if (r0<0 && r1<0) {
276 /* below window */
277 return;
278 }
279 if (r0>=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) {
280 /* above window */
281 return;
282 }
283
284 /* check if left edge is outside window */
285 skipcol = 0;
286 if (x<0) {
287 skipcol = -x;
288 m += x;
289 }
290 /* make sure span isn't too long or short */
291 if (m>maxwidth) {
292 m = maxwidth;
293 }
294 else if (m<=0) {
295 return;
296 }
297
298 ASSERT( m <= MAX_WIDTH );
299
300 /* zoom the span horizontally */
301 if (ctx->Pixel.ZoomX==-1.0F) {
302 /* n==m */
303 for (j=0;j<m;j++) {
304 i = n - (j+skipcol) - 1;
305 zindexes[j] = indexes[i];
306 zdepth[j] = z[i];
307 }
308 }
309 else {
310 GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
311 for (j=0;j<m;j++) {
312 i = (GLint) ((j+skipcol) * xscale);
313 if (i<0) i = n + i - 1;
314 zindexes[j] = indexes[i];
315 zdepth[j] = z[i];
316 }
317 }
318
319 /* write the span */
320 for (r=r0; r<r1; r++) {
321 gl_write_index_span( ctx, m, x+skipcol, r, zdepth, zindexes, GL_BITMAP );
322 }
323}
324
325
326
327/*
328 * As above, but write stencil values.
329 */
330void
331gl_write_zoomed_stencil_span( GLcontext *ctx,
332 GLuint n, GLint x, GLint y,
333 const GLstencil stencil[], GLint y0 )
334{
335 GLint m;
336 GLint r0, r1, row, r;
337 GLint i, j, skipcol;
338 GLstencil zstencil[MAX_WIDTH]; /* zoomed stencil values */
339 GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
340
341 /* compute width of output row */
342 m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
343 if (m==0) {
344 return;
345 }
346 if (ctx->Pixel.ZoomX<0.0) {
347 /* adjust x coordinate for left/right mirroring */
348 x = x - m;
349 }
350
351 /* compute which rows to draw */
352 row = y-y0;
353 r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
354 r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
355 if (r0==r1) {
356 return;
357 }
358 else if (r1<r0) {
359 GLint rtmp = r1;
360 r1 = r0;
361 r0 = rtmp;
362 }
363
364 /* return early if r0...r1 is above or below window */
365 if (r0<0 && r1<0) {
366 /* below window */
367 return;
368 }
369 if (r0>=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) {
370 /* above window */
371 return;
372 }
373
374 /* check if left edge is outside window */
375 skipcol = 0;
376 if (x<0) {
377 skipcol = -x;
378 m += x;
379 }
380 /* make sure span isn't too long or short */
381 if (m>maxwidth) {
382 m = maxwidth;
383 }
384 else if (m<=0) {
385 return;
386 }
387
388 ASSERT( m <= MAX_WIDTH );
389
390 /* zoom the span horizontally */
391 if (ctx->Pixel.ZoomX==-1.0F) {
392 /* n==m */
393 for (j=0;j<m;j++) {
394 i = n - (j+skipcol) - 1;
395 zstencil[j] = stencil[i];
396 }
397 }
398 else {
399 GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
400 for (j=0;j<m;j++) {
401 i = (GLint) ((j+skipcol) * xscale);
402 if (i<0) i = n + i - 1;
403 zstencil[j] = stencil[i];
404 }
405 }
406
407 /* write the span */
408 for (r=r0; r<r1; r++) {
409 gl_write_stencil_span( ctx, m, x+skipcol, r, zstencil );
410 }
411}
Note: See TracBrowser for help on using the repository browser.