bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GLenum attachment, const char** reason) const { ASSERT(attachedObject && attachedObject->valid()); ASSERT(reason); GLenum internalformat = attachedObject->format(); switch (attachment) { case GL_DEPTH_ATTACHMENT: if (!isDepthRenderable(internalformat, context()->isWebGL2OrHigher())) { *reason = "the internalformat of the attached image is not depth-renderable"; return false; } break; case GL_STENCIL_ATTACHMENT: if (!isStencilRenderable(internalformat, context()->isWebGL2OrHigher())) { *reason = "the internalformat of the attached image is not stencil-renderable"; return false; } break; case GL_DEPTH_STENCIL_ATTACHMENT: ASSERT(!context()->isWebGL2OrHigher()); if (internalformat != GL_DEPTH_STENCIL_OES) { *reason = "the internalformat of the attached image is not DEPTH_STENCIL"; return false; } break; default: ASSERT(attachment == GL_COLOR_ATTACHMENT0 || (attachment > GL_COLOR_ATTACHMENT0 && attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + context()->maxColorAttachments()))); if (!isColorRenderable(internalformat, context()->extensionEnabled(EXTColorBufferFloatName))) { *reason = "the internalformat of the attached image is not color-renderable"; return false; } break; } if (!attachedObject->width() || !attachedObject->height()) { *reason = "attachment has a 0 dimension"; return false; } if (attachedObject->object()->isTexture() && !attachedObject->isCubeComplete()) { *reason = "attachment is not cube complete"; return false; } return true; }
bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GLenum attachment, const char** reason) const { ASSERT(attachedObject && attachedObject->valid()); ASSERT(reason); GLenum internalformat = attachedObject->format(); WebGLSharedObject* object = attachedObject->object(); ASSERT(object && (object->isTexture() || object->isRenderbuffer())); if (attachment == GL_DEPTH_ATTACHMENT) { if (object->isRenderbuffer()) { if (internalformat != GL_DEPTH_COMPONENT16) { *reason = "the internalformat of the attached renderbuffer is not DEPTH_COMPONENT16"; return false; } } else if (object->isTexture()) { GLenum type = attachedObject->type(); if (!(context()->extensionEnabled(WebGLDepthTextureName) && internalformat == GL_DEPTH_COMPONENT && (type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT))) { *reason = "the attached texture is not a depth texture"; return false; } } } else if (attachment == GL_STENCIL_ATTACHMENT) { // Depend on the underlying GL drivers to check stencil textures // and check renderbuffer type here only. if (object->isRenderbuffer()) { if (internalformat != GL_STENCIL_INDEX8) { *reason = "the internalformat of the attached renderbuffer is not STENCIL_INDEX8"; return false; } } } else if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL) { if (object->isRenderbuffer()) { if (internalformat != GL_DEPTH_STENCIL_OES) { *reason = "the internalformat of the attached renderbuffer is not DEPTH_STENCIL"; return false; } } else if (object->isTexture()) { GLenum type = attachedObject->type(); if (!(context()->extensionEnabled(WebGLDepthTextureName) && internalformat == GL_DEPTH_STENCIL_OES && type == GL_UNSIGNED_INT_24_8_OES)) { *reason = "the attached texture is not a DEPTH_STENCIL texture"; return false; } } } else if (attachment == GL_COLOR_ATTACHMENT0 || (context()->extensionEnabled(WebGLDrawBuffersName) && attachment > GL_COLOR_ATTACHMENT0 && attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + context()->maxColorAttachments()))) { if (object->isRenderbuffer()) { if (!isColorRenderable(internalformat)) { *reason = "the internalformat of the attached renderbuffer is not color-renderable"; return false; } } else if (object->isTexture()) { GLenum type = attachedObject->type(); if (internalformat != GL_RGBA && internalformat != GL_RGB && !(internalformat == GL_SRGB_ALPHA_EXT && context()->extensionEnabled(EXTsRGBName))) { *reason = "the internalformat of the attached texture is not color-renderable"; return false; } // TODO: WEBGL_color_buffer_float and EXT_color_buffer_half_float extensions have not been implemented in // WebGL yet. It would be better to depend on the underlying GL drivers to check on rendering to floating point textures // and add the check back to WebGL when above two extensions are implemented. // Assume UNSIGNED_BYTE is renderable here without the need to explicitly check if GL_OES_rgb8_rgba8 extension is supported. if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT_5_6_5 && type != GL_UNSIGNED_SHORT_4_4_4_4 && type != GL_UNSIGNED_SHORT_5_5_5_1 && !(type == GL_FLOAT && context()->extensionEnabled(OESTextureFloatName)) && !(type == GL_HALF_FLOAT_OES && context()->extensionEnabled(OESTextureHalfFloatName))) { *reason = "unsupported type: The attached texture is not supported to be rendered to"; return false; } } } else { *reason = "unknown framebuffer attachment point"; return false; } if (!attachedObject->width() || !attachedObject->height()) { *reason = "attachment has a 0 dimension"; return false; } return true; }