📄 fbobject.c
字号:
rb->InternalFormat = GL_NONE; rb->_ActualFormat = GL_NONE; rb->_BaseFormat = GL_NONE; rb->RedBits = rb->GreenBits = rb->BlueBits = rb->AlphaBits = rb->IndexBits = rb->DepthBits = rb->StencilBits = 0; } /* test_framebuffer_completeness(ctx, fb); */ /* XXX if this renderbuffer is attached anywhere, invalidate attachment * points??? */}void GLAPIENTRY_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params){ GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (target != GL_RENDERBUFFER_EXT) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetRenderbufferParameterivEXT(target)"); return; } if (!ctx->CurrentRenderbuffer) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetRenderbufferParameterivEXT"); return; } FLUSH_VERTICES(ctx, _NEW_BUFFERS); switch (pname) { case GL_RENDERBUFFER_WIDTH_EXT: *params = ctx->CurrentRenderbuffer->Width; return; case GL_RENDERBUFFER_HEIGHT_EXT: *params = ctx->CurrentRenderbuffer->Height; return; case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT: *params = ctx->CurrentRenderbuffer->InternalFormat; return; case GL_RENDERBUFFER_RED_SIZE_EXT: *params = ctx->CurrentRenderbuffer->RedBits; break; case GL_RENDERBUFFER_GREEN_SIZE_EXT: *params = ctx->CurrentRenderbuffer->GreenBits; break; case GL_RENDERBUFFER_BLUE_SIZE_EXT: *params = ctx->CurrentRenderbuffer->BlueBits; break; case GL_RENDERBUFFER_ALPHA_SIZE_EXT: *params = ctx->CurrentRenderbuffer->AlphaBits; break; case GL_RENDERBUFFER_DEPTH_SIZE_EXT: *params = ctx->CurrentRenderbuffer->DepthBits; break; case GL_RENDERBUFFER_STENCIL_SIZE_EXT: *params = ctx->CurrentRenderbuffer->StencilBits; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetRenderbufferParameterivEXT(target)"); return; }}GLboolean GLAPIENTRY_mesa_IsFramebufferEXT(GLuint framebuffer){ GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (framebuffer) { struct gl_framebuffer *rb = _mesa_lookup_framebuffer(ctx, framebuffer); if (rb != NULL && rb != &DummyFramebuffer) return GL_TRUE; } return GL_FALSE;}static voidcheck_begin_texture_render(GLcontext *ctx, struct gl_framebuffer *fb){ GLuint i; ASSERT(ctx->Driver.RenderTexture); for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = fb->Attachment + i; struct gl_texture_object *texObj = att->Texture; if (texObj && att->Texture->Image[att->CubeMapFace][att->TextureLevel]) { ctx->Driver.RenderTexture(ctx, fb, att); } }}/** * Examine all the framebuffer's attachments to see if any are textures. * If so, call ctx->Driver.FinishRenderTexture() for each texture to * notify the device driver that the texture image may have changed. */static voidcheck_end_texture_render(GLcontext *ctx, struct gl_framebuffer *fb){ if (ctx->Driver.FinishRenderTexture) { GLuint i; for (i = 0; i < BUFFER_COUNT; i++) { struct gl_renderbuffer_attachment *att = fb->Attachment + i; struct gl_texture_object *texObj = att->Texture; if (texObj) { ctx->Driver.FinishRenderTexture(ctx, att); } } }}void GLAPIENTRY_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer){ struct gl_framebuffer *newFb, *oldFb; GLboolean bindReadBuf, bindDrawBuf; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (!ctx->Extensions.EXT_framebuffer_object) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFramebufferEXT(unsupported)"); return; } switch (target) {#if FEATURE_EXT_framebuffer_blit case GL_DRAW_FRAMEBUFFER_EXT: if (!ctx->Extensions.EXT_framebuffer_blit) { _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)"); return; } bindDrawBuf = GL_TRUE; bindReadBuf = GL_FALSE; break; case GL_READ_FRAMEBUFFER_EXT: if (!ctx->Extensions.EXT_framebuffer_blit) { _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)"); return; } bindDrawBuf = GL_FALSE; bindReadBuf = GL_TRUE; break;#endif case GL_FRAMEBUFFER_EXT: bindDrawBuf = GL_TRUE; bindReadBuf = GL_TRUE; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glBindFramebufferEXT(target)"); return; } FLUSH_VERTICES(ctx, _NEW_BUFFERS); if (framebuffer) { /* Binding a user-created framebuffer object */ newFb = _mesa_lookup_framebuffer(ctx, framebuffer); if (newFb == &DummyFramebuffer) { /* ID was reserved, but no real framebuffer object made yet */ newFb = NULL; } if (!newFb) { /* create new framebuffer object */ newFb = ctx->Driver.NewFramebuffer(ctx, framebuffer); if (!newFb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT"); return; } _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newFb); } _glthread_LOCK_MUTEX(newFb->Mutex); if (bindReadBuf) newFb->RefCount++; if (bindDrawBuf) newFb->RefCount++; _glthread_UNLOCK_MUTEX(newFb->Mutex); } else { /* Binding the window system framebuffer (which was originally set * with MakeCurrent). */ newFb = ctx->WinSysDrawBuffer; } ASSERT(newFb); ASSERT(newFb != &DummyFramebuffer); /* * XXX check if re-binding same buffer and skip some of this code. */ if (bindReadBuf) { oldFb = ctx->ReadBuffer; if (oldFb && oldFb->Name != 0) { _glthread_LOCK_MUTEX(oldFb->Mutex); oldFb->RefCount--; _glthread_UNLOCK_MUTEX(oldFb->Mutex); if (oldFb->RefCount == 0) { oldFb->Delete(oldFb); } } ctx->ReadBuffer = newFb; } if (bindDrawBuf) { oldFb = ctx->DrawBuffer; if (oldFb && oldFb->Name != 0) { /* check if old FB had any texture attachments */ check_end_texture_render(ctx, oldFb); /* check if time to delete this framebuffer */ _glthread_LOCK_MUTEX(oldFb->Mutex); oldFb->RefCount--; if (oldFb->RefCount == 0) { oldFb->Delete(oldFb); } _glthread_UNLOCK_MUTEX(oldFb->Mutex); } ctx->DrawBuffer = newFb; if (newFb->Name != 0) { /* check if newly bound framebuffer has any texture attachments */ check_begin_texture_render(ctx, newFb); } } if (ctx->Driver.BindFramebuffer) { ctx->Driver.BindFramebuffer(ctx, target, newFb); }}void GLAPIENTRY_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers){ GLint i; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_BUFFERS); for (i = 0; i < n; i++) { if (framebuffers[i] > 0) { struct gl_framebuffer *fb; fb = _mesa_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. */ _glthread_LOCK_MUTEX(fb->Mutex); fb->RefCount--; _glthread_UNLOCK_MUTEX(fb->Mutex); 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){ struct gl_framebuffer *buffer; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); switch (target) {#if FEATURE_EXT_framebuffer_blit case GL_DRAW_FRAMEBUFFER_EXT: if (!ctx->Extensions.EXT_framebuffer_blit) { _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)"); return 0; } buffer = ctx->DrawBuffer; break; case GL_READ_FRAMEBUFFER_EXT: if (!ctx->Extensions.EXT_framebuffer_blit) { _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)"); return 0; } buffer = ctx->ReadBuffer; break;#endif case GL_FRAMEBUFFER_EXT: buffer = ctx->DrawBuffer; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)"); return 0; /* formerly GL_FRAMEBUFFER_STATUS_ERROR_EXT */ } if (buffer->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, buffer); return buffer->_Status;}/** * Common code called by glFramebufferTexture1D/2D/3DEXT(). */static voidframebuffer_texture(GLuint dims, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset){ struct gl_renderbuffer_attachment *att; struct gl_texture_object *texObj = NULL; struct gl_framebuffer *fb; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (target != GL_FRAMEBUFFER_EXT) { _mesa_error(ctx, GL_INVALID_ENUM, "glFramebufferTexture%dDEXT(target)", dims); return; } fb = ctx->DrawBuffer; ASSERT(fb); /* check framebuffer binding */ if (fb->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferTexture%dDEXT", dims); return; } if (texture) { texObj = _mesa_lookup_texture(ctx, texture); } /* Check dimension-dependent things */ switch (dims) { case 1: if (textarget != GL_TEXTURE_1D) { _mesa_error(ctx, GL_INVALID_ENUM, "glFramebufferTexture1DEXT(textarget)"); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -