Camera perspective changes drastically when sketch is maximized.

edited February 2018 in Questions about Code

Hello friends!

I'm working on a sketch where you need to be able to zoom in fairly close to get a good look at the mesh, but the default near clipping plane is way too far. I'm setting the perspective manually in order to get a more preferable clipping plane and this works really great until the window is minimized or maximized as it resets the perspective each time.

I've tried calling perspective each frame to ensure that it remains correct, but when it's maximized the renderer is stretched out of control in the horizontal direction. The strange bit is that I'm using Processing's default arguments for the perspective function (minus a change in the near clipping plane), so I'm really confused as to why it's not working. Another strange bit is that if I avoid setting the perspective manually at all it works perfectly fine when it's maximized (aside from the near clipping plane being reset to too far away).

Here is the code:

float farPlane = ((height/2.0) / tan(PI*60.0/360.0)) * 10;
perspective(PI / 3.0, width / height, 0.1, farPlane);

Here is what it looks like when it starts (AKA functioning properly):

working_perspective

Here is what it looks like when it's been maximized:

broken_perspective

On a side not I would be 100% okay with disabling the ability to maximize the window at all as a solution, but surface.setResizable(false) has zero effect when I'm using the P3D renderer.

Any help would be greatly appreciated!

Thanks.

Answers

  • The maximised version looks to be a different aspect ratio so the width / height part of the perspective call will be wildly different. I think that's what's causing the disparity.

    Make your windowed view the same aspect ratio as the fullscreen view (size()) and it should look the same

  • @koogs thanks for the response!

    If that's the case I am a bit confused. Since width and height are updated when resizing the window, the calculations using width and size should output a result in line with the new aspect ratio.

    Like I said in the initial post, when I do not set perspective manually and switch between maximized and original size everything stays just fine. So I wonder what the code is doing behind the scenes to make that happen.

    Again, if anyone instead has a way to make setResizable() work with P3D that would be an acceptable solution.

  • bump

    Can anyone confirm a way to use setResizable() with the P3D renderer so as to avoid maximizing? I'm fine with hacky solutions as long as they work :P

  • Since width and height are updated when resizing the window, the calculations using width and size should output a result in line with the new aspect ratio.

    In your images, that looks like that is what is happening -- the width of your drawing output is proportional to the new width of the screen. When you set it manually, you are passing it a different aspect ratio after resize, so your view has a different aspect ratio. But I could be misunderstanding.

    An MCVE -- for example, with a simple plane or cube in the middle -- might help in getting more specific feedback on how to address your problem.

  • yeah, the width / height is ensuring that the image takes up the same proportion of the screen in each case. you can see that in the images you posted. in the top one it's about 40% of the height of the screen, in the bottom one it's also 40% of the height of the screen, but the screen height is different.

  • as for a fix, just hard code a value in that second parameter. but be aware that people can resize the screen so that they won't be able to see the terrain.

  • @koogs and @jeremydouglass thanks you guys for being so helpful.

    I ended up finding the issue by trying to recreate it in an MCVE :P

    My previous code:

    float farPlane = ((height/2.0) / tan(PI*60.0/360.0)) * 10;
    perspective(PI / 3.0, width / height, 0.1, farPlane);
    

    The new, working code (copied straight from Processing's perspective() ref page):

    float fov = PI/3.0;
    float cameraZ = (height/2.0) / tan(fov/2.0);
    perspective(fov, float(width)/float(height), 0.1, cameraZ*10.0);
    

    I'm not sure how I ended up with the explicit code for my far clipping plane... Using the fov field for calculations totally solved the issue.

    Thanks again for the help!

  • fixing the integer division problem with width / height probably helped too.

Sign In or Register to comment.