Implemented a new FrameBuffer class.

This commit is contained in:
Relintai 2024-01-19 22:03:10 +01:00
parent fad67db0ee
commit 5064a388e6
8 changed files with 417 additions and 0 deletions

View File

@ -71,6 +71,7 @@ ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/material.cpp -o sfw/re
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/mesh.cpp -o sfw/render_core/mesh.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/mesh_utils.cpp -o sfw/render_core/mesh_utils.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/texture.cpp -o sfw/render_core/texture.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/frame_buffer.cpp -o sfw/render_core/frame_buffer.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/image.cpp -o sfw/render_core/image.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/render_state.cpp -o sfw/render_core/render_state.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/keyboard.cpp -o sfw/render_core/keyboard.o
@ -126,6 +127,7 @@ ccache g++ -Wall -lX11 -D_REENTRANT -g sfw/core/aabb.o sfw/core/basis.o sfw/core
sfw/render_core/application.o sfw/render_core/scene.o sfw/render_core/app_window.o \
sfw/render_core/shader.o sfw/render_core/material.o sfw/render_core/mesh.o \
sfw/render_core/mesh_utils.o sfw/render_core/texture.o \
sfw/render_core/frame_buffer.o \
sfw/render_core/input_event.o sfw/render_core/input_map.o \
sfw/render_core/input.o sfw/render_core/shortcut.o \
sfw/render_core/keyboard.o sfw/render_core/font.o \

View File

@ -75,6 +75,7 @@ clang++ $args -D_REENTRANT -g -Isfw -c sfw/render_core/material.cpp -o sfw/rende
clang++ $args -D_REENTRANT -g -Isfw -c sfw/render_core/mesh.cpp -o sfw/render_core/mesh.o
clang++ $args -D_REENTRANT -g -Isfw -c sfw/render_core/mesh_utils.cpp -o sfw/render_core/mesh_utils.o
clang++ $args -D_REENTRANT -g -Isfw -c sfw/render_core/texture.cpp -o sfw/render_core/texture.o
clang++ $args -D_REENTRANT -g -Isfw -c sfw/render_core/frame_buffer.cpp -o sfw/render_core/frame_buffer.o
clang++ $args -D_REENTRANT -g -Isfw -c sfw/render_core/image.cpp -o sfw/render_core/image.o
clang++ $args -D_REENTRANT -g -Isfw -c sfw/render_core/render_state.cpp -o sfw/render_core/render_state.o
clang++ $args -D_REENTRANT -g -Isfw -c sfw/render_core/keyboard.cpp -o sfw/render_core/keyboard.o
@ -132,6 +133,7 @@ clang++ $args -D_REENTRANT -g sfw/core/aabb.o sfw/core/basis.o sfw/core/color.o
sfw/render_core/application.o sfw/render_core/scene.o sfw/render_core/app_window.o \
sfw/render_core/shader.o sfw/render_core/material.o sfw/render_core/mesh.o \
sfw/render_core/mesh_utils.o sfw/render_core/texture.o \
sfw/render_core/frame_buffer.o \
sfw/render_core/input_event.o sfw/render_core/input_map.o \
sfw/render_core/input.o sfw/render_core/shortcut.o \
sfw/render_core/keyboard.o sfw/render_core/font.o \

View File

@ -72,6 +72,7 @@ cl /D_REENTRANT /EHsc /Zi /Isfw /c sfw/render_core/material.cpp /Fo:sfw/render_c
cl /D_REENTRANT /EHsc /Zi /Isfw /c sfw/render_core/mesh.cpp /Fo:sfw/render_core/mesh.obj
cl /D_REENTRANT /EHsc /Zi /Isfw /c sfw/render_core/mesh_utils.cpp /Fo:sfw/render_core/mesh_utils.obj
cl /D_REENTRANT /EHsc /Zi /Isfw /c sfw/render_core/texture.cpp /Fo:sfw/render_core/texture.obj
cl /D_REENTRANT /EHsc /Zi /Isfw /c sfw/render_core/frame_buffer.cpp /Fo:sfw/render_core/frame_buffer.obj
cl /D_REENTRANT /EHsc /Zi /Isfw /c sfw/render_core/image.cpp /Fo:sfw/render_core/image.obj
cl /D_REENTRANT /EHsc /Zi /Isfw /c sfw/render_core/render_state.cpp /Fo:sfw/render_core/render_state.obj
cl /D_REENTRANT /EHsc /Zi /Isfw /c sfw/render_core/keyboard.cpp /Fo:sfw/render_core/keyboard.obj
@ -138,6 +139,7 @@ cl /D_REENTRANT /Zi ^
sfw/render_core/application.obj sfw/render_core/scene.obj sfw/render_core/app_window.obj ^
sfw/render_core/shader.obj sfw/render_core/material.obj sfw/render_core/mesh.obj ^
sfw/render_core/mesh_utils.obj sfw/render_core/texture.obj ^
sfw/render_core/frame_buffer.obj ^
sfw/render_core/input_event.obj sfw/render_core/input_map.obj ^
sfw/render_core/input.obj sfw/render_core/shortcut.obj ^
sfw/render_core/keyboard.obj sfw/render_core/font.obj ^

