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

📄 buffers.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
   }

   /* if we get here, there's no error so set new state */
   _mesa_drawbuffers(ctx, 1, &buffer, &destMask);
}


/**
 * Called by glDrawBuffersARB; specifies the destination color buffers
 * for N fragment program color outputs.
 *
 * XXX This function is called by _mesa_PopAttrib() and we need to do
 * some more work to deal with the current framebuffer binding state!
 */
void GLAPIENTRY
_mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
{
   GLint output;
   GLuint usedBufferMask, supportedMask;
   GLuint bufferID;
   GLuint destMask[MAX_DRAW_BUFFERS];
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

   if (!ctx->Extensions.ARB_draw_buffers) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB");
      return;
   }
   if (n < 1 || n > (GLsizei) ctx->Const.MaxDrawBuffers) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)");
      return;
   }

   bufferID = ctx->DrawBuffer->Name;

   supportedMask = supported_buffer_bitmask(ctx, bufferID);
   usedBufferMask = 0x0;

   /* complicated error checking... */
   for (output = 0; output < n; output++) {
      if (buffers[output] == GL_NONE) {
         destMask[output] = 0x0;
      }
      else {
         destMask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
         if (destMask[output] == BAD_MASK
             || _mesa_bitcount(destMask[output]) > 1) {
            _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
            return;
         }         
         destMask[output] &= supportedMask;
         if (destMask[output] == 0) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "glDrawBuffersARB(unsupported buffer)");
            return;
         }
         if (destMask[output] & usedBufferMask) {
            /* can't specify a dest buffer more than once! */
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "glDrawBuffersARB(duplicated buffer)");
            return;
         }

         /* update bitmask */
         usedBufferMask |= destMask[output];
      }
   }

   /* OK, if we get here, there were no errors so set the new state */
   _mesa_drawbuffers(ctx, n, buffers, destMask);
}


/**
 * Set color output state.  Traditionally, there was only one color
 * output, but fragment programs can now have several distinct color
 * outputs (see GL_ARB_draw_buffers).  This function sets the state
 * for one such color output.
 */
static void
set_color_output(GLcontext *ctx, GLuint output, GLenum buffer, GLuint destMask)
{
   struct gl_framebuffer *fb = ctx->DrawBuffer;

   ASSERT(output < ctx->Const.MaxDrawBuffers);

   fb->ColorDrawBuffer[output] = buffer;
   fb->_ColorDrawBufferMask[output] = destMask;

   if (fb->Name == 0) {
      /* Set traditional state var */
      ctx->Color.DrawBuffer[output] = buffer;
   }

   /* not really needed, will be set later */
   fb->_NumColorDrawBuffers[output] = 0;
}


/**
 * Helper routine used by _mesa_DrawBuffer, _mesa_DrawBuffersARB and
 * _mesa_PopAttrib to set drawbuffer state.
 */
void
_mesa_drawbuffers(GLcontext *ctx, GLsizei n, const GLenum *buffers,
                  const GLuint *destMask)
{
   GLuint mask[MAX_DRAW_BUFFERS];
   GLint output;

   if (!destMask) {
      /* compute destMask values now */
      const GLuint bufferID = ctx->DrawBuffer->Name;
      const GLuint supportedMask = supported_buffer_bitmask(ctx, bufferID);
      for (output = 0; output < n; output++) {
         mask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
         ASSERT(mask[output] != BAD_MASK);
         mask[output] &= supportedMask;
      }
      destMask = mask;
   }

   for (output = 0; output < n; output++) {
      set_color_output(ctx, output, buffers[output], destMask[output]);
   }

   /* set remaining color outputs to NONE */
   for (output = n; output < ctx->Const.MaxDrawBuffers; output++) {
      set_color_output(ctx, output, GL_NONE, 0x0);
   }

   ctx->NewState |= _NEW_COLOR;

   /*
    * Call device driver function.
    */
   if (ctx->Driver.DrawBuffers)
      ctx->Driver.DrawBuffers(ctx, n, buffers);
   else if (ctx->Driver.DrawBuffer)
      ctx->Driver.DrawBuffer(ctx, buffers[0]);
}



/**
 * Set the color buffer source for reading pixels.
 *
 * \param mode color buffer.
 *
 * \sa glReadBuffer().
 *
 */
void GLAPIENTRY
_mesa_ReadBuffer(GLenum buffer)
{
   struct gl_framebuffer *fb;
   GLuint srcMask, supportedMask;
   GLuint bufferID;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

   fb = ctx->ReadBuffer;
   bufferID = fb->Name;

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));

   if (bufferID > 0 && buffer == GL_NONE) {
      /* legal! */
      srcMask = 0x0;
   }
   else {
      /* general case */
      srcMask = read_buffer_enum_to_bitmask(buffer);
      if (srcMask == BAD_MASK) {
         _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(buffer)");
         return;
      }
      supportedMask = supported_buffer_bitmask(ctx, bufferID);
      if ((srcMask & supportedMask) == 0) {
         _mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(buffer)");
         return;
      }
   }

   if (bufferID == 0) {
      ctx->Pixel.ReadBuffer = buffer;
   }
   fb->ColorReadBuffer = buffer;
   fb->_ColorReadBufferMask = srcMask;

   ctx->NewState |= _NEW_PIXEL;

   /*
    * Call device driver function.
    */
   if (ctx->Driver.ReadBuffer)
      (*ctx->Driver.ReadBuffer)(ctx, buffer);
}


