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

📄 framebuffer.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Mesa 3-D graphics library
 * Version:  6.4
 *
 * Copyright (C) 1999-2005  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.
 */


/**
 * Functions for allocating/managing framebuffers and renderbuffers.
 * Also, routines for reading/writing renderbuffer data as ubytes,
 * ushorts, uints, etc.
 */


#include "glheader.h"
#include "imports.h"
#include "context.h"
#include "mtypes.h"
#include "fbobject.h"
#include "framebuffer.h"
#include "renderbuffer.h"



/**
 * Compute/set the _DepthMax field for the given framebuffer.
 * This value depends on the Z buffer resolution.
 */
static void
compute_depth_max(struct gl_framebuffer *fb)
{
   if (fb->Visual.depthBits == 0) {
      /* Special case.  Even if we don't have a depth buffer we need
       * good values for DepthMax for Z vertex transformation purposes
       * and for per-fragment fog computation.
       */
      fb->_DepthMax = (1 << 16) - 1;
   }
   else if (fb->Visual.depthBits < 32) {
      fb->_DepthMax = (1 << fb->Visual.depthBits) - 1;
   }
   else {
      /* Special case since shift values greater than or equal to the
       * number of bits in the left hand expression's type are undefined.
       */
      fb->_DepthMax = 0xffffffff;
   }
   fb->_DepthMaxF = (GLfloat) fb->_DepthMax;
   fb->_MRD = 1.0;  /* Minimum resolvable depth value, for polygon offset */
}


/**
 * Create and initialize a gl_framebuffer object.
 * This is intended for creating _window_system_ framebuffers, not generic
 * framebuffer objects ala GL_EXT_framebuffer_object.
 *
 * \sa _mesa_new_framebuffer
 */
struct gl_framebuffer *
_mesa_create_framebuffer(const GLvisual *visual)
{
   struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
   assert(visual);
   if (fb) {
      _mesa_initialize_framebuffer(fb, visual);
   }
   return fb;
}


/**
 * Allocate a new gl_framebuffer object.
 * This is the default function for ctx->Driver.NewFramebuffer().
 * This is for allocating user-created framebuffers, not window-system
 * framebuffers!
 * \sa _mesa_create_framebuffer
 */
struct gl_framebuffer *
_mesa_new_framebuffer(GLcontext *ctx, GLuint name)
{
   struct gl_framebuffer *fb;
   assert(name != 0);
   fb = CALLOC_STRUCT(gl_framebuffer);
   if (fb) {
      fb->Name = name;
      fb->RefCount = 1;
      fb->Delete = _mesa_destroy_framebuffer;
      fb->ColorDrawBuffer[0] = GL_COLOR_ATTACHMENT0_EXT;
      fb->_ColorDrawBufferMask[0] = BUFFER_BIT_COLOR0;
      fb->ColorReadBuffer = GL_COLOR_ATTACHMENT0_EXT;
      fb->_ColorReadBufferMask = BUFFER_BIT_COLOR0;
      fb->Delete = _mesa_destroy_framebuffer;
   }
   return fb;
}


/**
 * Initialize a gl_framebuffer object.
 * \sa _mesa_create_framebuffer
 */
void
_mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual)
{
   assert(fb);
   assert(visual);

   _mesa_bzero(fb, sizeof(struct gl_framebuffer));

   /* save the visual */
   fb->Visual = *visual;

   /* Init glRead/DrawBuffer state */
   if (visual->doubleBufferMode) {
      fb->ColorDrawBuffer[0] = GL_BACK;
      fb->_ColorDrawBufferMask[0] = BUFFER_BIT_BACK_LEFT;
      fb->ColorReadBuffer = GL_BACK;
      fb->_ColorReadBufferMask = BUFFER_BIT_BACK_LEFT;
   }
   else {
      fb->ColorDrawBuffer[0] = GL_FRONT;
      fb->_ColorDrawBufferMask[0] = BUFFER_BIT_FRONT_LEFT;
      fb->ColorReadBuffer = GL_FRONT;
      fb->_ColorReadBufferMask = BUFFER_BIT_FRONT_LEFT;
   }

   fb->Delete = _mesa_destroy_framebuffer;
   fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;

   compute_depth_max(fb);
}


