Renderer: Implement Framebuffers

This commit is contained in:
Jérôme Leclercq
2021-02-20 19:22:08 +01:00
parent 3ef74d6e1d
commit fb3468854f
32 changed files with 401 additions and 100 deletions

View File

@@ -126,6 +126,7 @@ namespace Nz::GL
bool Initialize(const ContextParams& params);
inline void NotifyBufferDestruction(GLuint buffer) const;
inline void NotifyFramebufferDestruction(GLuint fbo) const;
inline void NotifyProgramDestruction(GLuint program) const;
inline void NotifySamplerDestruction(GLuint sampler) const;
inline void NotifyTextureDestruction(GLuint texture) const;

View File

@@ -58,6 +58,15 @@ namespace Nz::GL
}
}
inline void Context::NotifyFramebufferDestruction(GLuint fbo) const
{
if (m_state.boundDrawFBO == fbo)
m_state.boundDrawFBO = 0;
if (m_state.boundReadFBO == fbo)
m_state.boundReadFBO = 0;
}
inline void Context::NotifyProgramDestruction(GLuint program) const
{
if (m_state.boundProgram == program)

View File

@@ -36,6 +36,7 @@ typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const G
cb(glBufferSubData, PFNGLBUFFERSUBDATAPROC) \
cb(glClear, PFNGLCLEARPROC) \
cb(glClearBufferfi, PFNGLCLEARBUFFERFIPROC) \
cb(glClearBufferfv, PFNGLCLEARBUFFERFVPROC) \
cb(glClearBufferuiv, PFNGLCLEARBUFFERUIVPROC) \
cb(glClearColor, PFNGLCLEARCOLORPROC) \
cb(glClearDepthf, PFNGLCLEARDEPTHFPROC) \
@@ -156,6 +157,9 @@ typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const G
\
extCb(glDebugMessageCallback, PFNGLDEBUGMESSAGECALLBACKPROC) \
\
extCb(glMemoryBarrier, PFNGLMEMORYBARRIERPROC) \
extCb(glMemoryBarrierByRegion, PFNGLMEMORYBARRIERBYREGIONPROC) \
\
extCb(glObjectLabel, PFNGLOBJECTLABELPROC) \
extCb(glPopDebugGroup, PFNGLPOPDEBUGGROUPPROC) \
extCb(glPushDebugGroup, PFNGLPUSHDEBUGGROUPPROC) \

View File

@@ -9,6 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/MovablePtr.hpp>
#include <Nazara/Core/MovableValue.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
#include <string>
@@ -26,6 +27,8 @@ namespace Nz::GL
bool Create(OpenGLDevice& device, CreateArgs... args);
void Destroy();
const Context& EnsureDeviceContext() const;
bool IsValid() const;
OpenGLDevice* GetDevice() const;
@@ -39,8 +42,6 @@ namespace Nz::GL
static constexpr GLuint InvalidObject = 0;
protected:
const Context& EnsureDeviceContext();
MovablePtr<OpenGLDevice> m_device;
MovableValue<GLuint> m_objectId;
};

View File

@@ -46,6 +46,24 @@ namespace Nz::GL
}
}
template<typename C, GLenum ObjectType, typename... CreateArgs>
const Context& DeviceObject<C, ObjectType, CreateArgs...>::EnsureDeviceContext() const
{
assert(m_device);
const Context* activeContext = Context::GetCurrentContext();
if (!activeContext || activeContext->GetDevice() != m_device)
{
const Context& referenceContext = m_device->GetReferenceContext();
if (!Context::SetCurrentContext(&referenceContext))
throw std::runtime_error("failed to activate context");
return referenceContext;
}
return *activeContext;
}
template<typename C, GLenum ObjectType, typename... CreateArgs>
bool DeviceObject<C, ObjectType, CreateArgs...>::IsValid() const
{
@@ -72,24 +90,6 @@ namespace Nz::GL
if (context.glObjectLabel)
context.glObjectLabel(ObjectType, m_objectId, name.size(), name.data());
}
template<typename C, GLenum ObjectType, typename... CreateArgs>
const Context& DeviceObject<C, ObjectType, CreateArgs...>::EnsureDeviceContext()
{
assert(m_device);
const Context* activeContext = Context::GetCurrentContext();
if (!activeContext || activeContext->GetDevice() != m_device)
{
const Context& referenceContext = m_device->GetReferenceContext();
if (!Context::SetCurrentContext(&referenceContext))
throw std::runtime_error("failed to activate context");
return referenceContext;
}
return *activeContext;
}
}
#include <Nazara/OpenGLRenderer/DebugOff.hpp>

