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

📄 fbobject.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
	 fb = lookup_framebuffer(ctx, framebuffers[i]);
	 if (fb) {
            ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]);

            /* check if deleting currently bound framebuffer object */
            if (fb == ctx->DrawBuffer) {
               /* bind default */
               ASSERT(fb->RefCount >= 2);
               _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
            }

	    /* remove from hash table immediately, to free the ID */
	    _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);

            if (fb != &DummyFramebuffer) {
               /* But the object will not be freed until it's no longer
                * bound in any context.
                */
               fb->RefCount--;
               if (fb->RefCount == 0) {
                  fb->Delete(fb);
               }
	    }
	 }
      }
   }
}


void GLAPIENTRY
_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers)
{
   GET_CURRENT_CONTEXT(ctx);
   GLuint first;
   GLint i;

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenFramebuffersEXT(n)");
      return;
   }

   if (!framebuffers)
      return;

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->FrameBuffers, n);

   for (i = 0; i < n; i++) {
      GLuint name = first + i;
      framebuffers[i] = name;
      /* insert dummy placeholder into hash table */
      _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
      _mesa_HashInsert(ctx->Shared->FrameBuffers, name, &DummyFramebuffer);
      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
   }
}



GLenum GLAPIENTRY
_mesa_CheckFramebufferStatusEXT(GLenum target)
{
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);

   if (target != GL_FRAMEBUFFER_EXT) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
      return 0; /* formerly GL_FRAMEBUFFER_STATUS_ERROR_EXT */
   }

   if (ctx->DrawBuffer->Name == 0) {
      /* The window system / default framebuffer is always complete */
      return GL_FRAMEBUFFER_COMPLETE_EXT;
   }

   FLUSH_VERTICES(ctx, _NEW_BUFFERS);

   _mesa_test_framebuffer_completeness(ctx, ctx->DrawBuffer);
   return ctx->DrawBuffer->_Status;
}



/**
 * Do error checking common to glFramebufferTexture1D/2D/3DEXT.
 * \return GL_TRUE if any error, GL_FALSE otherwise
 */
static GLboolean
error_check_framebuffer_texture(GLcontext *ctx, GLuint dims,
                                GLenum target, GLenum attachment,
                                GLenum textarget, GLuint texture, GLint level)
{
   ASSERT(dims >= 1 && dims <= 3);

   if (target != GL_FRAMEBUFFER_EXT) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glFramebufferTexture%dDEXT(target)", dims);
      return GL_TRUE;
   }

   /* check framebuffer binding */
   if (ctx->DrawBuffer->Name == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glFramebufferTexture%dDEXT", dims);
      return GL_TRUE;
   }

   /* only check textarget, level if texture ID is non-zero */
   if (texture) {
      if ((dims == 1 && textarget != GL_TEXTURE_1D) ||
	  (dims == 3 && textarget != GL_TEXTURE_3D) ||
	  (dims == 2 && textarget != GL_TEXTURE_2D &&
	   textarget != GL_TEXTURE_RECTANGLE_ARB &&
	   !IS_CUBE_FACE(textarget))) {
	 _mesa_error(ctx, GL_INVALID_VALUE,
		     "glFramebufferTexture%dDEXT(textarget)", dims);
	 return GL_TRUE;
      }

      if ((level < 0) || level >= _mesa_max_texture_levels(ctx, textarget)) {
	 _mesa_error(ctx, GL_INVALID_VALUE,
		     "glFramebufferTexture%dDEXT(level)", dims);
	 return GL_TRUE;
      }
   }

   return GL_FALSE;
}


