home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / zoom.c < prev    next >
C/C++ Source or Header  |  2000-01-07  |  10KB  |  416 lines

  1. /* $Id: zoom.c,v 1.4 1999/11/08 14:53:05 brianp 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.  */
  56. void
  57. gl_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.  
  146. void
  147. gl_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.  */
  243. void
  244. gl_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.  */
  334. void
  335. gl_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. }
  416.