home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / mesa3.1 / mesa-3_1.lha / src / logic.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-07  |  9.4 KB  |  402 lines

  1. /* $Id: logic.c,v 1.2.2.1 1999/12/12 18:30:47 keithw 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 <stdlib.h>
  36. #else
  37. #include "GL/xf86glx.h"
  38. #endif
  39. #include "alphabuf.h"
  40. #include "context.h"
  41. #include "logic.h"
  42. #include "macros.h"
  43. #include "pb.h"
  44. #include "span.h"
  45. #include "types.h"
  46. #endif
  47.  
  48.  
  49.  
  50. void gl_LogicOp( GLcontext *ctx, GLenum opcode )
  51. {
  52.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLogicOp");
  53.    switch (opcode) {
  54.       case GL_CLEAR:
  55.       case GL_SET:
  56.       case GL_COPY:
  57.       case GL_COPY_INVERTED:
  58.       case GL_NOOP:
  59.       case GL_INVERT:
  60.       case GL_AND:
  61.       case GL_NAND:
  62.       case GL_OR:
  63.       case GL_NOR:
  64.       case GL_XOR:
  65.       case GL_EQUIV:
  66.       case GL_AND_REVERSE:
  67.       case GL_AND_INVERTED:
  68.       case GL_OR_REVERSE:
  69.       case GL_OR_INVERTED:
  70.          ctx->Color.LogicOp = opcode;
  71.          ctx->NewState |= NEW_RASTER_OPS;
  72.      return;
  73.       default:
  74.          gl_error( ctx, GL_INVALID_ENUM, "glLogicOp" );
  75.      return;
  76.    }
  77.    
  78.    if (ctx->Driver.LogicOpcode)
  79.       ctx->Driver.LogicOpcode( ctx, opcode );
  80. }
  81.  
  82.  
  83.  
  84. /*
  85.  * Apply logic op to array of CI pixels.
  86.  */
  87. static void index_logicop( GLcontext *ctx, GLuint n,
  88.                            GLuint index[], const GLuint dest[],
  89.                            const GLubyte mask[] )
  90. {
  91.    GLuint i;
  92.    switch (ctx->Color.LogicOp) {
  93.       case GL_CLEAR:
  94.          for (i=0;i<n;i++) {
  95.         if (mask[i]) {
  96.            index[i] = 0;
  97.         }
  98.      }
  99.      break;
  100.       case GL_SET:
  101.          for (i=0;i<n;i++) {
  102.         if (mask[i]) {
  103.            index[i] = 1;
  104.         }
  105.      }
  106.      break;
  107.       case GL_COPY:
  108.      /* do nothing */
  109.      break;
  110.       case GL_COPY_INVERTED:
  111.          for (i=0;i<n;i++) {
  112.         if (mask[i]) {
  113.            index[i] = ~index[i];
  114.         }
  115.      }
  116.      break;
  117.       case GL_NOOP:
  118.          for (i=0;i<n;i++) {
  119.         if (mask[i]) {
  120.            index[i] = dest[i];
  121.         }
  122.      }
  123.      break;
  124.       case GL_INVERT:
  125.          for (i=0;i<n;i++) {
  126.         if (mask[i]) {
  127.            index[i] = ~dest[i];
  128.         }
  129.      }
  130.      break;
  131.       case GL_AND:
  132.          for (i=0;i<n;i++) {
  133.         if (mask[i]) {
  134.            index[i] &= dest[i];
  135.         }
  136.      }
  137.      break;
  138.       case GL_NAND:
  139.          for (i=0;i<n;i++) {
  140.         if (mask[i]) {
  141.            index[i] = ~(index[i] & dest[i]);
  142.         }
  143.      }
  144.      break;
  145.       case GL_OR:
  146.          for (i=0;i<n;i++) {
  147.         if (mask[i]) {
  148.            index[i] |= dest[i];
  149.         }
  150.      }
  151.      break;
  152.       case GL_NOR:
  153.          for (i=0;i<n;i++) {
  154.         if (mask[i]) {
  155.            index[i] = ~(index[i] | dest[i]);
  156.         }
  157.      }
  158.      break;
  159.       case GL_XOR:
  160.          for (i=0;i<n;i++) {
  161.         if (mask[i]) {
  162.            index[i] ^= dest[i];
  163.         }
  164.      }
  165.      break;
  166.       case GL_EQUIV:
  167.          for (i=0;i<n;i++) {
  168.         if (mask[i]) {
  169.            index[i] = ~(index[i] ^ dest[i]);
  170.         }
  171.      }
  172.      break;
  173.       case GL_AND_REVERSE:
  174.          for (i=0;i<n;i++) {
  175.         if (mask[i]) {
  176.            index[i] = index[i] & ~dest[i];
  177.         }
  178.      }
  179.      break;
  180.       case GL_AND_INVERTED:
  181.          for (i=0;i<n;i++) {
  182.         if (mask[i]) {
  183.            index[i] = ~index[i] & dest[i];
  184.         }
  185.      }
  186.      break;
  187.       case GL_OR_REVERSE:
  188.          for (i=0;i<n;i++) {
  189.         if (mask[i]) {
  190.            index[i] = index[i] | ~dest[i];
  191.         }
  192.      }
  193.      break;
  194.       case GL_OR_INVERTED:
  195.          for (i=0;i<n;i++) {
  196.         if (mask[i]) {
  197.            index[i] = ~index[i] | dest[i];
  198.         }
  199.      }
  200.      break;
  201.       default:
  202.      gl_error( ctx, GL_INVALID_ENUM, "gl_logic error" );
  203.    }
  204. }
  205.  
  206.  
  207.  
  208. /*
  209.  * Apply the current logic operator to a span of CI pixels.  This is only
  210.  * used if the device driver can't do logic ops.
  211.  */
  212. void gl_logicop_ci_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
  213.                          GLuint index[], const GLubyte mask[] )
  214. {
  215.    GLuint dest[MAX_WIDTH];
  216.    /* Read dest values from frame buffer */
  217.    (*ctx->Driver.ReadCI32Span)( ctx, n, x, y, dest );
  218.    index_logicop( ctx, n, index, dest, mask );
  219. }
  220.  
  221.  
  222.  
  223. /*
  224.  * Apply the current logic operator to an array of CI pixels.  This is only
  225.  * used if the device driver can't do logic ops.
  226.  */
  227. void gl_logicop_ci_pixels( GLcontext *ctx,
  228.                            GLuint n, const GLint x[], const GLint y[],
  229.                            GLuint index[], const GLubyte mask[] )
  230. {
  231.    GLuint dest[PB_SIZE];
  232.    /* Read dest values from frame buffer */
  233.    (*ctx->Driver.ReadCI32Pixels)( ctx, n, x, y, dest, mask );
  234.    index_logicop( ctx, n, index, dest, mask );
  235. }
  236.  
  237.  
  238.  
  239. /*
  240.  * Apply logic operator to rgba pixels.
  241.  * Input:  ctx - the context
  242.  *         n - number of pixels
  243.  *         mask - pixel mask array
  244.  * In/Out:  src - incoming pixels which will be modified
  245.  * Input:  dest - frame buffer values
  246.  *
  247.  * Note:  Since the R, G, B, and A channels are all treated the same we
  248.  * process them as 4-byte GLuints instead of four GLubytes.
  249.  */
  250. static void rgba_logicop( const GLcontext *ctx, GLuint n,
  251.                           const GLubyte mask[],
  252.                           GLuint src[], const GLuint dest[] )
  253. {
  254.    GLuint i;
  255.    switch (ctx->Color.LogicOp) {
  256.       case GL_CLEAR:
  257.          for (i=0;i<n;i++) {
  258.             if (mask[i]) {
  259.                src[i] = 0;
  260.             }
  261.          }
  262.          break;
  263.       case GL_SET:
  264.          for (i=0;i<n;i++) {
  265.             if (mask[i]) {
  266.                src[i] = 0xffffffff;
  267.             }
  268.          }
  269.          break;
  270.       case GL_COPY:
  271.          /* do nothing */
  272.          break;
  273.       case GL_COPY_INVERTED:
  274.          for (i=0;i<n;i++) {
  275.             if (mask[i]) {
  276.                src[i] = ~src[i];
  277.             }
  278.          }
  279.          break;
  280.       case GL_NOOP:
  281.          for (i=0;i<n;i++) {
  282.             if (mask[i]) {
  283.                src[i] = dest[i];
  284.             }
  285.          }
  286.          break;
  287.       case GL_INVERT:
  288.          for (i=0;i<n;i++) {
  289.             if (mask[i]) {
  290.                src[i] = ~dest[i];
  291.             }
  292.          }
  293.          break;
  294.       case GL_AND:
  295.          for (i=0;i<n;i++) {
  296.             if (mask[i]) {
  297.                src[i] &= dest[i];
  298.             }
  299.          }
  300.          break;
  301.       case GL_NAND:
  302.          for (i=0;i<n;i++) {
  303.             if (mask[i]) {
  304.                src[i] = ~(src[i] & src[i]);
  305.             }
  306.          }
  307.          break;
  308.       case GL_OR:
  309.          for (i=0;i<n;i++) {
  310.             if (mask[i]) {
  311.                src[i]|= dest[i];
  312.             }
  313.          }
  314.          break;
  315.       case GL_NOR:
  316.          for (i=0;i<n;i++) {
  317.             if (mask[i]) {
  318.                src[i] = ~(src[i] | dest[i]);
  319.             }
  320.          }
  321.          break;
  322.       case GL_XOR:
  323.          for (i=0;i<n;i++) {
  324.             if (mask[i]) {
  325.                src[i] ^= dest[i];
  326.             }
  327.          }
  328.          break;
  329.       case GL_EQUIV:
  330.          for (i=0;i<n;i++) {
  331.             if (mask[i]) {
  332.                src[i] = ~(src[i] ^ dest[i]);
  333.             }
  334.          }
  335.          break;
  336.       case GL_AND_REVERSE:
  337.          for (i=0;i<n;i++) {
  338.             if (mask[i]) {
  339.                src[i] = src[i] & ~dest[i];
  340.             }
  341.          }
  342.          break;
  343.       case GL_AND_INVERTED:
  344.          for (i=0;i<n;i++) {
  345.             if (mask[i]) {
  346.                src[i] = ~src[i] & dest[i];
  347.             }
  348.          }
  349.          break;
  350.       case GL_OR_REVERSE:
  351.          for (i=0;i<n;i++) {
  352.             if (mask[i]) {
  353.                src[i] = src[i] | ~dest[i];
  354.             }
  355.          }
  356.          break;
  357.       case GL_OR_INVERTED:
  358.          for (i=0;i<n;i++) {
  359.             if (mask[i]) {
  360.                src[i] = ~src[i] | dest[i];
  361.             }
  362.          }
  363.          break;
  364.       default:
  365.          /* should never happen */
  366.          gl_problem(ctx, "Bad function in rgba_logicop");
  367.    }
  368. }
  369.  
  370.  
  371.  
  372. /*
  373.  * Apply the current logic operator to a span of RGBA pixels.
  374.  * This is only used if the device driver can't do logic ops.
  375.  */
  376. void gl_logicop_rgba_span( GLcontext *ctx,
  377.                            GLuint n, GLint x, GLint y,
  378.                            GLubyte rgba[][4], const GLubyte mask[] )
  379. {
  380.    GLubyte dest[MAX_WIDTH][4];
  381.    gl_read_rgba_span( ctx, n, x, y, dest );
  382.    rgba_logicop( ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest );
  383. }
  384.  
  385.  
  386.  
  387. /*
  388.  * Apply the current logic operator to an array of RGBA pixels.
  389.  * This is only used if the device driver can't do logic ops.
  390.  */
  391. void gl_logicop_rgba_pixels( GLcontext *ctx,
  392.                              GLuint n, const GLint x[], const GLint y[],
  393.                              GLubyte rgba[][4], const GLubyte mask[] )
  394. {
  395.    GLubyte dest[PB_SIZE][4];
  396.    (*ctx->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
  397.    if (ctx->RasterMask & ALPHABUF_BIT) {
  398.       gl_read_alpha_pixels( ctx, n, x, y, dest, mask );
  399.    }
  400.    rgba_logicop( ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest );
  401. }
  402.