void GLAPIENTRY
_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
                              GLenum textarget, GLuint texture, GLint level)
{
   struct gl_renderbuffer_attachment *att;
   struct gl_texture_object *texObj;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (error_check_framebuffer_texture(ctx, 1, target, attachment,
				       textarget, texture, level))
      return;

   ASSERT(textarget == GL_TEXTURE_1D);

   att = get_attachment(ctx, ctx->DrawBuffer, attachment);
   if (att == NULL) {
      _mesa_error(ctx, GL_INVALID_ENUM,
		  "glFramebufferTexture1DEXT(attachment)");
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_BUFFERS);

   if (texture) {
      texObj = (struct gl_texture_object *)
	 _mesa_HashLookup(ctx->Shared->TexObjects, texture);
      if (!texObj) {
	 _mesa_error(ctx, GL_INVALID_VALUE,
		     "glFramebufferTexture1DEXT(texture)");
	 return;
      }
      if (texObj->Target != textarget) {
	 _mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
		     "glFramebufferTexture1DEXT(texture target)");
	 return;
      }
   }
   else {
      /* remove texture attachment */
      texObj = NULL;
   }
   ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget, level, 0);
}


void GLAPIENTRY
_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
                              GLenum textarget, GLuint texture, GLint level)
{
   struct gl_renderbuffer_attachment *att;
   struct gl_texture_object *texObj;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (error_check_framebuffer_texture(ctx, 2, target, attachment,
				       textarget, texture, level))
      return;

   ASSERT(textarget == GL_TEXTURE_2D ||
	  textarget == GL_TEXTURE_RECTANGLE_ARB ||
	  IS_CUBE_FACE(textarget));

   att = get_attachment(ctx, ctx->DrawBuffer, attachment);
   if (att == NULL) {
      _mesa_error(ctx, GL_INVALID_ENUM,
		  "glFramebufferTexture2DEXT(attachment)");
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_BUFFERS);

   if (texture) {
      texObj = (struct gl_texture_object *)
	 _mesa_HashLookup(ctx->Shared->TexObjects, texture);
      if (!texObj) {
	 _mesa_error(ctx, GL_INVALID_VALUE,
		     "glFramebufferTexture2DEXT(texture)");
	 return;
      }
      if ((texObj->Target == GL_TEXTURE_2D && textarget != GL_TEXTURE_2D) ||
	  (texObj->Target == GL_TEXTURE_RECTANGLE_ARB
	   && textarget != GL_TEXTURE_RECTANGLE_ARB) ||
	  (texObj->Target == GL_TEXTURE_CUBE_MAP
	   && !IS_CUBE_FACE(textarget))) {
	 _mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
		     "glFramebufferTexture2DEXT(texture target)");
	 return;
      }
   }
   else {
      /* remove texture attachment */
      texObj = NULL;
   }
   ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget, level, 0);
}


void GLAPIENTRY
_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
                              GLenum textarget, GLuint texture,
                              GLint level, GLint zoffset)
{
   struct gl_renderbuffer_attachment *att;
   struct gl_texture_object *texObj;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (error_check_framebuffer_texture(ctx, 3, target, attachment,
				       textarget, texture, level))
      return;

   ASSERT(textarget == GL_TEXTURE_3D);

   att = get_attachment(ctx, ctx->DrawBuffer, attachment);
   if (att == NULL) {
      _mesa_error(ctx, GL_INVALID_ENUM,
		  "glFramebufferTexture1DEXT(attachment)");
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_BUFFERS);

   if (texture) {
      const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
      texObj = (struct gl_texture_object *)
	 _mesa_HashLookup(ctx->Shared->TexObjects, texture);
      if (!texObj) {
	 _mesa_error(ctx, GL_INVALID_VALUE,
		     "glFramebufferTexture3DEXT(texture)");
	 return;
      }
      if (texObj->Target != textarget) {
	 _mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
		     "glFramebufferTexture3DEXT(texture target)");
	 return;
      }
      if (zoffset < 0 || zoffset >= maxSize) {
	 _mesa_error(ctx, GL_INVALID_VALUE,
		     "glFramebufferTexture3DEXT(zoffset)");
	 return;
      }
   }
   else {
      /* remove texture attachment */
      texObj = NULL;
   }
   ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget,
                                   level, zoffset);
}


