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

Last change on this file since 3582 was 2938, checked in by sandervl, 25 years ago

created

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