diff options
Diffstat (limited to 'src/Platform/OpenGL/OpenGLFramebuffer.cpp')
| -rw-r--r-- | src/Platform/OpenGL/OpenGLFramebuffer.cpp | 246 |
1 files changed, 0 insertions, 246 deletions
diff --git a/src/Platform/OpenGL/OpenGLFramebuffer.cpp b/src/Platform/OpenGL/OpenGLFramebuffer.cpp deleted file mode 100644 index c46e0e6..0000000 --- a/src/Platform/OpenGL/OpenGLFramebuffer.cpp +++ /dev/null @@ -1,246 +0,0 @@ -#include "OpenGLFramebuffer.h" -#include "Core/Log.h" - -#include <glad/glad.h> - -namespace Donut -{ - namespace Utils - { - static GLenum TextureTarget(bool multisampled) - { - return multisampled ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; - } - - static void BindTexture(bool multisampled, uint32_t id) - { - glBindTexture(TextureTarget(multisampled), id); - } - - static void CreateTextures(bool multisampled, uint32_t* outID, uint32_t count) - { - // glCreateTextures is 4.5 DSA; macOS caps at 4.1. Callers bind each - // texture (with the correct target) before use. - glGenTextures(count, outID); - } - - static void AttachColorTexture(uint32_t id, int samples, GLenum internalFormat, GLenum format, uint32_t width, uint32_t height, int index) - { - bool multisampled = samples > 1; - if (multisampled) - { - glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalFormat, width, height, GL_FALSE); - } - else - { - // Integer color formats require an integer pixel type even when - // data is null, or macOS's strict core profile rejects the call. - GLenum type = (format == GL_RED_INTEGER) ? GL_INT : GL_UNSIGNED_BYTE; - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index, TextureTarget(multisampled), id, 0); - } - - static void AttachDepthTexture(uint32_t id, int samples, GLenum format, GLenum attachmentType, uint32_t width, uint32_t height) - { - bool multisampled = samples > 1; - if (multisampled) - { - glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, format, width, height, GL_FALSE); - } - else - { - // glTexStorage2D is 4.2; use mutable storage for macOS (4.1). - GLenum depthFormat = (format == GL_DEPTH24_STENCIL8) ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT; - GLenum depthType = (format == GL_DEPTH24_STENCIL8) ? GL_UNSIGNED_INT_24_8 : GL_FLOAT; - glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, depthFormat, depthType, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - - glFramebufferTexture2D(GL_FRAMEBUFFER, attachmentType, TextureTarget(multisampled), id, 0); - } - - static bool IsDepthFormat(FramebufferTextureFormat format) - { - switch (format) - { - case FramebufferTextureFormat::DEPTH24STENCIL8: return true; - } - return false; - } - - static GLenum DonutFBTextureFormatToGL(FramebufferTextureFormat format) - { - switch (format) - { - case FramebufferTextureFormat::RGBA8: return GL_RGBA8; - case FramebufferTextureFormat::RED_INTEGER: return GL_RED_INTEGER; - } - - return 0; - } - } - - OpenGLFramebuffer::OpenGLFramebuffer(const FramebufferSpecification& spec) - : m_Specification(spec) - { - for (auto spec : m_Specification.Attachments.Attachments) - { - if (!Utils::IsDepthFormat(spec.TextureFormat)) - m_ColorAttachmentSpecifications.emplace_back(spec); - else - m_DepthAttachmentSpecification = spec; - } - - Invalidate(); - } - - OpenGLFramebuffer::~OpenGLFramebuffer() - { - glDeleteFramebuffers(1, &m_RendererID); - glDeleteTextures(static_cast<GLsizei>(m_ColorAttachments.size()), m_ColorAttachments.data()); - glDeleteTextures(1, &m_DepthAttachment); - } - - void OpenGLFramebuffer::Invalidate() - { - if (m_RendererID) - { - glDeleteFramebuffers(1, &m_RendererID); - glDeleteTextures(static_cast<GLsizei>(m_ColorAttachments.size()), m_ColorAttachments.data()); - glDeleteTextures(1, &m_DepthAttachment); - - m_ColorAttachments.clear(); - m_DepthAttachment = 0; - } - - glGenFramebuffers(1, &m_RendererID); // glCreateFramebuffers is 4.5 DSA; unavailable on macOS 4.1 - glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID); - - bool multisample = m_Specification.Samples > 1; - - if (m_ColorAttachmentSpecifications.size()) - { - m_ColorAttachments.resize(m_ColorAttachmentSpecifications.size()); - Utils::CreateTextures(multisample, m_ColorAttachments.data(), static_cast<uint32_t>(m_ColorAttachments.size())); - - for (size_t i = 0; i < m_ColorAttachments.size(); i++) - { - Utils::BindTexture(multisample, m_ColorAttachments[i]); - switch (m_ColorAttachmentSpecifications[i].TextureFormat) - { - case FramebufferTextureFormat::RGBA8: - Utils::AttachColorTexture(m_ColorAttachments[i], m_Specification.Samples, GL_RGBA8, GL_RGBA, m_Specification.Width, m_Specification.Height, static_cast<int>(i)); - break; - case FramebufferTextureFormat::RED_INTEGER: - Utils::AttachColorTexture(m_ColorAttachments[i], m_Specification.Samples, GL_R32I, GL_RED_INTEGER, m_Specification.Width, m_Specification.Height, static_cast<int>(i)); - break; - } - } - } - - if (m_DepthAttachmentSpecification.TextureFormat != FramebufferTextureFormat::None) - { - Utils::CreateTextures(multisample, &m_DepthAttachment, 1); - Utils::BindTexture(multisample, m_DepthAttachment); - switch (m_DepthAttachmentSpecification.TextureFormat) - { - case FramebufferTextureFormat::DEPTH24STENCIL8: - Utils::AttachDepthTexture(m_DepthAttachment, m_Specification.Samples, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL_ATTACHMENT, m_Specification.Width, m_Specification.Height); - break; - } - } - - if (m_ColorAttachments.size() > 1) - { - GLenum buffers[4] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; - glDrawBuffers(static_cast<GLsizei>(m_ColorAttachments.size()), buffers); - } - else if (m_ColorAttachments.empty()) - glDrawBuffer(GL_NONE); - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - { - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - switch (status) - { - case GL_FRAMEBUFFER_UNDEFINED: - DONUT_ERROR("Framebuffer is undefined"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - DONUT_ERROR("Framebuffer has incomplete attachment"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - DONUT_ERROR("Framebuffer is missing attachment"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - DONUT_ERROR("Framebuffer has incomplete draw buffer"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - DONUT_ERROR("Framebuffer has incomplete read buffer"); - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - DONUT_ERROR("Framebuffer format is unsupported"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: - DONUT_ERROR("Framebuffer has incomplete multisample"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: - DONUT_ERROR("Framebuffer has incomplete layer targets"); - break; - default: - DONUT_ERROR("Framebuffer is incomplete (unknown error: {})", status); - break; - } - } - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - - void OpenGLFramebuffer::Bind() - { - glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID); - glViewport(0, 0, m_Specification.Width, m_Specification.Height); - } - - void OpenGLFramebuffer::Unbind() - { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - - void OpenGLFramebuffer::Resize(uint32_t width, uint32_t height) - { - m_Specification.Width = width; - m_Specification.Height = height; - - Invalidate(); - } - - int OpenGLFramebuffer::ReadPixel(uint32_t attachmentIndex, int x, int y) - { - glReadBuffer(GL_COLOR_ATTACHMENT0 + attachmentIndex); - int pixelData; - glReadPixels(x, y, 1, 1, GL_RED_INTEGER, GL_INT, &pixelData); - return pixelData; - } - - void OpenGLFramebuffer::ClearAttachment(uint32_t attachmentIndex, int value) - { - // glClearTexImage is 4.4 and unavailable on macOS. Clear the integer - // attachment by binding this framebuffer and clearing its draw buffer. - glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID); - glClearBufferiv(GL_COLOR, static_cast<GLint>(attachmentIndex), &value); - } -}; |
