vumichien's picture
First commit
b4c8bc3
raw history blame
No virus
5.41 kB
"""Wrapper for offscreen rendering.
Author: Matthew Matl
"""
import os
from .renderer import Renderer
from .constants import RenderFlags
class OffscreenRenderer(object):
"""A wrapper for offscreen rendering.
Parameters
----------
viewport_width : int
The width of the main viewport, in pixels.
viewport_height : int
The height of the main viewport, in pixels.
point_size : float
The size of screen-space points in pixels.
"""
def __init__(self, viewport_width, viewport_height, point_size=1.0):
self.viewport_width = viewport_width
self.viewport_height = viewport_height
self.point_size = point_size
self._platform = None
self._renderer = None
self._create()
@property
def viewport_width(self):
"""int : The width of the main viewport, in pixels.
"""
return self._viewport_width
@viewport_width.setter
def viewport_width(self, value):
self._viewport_width = int(value)
@property
def viewport_height(self):
"""int : The height of the main viewport, in pixels.
"""
return self._viewport_height
@viewport_height.setter
def viewport_height(self, value):
self._viewport_height = int(value)
@property
def point_size(self):
"""float : The pixel size of points in point clouds.
"""
return self._point_size
@point_size.setter
def point_size(self, value):
self._point_size = float(value)
def render(self, scene, flags=RenderFlags.NONE, seg_node_map=None):
"""Render a scene with the given set of flags.
Parameters
----------
scene : :class:`Scene`
A scene to render.
flags : int
A bitwise or of one or more flags from :class:`.RenderFlags`.
seg_node_map : dict
A map from :class:`.Node` objects to (3,) colors for each.
If specified along with flags set to :attr:`.RenderFlags.SEG`,
the color image will be a segmentation image.
Returns
-------
color_im : (h, w, 3) uint8 or (h, w, 4) uint8
The color buffer in RGB format, or in RGBA format if
:attr:`.RenderFlags.RGBA` is set.
Not returned if flags includes :attr:`.RenderFlags.DEPTH_ONLY`.
depth_im : (h, w) float32
The depth buffer in linear units.
"""
self._platform.make_current()
# If platform does not support dynamically-resizing framebuffers,
# destroy it and restart it
if (self._platform.viewport_height != self.viewport_height or
self._platform.viewport_width != self.viewport_width):
if not self._platform.supports_framebuffers():
self.delete()
self._create()
self._platform.make_current()
self._renderer.viewport_width = self.viewport_width
self._renderer.viewport_height = self.viewport_height
self._renderer.point_size = self.point_size
if self._platform.supports_framebuffers():
flags |= RenderFlags.OFFSCREEN
retval = self._renderer.render(scene, flags, seg_node_map)
else:
self._renderer.render(scene, flags, seg_node_map)
depth = self._renderer.read_depth_buf()
if flags & RenderFlags.DEPTH_ONLY:
retval = depth
else:
color = self._renderer.read_color_buf()
retval = color, depth
# Make the platform not current
self._platform.make_uncurrent()
return retval
def delete(self):
"""Free all OpenGL resources.
"""
self._platform.make_current()
self._renderer.delete()
self._platform.delete_context()
del self._renderer
del self._platform
self._renderer = None
self._platform = None
import gc
gc.collect()
def _create(self):
if 'PYOPENGL_PLATFORM' not in os.environ:
from pyrender.platforms.pyglet_platform import PygletPlatform
self._platform = PygletPlatform(self.viewport_width,
self.viewport_height)
elif os.environ['PYOPENGL_PLATFORM'] == 'egl':
from pyrender.platforms import egl
device_id = int(os.environ.get('EGL_DEVICE_ID', '0'))
egl_device = egl.get_device_by_index(device_id)
self._platform = egl.EGLPlatform(self.viewport_width,
self.viewport_height,
device=egl_device)
elif os.environ['PYOPENGL_PLATFORM'] == 'osmesa':
from pyrender.platforms.osmesa import OSMesaPlatform
self._platform = OSMesaPlatform(self.viewport_width,
self.viewport_height)
else:
raise ValueError('Unsupported PyOpenGL platform: {}'.format(
os.environ['PYOPENGL_PLATFORM']
))
self._platform.init_context()
self._platform.make_current()
self._renderer = Renderer(self.viewport_width, self.viewport_height)
def __del__(self):
try:
self.delete()
except Exception:
pass
__all__ = ['OffscreenRenderer']