Route RTT lifecycle through GL backend
This commit is contained in:
@@ -748,6 +748,33 @@ pp::foundation::Status update_opengl_texture_2d(
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status set_opengl_texture_2d_parameters(
|
||||
std::uint32_t texture_id,
|
||||
std::span<const OpenGlTextureParameter> parameters,
|
||||
OpenGlTexture2DParameterDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.bind_texture == nullptr || dispatch.tex_parameter_f == nullptr) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL texture parameter dispatch callbacks must not be null");
|
||||
}
|
||||
|
||||
if (texture_id == 0U || parameters.empty()) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL texture parameter request is invalid");
|
||||
}
|
||||
|
||||
for (const auto parameter : parameters) {
|
||||
if (parameter.name == 0U) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL texture parameter name is invalid");
|
||||
}
|
||||
}
|
||||
|
||||
dispatch.bind_texture(texture_2d_target(), texture_id);
|
||||
for (const auto parameter : parameters) {
|
||||
dispatch.tex_parameter_f(texture_2d_target(), parameter.name, static_cast<float>(parameter.value));
|
||||
}
|
||||
dispatch.bind_texture(texture_2d_target(), default_framebuffer_id());
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status copy_opengl_framebuffer_to_texture_2d(
|
||||
OpenGlTexture2DFramebufferCopy copy,
|
||||
OpenGlTexture2DFramebufferCopyDispatch dispatch) noexcept
|
||||
@@ -969,6 +996,78 @@ pp::foundation::Status restore_opengl_framebuffer_binding(
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Result<OpenGlRenderTargetFramebufferAllocationResult> allocate_opengl_render_target_framebuffer(
|
||||
std::uint32_t texture_id,
|
||||
std::uint32_t depth_renderbuffer_id,
|
||||
OpenGlRenderTargetFramebufferAllocationDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.gen_framebuffers == nullptr
|
||||
|| dispatch.get_integer == nullptr
|
||||
|| dispatch.bind_framebuffer == nullptr
|
||||
|| dispatch.framebuffer_texture_2d == nullptr
|
||||
|| dispatch.framebuffer_renderbuffer == nullptr
|
||||
|| dispatch.check_framebuffer_status == nullptr) {
|
||||
return pp::foundation::Result<OpenGlRenderTargetFramebufferAllocationResult>::failure(
|
||||
pp::foundation::Status::invalid_argument(
|
||||
"OpenGL render-target framebuffer allocation dispatch callbacks must not be null"));
|
||||
}
|
||||
|
||||
if (texture_id == 0U) {
|
||||
return pp::foundation::Result<OpenGlRenderTargetFramebufferAllocationResult>::failure(
|
||||
pp::foundation::Status::invalid_argument("OpenGL render-target framebuffer texture id is invalid"));
|
||||
}
|
||||
|
||||
std::int32_t old_framebuffer = 0;
|
||||
dispatch.get_integer(draw_framebuffer_binding_query(), &old_framebuffer);
|
||||
|
||||
std::uint32_t framebuffer_id = 0U;
|
||||
dispatch.gen_framebuffers(1U, &framebuffer_id);
|
||||
if (framebuffer_id == 0U) {
|
||||
dispatch.bind_framebuffer(framebuffer_target(), static_cast<std::uint32_t>(old_framebuffer));
|
||||
return pp::foundation::Result<OpenGlRenderTargetFramebufferAllocationResult>::failure(
|
||||
pp::foundation::Status::out_of_range("OpenGL render-target framebuffer allocation returned id 0"));
|
||||
}
|
||||
|
||||
dispatch.bind_framebuffer(framebuffer_target(), framebuffer_id);
|
||||
dispatch.framebuffer_texture_2d(
|
||||
framebuffer_target(),
|
||||
framebuffer_color_attachment(),
|
||||
texture_2d_target(),
|
||||
texture_id,
|
||||
0);
|
||||
if (depth_renderbuffer_id != 0U) {
|
||||
dispatch.framebuffer_renderbuffer(
|
||||
framebuffer_target(),
|
||||
framebuffer_depth_attachment(),
|
||||
renderbuffer_target(),
|
||||
depth_renderbuffer_id);
|
||||
}
|
||||
|
||||
const auto framebuffer_status = dispatch.check_framebuffer_status(framebuffer_target());
|
||||
dispatch.bind_framebuffer(framebuffer_target(), static_cast<std::uint32_t>(old_framebuffer));
|
||||
return pp::foundation::Result<OpenGlRenderTargetFramebufferAllocationResult>::success(
|
||||
OpenGlRenderTargetFramebufferAllocationResult {
|
||||
.framebuffer_id = framebuffer_id,
|
||||
.framebuffer_status = framebuffer_status,
|
||||
});
|
||||
}
|
||||
|
||||
pp::foundation::Status delete_opengl_framebuffer(
|
||||
std::uint32_t framebuffer_id,
|
||||
OpenGlFramebufferDeleteDispatch dispatch) noexcept
|
||||
{
|
||||
if (dispatch.delete_framebuffers == nullptr) {
|
||||
return pp::foundation::Status::invalid_argument("OpenGL framebuffer delete dispatch callback must not be null");
|
||||
}
|
||||
|
||||
if (framebuffer_id == 0U) {
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
dispatch.delete_framebuffers(1U, &framebuffer_id);
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Result<std::uint32_t> allocate_opengl_pixel_buffer(
|
||||
OpenGlPixelBufferAllocationDispatch dispatch) noexcept
|
||||
{
|
||||
|
||||
@@ -172,6 +172,11 @@ struct OpenGlTexture2DReadbackResult {
|
||||
bool pixels_read = false;
|
||||
};
|
||||
|
||||
struct OpenGlRenderTargetFramebufferAllocationResult {
|
||||
std::uint32_t framebuffer_id = 0;
|
||||
std::uint32_t framebuffer_status = 0;
|
||||
};
|
||||
|
||||
struct OpenGlShaderCompileInfo {
|
||||
std::uint32_t shader_id = 0;
|
||||
std::int32_t compile_status = 0;
|
||||
@@ -442,6 +447,7 @@ using OpenGlTexSubImage2DFn = void (*)(
|
||||
std::uint32_t pixel_format,
|
||||
std::uint32_t component_type,
|
||||
const void* data) noexcept;
|
||||
using OpenGlTexParameterfFn = void (*)(std::uint32_t target, std::uint32_t parameter, float value) noexcept;
|
||||
using OpenGlCopyTexSubImage2DFn = void (*)(
|
||||
std::uint32_t target,
|
||||
std::int32_t level,
|
||||
@@ -607,6 +613,11 @@ struct OpenGlTexture2DUpdateDispatch {
|
||||
OpenGlTexSubImage2DFn tex_sub_image_2d = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlTexture2DParameterDispatch {
|
||||
OpenGlBindTextureFn bind_texture = nullptr;
|
||||
OpenGlTexParameterfFn tex_parameter_f = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlTexture2DFramebufferCopyDispatch {
|
||||
OpenGlCopyTexSubImage2DFn copy_tex_sub_image_2d = nullptr;
|
||||
};
|
||||
@@ -648,6 +659,19 @@ struct OpenGlFramebufferRestoreDispatch {
|
||||
OpenGlBindFramebufferFn bind_framebuffer = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlRenderTargetFramebufferAllocationDispatch {
|
||||
OpenGlGenObjectsFn gen_framebuffers = nullptr;
|
||||
OpenGlGetIntegerFn get_integer = nullptr;
|
||||
OpenGlBindFramebufferFn bind_framebuffer = nullptr;
|
||||
OpenGlFramebufferTexture2DFn framebuffer_texture_2d = nullptr;
|
||||
OpenGlFramebufferRenderbufferFn framebuffer_renderbuffer = nullptr;
|
||||
OpenGlCheckFramebufferStatusFn check_framebuffer_status = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlFramebufferDeleteDispatch {
|
||||
OpenGlDeleteObjectsFn delete_framebuffers = nullptr;
|
||||
};
|
||||
|
||||
struct OpenGlPixelBufferAllocationDispatch {
|
||||
OpenGlGenObjectsFn gen_buffers = nullptr;
|
||||
};
|
||||
@@ -874,6 +898,10 @@ struct OpenGlMeshDeleteDispatch {
|
||||
[[nodiscard]] pp::foundation::Status update_opengl_texture_2d(
|
||||
OpenGlTexture2DUpdate update,
|
||||
OpenGlTexture2DUpdateDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status set_opengl_texture_2d_parameters(
|
||||
std::uint32_t texture_id,
|
||||
std::span<const OpenGlTextureParameter> parameters,
|
||||
OpenGlTexture2DParameterDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status copy_opengl_framebuffer_to_texture_2d(
|
||||
OpenGlTexture2DFramebufferCopy copy,
|
||||
OpenGlTexture2DFramebufferCopyDispatch dispatch) noexcept;
|
||||
@@ -895,6 +923,13 @@ struct OpenGlMeshDeleteDispatch {
|
||||
[[nodiscard]] pp::foundation::Status restore_opengl_framebuffer_binding(
|
||||
OpenGlFramebufferBindingState binding,
|
||||
OpenGlFramebufferRestoreDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Result<OpenGlRenderTargetFramebufferAllocationResult> allocate_opengl_render_target_framebuffer(
|
||||
std::uint32_t texture_id,
|
||||
std::uint32_t depth_renderbuffer_id,
|
||||
OpenGlRenderTargetFramebufferAllocationDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status delete_opengl_framebuffer(
|
||||
std::uint32_t framebuffer_id,
|
||||
OpenGlFramebufferDeleteDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Result<std::uint32_t> allocate_opengl_pixel_buffer(
|
||||
OpenGlPixelBufferAllocationDispatch dispatch) noexcept;
|
||||
[[nodiscard]] pp::foundation::Result<std::uint32_t> readback_opengl_framebuffer_to_pixel_buffer(
|
||||
|
||||
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