#if _HAVE_FULL_GL

/**
 * GL_MESA_resize_buffers extension.
 *
 * When this function is called, we'll ask the window system how large
 * the current window is.  If it's a new size, we'll call the driver's
 * ResizeBuffers function.  The driver will then resize its color buffers
 * as needed, and maybe call the swrast's routine for reallocating
 * swrast-managed depth/stencil/accum/etc buffers.
 * \note This function may be called from within Mesa or called by the
 * user directly (see the GL_MESA_resize_buffers extension).
 */
void GLAPIENTRY
_mesa_ResizeBuffersMESA( void )
{
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx );

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glResizeBuffersMESA\n");

   if (ctx->DrawBuffer && ctx->DrawBuffer->Name == 0) {
      GLuint newWidth, newHeight;
      GLframebuffer *buffer = ctx->DrawBuffer;

      /* ask device driver for size of output buffer */
      ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );

      /* see if size of device driver's color buffer (window) has changed */
      if (buffer->Width != newWidth || buffer->Height != newHeight) {
         if (ctx->Driver.ResizeBuffers)
            ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
      }
   }

   if (ctx->ReadBuffer && ctx->ReadBuffer != ctx->DrawBuffer
       && ctx->ReadBuffer->Name == 0) {
      GLuint newWidth, newHeight;
      GLframebuffer *buffer = ctx->ReadBuffer;

      /* ask device driver for size of read buffer */
      ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight );

      /* see if size of device driver's color buffer (window) has changed */
      if (buffer->Width != newWidth || buffer->Height != newHeight) {
         if (ctx->Driver.ResizeBuffers)
            ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight );
      }
   }

   ctx->NewState |= _NEW_BUFFERS;  /* to update scissor / window bounds */
}


/*
 * XXX move somewhere else someday?
 */
void GLAPIENTRY
_mesa_SampleCoverageARB(GLclampf value, GLboolean invert)
{
   GET_CURRENT_CONTEXT(ctx);

   if (!ctx->Extensions.ARB_multisample) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleCoverageARB");
      return;
   }

   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx );
   ctx->Multisample.SampleCoverageValue = (GLfloat) CLAMP(value, 0.0, 1.0);
   ctx->Multisample.SampleCoverageInvert = invert;
   ctx->NewState |= _NEW_MULTISAMPLE;
}

#endif /* _HAVE_FULL_GL */



/**
 * Define the scissor box.
 *
 * \param x, y coordinates of the scissor box lower-left corner.
 * \param width width of the scissor box.
 * \param height height of the scissor box.
 *
 * \sa glScissor().
 *
 * Verifies the parameters and updates __GLcontextRec::Scissor. On a
 * change flushes the vertices and notifies the driver via
 * the dd_function_table::Scissor callback.
 */
void GLAPIENTRY
_mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height )
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (width < 0 || height < 0) {
      _mesa_error( ctx, GL_INVALID_VALUE, "glScissor" );
      return;
   }

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glScissor %d %d %d %d\n", x, y, width, height);

   if (x == ctx->Scissor.X &&
       y == ctx->Scissor.Y &&
       width == ctx->Scissor.Width &&
       height == ctx->Scissor.Height)
      return;

   FLUSH_VERTICES(ctx, _NEW_SCISSOR);
   ctx->Scissor.X = x;
   ctx->Scissor.Y = y;
   ctx->Scissor.Width = width;
   ctx->Scissor.Height = height;

   if (ctx->Driver.Scissor)
      ctx->Driver.Scissor( ctx, x, y, width, height );
}



/**********************************************************************/
/** \name Initialization */
/*@{*/

/**
 * Initialize the context's scissor state.
 * \param ctx  the GL context.
 */
void
_mesa_init_scissor(GLcontext *ctx)
{
   /* Scissor group */
   ctx->Scissor.Enabled = GL_FALSE;
   ctx->Scissor.X = 0;
   ctx->Scissor.Y = 0;
   ctx->Scissor.Width = 0;
   ctx->Scissor.Height = 0;
}


/**
 * Initialize the context's multisample state.
 * \param ctx  the GL context.
 */
void
_mesa_init_multisample(GLcontext *ctx)
{
   ctx->Multisample.Enabled = GL_FALSE;
   ctx->Multisample.SampleAlphaToCoverage = GL_FALSE;
   ctx->Multisample.SampleAlphaToOne = GL_FALSE;
   ctx->Multisample.SampleCoverage = GL_FALSE;
   ctx->Multisample.SampleCoverageValue = 1.0;
   ctx->Multisample.SampleCoverageInvert = GL_FALSE;
}

/*@}*/

⌨️ 快捷键说明

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