void GLAPIENTRY
_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
                                 GLenum renderbufferTarget,
                                 GLuint renderbuffer)
{
   struct gl_renderbuffer_attachment *att;
   struct gl_renderbuffer *rb;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (target != GL_FRAMEBUFFER_EXT) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glFramebufferRenderbufferEXT(target)");
      return;
   }

   if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glFramebufferRenderbufferEXT(renderbufferTarget)");
      return;
   }

   if (ctx->DrawBuffer->Name == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
      return;
   }

   att = get_attachment(ctx, ctx->DrawBuffer, attachment);
   if (att == NULL) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                 "glFramebufferRenderbufferEXT(attachment)");
      return;
   }

   if (renderbuffer) {
      rb = lookup_renderbuffer(ctx, renderbuffer);
      if (!rb) {
	 _mesa_error(ctx, GL_INVALID_OPERATION,
		     "glFramebufferRenderbufferEXT(renderbuffer)");
	 return;
      }
   }
   else {
      /* remove renderbuffer attachment */
      rb = NULL;
   }

   FLUSH_VERTICES(ctx, _NEW_BUFFERS);

   assert(ctx->Driver.FramebufferRenderbuffer);
   ctx->Driver.FramebufferRenderbuffer(ctx, att, rb);
}


void GLAPIENTRY
_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
                                             GLenum pname, GLint *params)
{
   const struct gl_renderbuffer_attachment *att;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (target != GL_FRAMEBUFFER_EXT) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glGetFramebufferAttachmentParameterivEXT(target)");
      return;
   }

   if (ctx->DrawBuffer->Name == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetFramebufferAttachmentParameterivEXT");
      return;
   }

   att = get_attachment(ctx, ctx->DrawBuffer, attachment);
   if (att == NULL) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glGetFramebufferAttachmentParameterivEXT(attachment)");
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_BUFFERS);

   switch (pname) {
   case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
      *params = att->Type;
      return;
   case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
      if (att->Type == GL_RENDERBUFFER_EXT) {
	 *params = att->Renderbuffer->Name;
      }
      else if (att->Type == GL_TEXTURE) {
	 *params = att->Texture->Name;
      }
      else {
	 _mesa_error(ctx, GL_INVALID_ENUM,
		     "glGetFramebufferAttachmentParameterivEXT(pname)");
      }
      return;
   case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
      if (att->Type == GL_TEXTURE) {
	 *params = att->TextureLevel;
      }
      else {
	 _mesa_error(ctx, GL_INVALID_ENUM,
		     "glGetFramebufferAttachmentParameterivEXT(pname)");
      }
      return;
   case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT:
      if (att->Type == GL_TEXTURE) {
	 *params = GL_TEXTURE_CUBE_MAP_POSITIVE_X + att->CubeMapFace;
      }
      else {
	 _mesa_error(ctx, GL_INVALID_ENUM,
		     "glGetFramebufferAttachmentParameterivEXT(pname)");
      }
      return;
   case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT:
      if (att->Type == GL_TEXTURE) {
	 *params = att->Zoffset;
      }
      else {
	 _mesa_error(ctx, GL_INVALID_ENUM,
		     "glGetFramebufferAttachmentParameterivEXT(pname)");
      }
      return;
   default:
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glGetFramebufferAttachmentParameterivEXT(pname)");
      return;
   }
}


void GLAPIENTRY
_mesa_GenerateMipmapEXT(GLenum target)
{
   struct gl_texture_unit *texUnit;
   struct gl_texture_object *texObj;
   GET_CURRENT_CONTEXT(ctx);

   ASSERT_OUTSIDE_BEGIN_END(ctx);
   FLUSH_VERTICES(ctx, _NEW_BUFFERS);

   switch (target) {
   case GL_TEXTURE_1D:
   case GL_TEXTURE_2D:
   case GL_TEXTURE_3D:
   case GL_TEXTURE_CUBE_MAP:
      /* OK, legal value */
      break;
   default:
      _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)");
      return;
   }

   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
   texObj = _mesa_select_tex_object(ctx, texUnit, target);

   /* XXX this might not handle cube maps correctly */
   _mesa_generate_mipmap(ctx, target, texUnit, texObj);
}

⌨️ 快捷键说明

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