Renderer: Implement Framebuffers
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user