home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / MesaDLL / buffers.cpp < prev    next >
C/C++ Source or Header  |  2002-12-14  |  15KB  |  477 lines

  1. /* $Id: buffers.c,v 1.42 2002/10/24 23:57:19 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  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. #include "glheader.h"
  29. #include "imports.h"
  30. #include "accum.h"
  31. #include "buffers.h"
  32. #include "colormac.h"
  33. #include "context.h"
  34. #include "depth.h"
  35. #include "enums.h"
  36. #include "macros.h"
  37. #include "stencil.h"
  38. #include "state.h"
  39. #include "mtypes.h"
  40.  
  41.  
  42.  
  43. void
  44. _mesa_ClearIndex( GLfloat c )
  45. {
  46.    GET_CURRENT_CONTEXT(ctx);
  47.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  48.  
  49.    if (ctx->Color.ClearIndex == (GLuint) c)
  50.       return;
  51.  
  52.    FLUSH_VERTICES(ctx, _NEW_COLOR);
  53.    ctx->Color.ClearIndex = (GLuint) c;
  54.  
  55.    if (!ctx->Visual.rgbMode && ctx->Driver.ClearIndex) {
  56.       /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */
  57.       (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex );
  58.    }
  59. }
  60.  
  61.  
  62.  
  63. void
  64. _mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
  65. {
  66.    GLfloat tmp[4];
  67.    GET_CURRENT_CONTEXT(ctx);
  68.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  69.  
  70.    tmp[0] = CLAMP(red,   0.0F, 1.0F);
  71.    tmp[1] = CLAMP(green, 0.0F, 1.0F);
  72.    tmp[2] = CLAMP(blue,  0.0F, 1.0F);
  73.    tmp[3] = CLAMP(alpha, 0.0F, 1.0F);
  74.  
  75.    if (TEST_EQ_4V(tmp, ctx->Color.ClearColor))
  76.       return; /* no change */
  77.  
  78.    FLUSH_VERTICES(ctx, _NEW_COLOR);
  79.    COPY_4V(ctx->Color.ClearColor, tmp);
  80.  
  81.    if (ctx->Visual.rgbMode && ctx->Driver.ClearColor) {
  82.       /* it's OK to call glClearColor in CI mode but it should be a NOP */
  83.       (*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColor);
  84.    }
  85. }
  86.  
  87.  
  88.  
  89. void
  90. _mesa_Clear( GLbitfield mask )
  91. {
  92.    GET_CURRENT_CONTEXT(ctx);
  93.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  94.  
  95.    if (MESA_VERBOSE & VERBOSE_API)
  96.       _mesa_debug(ctx, "glClear 0x%x\n", mask);
  97.  
  98.    if (mask & ~(GL_COLOR_BUFFER_BIT |
  99.                 GL_DEPTH_BUFFER_BIT |
  100.                 GL_STENCIL_BUFFER_BIT |
  101.                 GL_ACCUM_BUFFER_BIT)) {
  102.       /* invalid bit set */
  103.       _mesa_error( ctx, GL_INVALID_VALUE, "glClear(mask)");
  104.       return;
  105.    }
  106.  
  107.    if (ctx->NewState) {
  108.       _mesa_update_state( ctx );    /* update _Xmin, etc */
  109.    }
  110.  
  111.    if (ctx->RenderMode==GL_RENDER) {
  112.       const GLint x = ctx->DrawBuffer->_Xmin;
  113.       const GLint y = ctx->DrawBuffer->_Ymin;
  114.       const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
  115.       const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
  116.       GLbitfield ddMask;
  117.  
  118.       /* don't clear depth buffer if depth writing disabled */
  119.       if (!ctx->Depth.Mask)
  120.          mask &= ~GL_DEPTH_BUFFER_BIT;
  121.  
  122.       /* Build bitmask to send to driver Clear function */
  123.       ddMask = mask & (GL_DEPTH_BUFFER_BIT |
  124.                        GL_STENCIL_BUFFER_BIT |
  125.                        GL_ACCUM_BUFFER_BIT);
  126.       if (mask & GL_COLOR_BUFFER_BIT) {
  127.          ddMask |= ctx->Color._DrawDestMask;
  128.       }
  129.  
  130.       ASSERT(ctx->Driver.Clear);
  131.       ctx->Driver.Clear( ctx, ddMask, (GLboolean) !ctx->Scissor.Enabled,
  132.              x, y, width, height );
  133.    }
  134. }
  135.  
  136.  
  137. void
  138. _mesa_DrawBuffer( GLenum mode )
  139. {
  140.    GET_CURRENT_CONTEXT(ctx);
  141.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */
  142.  
  143.    if (MESA_VERBOSE & VERBOSE_API)
  144.       _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(mode));
  145.  
  146.    /*
  147.     * Do error checking and compute the _DrawDestMask bitfield.
  148.     */
  149.    switch (mode) {
  150.       case GL_RIGHT:
  151.          if (!ctx->Visual.stereoMode) {
  152.             _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  153.             return;}
  154.          if (ctx->Visual.doubleBufferMode)
  155.             ctx->Color._DrawDestMask = FRONT_RIGHT_BIT | BACK_RIGHT_BIT;
  156.          else
  157.             ctx->Color._DrawDestMask = FRONT_RIGHT_BIT;
  158.          break;
  159.       case GL_FRONT_RIGHT:
  160.          if (!ctx->Visual.stereoMode) {
  161.             _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  162.             return;
  163.          }
  164.          ctx->Color._DrawDestMask = FRONT_RIGHT_BIT;
  165.          break;
  166.       case GL_BACK_RIGHT:
  167.          if (!ctx->Visual.stereoMode || !ctx->Visual.doubleBufferMode) {
  168.             _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  169.             return;
  170.          }
  171.          ctx->Color._DrawDestMask = BACK_RIGHT_BIT;
  172.          break;
  173.       case GL_BACK_LEFT:
  174.          if (!ctx->Visual.doubleBufferMode) {
  175.             _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  176.             return;
  177.          }
  178.          ctx->Color._DrawDestMask = BACK_LEFT_BIT;
  179.          break;
  180.       case GL_FRONT_AND_BACK:
  181.          if (!ctx->Visual.doubleBufferMode) {
  182.             _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  183.             return;
  184.          }
  185.          if (ctx->Visual.stereoMode)
  186.             ctx->Color._DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT
  187.                                     | FRONT_RIGHT_BIT | BACK_RIGHT_BIT;
  188.          else
  189.             ctx->Color._DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT;
  190.          break;
  191.       case GL_BACK:
  192.          if (!ctx->Visual.doubleBufferMode) {
  193.             _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  194.             return;
  195.          }
  196.          if (ctx->Visual.stereoMode)
  197.             ctx->Color._DrawDestMask = BACK_LEFT_BIT | BACK_RIGHT_BIT;
  198.          else
  199.             ctx->Color._DrawDestMask = BACK_LEFT_BIT;
  200.          break;
  201.       case GL_LEFT:
  202.          /* never an error */
  203.          if (ctx->Visual.doubleBufferMode)
  204.             ctx->Color._DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT;
  205.          else
  206.             ctx->Color._DrawDestMask = FRONT_LEFT_BIT;
  207.          break;
  208.       case GL_FRONT_LEFT:
  209.          /* never an error */
  210.          ctx->Color._DrawDestMask = FRONT_LEFT_BIT;
  211.          break;
  212.       case GL_FRONT:
  213.          /* never an error */
  214.          if (ctx->Visual.stereoMode)
  215.             ctx->Color._DrawDestMask = FRONT_LEFT_BIT | FRONT_RIGHT_BIT;
  216.          else
  217.             ctx->Color._DrawDestMask = FRONT_LEFT_BIT;
  218.          break;
  219.       case GL_NONE:
  220.          /* never an error */
  221.          ctx->Color._DrawDestMask = 0;
  222.          break;
  223.       case GL_AUX0:
  224.          if (ctx->Const.NumAuxBuffers >= 1) {
  225.             ctx->Color._DrawDestMask = AUX0_BIT;
  226.          }
  227.          else {
  228.             _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer(GL_AUX0)" );
  229.             return;
  230.          }
  231.          break;
  232.       case GL_AUX1:
  233.          if (ctx->Const.NumAuxBuffers >= 2) {
  234.             ctx->Color._DrawDestMask = AUX1_BIT;
  235.          }
  236.          else {
  237.             _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer(GL_AUX1)" );
  238.             return;
  239.          }
  240.          break;
  241.       case GL_AUX2:
  242.          if (ctx->Const.NumAuxBuffers >= 3) {
  243.             ctx->Color._DrawDestMask = AUX2_BIT;
  244.          }
  245.          else {
  246.             _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer(GL_AUX2)" );
  247.             return;
  248.          }
  249.          break;
  250.       case GL_AUX3:
  251.          if (ctx->Const.NumAuxBuffers >= 4) {
  252.             ctx->Color._DrawDestMask = AUX3_BIT;
  253.          }
  254.          else {
  255.             _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer(GL_AUX3)" );
  256.             return;
  257.          }
  258.          break;
  259.       default:
  260.          _mesa_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
  261.          return;
  262.    }
  263.  
  264.    ctx->Color.DrawBuffer = mode;
  265.    ctx->NewState |= _NEW_COLOR;
  266.  
  267.    /*
  268.     * Call device driver function.
  269.     */
  270.    if (ctx->Driver.DrawBuffer)
  271.       (*ctx->Driver.DrawBuffer)(ctx, mode);
  272. }
  273.  
  274.  
  275.  
  276. void
  277. _mesa_ReadBuffer( GLenum mode )
  278. {
  279.    GET_CURRENT_CONTEXT(ctx);
  280.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  281.  
  282.    if (MESA_VERBOSE & VERBOSE_API)
  283.       _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(mode));
  284.  
  285.    /*
  286.     * Do error checking and compute ctx->Pixel._ReadSrcMask.
  287.     */
  288.    switch (mode) {
  289.       case GL_LEFT:
  290.       case GL_FRONT:
  291.       case GL_FRONT_LEFT:
  292.          /* Front-Left buffer, always exists */
  293.          ctx->Pixel._ReadSrcMask = FRONT_LEFT_BIT;
  294.          break;
  295.       case GL_BACK:
  296.       case GL_BACK_LEFT:
  297.          /* Back-Left buffer, requires double buffering */
  298.          if (!ctx->Visual.doubleBufferMode) {
  299.             _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
  300.             return;
  301.          }
  302.          ctx->Pixel._ReadSrcMask = BACK_LEFT_BIT;
  303.          break;
  304.       case GL_FRONT_RIGHT:
  305.       case GL_RIGHT:
  306.          if (!ctx->Visual.stereoMode) {
  307.             _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
  308.             return;
  309.          }
  310.          ctx->Pixel._ReadSrcMask = FRONT_RIGHT_BIT;
  311.          break;
  312.       case GL_BACK_RIGHT:
  313.          if (!ctx->Visual.stereoMode || !ctx->Visual.doubleBufferMode) {
  314.             _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
  315.             return;
  316.          }
  317.          ctx->Pixel._ReadSrcMask = BACK_RIGHT_BIT;
  318.          break;
  319.       case GL_AUX0:
  320.          if (ctx->Const.NumAuxBuffers >= 1) {
  321.             ctx->Pixel._ReadSrcMask = AUX0_BIT;
  322.          }
  323.          else {
  324.             _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer(GL_AUX0)" );
  325.             return;
  326.          }
  327.          break;
  328.       case GL_AUX1:
  329.          if (ctx->Const.NumAuxBuffers >= 2) {
  330.             ctx->Pixel._ReadSrcMask = AUX1_BIT;
  331.          }
  332.          else {
  333.             _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer(GL_AUX1)" );
  334.             return;
  335.          }
  336.          break;
  337.       case GL_AUX2:
  338.          if (ctx->Const.NumAuxBuffers >= 3) {
  339.             ctx->Pixel._ReadSrcMask = AUX2_BIT;
  340.          }
  341.          else {
  342.             _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer(GL_AUX2)" );
  343.             return;
  344.          }
  345.          break;
  346.       case GL_AUX3:
  347.          if (ctx->Const.NumAuxBuffers >= 4) {
  348.             ctx->Pixel._ReadSrcMask = AUX3_BIT;
  349.          }
  350.          else {
  351.             _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer(GL_AUX3)" );
  352.             return;
  353.          }
  354.          break;
  355.       default:
  356.          _mesa_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
  357.          return;
  358.    }
  359.  
  360.    ctx->Pixel.ReadBuffer = mode;
  361.    ctx->NewState |= _NEW_PIXEL;
  362.  
  363.    /*
  364.     * Call device driver function.
  365.     */
  366.    if (ctx->Driver.ReadBuffer)
  367.       (*ctx->Driver.ReadBuffer)(ctx, mode);
  368. }
  369.  
  370.  
  371. /*
  372.  * GL_MESA_resize_buffers extension
  373.  * When this function is called, we'll ask the window system how large
  374.  * the current window is.  If it's not what we expect, we'll have to
  375.  * resize/reallocate the software accum/stencil/depth/alpha buffers.
  376.  */
  377. void
  378. _mesa_ResizeBuffersMESA( void )
  379. {
  380.    GLcontext *ctx = _mesa_get_current_context();
  381.  
  382.    if (MESA_VERBOSE & VERBOSE_API)
  383.       _mesa_debug(ctx, "glResizeBuffersMESA\n");
  384.  
  385.    if (ctx) {
  386.       ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx );
  387.  
  388.       if (ctx->DrawBuffer) {
  389.          GLuint buf_width, buf_height;
  390.          GLframebuffer *buffer = ctx->DrawBuffer;
  391.  
  392.          /* ask device driver for size of output buffer */
  393.          (*ctx->Driver.GetBufferSize)( buffer, &buf_width, &buf_height );
  394.  
  395.          /* see if size of device driver's color buffer (window) has changed */
  396.          if (buffer->Width == buf_width && buffer->Height == buf_height)
  397.             return; /* size is as expected */
  398.  
  399.          buffer->Width = buf_width;
  400.          buffer->Height = buf_height;
  401.  
  402.          ctx->Driver.ResizeBuffers( buffer );
  403.       }
  404.  
  405.       if (ctx->ReadBuffer && ctx->ReadBuffer != ctx->DrawBuffer) {
  406.          GLuint buf_width, buf_height;
  407.          GLframebuffer *buffer = ctx->DrawBuffer;
  408.  
  409.          /* ask device driver for size of output buffer */
  410.          (*ctx->Driver.GetBufferSize)( buffer, &buf_width, &buf_height );
  411.  
  412.          /* see if size of device driver's color buffer (window) has changed */
  413.          if (buffer->Width == buf_width && buffer->Height == buf_height)
  414.             return; /* size is as expected */
  415.  
  416.          buffer->Width = buf_width;
  417.          buffer->Height = buf_height;
  418.  
  419.          ctx->Driver.ResizeBuffers( buffer );
  420.       }
  421.  
  422.       ctx->NewState |= _NEW_BUFFERS;  /* to update scissor / window bounds */
  423.    }
  424. }
  425.  
  426.  
  427. void
  428. _mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height )
  429. {
  430.    GET_CURRENT_CONTEXT(ctx);
  431.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  432.  
  433.    if (width < 0 || height < 0) {
  434.       _mesa_error( ctx, GL_INVALID_VALUE, "glScissor" );
  435.       return;
  436.    }
  437.  
  438.    if (MESA_VERBOSE & VERBOSE_API)
  439.       _mesa_debug(ctx, "glScissor %d %d %d %d\n", x, y, width, height);
  440.  
  441.    if (x == ctx->Scissor.X &&
  442.        y == ctx->Scissor.Y &&
  443.        width == ctx->Scissor.Width &&
  444.        height == ctx->Scissor.Height)
  445.       return;
  446.  
  447.    FLUSH_VERTICES(ctx, _NEW_SCISSOR);
  448.    ctx->Scissor.X = x;
  449.    ctx->Scissor.Y = y;
  450.    ctx->Scissor.Width = width;
  451.    ctx->Scissor.Height = height;
  452.  
  453.    if (ctx->Driver.Scissor)
  454.       ctx->Driver.Scissor( ctx, x, y, width, height );
  455. }
  456.  
  457.  
  458. /*
  459.  * XXX move somewhere else someday?
  460.  */
  461. void
  462. _mesa_SampleCoverageARB(GLclampf value, GLboolean invert)
  463. {
  464.    GLcontext *ctx = _mesa_get_current_context();
  465.  
  466.    if (!ctx->Extensions.ARB_multisample) {
  467.       _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleCoverageARB");
  468.       return;
  469.    }
  470.  
  471.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx );
  472.    ctx->Multisample.SampleCoverageValue = (GLfloat) CLAMP(value, 0.0, 1.0);
  473.    ctx->Multisample.SampleCoverageInvert = invert;
  474.    ctx->NewState |= _NEW_MULTISAMPLE;
  475. }
  476.                
  477.