/**
 * Create/attach software-based renderbuffers to the given framebuffer.
 * This is a helper routine for device drivers.  Drivers can just as well
 * call the individual _mesa_add_*_renderbuffer() routines directly.
 */
void
_mesa_add_soft_renderbuffers(struct gl_framebuffer *fb,
                             GLboolean color,
                             GLboolean depth,
                             GLboolean stencil,
                             GLboolean accum,
                             GLboolean alpha,
                             GLboolean aux)
{
   GLboolean frontLeft = GL_TRUE;
   GLboolean backLeft = fb->Visual.doubleBufferMode;
   GLboolean frontRight = fb->Visual.stereoMode;
   GLboolean backRight = fb->Visual.stereoMode && fb->Visual.doubleBufferMode;

   if (color) {
      if (fb->Visual.rgbMode) {
         assert(fb->Visual.redBits == fb->Visual.greenBits);
         assert(fb->Visual.redBits == fb->Visual.blueBits);
         _mesa_add_color_renderbuffers(NULL, fb,
                                       fb->Visual.redBits,
                                       fb->Visual.alphaBits,
                                       frontLeft, backLeft,
                                       frontRight, backRight);
      }
      else {
         _mesa_add_color_index_renderbuffers(NULL, fb,
                                             fb->Visual.indexBits,
                                             frontLeft, backLeft,
                                             frontRight, backRight);
      }
   }

   if (depth) {
      assert(fb->Visual.depthBits > 0);
      _mesa_add_depth_renderbuffer(NULL, fb, fb->Visual.depthBits);
   }

   if (stencil) {
      assert(fb->Visual.stencilBits > 0);
      _mesa_add_stencil_renderbuffer(NULL, fb, fb->Visual.stencilBits);
   }

   if (accum) {
      assert(fb->Visual.rgbMode);
      assert(fb->Visual.accumRedBits > 0);
      assert(fb->Visual.accumGreenBits > 0);
      assert(fb->Visual.accumBlueBits > 0);
      _mesa_add_accum_renderbuffer(NULL, fb,
                                   fb->Visual.accumRedBits,
                                   fb->Visual.accumGreenBits,
                                   fb->Visual.accumBlueBits,
                                   fb->Visual.accumAlphaBits);
   }

   if (aux) {
      assert(fb->Visual.rgbMode);
      assert(fb->Visual.numAuxBuffers > 0);
      _mesa_add_aux_renderbuffers(NULL, fb, fb->Visual.redBits,
                                  fb->Visual.numAuxBuffers);
   }

#if 1
   if (alpha) {
      assert(fb->Visual.rgbMode);
      assert(fb->Visual.alphaBits > 0);
      _mesa_add_alpha_renderbuffers(NULL, fb, fb->Visual.alphaBits,
                                    frontLeft, backLeft,
                                    frontRight, backRight);
   }
#endif

#if 0
   if (multisample) {
      /* maybe someday */
   }
#endif
}


/**
 * Deallocate buffer and everything attached to it.
 */
void
_mesa_destroy_framebuffer(struct gl_framebuffer *buffer)
{
   if (buffer) {
      _mesa_free_framebuffer_data(buffer);
      FREE(buffer);
   }
}


/**
 * Free all the data hanging off the given gl_framebuffer, but don't free
 * the gl_framebuffer object itself.
 */
void
_mesa_free_framebuffer_data(struct gl_framebuffer *fb)
{
   GLuint i;

   assert(fb);

   for (i = 0; i < BUFFER_COUNT; i++) {
      struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
      if (att->Type == GL_RENDERBUFFER_EXT && att->Renderbuffer) {
         struct gl_renderbuffer *rb = att->Renderbuffer;

⌨️ 快捷键说明

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