Aardappeltaart
Posts: 6
Joined: Wed Mar 02, 2016 11:32 am

Pi3D rendering two images on screen problem

Sat Oct 14, 2017 8:09 am

Just starting with Pi3d and I try to show two images next to each other, but my code only shows one picture and the other one black

Code: Select all


DISPLAY = pi3d.Display.create(0,0,1920, 1080, frames_per_second=4)
DISPLAY.set_background(0.2,0,0,1)
shader1 = pi3d.Shader("uv_flat")
shader2 = pi3d.Shader("uv_flat")
CAMERA = pi3d.Camera(is_3d=False)
CAMERA.was_moved=False
ntex1 = pi3d.Texture("/home/pi/dev/images/1.jpg", blend=True)
pic1 = pi3d.ImageSprite(ntex1,  shader1,  w=660.0,  h=1080.0,  x=-660.0, y=0.0, z=5.0)
ntex2 = pi3d.Texture("/home/pi/dev/images/2.jpg", blend=True)
pic2 = pi3d.ImageSprite(ntex2,  shader2,  w=660.0,  h=1080.0,  x=660.0, y=0.0, z=6.0)

#mykeys = pi3d.Keyboard();

while DISPLAY.loop_running():

    pic1.draw()
    pic2.draw()


It seems I'm missing something:
- the picture always seems to be centered, why isn't x=0 and y=o not the left upper corner. Is it possible to make it work that way?
- why do I not see the two pictures rendered but one as a black box?

User avatar
paddyg
Posts: 1995
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: Pi3D rendering two images on screen problem

Sun Oct 15, 2017 11:46 pm

Hi, I'm not completely sure from your code what you're trying to do. This is what I would expect to happen:
temp1.jpg
temp1.jpg (11.54 KiB) Viewed 248 times
i.e. you are putting the centre of an image scaled to 660 wide 660 to the left of the centre of the screen and another image 660 to the right. which will leave a gap of 330 x 2 between them and the overall width will be 660 x 3 = 1980 going 30 pixels off either side of the display drawing surface.

To get the images side by side touching they need to be -330 and +330

If you don't specify any dimensions for Display.create() it will fill the whole of the available screen, so that might be an option to try. You can get the dimensions later for positioning thing with DISPLAY.width and DISPLAY.height.

If the ImageSprite is rendering but showing black then that's a different problem, the most likely cause I can think of is not enough GPU memory. What did you set it to?

PS you only need one instance of each different type of shader which you can pass to multiple objects for drawing.
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

Aardappeltaart
Posts: 6
Joined: Wed Mar 02, 2016 11:32 am

Re: Pi3D rendering two images on screen problem

Mon Oct 16, 2017 9:21 am

Thx paddyg.

I was puzzled the most by the black image, indeed that is a memory split issue. The GPU needs at least 128MB for this, I guess, so I got that working. Foolish me, I thought about that earlier, but forgot to try.

And the placement on the display, I get that the it's the center origin .

To place an image left top, you don't set x=0, y=0 (like in HTML), but something like

Code: Select all

x=- (display.width - image.width)/2
y=- (display.height - image.height)/2
I understand I can re-use the shader, but I wanted to try out different ones.
Assigning a new shader, does that have a huge memory impact?

User avatar
paddyg
Posts: 1995
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: Pi3D rendering two images on screen problem

Mon Oct 16, 2017 10:09 am

The different coordinate origins are a bit messy. The GPU coordinates seem to naturally lend themselves to things being relative to the camera direction (the 'camera' is really just a translation matrix for mapping xyz vertices to the flat screen) so bang in the middle of the display with depth (z) increasing away from the viewer. x goes from left to right and y goes from bottom to top as with a 'normal' xy graph. Unfortunately this is at odds with normal left hand axes of geometry and the arrangement-of-text-x-across-y-down convention of 2D graphics. It's further confused within the shader language where UV mapping goes from 0,0 in one corner to 1,1 and the gl_FragCoord goes from an origin in the top left corner of the screen.

So, yes, (nearly) to position something on the left and top edges you would use
x, y = -(display.width - image.width) / 2, +(display.height - image.height) / 2

I'm not sure if there is maximum number of shaders but there is a memory limit that will cut in eventually. However I don't think it's a practical limit. The pi3d_demos/FilterDemo.py on the RPi 3 seems to get up to the fourth filter shader on top of the two shaders used to do the off screen render before it runs out of memory.

Paddy
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

Return to “Python”

Who is online

Users browsing this forum: No registered users and 17 guests