View File

@ -72,6 +72,7 @@ ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/material.cpp -o sfw/re
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/mesh.cpp -o sfw/render_core/mesh.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/mesh_utils.cpp -o sfw/render_core/mesh_utils.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/texture.cpp -o sfw/render_core/texture.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/frame_buffer.cpp -o sfw/render_core/frame_buffer.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/image.cpp -o sfw/render_core/image.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/render_state.cpp -o sfw/render_core/render_state.o
ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/keyboard.cpp -o sfw/render_core/keyboard.o
@ -128,6 +129,7 @@ ccache g++ -Wall \
sfw/render_core/application.o sfw/render_core/scene.o sfw/render_core/window.o \
sfw/render_core/shader.o sfw/render_core/material.o sfw/render_core/mesh.o \
sfw/render_core/mesh_utils.o sfw/render_core/texture.o \
sfw/render_core/frame_buffer.o \
sfw/render_core/input_event.o sfw/render_core/input_map.o \
sfw/render_core/input.o sfw/render_core/shortcut.o \
sfw/render_core/keyboard.o sfw/render_core/font.o \

View File

@ -0,0 +1,317 @@
//--STRIP
#include "render_core/frame_buffer.h"
#include "core/memory.h"
#include <stdio.h>
#include "render_core/app_window.h"
//--STRIP
int FrameBuffer::get_texture_flags() const {
return _texture_flags;
}
void FrameBuffer::set_texture_flags(const int p_flags) {
_texture_flags = p_flags;
}
int FrameBuffer::create(const int p_width, const int p_height, const int p_msaa_count) {
ERR_FAIL_COND_V(p_width <= 0, -1);
ERR_FAIL_COND_V(p_height <= 0, -1);
ERR_FAIL_COND_V(p_msaa_count < 0, -1);
int max_msaa_levels = 0;
glGetIntegerv(GL_MAX_SAMPLES, &max_msaa_levels);
int msaa = MIN(max_msaa_levels, p_msaa_count);
if (msaa % 2 == 0) {
--msaa;
}
_fbo_width = p_width;
_fbo_height = p_height;
_fbo_msaa_count = msaa;
destroy();
glGenFramebuffers(1, &_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_2D, _texture);
if ((_texture_flags & FRAMEBUFFER_TEXTURE_FLAG_MIP_MAPS)) {
if ((_texture_flags & FRAMEBUFFER_TEXTURE_FLAG_FILTER)) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
}
} else {
if ((_texture_flags & FRAMEBUFFER_TEXTURE_FLAG_FILTER)) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
}
if ((_texture_flags & FRAMEBUFFER_TEXTURE_FLAG_FILTER)) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering
}
if ((_texture_flags & FRAMEBUFFER_TEXTURE_FLAG_REPEAT) || (_texture_flags & FRAMEBUFFER_TEXTURE_FLAG_MIRRORED_REPEAT)) {
if (_texture_flags & FRAMEBUFFER_TEXTURE_FLAG_MIRRORED_REPEAT) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
} else {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
} else {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, ((_texture_flags & FRAMEBUFFER_TEXTURE_FLAG_MIP_MAPS) > 0) ? GL_TRUE : GL_FALSE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _fbo_width, _fbo_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0);
int status = get_status();
if (status != GL_FRAMEBUFFER_COMPLETE) {
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return status;
}
if (_fbo_msaa_count > 0) {
glGenFramebuffers(1, &_msaa_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, _msaa_fbo);
glGenRenderbuffers(1, &_msaa_rbo_color);
glBindRenderbuffer(GL_RENDERBUFFER, _msaa_rbo_color);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, _fbo_msaa_count, GL_RGBA8, _fbo_width, _fbo_height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _msaa_rbo_color);
glGenRenderbuffers(1, &_msaa_rbo_depth);
glBindRenderbuffer(GL_RENDERBUFFER, _msaa_rbo_depth);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, _fbo_msaa_count, GL_DEPTH_COMPONENT, _fbo_width, _fbo_height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _msaa_rbo_depth);
status = get_status();
}
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return status;
}
void FrameBuffer::destroy() {
if (!_fbo) {
return;
}
if (_msaa_rbo_color) {
glDeleteRenderbuffers(1, &_msaa_rbo_color);
_msaa_rbo_color = 0;
}
if (_msaa_rbo_depth) {
glDeleteRenderbuffers(1, &_msaa_rbo_depth);
_msaa_rbo_depth = 0;
}
if (_msaa_fbo) {
glDeleteFramebuffers(1, &_msaa_fbo);
_msaa_fbo = 0;
}
if (_texture) {
glDeleteTextures(1, &_texture);
_texture = 0;
}
if (_rbo) {
glDeleteRenderbuffers(1, &_rbo);
_rbo = 0;
}
if (_fbo) {
glDeleteFramebuffers(1, &_fbo);
_fbo = 0;
}
}
int FrameBuffer::get_status() {
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
return status;
}
uint32_t FrameBuffer::get_gl_fbo() {
if (!_msaa_fbo) {
return _fbo;
}
return _msaa_fbo;
}
uint32_t FrameBuffer::get_gl_texture() {
return _texture;
}
void FrameBuffer::bind() {
glBindFramebuffer(GL_FRAMEBUFFER, get_gl_fbo());
}
void FrameBuffer::unbind() {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void FrameBuffer::update() {
if (_fbo_msaa_count > 0) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, _msaa_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo);
glBlitFramebuffer(0, 0, _fbo_width, _fbo_height, 0, 0, _fbo_width, _fbo_height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
glBlitFramebuffer(0, 0, _fbo_width, _fbo_height, 0, 0, _fbo_width, _fbo_height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
}
if (((_texture_flags & FRAMEBUFFER_TEXTURE_FLAG_MIP_MAPS) > 0)) {
glBindTexture(GL_TEXTURE_2D, _texture);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
Ref<Image> FrameBuffer::get_image_color() {
Ref<Image> img;
img.instance();
Vector<uint8_t> cb = get_color_buffer();
img->create(_fbo_width, _fbo_height, false, Image::FORMAT_RGBA8, cb);
if (((_texture_flags & FRAMEBUFFER_TEXTURE_FLAG_MIP_MAPS) > 0)) {
img->generate_mipmaps();
}
return img;
}
Ref<Image> FrameBuffer::get_image_depth() {
Ref<Image> img;
img.instance();
Vector<float> db = get_depth_buffer();
img->create(_fbo_width, _fbo_height, false, Image::FORMAT_RF);
ERR_FAIL_COND_V(db.size() * (int)sizeof(float) != img->get_data_size(), img);
const float *db_ptr = db.ptr();
float *ifptr = (float *)img->dataw();
int db_size = db.size();
for (int i = 0; i < db_size; ++i) {
ifptr[i] = db_ptr[i];
}
if (((_texture_flags & FRAMEBUFFER_TEXTURE_FLAG_MIP_MAPS) > 0)) {
img->generate_mipmaps();
}
return img;
}
Vector<uint8_t> FrameBuffer::get_color_buffer() {
Vector<uint8_t> color_buffer;
color_buffer.resize(_fbo_width * _fbo_height * 4);
if (_fbo_msaa_count > 0) {
blit_color_to(_fbo);
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, _fbo);
glReadPixels(0, 0, _fbo_width, _fbo_height, GL_RGBA, GL_UNSIGNED_BYTE, color_buffer.ptrw());
return color_buffer;
}
Vector<float> FrameBuffer::get_depth_buffer() {
Vector<float> depth_buffer;
depth_buffer.resize(_fbo_width * _fbo_height);
if (_fbo_msaa_count > 0) {
blit_depth_to(_fbo);
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, _fbo);
glReadPixels(0, 0, _fbo_width, _fbo_height, GL_DEPTH_COMPONENT, GL_FLOAT, depth_buffer.ptrw());
return depth_buffer;
}
Vector2i FrameBuffer::get_size() const {
return Vector2i(_fbo_width, _fbo_height);
}
void FrameBuffer::blit_color_to(const uint32_t p_destination_framebuffer, const Rect2i &p_rect) {
ERR_FAIL_COND(!p_destination_framebuffer);
int width = p_rect.size.width == 0 ? p_rect.size.width : _fbo_width;
int height = p_rect.size.height == 0 ? p_rect.size.height : _fbo_height;
uint32_t fbo = get_gl_fbo();
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, p_destination_framebuffer);
glBlitFramebuffer(0, 0, _fbo_width, _fbo_height, p_rect.position.x, p_rect.position.y, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
}
void FrameBuffer::blit_depth_to(const uint32_t p_destination_framebuffer, const Rect2i &p_rect) {
ERR_FAIL_COND(!p_destination_framebuffer);
int width = p_rect.size.width == 0 ? p_rect.size.width : _fbo_width;
int height = p_rect.size.height == 0 ? p_rect.size.height : _fbo_height;
uint32_t fbo = get_gl_fbo();
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, p_destination_framebuffer);
glBlitFramebuffer(0, 0, _fbo_width, _fbo_height, p_rect.position.x, p_rect.position.y, width, height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
}
void FrameBuffer::set_as_viewport() {
glViewport(0, 0, _fbo_width, _fbo_height);
}
void FrameBuffer::reset_as_viewport() {
glViewport(0, 0, AppWindow::get_singleton()->get_width(), AppWindow::get_singleton()->get_height());
}
float FrameBuffer::get_aspect() const {
return _fbo_width / (float)_fbo_height;
}
FrameBuffer::FrameBuffer() {
_texture = 0;
_msaa_fbo = 0;
_msaa_rbo_color = 0;
_msaa_rbo_depth = 0;
_fbo_width = 0;
_fbo_height = 0;
_fbo_msaa_count = 0;
_rbo = 0;
_fbo = 0;
_texture_flags = 0;
}
FrameBuffer::~FrameBuffer() {
destroy();
}

View File

@ -0,0 +1,78 @@
//--STRIP
#ifndef FRAME_BUFFER_H
#define FRAME_BUFFER_H
//--STRIP
//--STRIP
#include "core/vector2i.h"
#include "object/resource.h"
#include "render_core/3rd_glad.h"
#include "render_core/image.h"
//--STRIP
class FrameBuffer : public Resource {
SFW_OBJECT(FrameBuffer, Resource);
public:
enum FrameBufferFlags {
FRAMEBUFFER_TEXTURE_FLAG_FILTER = 1 << 0,
FRAMEBUFFER_TEXTURE_FLAG_REPEAT = 1 << 1,
FRAMEBUFFER_TEXTURE_FLAG_MIRRORED_REPEAT = 1 << 2,
FRAMEBUFFER_TEXTURE_FLAG_MIP_MAPS = 1 << 3,
};
int get_texture_flags() const;
void set_texture_flags(const int p_flags);
int create(const int p_width, const int p_height, const int p_msaa_count = 0);
void destroy();
int get_status();
uint32_t get_gl_fbo();
uint32_t get_gl_texture();
void bind();
void unbind();
void update();
Ref<Image> get_image_color();
Ref<Image> get_image_depth();
Vector<uint8_t> get_color_buffer();
Vector<float> get_depth_buffer();
Vector2i get_size() const;
void blit_color_to(const uint32_t p_destination_framebuffer, const Rect2i &p_rect = Rect2i());
void blit_depth_to(const uint32_t p_destination_framebuffer, const Rect2i &p_rect = Rect2i());
void set_as_viewport();
void reset_as_viewport();
float get_aspect() const;
FrameBuffer();
virtual ~FrameBuffer();
protected:
uint32_t _texture;
uint32_t _msaa_fbo;
uint32_t _msaa_rbo_color;
uint32_t _msaa_rbo_depth;
int _fbo_width;
int _fbo_height;
int _fbo_msaa_count;
uint32_t _rbo;
uint32_t _fbo;
int _texture_flags;
};
//--STRIP
#endif // TEXTURE_H
//--STRIP

View File

@ -503,12 +503,19 @@
{{FILE:sfw/render_core/font_data_bm_mini.inc.h}}
{{FILE:sfw/render_core/font_data_tables.inc.h}}
//--STRIP
//#include "render_core/texture.h"
//#include "core/memory.h"
//#include "render_core/app_window.h"
//--STRIP
{{FILE:sfw/render_core/frame_buffer.cpp}}
//--STRIP
//#include "render_core/texture.h"
//#include "core/memory.h"
//#include "render_core/app_window.h"
//--STRIP
{{FILE:sfw/render_core/texture.cpp}}
//--STRIP
//#include "render_core/application.h"
//#include "core/math_defs.h"

View File

@ -582,6 +582,13 @@
//#include "render_core/3rd_glad.h"
//#include "render_core/image.h"
//--STRIP
{{FILE:sfw/render_core/frame_buffer.h}}
//--STRIP
//#include "core/vector2i.h"
//#include "object/resource.h"
//#include "render_core/3rd_glad.h"
//#include "render_core/image.h"
//--STRIP
{{FILE:sfw/render_core/texture.h}}