Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
RoboGuide
scigl_render
Commits
bbdd6d5c
Commit
bbdd6d5c
authored
Mar 06, 2019
by
Tim Übelhör
Browse files
Reading from textures
parent
5f2ef2d9
Changes
7
Show whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
bbdd6d5c
...
...
@@ -28,6 +28,7 @@ add_library(scigl_render
src/buffer/frame_buffer.cpp
src/buffer/frame_buffer_reader.cpp
src/buffer/texture2d.cpp
src/buffer/texture_reader.cpp
src/render/depth_simulator.cpp
src/render/onscreen_render.cpp
src/render/rasterizer.cpp
...
...
include/scigl_render/buffer/texture2d.hpp
View file @
bbdd6d5c
...
...
@@ -28,6 +28,15 @@ public:
/** unbinds this texture */
void
unbind
()
const
;
/**
* Reads the texture in the pixels pointer.
* Note: If a non-zero named buffer object is bound to the
* GL_PIXEL_PACK_BUFFER target (see glBindBuffer) while a texture image is
* specified, pixels is treated as a byte offset into the buffer object's
* data store.
*/
void
read_image
(
GLvoid
*
pixels
);
/** upload an image to the texture. */
void
store_image
(
const
GLvoid
*
image
)
const
;
...
...
include/scigl_render/buffer/texture_reader.hpp
0 → 100644
View file @
bbdd6d5c
#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
include/scigl_render/example/depth_offscreen_render.hpp
View file @
bbdd6d5c
...
...
@@ -2,7 +2,7 @@
#include
<scigl_render/gl_context.hpp>
#include
<scigl_render/render/depth_simulator.hpp>
#include
<scigl_render/buffer/frame_buffer.hpp>
#include
<scigl_render/buffer/
frame_buffer
_reader.hpp>
#include
<scigl_render/buffer/
texture
_reader.hpp>
#include
<scigl_render/render/rasterizer.hpp>
#include
<scigl_render/render/texture_fullscreen_render.hpp>
#include
<memory>
...
...
@@ -44,7 +44,7 @@ private:
// render to fbo
std
::
shared_ptr
<
Texture2D
>
fbo_texture
;
std
::
shared_ptr
<
FrameBuffer
>
framebuffer
;
std
::
unique_ptr
<
Framebuffer
Reader
>
fbo
_reader
;
std
::
unique_ptr
<
Texture
Reader
>
tex
_reader
;
// display fullscreen quad from other texture (to showcase the mapping)
TextureFullscreenRender
texture_render
;
std
::
shared_ptr
<
Texture2D
>
quad_texture
;
...
...
src/buffer/texture2d.cpp
View file @
bbdd6d5c
...
...
@@ -65,6 +65,13 @@ void Texture2D::unbind() const
glBindTexture
(
GL_TEXTURE_2D
,
0
);
}
void
Texture2D
::
read_image
(
GLvoid
*
pixels
)
{
bind
();
glGetTexImage
(
GL_TEXTURE_2D
,
0
,
format
,
type
,
pixels
);
unbind
();
}
void
Texture2D
::
store_image
(
const
GLvoid
*
image
)
const
{
bind
();
...
...
src/buffer/texture_reader.cpp
0 → 100644
View file @
bbdd6d5c
#include
<algorithm>
#include
<scigl_render/check_gl_error.hpp>
#include
<scigl_render/buffer/texture_reader.hpp>
#include
<stdexcept>
namespace
scigl_render
{
TextureReader
::
TextureReader
(
std
::
shared_ptr
<
Texture2D
>
buffer
,
size_t
pixel_size
)
:
texture
(
buffer
)
{
glGenBuffers
(
pbos
.
size
(),
pbos
.
data
());
size_t
buffer_size
=
texture
->
get_width
()
*
texture
->
get_height
()
*
pixel_size
;
for
(
size_t
i
=
0
;
i
<
pbos
.
size
();
i
++
)
{
glBindBuffer
(
GL_PIXEL_PACK_BUFFER
,
pbos
[
i
]);
// constantly reading new contents
glBufferData
(
GL_PIXEL_PACK_BUFFER
,
buffer_size
,
0
,
GL_DYNAMIC_READ
);
}
glBindBuffer
(
GL_PIXEL_PACK_BUFFER
,
0
);
check_gl_error
(
"framebuffer-reader created pbos"
);
}
void
TextureReader
::
start_read
()
const
{
glBindBuffer
(
GL_PIXEL_PACK_BUFFER
,
pbos
[
backbuffer_index
]);
texture
->
read_image
(
0
);
glBindBuffer
(
GL_PIXEL_PACK_BUFFER
,
0
);
}
void
*
TextureReader
::
do_read
()
const
{
glBindBuffer
(
GL_PIXEL_PACK_BUFFER
,
pbos
[
frontbuffer_index
]);
return
glMapBuffer
(
GL_PIXEL_PACK_BUFFER
,
GL_READ_ONLY
);
}
void
TextureReader
::
end_read
()
const
{
glUnmapBuffer
(
GL_PIXEL_PACK_BUFFER
);
}
void
TextureReader
::
swap_buffers
()
{
std
::
swap
(
backbuffer_index
,
frontbuffer_index
);
}
}
// namespace scigl_render
src/example/depth_offscreen_render.cpp
View file @
bbdd6d5c
...
...
@@ -15,8 +15,7 @@ DepthOffscreenRender::DepthOffscreenRender(std::shared_ptr<GLContext> context,
fbo_texture
(
texture
)
{
framebuffer
=
std
::
make_shared
<
FrameBuffer
>
(
fbo_texture
);
fbo_reader
=
std
::
unique_ptr
<
FramebufferReader
>
(
new
FramebufferReader
(
framebuffer
,
pixel_size
));
tex_reader
.
reset
(
new
TextureReader
(
fbo_texture
,
pixel_size
));
// create second texture to copy the data to
quad_texture
=
std
::
make_shared
<
Texture2D
>
(
fbo_texture
->
get_width
(),
fbo_texture
->
get_height
(),
...
...
@@ -48,16 +47,16 @@ void DepthOffscreenRender::next_frame(
rasterizer
.
activate_all
();
framebuffer
->
deactivate
();
// read data from
fbo
fbo
_reader
->
start_read
();
// read data from
texture
tex
_reader
->
start_read
();
check_gl_error
(
"asynchronous reading to pbo"
);
auto
data
=
fbo
_reader
->
do_read
();
auto
data
=
tex
_reader
->
do_read
();
check_gl_error
(
"synchronous reading from pbo"
);
// display the data on screen
display_data
(
data
);
fbo
_reader
->
end_read
();
fbo
_reader
->
swap_buffers
();
tex
_reader
->
end_read
();
tex
_reader
->
swap_buffers
();
check_gl_error
(
"end synchronous reading"
);
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment