renderer: add r_framebuffer_copy

This commit is contained in:
Andrei Alexeyev 2023-04-09 04:01:48 +02:00
parent 3dc0faec9e
commit b50b57803e
No known key found for this signature in database
GPG key ID: 72D26128040B9690
7 changed files with 31 additions and 0 deletions

View file

@ -597,6 +597,10 @@ void r_framebuffer_clear(Framebuffer *fb, BufferKindFlags flags, const Color *co
B.framebuffer_clear(fb, flags, colorval, depthval);
}
void r_framebuffer_copy(Framebuffer *dst, Framebuffer *src, BufferKindFlags flags) {
B.framebuffer_copy(dst, src, flags);
}
void r_framebuffer_viewport(Framebuffer *fb, float x, float y, float w, float h) {
r_framebuffer_viewport_rect(fb, (FloatRect) { x, y, w, h });
}

View file

@ -769,6 +769,7 @@ void r_framebuffer_viewport_rect(Framebuffer *fb, FloatRect viewport);
void r_framebuffer_viewport_current(Framebuffer *fb, FloatRect *viewport) attr_nonnull(2);
void r_framebuffer_destroy(Framebuffer *fb) attr_nonnull(1);
void r_framebuffer_clear(Framebuffer *fb, BufferKindFlags flags, const Color *colorval, float depthval);
void r_framebuffer_copy(Framebuffer *dst, Framebuffer *src, BufferKindFlags flags) attr_nonnull_all;
IntExtent r_framebuffer_get_size(Framebuffer *fb);
void r_framebuffer(Framebuffer *fb);

View file

@ -90,6 +90,7 @@ typedef struct RendererFuncs {
FramebufferAttachmentQueryResult (*framebuffer_query_attachment)(Framebuffer *framebuffer, FramebufferAttachment attachment);
void (*framebuffer_outputs)(Framebuffer *framebuffer, FramebufferAttachment config[FRAMEBUFFER_MAX_OUTPUTS], uint8_t write_mask);
void (*framebuffer_clear)(Framebuffer *framebuffer, BufferKindFlags flags, const Color *colorval, float depthval);
void (*framebuffer_copy)(Framebuffer *dst, Framebuffer *src, BufferKindFlags flags);
IntExtent (*framebuffer_get_size)(Framebuffer *framebuffer);
void (*framebuffer)(Framebuffer *framebuffer);

View file

@ -198,6 +198,27 @@ void gl33_framebuffer_clear(Framebuffer *framebuffer, BufferKindFlags flags, con
r_framebuffer(fb_saved);
}
void gl33_framebuffer_copy(Framebuffer *dst, Framebuffer *src, BufferKindFlags flags) {
GLuint glflags = buffer_flags_to_gl(flags);
r_flush_sprites();
IntExtent size = r_framebuffer_get_size(dst);
GLint X0 = 0;
GLint X1 = size.w;
GLint Y0 = 0;
GLint Y1 = size.h;
Framebuffer *fb_saved = r_framebuffer_current();
r_framebuffer(dst);
gl33_sync_framebuffer();
gl33_sync_scissor();
// TODO track this?
glBindFramebuffer(GL_READ_FRAMEBUFFER, src->gl_fbo);
glBlitFramebuffer(X0, Y0, X1, Y1, X0, Y0, X1, Y1, glflags, GL_NEAREST);
r_framebuffer(fb_saved);
}
IntExtent gl33_framebuffer_get_effective_size(Framebuffer *framebuffer) {
// According to the OpenGL wiki:
// "The effective size of the FBO is the intersection of all of the sizes of the bound images (ie: the smallest in each dimension)."

View file

@ -32,6 +32,7 @@ void gl33_framebuffer_outputs(Framebuffer *framebuffer, FramebufferAttachment co
void gl33_framebuffer_destroy(Framebuffer *framebuffer);
void gl33_framebuffer_taint(Framebuffer *framebuffer);
void gl33_framebuffer_clear(Framebuffer *framebuffer, BufferKindFlags flags, const Color *colorval, float depthval);
void gl33_framebuffer_copy(Framebuffer *dst, Framebuffer *src, BufferKindFlags flags);
IntExtent gl33_framebuffer_get_effective_size(Framebuffer *framebuffer);
void gl33_framebuffer_set_debug_label(Framebuffer *fb, const char *label);
const char *gl33_framebuffer_get_debug_label(Framebuffer* fb);

View file

@ -1500,6 +1500,7 @@ RendererBackend _r_backend_gl33 = {
.framebuffer = gl33_framebuffer,
.framebuffer_current = gl33_framebuffer_current,
.framebuffer_clear = gl33_framebuffer_clear,
.framebuffer_copy = gl33_framebuffer_copy,
.framebuffer_get_size = gl33_framebuffer_get_size,
.vertex_buffer_create = gl33_vertex_buffer_create,
.vertex_buffer_set_debug_label = gl33_vertex_buffer_set_debug_label,

View file

@ -130,6 +130,7 @@ static void null_framebuffer_viewport_current(Framebuffer *framebuffer, FloatRec
static void null_framebuffer(Framebuffer *framebuffer) { }
static Framebuffer* null_framebuffer_current(void) { return (void*)&placeholder; }
static void null_framebuffer_clear(Framebuffer *framebuffer, BufferKindFlags flags, const Color *colorval, float depthval) { }
static void null_framebuffer_copy(Framebuffer *dst, Framebuffer *src, BufferKindFlags flags) { }
static IntExtent null_framebuffer_get_size(Framebuffer *framebuffer) { return (IntExtent) { 64, 64 }; }
static int64_t null_vertex_buffer_stream_seek(SDL_RWops *rw, int64_t offset, int whence) { return 0; }
@ -254,6 +255,7 @@ RendererBackend _r_backend_null = {
.framebuffer = null_framebuffer,
.framebuffer_current = null_framebuffer_current,
.framebuffer_clear = null_framebuffer_clear,
.framebuffer_copy = null_framebuffer_copy,
.framebuffer_get_size = null_framebuffer_get_size,
.vertex_buffer_create = null_vertex_buffer_create,
.vertex_buffer_get_debug_label = null_vertex_buffer_get_debug_label,