GC3Denum WebGLFramebuffer::checkStatus() const { unsigned int count = 0; GC3Dsizei width = 0, height = 0; if (isDepthAttached()) { if (!isAttachmentComplete(m_depthAttachment.get(), GraphicsContext3D::DEPTH_ATTACHMENT)) return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT; width = getImageWidth(m_depthAttachment.get()); height = getImageHeight(m_depthAttachment.get()); count++; } if (isStencilAttached()) { if (!isAttachmentComplete(m_stencilAttachment.get(), GraphicsContext3D::STENCIL_ATTACHMENT)) return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT; if (!count) { width = getImageWidth(m_stencilAttachment.get()); height = getImageHeight(m_stencilAttachment.get()); } else { if (width != getImageWidth(m_stencilAttachment.get()) || height != getImageHeight(m_stencilAttachment.get())) return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS; } count++; } if (isDepthStencilAttached()) { if (!isAttachmentComplete(m_depthStencilAttachment.get(), GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT)) return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT; if (!isValidRenderbuffer(m_depthStencilAttachment.get())) return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED; if (!count) { width = getImageWidth(m_depthStencilAttachment.get()); height = getImageHeight(m_depthStencilAttachment.get()); } else { if (width != getImageWidth(m_depthStencilAttachment.get()) || height != getImageHeight(m_depthStencilAttachment.get())) return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS; } count++; } // WebGL specific: no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments. if (count > 1) return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED; if (isColorAttached()) { // FIXME: if color buffer is texture, is ALPHA, LUMINANCE or LUMINANCE_ALPHA valid? if (!getColorBufferFormat()) return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT; if (!count) { if (!getColorBufferWidth() || !getColorBufferHeight()) return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } else { if (width != getColorBufferWidth() || height != getColorBufferHeight()) return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS; } } else { if (!count) return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; } return GraphicsContext3D::FRAMEBUFFER_COMPLETE; }
GC3Denum WebGLFramebuffer::checkStatus(const char** reason) const { unsigned int count = 0; GC3Dsizei width = 0, height = 0; bool haveDepth = false; bool haveStencil = false; bool haveDepthStencil = false; for (AttachmentMap::const_iterator it = m_attachments.begin(); it != m_attachments.end(); ++it) { WebGLAttachment* attachment = it->value.get(); if (!isAttachmentComplete(attachment, it->key, reason)) return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT; if (!attachment->isValid()) { *reason = "attachment is not valid"; return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED; } if (!attachment->getFormat()) { *reason = "attachment is an unsupported format"; return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } switch (it->key) { case GraphicsContext3D::DEPTH_ATTACHMENT: haveDepth = true; break; case GraphicsContext3D::STENCIL_ATTACHMENT: haveStencil = true; break; case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT: haveDepthStencil = true; break; } if (!count) { width = attachment->getWidth(); height = attachment->getHeight(); } else { if (width != attachment->getWidth() || height != attachment->getHeight()) { *reason = "attachments do not have the same dimensions"; return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS; } } ++count; } if (!count) { *reason = "no attachments"; return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; } if (!width || !height) { *reason = "framebuffer has a 0 dimension"; return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } // WebGL specific: no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments. if ((haveDepthStencil && (haveDepth || haveStencil)) || (haveDepth && haveStencil)) { *reason = "conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments"; return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED; } return GraphicsContext3D::FRAMEBUFFER_COMPLETE; }
GLenum WebGLFramebuffer::checkStatus(const char** reason) const { unsigned count = 0; GLsizei width = 0, height = 0; bool haveDepth = false; bool haveStencil = false; bool haveDepthStencil = false; for (const auto& it : m_attachments) { WebGLAttachment* attachment = it.value.get(); if (!isAttachmentComplete(attachment, it.key, reason)) return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; if (!attachment->valid()) { *reason = "attachment is not valid"; return GL_FRAMEBUFFER_UNSUPPORTED; } if (!attachment->format()) { *reason = "attachment is an unsupported format"; return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } switch (it.key) { case GL_DEPTH_ATTACHMENT: haveDepth = true; break; case GL_STENCIL_ATTACHMENT: haveStencil = true; break; case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL: haveDepthStencil = true; break; } if (!count) { width = attachment->width(); height = attachment->height(); } else { if (width != attachment->width() || height != attachment->height()) { *reason = "attachments do not have the same dimensions"; return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; } } ++count; } if (!count) { *reason = "no attachments"; return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; } if (!width || !height) { *reason = "framebuffer has a 0 dimension"; return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } // WebGL specific: no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments. if ((haveDepthStencil && (haveDepth || haveStencil)) || (haveDepth && haveStencil)) { *reason = "conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments"; return GL_FRAMEBUFFER_UNSUPPORTED; } return GL_FRAMEBUFFER_COMPLETE; }
GLenum WebGLFramebuffer::checkStatus(const char** reason) const { unsigned count = 0; GLsizei width = 0, height = 0, depth = 0; WebGLAttachment* depthAttachment = nullptr; WebGLAttachment* stencilAttachment = nullptr; WebGLAttachment* depthStencilAttachment = nullptr; bool isWebGL2OrHigher = context()->isWebGL2OrHigher(); for (const auto& it : m_attachments) { WebGLAttachment* attachment = it.value.get(); if (!isAttachmentComplete(attachment, it.key, reason)) return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; if (!attachment->valid()) { *reason = "attachment is not valid"; return GL_FRAMEBUFFER_UNSUPPORTED; } if (!attachment->format()) { *reason = "attachment is an unsupported format"; return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } switch (it.key) { case GL_DEPTH_ATTACHMENT: depthAttachment = attachment; break; case GL_STENCIL_ATTACHMENT: stencilAttachment = attachment; break; case GL_DEPTH_STENCIL_ATTACHMENT: depthStencilAttachment = attachment; break; } // Note: In GLES 3, images for a framebuffer need not to have the same dimensions to be framebuffer complete. // However, in Direct3D 11, on top of which OpenGL ES 3 behavior is emulated in Windows, all render targets // must have the same size in all dimensions. In order to have consistent WebGL 2 behaviors across platforms, // we generate FRAMEBUFFER_INCOMPLETE_DIMENSIONS in this situation. if (!count) { width = attachment->width(); height = attachment->height(); depth = attachment->depth(); } else { if (width != attachment->width() || height != attachment->height() || depth != attachment->depth()) { *reason = "attachments do not have the same dimensions"; return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; } } ++count; } if (!count) { *reason = "no attachments"; return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; } // WebGL 1 specific: no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments. if (!isWebGL2OrHigher && ((depthStencilAttachment && (depthAttachment || stencilAttachment)) || (depthAttachment && stencilAttachment))) { *reason = "conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments"; return GL_FRAMEBUFFER_UNSUPPORTED; } if (isWebGL2OrHigher && (depthAttachment && stencilAttachment && depthAttachment->object() != stencilAttachment->object())) { *reason = "both DEPTH/STENCIL attachments are present and not the same image"; return GL_FRAMEBUFFER_UNSUPPORTED; } return GL_FRAMEBUFFER_COMPLETE; }
GLenum WebGLFramebuffer::checkStatus(const char** reason) const { unsigned count = 0; GLsizei width = 0, height = 0; WebGLAttachment* depthAttachment = nullptr; WebGLAttachment* stencilAttachment = nullptr; WebGLAttachment* depthStencilAttachment = nullptr; bool isWebGL2OrHigher = context()->isWebGL2OrHigher(); for (const auto& it : m_attachments) { WebGLAttachment* attachment = it.value.get(); if (!isAttachmentComplete(attachment, it.key, reason)) return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; if (!attachment->valid()) { *reason = "attachment is not valid"; return GL_FRAMEBUFFER_UNSUPPORTED; } if (!attachment->format()) { *reason = "attachment is an unsupported format"; return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } switch (it.key) { case GL_DEPTH_ATTACHMENT: depthAttachment = attachment; break; case GL_STENCIL_ATTACHMENT: stencilAttachment = attachment; break; case GL_DEPTH_STENCIL_ATTACHMENT: depthStencilAttachment = attachment; break; } if (!isWebGL2OrHigher) { if (!count) { width = attachment->width(); height = attachment->height(); } else { if (width != attachment->width() || height != attachment->height()) { *reason = "attachments do not have the same dimensions"; return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; } } } ++count; } if (!count) { *reason = "no attachments"; return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; } // WebGL 1 specific: no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments. if (!isWebGL2OrHigher && ((depthStencilAttachment && (depthAttachment || stencilAttachment)) || (depthAttachment && stencilAttachment))) { *reason = "conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments"; return GL_FRAMEBUFFER_UNSUPPORTED; } if (isWebGL2OrHigher && (depthAttachment && stencilAttachment && depthAttachment->object() != stencilAttachment->object())) { *reason = "both DEPTH/STENCIL attachments are present and not the same image"; return GL_FRAMEBUFFER_UNSUPPORTED; } return GL_FRAMEBUFFER_COMPLETE; }