def render(self, overlays=(), depth=False, scene_option=None): """Renders the camera view as a numpy array of pixel values. Args: overlays: An optional sequence of `TextOverlay` instances to draw. Only supported if `depth` is False. depth: An optional boolean. If True make the camera measure depth scene_option: A custom `wrapper.MjvOption` instance to use to render the scene instead of the default. If None, will use the default. Returns: The rendered scene. If `depth` is False this is a NumPy uint8 array of RGB values, otherwise it is a float NumPy array of depth values (in meters). Raises: ValueError: If overlays are requested with depth rendering. """ if depth and overlays: raise ValueError( 'Overlays are not supported with depth rendering.') self.update(scene_option=scene_option) with self._physics.contexts.gl.make_current(self._width, self._height): mjlib.mjr_render(self._rect, self._scene.ptr, self._physics.contexts.mujoco.ptr) if depth: mjlib.mjr_readPixels(None, self._depth_buffer, self._rect, self._physics.contexts.mujoco.ptr) # Get distance of near and far clipping planes. extent = self._physics.model.stat.extent near = self._physics.model.vis.map_.znear * extent far = self._physics.model.vis.map_.zfar * extent # Convert from [0 1] to depth in meters, see links below. # http://stackoverflow.com/a/6657284/1461210 # https://www.khronos.org/opengl/wiki/Depth_Buffer_Precision self._depth_buffer = near / (1 - self._depth_buffer * (1 - near / far)) else: for overlay in overlays: overlay.draw(self._physics.contexts.mujoco.ptr, self._rect) mjlib.mjr_readPixels(self._rgb_buffer, None, self._rect, self._physics.contexts.mujoco.ptr) return np.flipud(self._depth_buffer if depth else self._rgb_buffer)
def _render_on_gl_thread(self, depth, overlays): """Performs only those rendering calls that require an OpenGL context.""" # Render the scene. mjlib.mjr_render(self._rect, self._scene.ptr, self._physics.contexts.mujoco.ptr) if not depth: # If rendering RGB, draw any text overlays on top of the image. for overlay in overlays: overlay.draw(self._physics.contexts.mujoco.ptr, self._rect) # Read the contents of either the RGB or depth buffer. mjlib.mjr_readPixels(self._rgb_buffer if not depth else None, self._depth_buffer if depth else None, self._rect, self._physics.contexts.mujoco.ptr)