Commit 912efd38 authored by Tim Übelhör's avatar Tim Übelhör

single responsibility for fbo reader

parent cd5a1798
......@@ -4,14 +4,16 @@
"name": "Linux",
"includePath": [
"${workspaceFolder}/include",
"~/.conan/data/"
],
"defines": [],
"cStandard": "c11",
"cppStandard": "c++11",
"configurationProvider": "vector-of-bool.cmake-tools",
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
}
],
"version": 4
"~/.conan/data/",
"/home/tim/.conan/data/gl3w/0.2/tuebel/testing/package/1a651c5b4129ad794b88522bece2281a7453aee4/include",
"/home/tim/.conan/data/glfw/3.2.1/bincrafters/stable/package/db2ca884c9793e0b0fb54ec3f846326d1addacc8/include"
],
"defines": [],
"cStandard": "c11",
"cppStandard": "c++11",
"configurationProvider": "vector-of-bool.cmake-tools",
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
}
],
"version": 4
}
\ No newline at end of file
......@@ -24,9 +24,9 @@ set(OpenGL_GL_PREFERENCE "GLVND")
# library
add_library(scigl_render
src/gl_context.cpp
src/buffer/frame_buffer.cpp
src/buffer/frame_buffer_reader.cpp
src/render/depth_simulator.cpp
src/render/frame_buffer.cpp
src/render/offscreen_render.cpp
src/render/onscreen_render.cpp
src/render/rasterizer.cpp
src/render/texture_fullscreen_render.cpp
......
......@@ -19,19 +19,19 @@ public:
\param height of the texture
\param internal_format color components & size of each
*/
FrameBuffer(int width, int height, GLenum internal_format = GL_RGB8);
FrameBuffer(int width, int height, GLenum internal_format);
FrameBuffer(const FrameBuffer &) = delete;
~FrameBuffer();
/*!
Use this framebuffer for rendering, sets the color mask and depth testing.
*/
void activate();
void activate() const;
/*!
Do not use this framebuffer for rendering anymore.
*/
void deactivate();
void deactivate() const;
/*!
Clears the color and depth values.
......@@ -39,7 +39,10 @@ public:
\param depth (for depth testing) using default OpenGL value 1
\param stencil (what to ignore) using OpenGL default value 0
*/
void clear(float color = 0, float depth = 1, int stencil = 0);
void clear(float color = 0, float depth = 1, int stencil = 0) const;
/** gets the maximum rbo size */
static int get_max_size();
private:
// Parameterization
......
#pragma once
#include <scigl_render/render/frame_buffer.hpp>
#include <scigl_render/buffer/frame_buffer.hpp>
#include <array>
#include <functional>
#include <memory>
......@@ -7,53 +7,43 @@
namespace scigl_render
{
/*!
The intedented use case is rendering data offscreen that needs to be processed.
Transfer data from a framebuffer to the CPU.
Two pixel buffer objects are use like a double buffer: one PBO is filled
asynchronously with data from the frame buffer while the other one is ready to
be mapped to the clients memory. Consequently the results of a rendering is
delayed by one read call.
*/
class OffscreenRender
class FramebufferReader
{
public:
/*!
Renders the scene off-screen and calculates the depth values.
Throws a runtime_error if the creation failed.
\param width number of image columns
\param height number of image rows
\param pixel_size the size of each pixel: number_channels * sizeof_component
\param pixel_size the size of each pixel: number_channels * sizeof(type)
*/
OffscreenRender(int width, int height, size_t pixel_size,
GLenum internal_format);
/*! Activates the underlying framebuffer for rendering */
void activate_fbo();
/*! Clears the contents of the framebuffer */
void clear_fbo();
/*! Deactivates the framebuffer. Good practice after finishing the render */
void deactivate_fbo();
FramebufferReader(int width, int height, size_t pixel_size);
/*!
Starts reading from the FBO to the backbuffer PBO. This operation is
asynchronous.
\param format specifies the channels, for example GL_RGB
\param type primitive to store, for example GL_UNSIGNED_BYTE
\param buffer transfer data from this FBO to the PBO
*/
void start_read(GLenum format, GLenum type);
void start_read(GLenum format, GLenum type, const FrameBuffer& buffer) const;
/*!
Reads synchronously from the frontbuffer PBO. Operate on this data while
another read is running on the backbuffer :)
\retuns might return NULL otherwise the data
*/
void *do_read();
void *do_read() const;
/*!
Unmaps the OpenGL memory.
*/
void end_read();
void end_read() const;
/*! Swap the front- and backbuffer */
void swap_buffers();
......@@ -61,8 +51,6 @@ public:
private:
int width;
int height;
// Render to this
FrameBuffer framebuffer;
// Two pbos one to read to the other one to map form, alternating
std::array<GLuint, 2> pbos;
// transfer from fbo to pbo via glReadPixels
......
#pragma once
#include <scigl_render/gl_context.hpp>
#include <scigl_render/render/depth_simulator.hpp>
#include <scigl_render/render/offscreen_render.hpp>
#include <scigl_render/buffer/frame_buffer.hpp>
#include <scigl_render/buffer/frame_buffer_reader.hpp>
#include <scigl_render/render/rasterizer.hpp>
#include <scigl_render/render/texture_fullscreen_render.hpp>
#include <memory>
......@@ -53,7 +54,8 @@ private:
size_t pixel_size;
std::shared_ptr<GLContext> gl_context;
// Render targets
OffscreenRender offscreen_render;
FrameBuffer framebuffer;
FramebufferReader fbo_reader;
TextureFullscreenRender texture_render;
// buffer for reading from the offscreen render
std::vector<unsigned char> image_buffer;
......
#include <scigl_render/render/frame_buffer.hpp>
#include <scigl_render/buffer/frame_buffer.hpp>
#include <stdexcept>
namespace scigl_render
......@@ -36,17 +36,17 @@ FrameBuffer::~FrameBuffer()
glDeleteRenderbuffers(1, &color_rbo);
}
void FrameBuffer::activate()
void FrameBuffer::activate() const
{
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
}
void FrameBuffer::deactivate()
void FrameBuffer::deactivate() const
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void FrameBuffer::clear(float color, float depth, int stencil)
void FrameBuffer::clear(float color, float depth, int stencil) const
{
activate();
glClearColor(color, color, color, 1);
......@@ -55,4 +55,11 @@ void FrameBuffer::clear(float color, float depth, int stencil)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
deactivate();
}
static int get_max_size()
{
int max_rbo_size;
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &max_rbo_size);
return max_rbo_size;
}
} // namespace scigl_render
\ No newline at end of file
#include <algorithm>
#include <scigl_render/check_gl_error.hpp>
#include <scigl_render/render/offscreen_render.hpp>
#include <scigl_render/buffer/frame_buffer_reader.hpp>
#include <stdexcept>
namespace scigl_render
{
OffscreenRender::OffscreenRender(int width, int height, size_t pixel_size,
GLenum internal_format)
: width(width), height(height),
framebuffer(width, height, internal_format)
FramebufferReader::FramebufferReader(int width, int height, size_t pixel_size)
: width(width), height(height)
{
glGenBuffers(pbos.size(), pbos.data());
for (size_t i = 0; i < pbos.size(); i++)
......@@ -19,46 +17,32 @@ OffscreenRender::OffscreenRender(int width, int height, size_t pixel_size,
GL_DYNAMIC_READ);
}
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
check_gl_error("OffscreenRender created");
check_gl_error("framebuffer-reader created pbos");
}
void OffscreenRender::activate_fbo()
void FramebufferReader::start_read(GLenum format, GLenum type,
const FrameBuffer &buffer) const
{
framebuffer.activate();
}
void OffscreenRender::clear_fbo()
{
framebuffer.clear();
}
void OffscreenRender::deactivate_fbo()
{
framebuffer.deactivate();
}
void OffscreenRender::start_read(GLenum format, GLenum type)
{
framebuffer.activate();
buffer.activate();
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos[backbuffer_index]);
glReadPixels(0, 0, width, height, format, type, nullptr);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
framebuffer.deactivate();
buffer.deactivate();
}
void *OffscreenRender::do_read()
void *FramebufferReader::do_read() const
{
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos[frontbuffer_index]);
return glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
}
void OffscreenRender::end_read()
void FramebufferReader::end_read() const
{
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
}
void OffscreenRender::swap_buffers()
void FramebufferReader::swap_buffers()
{
std::swap(backbuffer_index, frontbuffer_index);
}
......
#include <scigl_render/check_gl_error.hpp>
#include <scigl_render/example/depth_offscreen_render.hpp>
#include <scigl_render/render/offscreen_render.hpp>
namespace scigl_render
{
......@@ -14,10 +13,12 @@ DepthOffscreenRender::DepthOffscreenRender(
texture_internal_format(tex_internal_format),
pixel_size(pixel_size),
gl_context(context),
offscreen_render(gl_context->get_width(),
gl_context->get_height(),
pixel_size,
tex_internal_format),
framebuffer(gl_context->get_width(),
gl_context->get_height(),
tex_internal_format),
fbo_reader(gl_context->get_width(),
gl_context->get_height(),
pixel_size),
texture_render(gl_context->get_width(),
gl_context->get_height(),
tex_internal_format),
......@@ -37,10 +38,11 @@ void DepthOffscreenRender::next_frame(
{
using namespace std::placeholders;
check_gl_error("next frame begin");
// clear all the space
offscreen_render.clear_fbo();
offscreen_render.activate_fbo();
// render to cleared fbo
framebuffer.clear();
framebuffer.activate();
check_gl_error("activated fbo");
// render 4 poses via rasterization
for (int i = 0; i < 4; i++)
{
......@@ -52,15 +54,16 @@ void DepthOffscreenRender::next_frame(
}
// back to default
rasterizer.activate_all();
offscreen_render.deactivate_fbo();
// read asynchronously using the pbos
offscreen_render.start_read(texture_format, texture_type);
framebuffer.deactivate();
// read data from fbo
fbo_reader.start_read(texture_format, texture_type, framebuffer);
check_gl_error("asynchronous reading to pbo");
auto data = offscreen_render.do_read();
auto data = fbo_reader.do_read();
check_gl_error("synchronous reading from pbo");
display_data(data);
offscreen_render.end_read();
offscreen_render.swap_buffers();
fbo_reader.end_read();
fbo_reader.swap_buffers();
check_gl_error("end synchronous reading");
}
......@@ -79,12 +82,15 @@ void DepthOffscreenRender::display_data(const void *data)
void DepthOffscreenRender::resize_buffers()
{
offscreen_render = scigl_render::OffscreenRender(
framebuffer = FrameBuffer(
gl_context->get_width(),
gl_context->get_height(),
pixel_size,
texture_internal_format);
texture_render = scigl_render::TextureFullscreenRender(
fbo_reader = FramebufferReader(
gl_context->get_width(),
gl_context->get_height(),
pixel_size);
texture_render = TextureFullscreenRender(
gl_context->get_width(),
gl_context->get_height(),
texture_internal_format),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment