Overlay image on display regions

Hello,
I wish to adjust specific part of my 3d scene for which i am using key-bindings. To effectively do this adjustment, i need to overlay an image on top of the screen buffer for that specific camera mode.

Right now, the overlay is rendered on top of panda mainscreen since i used this (IMAGE IS BELOW)

def overlay_image(self, image_path):

    # Create a card for the overlay image
    cm = CardMaker("overlay_card")
    cm.setFrame(-1, 1, -1, 1)  # Fullscreen quad
    overlay_card = self.render2d.attachNewNode(cm.generate())
    
    
    # Load the image texture
    tex = self.loader.loadTexture(image_path)
    overlay_card.setTexture(tex)
    overlay_card.setTransparency(TransparencyAttrib.MAlpha)
    overlay_card.setAlphaScale(0.5)  # Adjust transparency as needed

    # Reparent the overlay card to the buffer's camera
    #overlay_card.reparentTo(self.altCam)  # Attach to altCam
    overlay_card.setPos(0, 10, 0)  # Position slightly in front of the camera

    print(f"Overlay image set from: {image_path}")

How do i even attach the image on the buffer screen for the camera?

Here is the snippet for the buffer screen

def find_all_cameras(self):
    cameras = []
    for camera_path in self.render.findAllMatches("**/*"):
        node = camera_path.node()
        if isinstance(node, Camera):
            camera_name = camera_path.getName()
            if camera_name.startswith("Camera_"):
                cameras.append(camera_path)
                node.active = False
                break
    return cameras

def create_render_buffer(self):
    buffer = self.win.make_texture_buffer("shared_buffer", self.img_width, self.img_height)
    
    self.altCam = self.makeCamera(buffer)
    self.altCam.reparentTo(self.render)
    
    self.accept("v", self.bufferViewer.toggleEnable)
    self.bufferViewer.setPosition("llcorner")
    self.bufferViewer.setCardSize(1.0, 0.0)

    return buffer

   def render_to_textures(self, task):
    """
    Render the scene to the textures and analyze the buffer to cast rays only where the table is visible.
    Also saves the screenshot for future use.
    """
    self.graphics_engine.render_frame()
    
    buffer = self.render_buffer
    for camera_path in self.cameras:
        # Set the camera's lens and position
        self.altCam.node().setLens(camera_path.node().getLens())
        self.altCam.reparentTo(camera_path)
        
        self.graphics_engine.render_frame()
        
        screenshot_filename = join(self.output_folder, f"{camera_path.getName()}_screenshot.png")
        screenshot = PNMImage(self.img_width, self.img_height)
        
        if buffer.get_screenshot(screenshot):
            # Save the screenshot
            screenshot.write(screenshot_filename)
            print(f"Screenshot saved at {screenshot_filename}")
            
        else:
            print(f"Failed to capture screenshot from buffer for camera: {camera_path.getName()}")

Currently its this way

Output - The image should be overlayed on top of the buffer screen, so i can adjust accordingly
Thank youuu!!

You need to create a new display region on the buffer with buffer.makeDisplayRegion(), assign a camera to it with an OrthographicLens that is inside a scene graph containing the card you want to render. Creating your own render2d, if you will.

1 Like

my current buffer region(scene at the llcorner) already holds the camera inside the scene graph. Do i again need another camera just to superimpose a basic rgb image onto that pre-existing buffer?

Technically, you could probably create a card within the 3D scene, sized and placed to fit the display region when rendered by the lens. (And perhaps with some settings to prevent anything from rendering over it, and to ensure that it’s rendered by only the camera specific to that buffer.)

That should work, I daresay.

Otherwise, I think that indeed, rendering a 2D scene (even if that “scene” is just a single object) calls for a 2D camera.

(I’m pretty sure that that’s how the default 2D scene-graphs work: they have their own, dedicated cameras.)

Yes, i created a card with the specific camera image which needs to be displayed but instead of overlaying it on the display region, i set the image position at the focal_length of that camera and set the scale accordingly to adjust it with the dimensions of the buffer region.

Then created camera specific bitmask to display on the specific image for that camera itself.

Thank you once again

1 Like

Yes, or you can use the convenience function base.makeCamera2d, which creates a display region and orthographic-lens camera in one.

Putting a card in front of the camera works just as well, if you can line it up properly.

1 Like

Thank you tried it as well and it works!

1 Like