⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buffers.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Mesa 3-D graphics library * Version:  7.1 * * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//** * \file buffers.c * General framebuffer-related functions, like glClear, glScissor, etc. */#include "glheader.h"#include "buffers.h"#include "colormac.h"#include "context.h"#include "enums.h"#include "fbobject.h"#include "state.h"#define BAD_MASK ~0u#if _HAVE_FULL_GLvoid GLAPIENTRY_mesa_ClearIndex( GLfloat c ){   GET_CURRENT_CONTEXT(ctx);   ASSERT_OUTSIDE_BEGIN_END(ctx);   if (ctx->Color.ClearIndex == (GLuint) c)      return;   FLUSH_VERTICES(ctx, _NEW_COLOR);   ctx->Color.ClearIndex = (GLuint) c;   if (!ctx->Visual.rgbMode && ctx->Driver.ClearIndex) {      /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */      (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex );   }}#endif/** * Specify the clear values for the color buffers. * * \param red red color component. * \param green green color component. * \param blue blue color component. * \param alpha alpha component. * * \sa glClearColor(). * * Clamps the parameters and updates gl_colorbuffer_attrib::ClearColor.  On a * change, flushes the vertices and notifies the driver via the * dd_function_table::ClearColor callback. */void GLAPIENTRY_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ){   GLfloat tmp[4];   GET_CURRENT_CONTEXT(ctx);   ASSERT_OUTSIDE_BEGIN_END(ctx);   tmp[0] = CLAMP(red,   0.0F, 1.0F);   tmp[1] = CLAMP(green, 0.0F, 1.0F);   tmp[2] = CLAMP(blue,  0.0F, 1.0F);   tmp[3] = CLAMP(alpha, 0.0F, 1.0F);   if (TEST_EQ_4V(tmp, ctx->Color.ClearColor))      return; /* no change */   FLUSH_VERTICES(ctx, _NEW_COLOR);   COPY_4V(ctx->Color.ClearColor, tmp);   if (ctx->Visual.rgbMode && ctx->Driver.ClearColor) {      /* it's OK to call glClearColor in CI mode but it should be a NOP */      (*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColor);   }}/** * Clear buffers. *  * \param mask bit-mask indicating the buffers to be cleared. * * Flushes the vertices and verifies the parameter. If __GLcontextRec::NewState * is set then calls _mesa_update_state() to update gl_frame_buffer::_Xmin, * etc. If the rasterization mode is set to GL_RENDER then requests the driver * to clear the buffers, via the dd_function_table::Clear callback. */ void GLAPIENTRY_mesa_Clear( GLbitfield mask ){   GET_CURRENT_CONTEXT(ctx);   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);   if (MESA_VERBOSE & VERBOSE_API)      _mesa_debug(ctx, "glClear 0x%x\n", mask);   if (mask & ~(GL_COLOR_BUFFER_BIT |                GL_DEPTH_BUFFER_BIT |                GL_STENCIL_BUFFER_BIT |                GL_ACCUM_BUFFER_BIT)) {      /* invalid bit set */      _mesa_error( ctx, GL_INVALID_VALUE, "glClear(0x%x)", mask);      return;   }   if (ctx->NewState) {      _mesa_update_state( ctx );	/* update _Xmin, etc */   }   if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,                  "glClear(incomplete framebuffer)");      return;   }   if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 ||       ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax ||       ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax)      return;   if (ctx->RenderMode == GL_RENDER) {      GLbitfield bufferMask;      /* don't clear depth buffer if depth writing disabled */      if (!ctx->Depth.Mask)         mask &= ~GL_DEPTH_BUFFER_BIT;      /* Build the bitmask to send to device driver's Clear function.       * Note that the GL_COLOR_BUFFER_BIT flag will expand to 0, 1, 2 or 4       * of the BUFFER_BIT_FRONT/BACK_LEFT/RIGHT flags, or one of the       * BUFFER_BIT_COLORn flags.       */      bufferMask = 0;      if (mask & GL_COLOR_BUFFER_BIT) {         GLuint i;         for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {            bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndexes[i]);         }      }      if ((mask & GL_DEPTH_BUFFER_BIT)          && ctx->DrawBuffer->Visual.haveDepthBuffer) {         bufferMask |= BUFFER_BIT_DEPTH;      }      if ((mask & GL_STENCIL_BUFFER_BIT)          && ctx->DrawBuffer->Visual.haveStencilBuffer) {         bufferMask |= BUFFER_BIT_STENCIL;      }      if ((mask & GL_ACCUM_BUFFER_BIT)          && ctx->DrawBuffer->Visual.haveAccumBuffer) {         bufferMask |= BUFFER_BIT_ACCUM;      }      ASSERT(ctx->Driver.Clear);      ctx->Driver.Clear(ctx, bufferMask);   }}/** * Return bitmask of BUFFER_BIT_* flags indicating which color buffers are * available to the rendering context (for drawing or reading). * This depends on the type of framebuffer.  For window system framebuffers * we look at the framebuffer's visual.  But for user-create framebuffers we * look at the number of supported color attachments. * \param fb  the framebuffer to draw to, or read from * \return  bitmask of BUFFER_BIT_* flags */static GLbitfieldsupported_buffer_bitmask(const GLcontext *ctx, const struct gl_framebuffer *fb){   GLbitfield mask = 0x0;   if (fb->Name > 0) {      /* A user-created renderbuffer */      GLuint i;      ASSERT(ctx->Extensions.EXT_framebuffer_object);      for (i = 0; i < ctx->Const.MaxColorAttachments; i++) {         mask |= (BUFFER_BIT_COLOR0 << i);      }   }   else {      /* A window system framebuffer */      GLint i;      mask = BUFFER_BIT_FRONT_LEFT; /* always have this */      if (fb->Visual.stereoMode) {         mask |= BUFFER_BIT_FRONT_RIGHT;         if (fb->Visual.doubleBufferMode) {            mask |= BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;         }      }      else if (fb->Visual.doubleBufferMode) {         mask |= BUFFER_BIT_BACK_LEFT;      }      for (i = 0; i < fb->Visual.numAuxBuffers; i++) {         mask |= (BUFFER_BIT_AUX0 << i);      }   }   return mask;}/** * Helper routine used by glDrawBuffer and glDrawBuffersARB. * Given a GLenum naming one or more color buffers (such as * GL_FRONT_AND_BACK), return the corresponding bitmask of BUFFER_BIT_* flags. */static GLbitfielddraw_buffer_enum_to_bitmask(GLenum buffer){   switch (buffer) {      case GL_NONE:         return 0;      case GL_FRONT:         return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT;      case GL_BACK:         return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;      case GL_RIGHT:         return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;      case GL_FRONT_RIGHT:         return BUFFER_BIT_FRONT_RIGHT;      case GL_BACK_RIGHT:         return BUFFER_BIT_BACK_RIGHT;      case GL_BACK_LEFT:         return BUFFER_BIT_BACK_LEFT;      case GL_FRONT_AND_BACK:         return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT              | BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;      case GL_LEFT:         return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT;      case GL_FRONT_LEFT:         return BUFFER_BIT_FRONT_LEFT;      case GL_AUX0:         return BUFFER_BIT_AUX0;      case GL_AUX1:         return BUFFER_BIT_AUX1;      case GL_AUX2:         return BUFFER_BIT_AUX2;      case GL_AUX3:         return BUFFER_BIT_AUX3;      case GL_COLOR_ATTACHMENT0_EXT:         return BUFFER_BIT_COLOR0;      case GL_COLOR_ATTACHMENT1_EXT:         return BUFFER_BIT_COLOR1;      case GL_COLOR_ATTACHMENT2_EXT:         return BUFFER_BIT_COLOR2;      case GL_COLOR_ATTACHMENT3_EXT:         return BUFFER_BIT_COLOR3;      case GL_COLOR_ATTACHMENT4_EXT:         return BUFFER_BIT_COLOR4;      case GL_COLOR_ATTACHMENT5_EXT:         return BUFFER_BIT_COLOR5;      case GL_COLOR_ATTACHMENT6_EXT:         return BUFFER_BIT_COLOR6;      case GL_COLOR_ATTACHMENT7_EXT:         return BUFFER_BIT_COLOR7;      default:         /* error */         return BAD_MASK;   }}/** * Helper routine used by glReadBuffer. * Given a GLenum naming a color buffer, return the index of the corresponding * renderbuffer (a BUFFER_* value). * return -1 for an invalid buffer. */static GLintread_buffer_enum_to_index(GLenum buffer){   switch (buffer) {      case GL_FRONT:         return BUFFER_FRONT_LEFT;      case GL_BACK:         return BUFFER_BACK_LEFT;      case GL_RIGHT:         return BUFFER_FRONT_RIGHT;      case GL_FRONT_RIGHT:         return BUFFER_FRONT_RIGHT;      case GL_BACK_RIGHT:         return BUFFER_BACK_RIGHT;      case GL_BACK_LEFT:         return BUFFER_BACK_LEFT;      case GL_LEFT:         return BUFFER_FRONT_LEFT;      case GL_FRONT_LEFT:         return BUFFER_FRONT_LEFT;      case GL_AUX0:         return BUFFER_AUX0;      case GL_AUX1:         return BUFFER_AUX1;      case GL_AUX2:         return BUFFER_AUX2;      case GL_AUX3:         return BUFFER_AUX3;      case GL_COLOR_ATTACHMENT0_EXT:         return BUFFER_COLOR0;      case GL_COLOR_ATTACHMENT1_EXT:         return BUFFER_COLOR1;      case GL_COLOR_ATTACHMENT2_EXT:         return BUFFER_COLOR2;      case GL_COLOR_ATTACHMENT3_EXT:         return BUFFER_COLOR3;      case GL_COLOR_ATTACHMENT4_EXT:         return BUFFER_COLOR4;      case GL_COLOR_ATTACHMENT5_EXT:         return BUFFER_COLOR5;      case GL_COLOR_ATTACHMENT6_EXT:         return BUFFER_COLOR6;      case GL_COLOR_ATTACHMENT7_EXT:         return BUFFER_COLOR7;      default:         /* error */         return -1;   }}/** * Called by glDrawBuffer(). * Specify which renderbuffer(s) to draw into for the first color output. * <buffer> can name zero, one, two or four renderbuffers! * \sa _mesa_DrawBuffersARB * * \param buffer  buffer token such as GL_LEFT or GL_FRONT_AND_BACK, etc. * * Note that the behaviour of this function depends on whether the * current ctx->DrawBuffer is a window-system framebuffer (Name=0) or * a user-created framebuffer object (Name!=0). *   In the former case, we update the per-context ctx->Color.DrawBuffer *   state var _and_ the FB's ColorDrawBuffer state. *   In the later case, we update the FB's ColorDrawBuffer state only. * * Furthermore, upon a MakeCurrent() or BindFramebuffer() call, if the * new FB is a window system FB, we need to re-update the FB's * ColorDrawBuffer state to match the context.  This is handled in * _mesa_update_framebuffer(). * * See the GL_EXT_framebuffer_object spec for more info. */void GLAPIENTRY_mesa_DrawBuffer(GLenum buffer){   GLbitfield destMask;   GET_CURRENT_CONTEXT(ctx);   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */   if (MESA_VERBOSE & VERBOSE_API) {      _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));   }   if (buffer == GL_NONE) {      destMask = 0x0;   }   else {      const GLbitfield supportedMask         = supported_buffer_bitmask(ctx, ctx->DrawBuffer);      destMask = draw_buffer_enum_to_bitmask(buffer);      if (destMask == BAD_MASK) {         /* totally bogus buffer */         _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(buffer)");         return;      }      destMask &= supportedMask;      if (destMask == 0x0) {         /* none of the named color buffers exist! */         _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(buffer)");         return;      }   }   /* if we get here, there's no error so set new state */   _mesa_drawbuffers(ctx, 1, &buffer, &destMask);   /*    * Call device driver function.    */   if (ctx->Driver.DrawBuffers)      ctx->Driver.DrawBuffers(ctx, 1, &buffer);   else if (ctx->Driver.DrawBuffer)      ctx->Driver.DrawBuffer(ctx, buffer);}/** * Called by glDrawBuffersARB; specifies the destination color renderbuffers * for N fragment program color outputs.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -