Commit 9e945bd6 authored by Tim Übelhör's avatar Tim Übelhör

OffscreenRender without ugly callback.

The user must take more care!
parent a5dd833c
......@@ -3,7 +3,7 @@ from conans import ConanFile, CMake
class SciglRenderConan(ConanFile):
name = "scigl_render"
version = "0.4"
version = "0.5"
license = "MIT"
url = "https://git.rwth-aachen.de/robo_guide/scigl_render"
description = ("Library to simplify rendering objects via OpenGL."
......
......@@ -63,8 +63,8 @@ private:
Shader scene_shader;
/*!
Callback for the offscreen render
Display the data from the framebuffer
*/
void process_data(const void *data);
void display_data(const void *data);
};
} // namespace scigl_render
\ No newline at end of file
......@@ -16,13 +16,6 @@ delayed by one read call.
class OffscreenRender
{
public:
/*!
Defines a callback when new data has been mapped to the CPU memory.
Advice: avoid copying the data and use it as readonly memory inside the
callback to gain the most performance.
*/
using ProcessDataCallback = std::function<void(const void *data)>;
/*!
Renders the scene off-screen and calculates the depth values.
Throws a runtime_error if the creation failed.
......@@ -43,21 +36,24 @@ public:
void deactivate_fbo();
/*!
Starts reading from the FBO to the backbuffer PBO.
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
*/
void start_read(GLenum format, GLenum type);
/*!
Synchronously reads the data from the front buffer (one frame delayed!). After
finishing the PBOs are swapped, so the next start_render / read_data call will
use the other PBO. It is important to execute the calculations in the
process_data callback to gain performance.
\param process_data the callback function will be executed if data has been
read successfully.
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();
/*!
Unmaps the OpenGL memory and swaps front- & backbuffer.
*/
void read_data(const ProcessDataCallback &process_data);
void end_read();
private:
int width;
......@@ -67,11 +63,11 @@ private:
// 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
int pbo_fbo_index = 0;
int backbuffer_index = 0;
// transfer from pbo to CPU memory
int pbo_map_index = 1;
int frontbuffer_index = 1;
/*! Swap the indices for fbo->pbo and mapping */
void swap_indices();
/*! Swap the front- and backbuffer */
void swap_buffers();
};
} // namespace scigl_render
......@@ -2,7 +2,7 @@
<?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="2">
<name>scigl_render</name>
<version>0.4</version>
<version>0.5</version>
<description>
Library to simplify rendering objects via OpenGL. The intendet use case
is scientific (e.g. probabalistic filtering). It is not supposed to be a
......
......@@ -36,31 +36,36 @@ void ExampleRender::next_frame(const CvCamera &camera, const Model &model,
{
using namespace std::placeholders;
check_gl_error("next frame begin");
// render to fbo
offscreen_render.clear_fbo();
offscreen_render.activate_fbo();
check_gl_error("activated fbo");
glEnable(GL_DEPTH_TEST);
camera.set_in_shader(scene_shader);
light.set_in_shader(scene_shader);
model.draw(scene_shader);
offscreen_render.deactivate_fbo();
// read asynchronously using the pbos
offscreen_render.start_read(texture_format, texture_type);
offscreen_render.read_data(std::bind(&ExampleRender::process_data,
this, _1));
check_gl_error("next frame end");
check_gl_error("asynchronous reading to pbo");
auto data = offscreen_render.do_read();
check_gl_error("synchronous reading from pbo");
display_data(data);
offscreen_render.end_read();
check_gl_error("end synchronous reading");
}
void ExampleRender::process_data(const void *data)
void ExampleRender::display_data(const void *data)
{
check_gl_error("process data begin");
// Test copying the data, buffer_size is in bytes
memcpy(image_buffer.data(), data, image_buffer.size());
// draw the copy
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
texture_render.draw(image_buffer.data(), texture_format, texture_type);
check_gl_error("drawing fullscreen quad");
// update
glfwSwapBuffers(gl_context->get_window());
check_gl_error("process data end");
}
void ExampleRender::resize_buffers()
......
......@@ -64,6 +64,15 @@ int main(int argc, char *argv[])
camera_intrinsics.c_y = 310;
camera_intrinsics.f_x = 511;
camera_intrinsics.f_y = 513;
float dist_coeffs[] = {
4.1925421198910247e-02,
-9.6463442423611379e-02,
-2.3391717576772839e-03,
5.8792609967242386e-04,
4.9171950039135250e-02,
0, 0, 0};
std::copy(std::begin(dist_coeffs), std::end(dist_coeffs),
std::begin(camera_intrinsics.dist_coeffs));
CvCamera camera(camera_intrinsics);
// Test if Cartesian -> Quaternion works
CartesianPose camera_pose = {glm::vec3(0, 0, 0), glm::vec3(0, 0, 0)};
......
......@@ -41,27 +41,26 @@ void OffscreenRender::start_read(GLenum format, GLenum type)
{
framebuffer.activate();
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos[pbo_fbo_index]);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos[backbuffer_index]);
glReadPixels(0, 0, width, height, format, type, nullptr);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
framebuffer.deactivate();
}
void OffscreenRender::read_data(
const ProcessDataCallback &process_data)
void *OffscreenRender::do_read()
{
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos[frontbuffer_index]);
return glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
}
void OffscreenRender::end_read()
{
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos[pbo_map_index]);
void *data = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
if (data)
{
process_data(data);
}
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
swap_indices();
swap_buffers();
}
void OffscreenRender::swap_indices()
void OffscreenRender::swap_buffers()
{
std::swap(pbo_fbo_index, pbo_map_index);
std::swap(backbuffer_index, frontbuffer_index);
}
} // namespace scigl_render
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