texture_reader.hpp 1.5 KB
Newer Older
Tim Übelhör's avatar
Tim Übelhör committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#pragma once
#include <scigl_render/buffer/texture2d.hpp>
#include <array>
#include <functional>
#include <memory>

namespace scigl_render
{
/*!
Transfer data from a texture to the CPU.
Two pixel buffer objects are used 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 TextureReader
{
public:
  /*!
  Renders the scene off-screen and calculates the depth values.
  \param buffer read from this texture
  \param pixel_size the size of each pixel: number_channels * sizeof(type)
  */
  TextureReader(std::shared_ptr<Texture2D> buffer,
                size_t pixel_size);

  /*!
  Starts reading from the FBO to the backbuffer PBO. This operation is 
  asynchronous.
  */
  void start_read() 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() const;

  /*!
  Unmaps the OpenGL memory.
  */
  void end_read() const;

  /*! Swap the front- and backbuffer */
  void swap_buffers();

private:
  std::shared_ptr<Texture2D> texture;
  // 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 backbuffer_index = 0;
  // transfer from pbo to CPU memory
  int frontbuffer_index = 1;
};
} // namespace scigl_render