Browse Source

python: expose framebuffer reading to an image (not a view).

pull/8/head
Vladimír Vondruš 7 years ago
parent
commit
f8f0f3f1b7
  1. 2
      src/python/magnum/gl.cpp
  2. 3
      src/python/magnum/test/test.py
  3. 54
      src/python/magnum/test/test_gl_gl.py

2
src/python/magnum/gl.cpp

@ -27,6 +27,7 @@
#include <pybind11/stl.h> /* for Mesh.buffers */ #include <pybind11/stl.h> /* for Mesh.buffers */
#include <Corrade/Containers/ArrayView.h> #include <Corrade/Containers/ArrayView.h>
#include <Corrade/Utility/FormatStl.h> #include <Corrade/Utility/FormatStl.h>
#include <Magnum/Image.h>
#include <Magnum/ImageView.h> #include <Magnum/ImageView.h>
#include <Magnum/GL/AbstractShaderProgram.h> #include <Magnum/GL/AbstractShaderProgram.h>
#include <Magnum/GL/Attribute.h> #include <Magnum/GL/Attribute.h>
@ -686,6 +687,7 @@ void gl(py::module& m) {
self.clear(mask); self.clear(mask);
}, "Clear specified buffers in the framebuffer") }, "Clear specified buffers in the framebuffer")
.def("read", static_cast<void(GL::AbstractFramebuffer::*)(const Range2Di&, const MutableImageView2D&)>(&GL::AbstractFramebuffer::read), "Read block of pixels from the framebuffer to an image view") .def("read", static_cast<void(GL::AbstractFramebuffer::*)(const Range2Di&, const MutableImageView2D&)>(&GL::AbstractFramebuffer::read), "Read block of pixels from the framebuffer to an image view")
.def("read", static_cast<void(GL::AbstractFramebuffer::*)(const Range2Di&, Image2D&)>(&GL::AbstractFramebuffer::read), "Read block of pixels from the framebuffer to an image")
/** @todo more */; /** @todo more */;
py::class_<GL::DefaultFramebuffer, GL::AbstractFramebuffer, NonDefaultFramebufferHolder<GL::DefaultFramebuffer>> defaultFramebuffer{m, py::class_<GL::DefaultFramebuffer, GL::AbstractFramebuffer, NonDefaultFramebufferHolder<GL::DefaultFramebuffer>> defaultFramebuffer{m,

3
src/python/magnum/test/test.py

@ -65,6 +65,7 @@ class Image(unittest.TestCase):
@unittest.skip("No way to create a non-empty Image at the moment") @unittest.skip("No way to create a non-empty Image at the moment")
def test_data(self): def test_data(self):
# Tested in test_gl_gl.Framebuffer.test_read_image instead
a = Image2D(PixelFormat.R8I, Vector2i(3, 17)) # TODO a = Image2D(PixelFormat.R8I, Vector2i(3, 17)) # TODO
a_refcount = sys.getrefcount(a) a_refcount = sys.getrefcount(a)
@ -87,6 +88,7 @@ class Image(unittest.TestCase):
@unittest.skip("No way to create a non-empty Image at the moment") @unittest.skip("No way to create a non-empty Image at the moment")
def test_pixels(self): def test_pixels(self):
# Tested in test_gl_gl.Framebuffer.test_read_image instead
a = Image2D(PixelFormat.RG32UI, Vector2i(3, 17)) # TODO a = Image2D(PixelFormat.RG32UI, Vector2i(3, 17)) # TODO
a_refcount = sys.getrefcount(a) a_refcount = sys.getrefcount(a)
@ -197,6 +199,7 @@ class ImageView(unittest.TestCase):
@unittest.skip("No way to create a non-empty Image at the moment") @unittest.skip("No way to create a non-empty Image at the moment")
def test_init_image(self): def test_init_image(self):
# Tested in test_gl_gl.Framebuffer.test_read_image instead
a = Image2D(PixelFormat.R32F, Vector2i(3, 17)) # TODO a = Image2D(PixelFormat.R32F, Vector2i(3, 17)) # TODO
a_refcount = sys.getrefcount(a) a_refcount = sys.getrefcount(a)

54
src/python/magnum/test/test_gl_gl.py

@ -154,7 +154,59 @@ class Framebuffer(GLTestCase):
self.assertIs(framebuffer.attachments[0], renderbuffer) self.assertIs(framebuffer.attachments[0], renderbuffer)
self.assertEqual(sys.getrefcount(renderbuffer), renderbuffer_refcount + 1) self.assertEqual(sys.getrefcount(renderbuffer), renderbuffer_refcount + 1)
def test_read(self): def test_read_image(self):
renderbuffer = gl.Renderbuffer()
renderbuffer.set_storage(gl.RenderbufferFormat.RGBA8, (4, 4))
framebuffer = gl.Framebuffer(((0, 0), (4, 4)))
framebuffer.attach_renderbuffer(gl.Framebuffer.ColorAttachment(0), renderbuffer)
gl.Renderer.clear_color = Color4(1.0, 0.5, 0.75)
framebuffer.clear(gl.FramebufferClear.COLOR)
a = Image2D(PixelFormat.RGBA8_UNORM)
framebuffer.read(Range2Di.from_size((1, 1), (2, 2)), a)
self.assertEqual(a.size, Vector2i(2, 2))
# This tests Image internals because this is the only way how to get a
# non-empty Image ATM (sorry)
# TODO: remove once Image can be created non-empty
a_refcount = sys.getrefcount(a)
data = a.data
self.assertIs(data.owner, a)
self.assertEqual(sys.getrefcount(a), a_refcount + 1)
del data
self.assertEqual(sys.getrefcount(a), a_refcount)
pixels = a.pixels
self.assertIs(pixels.owner, a)
self.assertEqual(sys.getrefcount(a), a_refcount + 1)
self.assertEqual(ord(a.pixels[0, 0, 0]), 0xff)
self.assertEqual(ord(a.pixels[0, 1, 1]), 0x80)
self.assertEqual(ord(a.pixels[1, 0, 2]), 0xbf)
del pixels
self.assertEqual(sys.getrefcount(a), a_refcount)
view = ImageView2D(a)
self.assertEqual(view.size, (2, 2))
self.assertIs(view.owner, a)
self.assertEqual(sys.getrefcount(a), a_refcount + 1)
del view
self.assertEqual(sys.getrefcount(a), a_refcount)
mview = MutableImageView2D(a)
self.assertEqual(mview.size, (2, 2))
self.assertIs(mview.owner, a)
self.assertEqual(sys.getrefcount(a), a_refcount + 1)
del mview
self.assertEqual(sys.getrefcount(a), a_refcount)
def test_read_view(self):
renderbuffer = gl.Renderbuffer() renderbuffer = gl.Renderbuffer()
renderbuffer.set_storage(gl.RenderbufferFormat.RGBA8, (4, 4)) renderbuffer.set_storage(gl.RenderbufferFormat.RGBA8, (4, 4))

Loading…
Cancel
Save