View File

@@ -4,36 +4,38 @@
#pragma once
#ifndef NAZARA_OPENGLRENDERER_VKFRAMEBUFFER_HPP
#define NAZARA_OPENGLRENDERER_VKFRAMEBUFFER_HPP
#ifndef NAZARA_OPENGLRENDERER_GLFRAMEBUFFER_HPP
#define NAZARA_OPENGLRENDERER_GLFRAMEBUFFER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/DeviceObject.hpp>
namespace Nz
namespace Nz::GL
{
namespace Vk
class Framebuffer : public DeviceObject<Framebuffer, GL_FRAMEBUFFER>
{
class Framebuffer : public DeviceObject<Framebuffer, VkFramebuffer, VkFramebufferCreateInfo, VK_OBJECT_TYPE_FRAMEBUFFER>
{
friend DeviceObject;
friend DeviceObject;
public:
Framebuffer() = default;
Framebuffer(const Framebuffer&) = delete;
Framebuffer(Framebuffer&&) = default;
~Framebuffer() = default;
public:
Framebuffer() = default;
Framebuffer(const Framebuffer&) = delete;
Framebuffer(Framebuffer&&) noexcept = default;
~Framebuffer() = default;
Framebuffer& operator=(const Framebuffer&) = delete;
Framebuffer& operator=(Framebuffer&&) = delete;
inline GLenum Check() const;
private:
static inline VkResult CreateHelper(Device& device, const VkFramebufferCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkFramebuffer* handle);
static inline void DestroyHelper(Device& device, VkFramebuffer handle, const VkAllocationCallbacks* allocator);
};
}
inline void Renderbuffer(GLenum attachment, GLenum renderbuffer);
inline void Texture2D(GLenum attachment, GLenum textarget, GLuint texture, GLint level = 0);
Framebuffer& operator=(const Framebuffer&) = delete;
Framebuffer& operator=(Framebuffer&&) noexcept = default;
private:
static inline GLuint CreateHelper(OpenGLDevice& device, const Context& context);
static inline void DestroyHelper(OpenGLDevice& device, const Context& context, GLuint objectId);
};
}
#include <Nazara/OpenGLRenderer/Wrapper/Framebuffer.inl>
#endif // NAZARA_OPENGLRENDERER_VKFRAMEBUFFER_HPP
#endif

View File

@@ -3,21 +3,51 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/OpenGLRenderer/Wrapper/Framebuffer.hpp>
#include <Nazara/OpenGLRenderer/OpenGLDevice.hpp>
#include <Nazara/OpenGLRenderer/Debug.hpp>
namespace Nz
namespace Nz::GL
{
namespace Vk
inline GLenum Framebuffer::Check() const
{
inline VkResult Framebuffer::CreateHelper(Device& device, const VkFramebufferCreateInfo* createInfo, const VkAllocationCallbacks* allocator, VkFramebuffer* handle)
{
return device.vkCreateFramebuffer(device, createInfo, allocator, handle);
}
assert(m_objectId);
inline void Framebuffer::DestroyHelper(Device& device, VkFramebuffer handle, const VkAllocationCallbacks* allocator)
{
return device.vkDestroyFramebuffer(device, handle, allocator);
}
const Context& context = EnsureDeviceContext();
context.BindFramebuffer(m_objectId);
return context.glCheckFramebufferStatus(GL_FRAMEBUFFER);
}
inline void Framebuffer::Renderbuffer(GLenum attachment, GLenum renderbuffer)
{
assert(m_objectId);
const Context& context = EnsureDeviceContext();
context.BindFramebuffer(m_objectId);
context.glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, renderbuffer);
}
inline void Framebuffer::Texture2D(GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
assert(m_objectId);
const Context& context = EnsureDeviceContext();
context.BindFramebuffer(m_objectId);
context.glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, textarget, texture, level);
}
inline GLuint Framebuffer::CreateHelper(OpenGLDevice& /*device*/, const Context& context)
{
GLuint fbo = 0;
context.glGenFramebuffers(1U, &fbo);
return fbo;
}
inline void Framebuffer::DestroyHelper(OpenGLDevice& device, const Context& context, GLuint objectId)
{
context.glDeleteFramebuffers(1U, &objectId);
device.NotifyFramebufferDestruction(objectId);
}
}