Route RTT lifecycle through GL backend
This commit is contained in:
266
src/rtt.cpp
266
src/rtt.cpp
@@ -34,6 +34,120 @@ void bind_opengl_framebuffer(std::uint32_t target, std::uint32_t framebuffer) no
|
||||
glBindFramebuffer(static_cast<GLenum>(target), static_cast<GLuint>(framebuffer));
|
||||
}
|
||||
|
||||
void gen_opengl_textures(std::uint32_t count, std::uint32_t* ids) noexcept
|
||||
{
|
||||
glGenTextures(static_cast<GLsizei>(count), reinterpret_cast<GLuint*>(ids));
|
||||
}
|
||||
|
||||
void delete_opengl_textures(std::uint32_t count, const std::uint32_t* ids) noexcept
|
||||
{
|
||||
glDeleteTextures(static_cast<GLsizei>(count), reinterpret_cast<const GLuint*>(ids));
|
||||
}
|
||||
|
||||
void bind_opengl_texture(std::uint32_t target, std::uint32_t texture) noexcept
|
||||
{
|
||||
glBindTexture(static_cast<GLenum>(target), static_cast<GLuint>(texture));
|
||||
}
|
||||
|
||||
void set_opengl_texture_2d_image(
|
||||
std::uint32_t target,
|
||||
std::int32_t level,
|
||||
std::int32_t internal_format,
|
||||
std::int32_t width,
|
||||
std::int32_t height,
|
||||
std::int32_t border,
|
||||
std::uint32_t pixel_format,
|
||||
std::uint32_t component_type,
|
||||
const void* data) noexcept
|
||||
{
|
||||
glTexImage2D(
|
||||
static_cast<GLenum>(target),
|
||||
static_cast<GLint>(level),
|
||||
static_cast<GLint>(internal_format),
|
||||
static_cast<GLsizei>(width),
|
||||
static_cast<GLsizei>(height),
|
||||
static_cast<GLint>(border),
|
||||
static_cast<GLenum>(pixel_format),
|
||||
static_cast<GLenum>(component_type),
|
||||
data);
|
||||
}
|
||||
|
||||
void set_opengl_texture_parameter_f(std::uint32_t target, std::uint32_t parameter, float value) noexcept
|
||||
{
|
||||
glTexParameterf(static_cast<GLenum>(target), static_cast<GLenum>(parameter), static_cast<GLfloat>(value));
|
||||
}
|
||||
|
||||
void gen_opengl_renderbuffers(std::uint32_t count, std::uint32_t* ids) noexcept
|
||||
{
|
||||
glGenRenderbuffers(static_cast<GLsizei>(count), reinterpret_cast<GLuint*>(ids));
|
||||
}
|
||||
|
||||
void delete_opengl_renderbuffers(std::uint32_t count, const std::uint32_t* ids) noexcept
|
||||
{
|
||||
glDeleteRenderbuffers(static_cast<GLsizei>(count), reinterpret_cast<const GLuint*>(ids));
|
||||
}
|
||||
|
||||
void bind_opengl_renderbuffer(std::uint32_t target, std::uint32_t renderbuffer) noexcept
|
||||
{
|
||||
glBindRenderbuffer(static_cast<GLenum>(target), static_cast<GLuint>(renderbuffer));
|
||||
}
|
||||
|
||||
void set_opengl_renderbuffer_storage(
|
||||
std::uint32_t target,
|
||||
std::uint32_t internal_format,
|
||||
std::int32_t width,
|
||||
std::int32_t height) noexcept
|
||||
{
|
||||
glRenderbufferStorage(
|
||||
static_cast<GLenum>(target),
|
||||
static_cast<GLenum>(internal_format),
|
||||
static_cast<GLsizei>(width),
|
||||
static_cast<GLsizei>(height));
|
||||
}
|
||||
|
||||
void gen_opengl_framebuffers(std::uint32_t count, std::uint32_t* ids) noexcept
|
||||
{
|
||||
glGenFramebuffers(static_cast<GLsizei>(count), reinterpret_cast<GLuint*>(ids));
|
||||
}
|
||||
|
||||
void delete_opengl_framebuffers(std::uint32_t count, const std::uint32_t* ids) noexcept
|
||||
{
|
||||
glDeleteFramebuffers(static_cast<GLsizei>(count), reinterpret_cast<const GLuint*>(ids));
|
||||
}
|
||||
|
||||
void attach_opengl_framebuffer_texture_2d(
|
||||
std::uint32_t target,
|
||||
std::uint32_t attachment,
|
||||
std::uint32_t texture_target,
|
||||
std::uint32_t texture,
|
||||
std::int32_t level) noexcept
|
||||
{
|
||||
glFramebufferTexture2D(
|
||||
static_cast<GLenum>(target),
|
||||
static_cast<GLenum>(attachment),
|
||||
static_cast<GLenum>(texture_target),
|
||||
static_cast<GLuint>(texture),
|
||||
static_cast<GLint>(level));
|
||||
}
|
||||
|
||||
void attach_opengl_framebuffer_renderbuffer(
|
||||
std::uint32_t target,
|
||||
std::uint32_t attachment,
|
||||
std::uint32_t renderbuffer_target,
|
||||
std::uint32_t renderbuffer) noexcept
|
||||
{
|
||||
glFramebufferRenderbuffer(
|
||||
static_cast<GLenum>(target),
|
||||
static_cast<GLenum>(attachment),
|
||||
static_cast<GLenum>(renderbuffer_target),
|
||||
static_cast<GLuint>(renderbuffer));
|
||||
}
|
||||
|
||||
std::uint32_t check_opengl_framebuffer_status(std::uint32_t target) noexcept
|
||||
{
|
||||
return static_cast<std::uint32_t>(glCheckFramebufferStatus(static_cast<GLenum>(target)));
|
||||
}
|
||||
|
||||
void blit_opengl_framebuffer(
|
||||
std::int32_t source_x0,
|
||||
std::int32_t source_y0,
|
||||
@@ -243,18 +357,36 @@ void RTT::destroy()
|
||||
{
|
||||
if (rboID)
|
||||
{
|
||||
glDeleteRenderbuffers(1, &rboID);
|
||||
const auto status = pp::renderer::gl::delete_opengl_renderbuffer(
|
||||
static_cast<std::uint32_t>(rboID),
|
||||
pp::renderer::gl::OpenGlRenderbufferDeleteDispatch {
|
||||
.delete_renderbuffers = delete_opengl_renderbuffers,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("RTT::destroy renderbuffer delete failed because: %s", status.message);
|
||||
}
|
||||
if (texID)
|
||||
{
|
||||
//unbindTexture();
|
||||
glDeleteTextures(1, &texID);
|
||||
const auto status = pp::renderer::gl::delete_opengl_texture_2d(
|
||||
static_cast<std::uint32_t>(texID),
|
||||
pp::renderer::gl::OpenGlTexture2DDeleteDispatch {
|
||||
.delete_textures = delete_opengl_textures,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("RTT::destroy texture delete failed because: %s", status.message);
|
||||
//LOG("TEX rtt destroy %d", texID)
|
||||
}
|
||||
if (fboID)
|
||||
{
|
||||
//unbindFramebuffer();
|
||||
glDeleteFramebuffers(1, &fboID);
|
||||
const auto status = pp::renderer::gl::delete_opengl_framebuffer(
|
||||
static_cast<std::uint32_t>(fboID),
|
||||
pp::renderer::gl::OpenGlFramebufferDeleteDispatch {
|
||||
.delete_framebuffers = delete_opengl_framebuffers,
|
||||
});
|
||||
if (!status.ok())
|
||||
LOG("RTT::destroy framebuffer delete failed because: %s", status.message);
|
||||
//LOG("RTT DESTROY %d", fboID);
|
||||
}
|
||||
});
|
||||
@@ -354,7 +486,7 @@ bool RTT::create(int width, int height, int tex)
|
||||
|
||||
bool RTT::create(int width, int height, int tex/* = -1*/, GLint internal_format, bool depth_buffer /*= false*/)
|
||||
{
|
||||
GLenum status = 0;
|
||||
std::uint32_t status = 0;
|
||||
App::I->render_task([&]
|
||||
{
|
||||
// Destroy any previously created object
|
||||
@@ -366,7 +498,28 @@ bool RTT::create(int width, int height, int tex/* = -1*/, GLint internal_format,
|
||||
|
||||
if (tex == -1)
|
||||
{
|
||||
glGenTextures(1, &texID);
|
||||
const auto texture = pp::renderer::gl::allocate_opengl_texture_2d(
|
||||
pp::renderer::gl::OpenGlTexture2DAllocation {
|
||||
.width = width,
|
||||
.height = height,
|
||||
.internal_format = internal_format,
|
||||
.pixel_format = pp::renderer::gl::rgba_pixel_format(),
|
||||
.component_type = pp::renderer::gl::texture_upload_type_for_internal_format(
|
||||
static_cast<std::uint32_t>(internal_format)),
|
||||
.data = nullptr,
|
||||
},
|
||||
pp::renderer::gl::OpenGlTexture2DAllocationDispatch {
|
||||
.gen_textures = gen_opengl_textures,
|
||||
.bind_texture = bind_opengl_texture,
|
||||
.tex_image_2d = set_opengl_texture_2d_image,
|
||||
});
|
||||
if (!texture.ok())
|
||||
{
|
||||
LOG("RTT::create texture allocation failed because: %s", texture.status().message);
|
||||
status = 0;
|
||||
return;
|
||||
}
|
||||
texID = static_cast<GLuint>(texture.value());
|
||||
//LOG("TEX rtt create %d", texID);
|
||||
}
|
||||
else
|
||||
@@ -374,81 +527,72 @@ bool RTT::create(int width, int height, int tex/* = -1*/, GLint internal_format,
|
||||
texID = tex;
|
||||
}
|
||||
|
||||
const auto ifmt = static_cast<GLenum>(
|
||||
pp::renderer::gl::texture_upload_type_for_internal_format(static_cast<std::uint32_t>(internal_format)));
|
||||
|
||||
glBindTexture(texture_2d_target(), texID);
|
||||
if (tex == -1)
|
||||
glTexImage2D(
|
||||
texture_2d_target(),
|
||||
0,
|
||||
internal_format,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
static_cast<GLenum>(pp::renderer::gl::rgba_pixel_format()),
|
||||
ifmt,
|
||||
0);
|
||||
for (const auto parameter : pp::renderer::gl::default_render_target_texture_parameters())
|
||||
const auto parameter_status = pp::renderer::gl::set_opengl_texture_2d_parameters(
|
||||
static_cast<std::uint32_t>(texID),
|
||||
pp::renderer::gl::default_render_target_texture_parameters(),
|
||||
pp::renderer::gl::OpenGlTexture2DParameterDispatch {
|
||||
.bind_texture = bind_opengl_texture,
|
||||
.tex_parameter_f = set_opengl_texture_parameter_f,
|
||||
});
|
||||
if (!parameter_status.ok())
|
||||
{
|
||||
glTexParameterf(
|
||||
texture_2d_target(),
|
||||
static_cast<GLenum>(parameter.name),
|
||||
static_cast<GLfloat>(parameter.value));
|
||||
LOG("RTT::create texture parameter setup failed because: %s", parameter_status.message);
|
||||
status = 0;
|
||||
return;
|
||||
}
|
||||
glBindTexture(texture_2d_target(), 0);
|
||||
|
||||
// Create a renderbuffer object to store depth info
|
||||
if (depth_buffer)
|
||||
{
|
||||
glGenRenderbuffers(1, &rboID);
|
||||
glBindRenderbuffer(renderbuffer_target(), rboID);
|
||||
glRenderbufferStorage(
|
||||
renderbuffer_target(),
|
||||
static_cast<GLenum>(pp::renderer::gl::depth_component24_format()),
|
||||
const auto renderbuffer = pp::renderer::gl::allocate_opengl_depth_renderbuffer(
|
||||
width,
|
||||
height);
|
||||
glBindRenderbuffer(renderbuffer_target(), 0);
|
||||
height,
|
||||
pp::renderer::gl::OpenGlDepthRenderbufferAllocationDispatch {
|
||||
.gen_renderbuffers = gen_opengl_renderbuffers,
|
||||
.bind_renderbuffer = bind_opengl_renderbuffer,
|
||||
.renderbuffer_storage = set_opengl_renderbuffer_storage,
|
||||
});
|
||||
if (!renderbuffer.ok())
|
||||
{
|
||||
LOG("RTT::create depth renderbuffer allocation failed because: %s", renderbuffer.status().message);
|
||||
status = 0;
|
||||
return;
|
||||
}
|
||||
rboID = static_cast<GLuint>(renderbuffer.value());
|
||||
}
|
||||
|
||||
GLint oldFboID;
|
||||
glGetIntegerv(static_cast<GLenum>(pp::renderer::gl::draw_framebuffer_binding_query()), &oldFboID);
|
||||
|
||||
// Create a framebuffer object
|
||||
glGenFramebuffers(1, &fboID);
|
||||
glBindFramebuffer(framebuffer_target(), fboID);
|
||||
const auto framebuffer = pp::renderer::gl::allocate_opengl_render_target_framebuffer(
|
||||
static_cast<std::uint32_t>(texID),
|
||||
static_cast<std::uint32_t>(rboID),
|
||||
pp::renderer::gl::OpenGlRenderTargetFramebufferAllocationDispatch {
|
||||
.gen_framebuffers = gen_opengl_framebuffers,
|
||||
.get_integer = query_opengl_integer,
|
||||
.bind_framebuffer = bind_opengl_framebuffer,
|
||||
.framebuffer_texture_2d = attach_opengl_framebuffer_texture_2d,
|
||||
.framebuffer_renderbuffer = attach_opengl_framebuffer_renderbuffer,
|
||||
.check_framebuffer_status = check_opengl_framebuffer_status,
|
||||
});
|
||||
if (!framebuffer.ok())
|
||||
{
|
||||
LOG("RTT::create framebuffer allocation failed because: %s", framebuffer.status().message);
|
||||
status = 0;
|
||||
return;
|
||||
}
|
||||
fboID = static_cast<GLuint>(framebuffer.value().framebuffer_id);
|
||||
status = framebuffer.value().framebuffer_status;
|
||||
//LOG("RTT CREATE %d - tex %d", fboID, texID);
|
||||
|
||||
// Attach the texture to FBO color attachment point
|
||||
glFramebufferTexture2D(
|
||||
framebuffer_target(),
|
||||
static_cast<GLenum>(pp::renderer::gl::framebuffer_color_attachment()),
|
||||
texture_2d_target(),
|
||||
texID,
|
||||
0);
|
||||
if (depth_buffer)
|
||||
{
|
||||
// Attach the renderbuffer to depth attachment point
|
||||
glFramebufferRenderbuffer(
|
||||
framebuffer_target(),
|
||||
static_cast<GLenum>(pp::renderer::gl::framebuffer_depth_attachment()),
|
||||
renderbuffer_target(),
|
||||
rboID);
|
||||
}
|
||||
|
||||
// Check FBO status
|
||||
status = glCheckFramebufferStatus(framebuffer_target());
|
||||
if (status != static_cast<GLenum>(pp::renderer::gl::framebuffer_complete_status()))
|
||||
if (status != pp::renderer::gl::framebuffer_complete_status())
|
||||
LOG("RTT::create failed because: %s",
|
||||
pp::renderer::gl::framebuffer_status_name(static_cast<std::uint32_t>(status)));
|
||||
pp::renderer::gl::framebuffer_status_name(status));
|
||||
|
||||
// Switch back to window-system-provided framebuffer
|
||||
glBindFramebuffer(framebuffer_target(), oldFboID);
|
||||
oldRFboID = 0;
|
||||
oldDFboID = 0;
|
||||
});
|
||||
|
||||
return status == static_cast<GLenum>(pp::renderer::gl::framebuffer_complete_status());
|
||||
return status == pp::renderer::gl::framebuffer_complete_status();
|
||||
}
|
||||
|
||||
void RTT::bindFramebuffer()
|
||||
|
||||
Reference in New Issue
Block a user