Hi, everyone.
I have some texture buffers in my game, and they work well in “onscreen” mode, that is, I can get the images of my cameras from texture buffer. However, by using the similar way to get the images in “offscreen” mode, the images obtained from these texture buffers are all blank. It’s strange that I can get them from texture buffer, and the x-size and y-size is correct, but nothing in the images. To find the problem, I use the same code to get the image of base.cam from base.win in “offscreen” mode. Fortunately, base.win works well in “offscreen” mode, and my scene is shown on the image. Maybe there are some differences between base.win and buffers which are made by makeTextureBuffer().
The following code is how I create my buffer and get the images from buffer
from panda3d.core import NodePath, Vec3, Vec4
import logging
from typing import Union
import numpy as np
from panda3d.core import Texture, GraphicsOutput, PNMImage, Ostream, PNMFileType
class ImageBuffer:
CAM_MASK = None
BUFFER_L = 800
BUFFER_W = 800
BKG_COLOR = Vec4(0., 0., 0., 0.1)
display_bottom = 0.8
display_top = 1
def __init__(
self, length: float, width: float, pos: Vec3, bkg_color: Union[Vec4, Vec3], make_buffer_func, make_camera_func,
parent_node: NodePath
):
assert self.CAM_MASK is not None, "define a camera mask for every image buffer"
self.texture = Texture()
self.buffer = make_buffer_func("camera", length, width, tex=self.texture, to_ram=True)
# now we have to setup a new scene graph to make this scene
self.node_path = NodePath("new render")
# this takes care of setting up their camera properly
self.cam = make_camera_func(self.buffer, clearColor=bkg_color)
self.cam.reparentTo(self.node_path)
self.cam.setPos(pos)
self.cam.node().setCameraMask(self.CAM_MASK)
self.node_path.reparentTo(parent_node)
def get_image(self):
"""
Bugs here! when use offscreen mode, thus the front cam obs is not from front cam now
"""
# raise PermissionError
from panda3d.core import Texture, GraphicsOutput, PNMImage, Ostream, PNMFileType
import numpy as np
img = PNMImage()
self.buffer.getScreenshot(img)
# save for debug
# img.write("img.jpg")
return img
def get_gray_pixels_array(self) -> np.ndarray:
img = self.get_image()
img.makeGrayscale()
numpy_array = np.array([[img.getGray(i, j) for j in range(img.getYSize())] for i in range(img.getXSize())])
return np.clip(numpy_array, 0, 1)
def __del__(self):
logging.debug("{} is destroyed".format(self.__class__.__name__))
I have tried to use addRenderToTexture() method and trigger_copy mode mentioned by @David and @rdb, instead of PNMImage, but the result is same. The images I get under “offscreen” mode are still blank.
Really appreciate your help!