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

📄 fbobject.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Mesa 3-D graphics library * Version:  6.5 * * Copyright (C) 1999-2006  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. *//* * Authors: *   Brian Paul */#include "context.h"#include "fbobject.h"#include "framebuffer.h"#include "hash.h"#include "renderbuffer.h"#include "state.h"#include "teximage.h"#include "texobj.h"#include "texstore.h"/** * Notes: * * None of the GL_EXT_framebuffer_object functions are compiled into * display lists. *//* * When glGenRender/FramebuffersEXT() is called we insert pointers to * these placeholder objects into the hash table. * Later, when the object ID is first bound, we replace the placeholder * with the real frame/renderbuffer. */static struct gl_framebuffer DummyFramebuffer;static struct gl_renderbuffer DummyRenderbuffer;#define IS_CUBE_FACE(TARGET) \   ((TARGET) >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && \    (TARGET) <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)/** * Helper routine for getting a gl_renderbuffer. */struct gl_renderbuffer *_mesa_lookup_renderbuffer(GLcontext *ctx, GLuint id){   struct gl_renderbuffer *rb;   if (id == 0)      return NULL;   rb = (struct gl_renderbuffer *)      _mesa_HashLookup(ctx->Shared->RenderBuffers, id);   return rb;}/** * Helper routine for getting a gl_framebuffer. */struct gl_framebuffer *_mesa_lookup_framebuffer(GLcontext *ctx, GLuint id){   struct gl_framebuffer *fb;   if (id == 0)      return NULL;   fb = (struct gl_framebuffer *)      _mesa_HashLookup(ctx->Shared->FrameBuffers, id);   return fb;}/** * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding * gl_renderbuffer_attachment object. */struct gl_renderbuffer_attachment *_mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,                     GLenum attachment){   GLuint i;   switch (attachment) {   case GL_COLOR_ATTACHMENT0_EXT:   case GL_COLOR_ATTACHMENT1_EXT:   case GL_COLOR_ATTACHMENT2_EXT:   case GL_COLOR_ATTACHMENT3_EXT:   case GL_COLOR_ATTACHMENT4_EXT:   case GL_COLOR_ATTACHMENT5_EXT:   case GL_COLOR_ATTACHMENT6_EXT:   case GL_COLOR_ATTACHMENT7_EXT:   case GL_COLOR_ATTACHMENT8_EXT:   case GL_COLOR_ATTACHMENT9_EXT:   case GL_COLOR_ATTACHMENT10_EXT:   case GL_COLOR_ATTACHMENT11_EXT:   case GL_COLOR_ATTACHMENT12_EXT:   case GL_COLOR_ATTACHMENT13_EXT:   case GL_COLOR_ATTACHMENT14_EXT:   case GL_COLOR_ATTACHMENT15_EXT:      i = attachment - GL_COLOR_ATTACHMENT0_EXT;      if (i >= ctx->Const.MaxColorAttachments) {	 return NULL;      }      return &fb->Attachment[BUFFER_COLOR0 + i];   case GL_DEPTH_ATTACHMENT_EXT:      return &fb->Attachment[BUFFER_DEPTH];   case GL_STENCIL_ATTACHMENT_EXT:      return &fb->Attachment[BUFFER_STENCIL];   default:      return NULL;   }}/** * Remove any texture or renderbuffer attached to the given attachment * point.  Update reference counts, etc. */void_mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att){   if (att->Type == GL_TEXTURE) {      ASSERT(att->Texture);      att->Texture->RefCount--;      if (att->Texture->RefCount == 0) {	 ctx->Driver.DeleteTexture(ctx, att->Texture);      }      else {         /* tell driver that we're done rendering to this texture. */         if (ctx->Driver.FinishRenderTexture) {            ctx->Driver.FinishRenderTexture(ctx, att);         }      }      att->Texture = NULL;   }   if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {      ASSERT(att->Renderbuffer);      ASSERT(!att->Texture);      att->Renderbuffer->RefCount--;      if (att->Renderbuffer->RefCount == 0) {         att->Renderbuffer->Delete(att->Renderbuffer);      }      att->Renderbuffer = NULL;   }   att->Type = GL_NONE;   att->Complete = GL_TRUE;}/** * Bind a texture object to an attachment point. * The previous binding, if any, will be removed first. */void_mesa_set_texture_attachment(GLcontext *ctx,                             struct gl_framebuffer *fb,                             struct gl_renderbuffer_attachment *att,                             struct gl_texture_object *texObj,                             GLenum texTarget, GLuint level, GLuint zoffset){   if (att->Texture == texObj) {      /* re-attaching same texture */      ASSERT(att->Type == GL_TEXTURE);   }   else {      /* new attachment */      _mesa_remove_attachment(ctx, att);      att->Type = GL_TEXTURE;      att->Texture = texObj;      texObj->RefCount++;   }   /* always update these fields */   att->TextureLevel = level;   if (IS_CUBE_FACE(texTarget)) {      att->CubeMapFace = texTarget - GL_TEXTURE_CUBE_MAP_POSITIVE_X;   }   else {      att->CubeMapFace = 0;   }   att->Zoffset = zoffset;   att->Complete = GL_FALSE;   if (att->Texture->Image[att->CubeMapFace][att->TextureLevel]) {      ctx->Driver.RenderTexture(ctx, fb, att);   }}/** * Bind a renderbuffer to an attachment point. * The previous binding, if any, will be removed first. */void_mesa_set_renderbuffer_attachment(GLcontext *ctx,                                  struct gl_renderbuffer_attachment *att,                                  struct gl_renderbuffer *rb){   /* XXX check if re-doing same attachment, exit early */   _mesa_remove_attachment(ctx, att);   att->Type = GL_RENDERBUFFER_EXT;   att->Renderbuffer = rb;   att->Texture = NULL; /* just to be safe */   att->Complete = GL_FALSE;   rb->RefCount++;}/** * Fallback for ctx->Driver.FramebufferRenderbuffer() * Attach a renderbuffer object to a framebuffer object. */void_mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,                               GLenum attachment, struct gl_renderbuffer *rb){   struct gl_renderbuffer_attachment *att;   _glthread_LOCK_MUTEX(fb->Mutex);   if (rb)      _glthread_LOCK_MUTEX(rb->Mutex);   att = _mesa_get_attachment(ctx, fb, attachment);   ASSERT(att);   if (rb) {      _mesa_set_renderbuffer_attachment(ctx, att, rb);   }   else {      _mesa_remove_attachment(ctx, att);   }   if (rb)      _glthread_UNLOCK_MUTEX(rb->Mutex);   _glthread_UNLOCK_MUTEX(fb->Mutex);}/** * Test if an attachment point is complete and update its Complete field. * \param format if GL_COLOR, this is a color attachment point, *               if GL_DEPTH, this is a depth component attachment point, *               if GL_STENCIL, this is a stencil component attachment point. */static voidtest_attachment_completeness(const GLcontext *ctx, GLenum format,                             struct gl_renderbuffer_attachment *att){   assert(format == GL_COLOR || format == GL_DEPTH || format == GL_STENCIL);   /* assume complete */   att->Complete = GL_TRUE;   /* Look for reasons why the attachment might be incomplete */   if (att->Type == GL_TEXTURE) {      const struct gl_texture_object *texObj = att->Texture;      struct gl_texture_image *texImage;      if (!texObj) {         att->Complete = GL_FALSE;         return;      }      texImage = texObj->Image[att->CubeMapFace][att->TextureLevel];      if (!texImage) {         att->Complete = GL_FALSE;         return;      }      if (texImage->Width < 1 || texImage->Height < 1) {         att->Complete = GL_FALSE;         return;      }      if (texObj->Target == GL_TEXTURE_3D && att->Zoffset >= texImage->Depth) {         att->Complete = GL_FALSE;         return;      }      if (format == GL_COLOR) {         if (texImage->TexFormat->BaseFormat != GL_RGB &&             texImage->TexFormat->BaseFormat != GL_RGBA) {            att->Complete = GL_FALSE;            return;         }      }      else if (format == GL_DEPTH) {         if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {            /* OK */         }         else if (ctx->Extensions.EXT_packed_depth_stencil &&                  att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {            /* OK */         }         else {            att->Complete = GL_FALSE;            return;         }      }      else {         /* no such thing as stencil textures */         att->Complete = GL_FALSE;         return;      }   }   else if (att->Type == GL_RENDERBUFFER_EXT) {      ASSERT(att->Renderbuffer);      if (!att->Renderbuffer->InternalFormat ||          att->Renderbuffer->Width < 1 ||          att->Renderbuffer->Height < 1) {         att->Complete = GL_FALSE;         return;      }      if (format == GL_COLOR) {         if (att->Renderbuffer->_BaseFormat != GL_RGB &&             att->Renderbuffer->_BaseFormat != GL_RGBA) {            ASSERT(att->Renderbuffer->RedBits);            ASSERT(att->Renderbuffer->GreenBits);            ASSERT(att->Renderbuffer->BlueBits);            att->Complete = GL_FALSE;            return;         }      }      else if (format == GL_DEPTH) {         ASSERT(att->Renderbuffer->DepthBits);         if (att->Renderbuffer->_BaseFormat == GL_DEPTH_COMPONENT) {            /* OK */         }         else if (ctx->Extensions.EXT_packed_depth_stencil &&                  att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {            /* OK */         }         else {            att->Complete = GL_FALSE;            return;         }      }      else {         assert(format == GL_STENCIL);         ASSERT(att->Renderbuffer->StencilBits);         if (att->Renderbuffer->_BaseFormat == GL_STENCIL_INDEX) {            /* OK */         }         else if (ctx->Extensions.EXT_packed_depth_stencil &&                  att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {            /* OK */         }         else {            att->Complete = GL_FALSE;            return;         }      }   }   else {      ASSERT(att->Type == GL_NONE);      /* complete */      return;   }}/** * Helpful for debugging */static voidfbo_incomplete(const char *msg, int index){   /*   _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index);   */}/** * Test if the given framebuffer object is complete and update its * Status field with the results. * Also update the framebuffer's Width and Height fields if the * framebuffer is complete. */void_mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb){   GLuint numImages, width = 0, height = 0;   GLenum intFormat = GL_NONE;   GLuint w = 0, h = 0;   GLint i;

⌨️ 快捷键说明

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