Using the Projection Matrix to zoom in on a screen

BlitzMax Forums/BlitzMax Programming/Using the Projection Matrix to zoom in on a screen

Grey Alien(Posted 2008) [#1]
Hi, anyone know if it's possible to use a DX/OGL projection matrix (like via Yan's code, Indiepaths module and Mutley's retro-remakes code) to zoom into the screen so that everything scales up and the coords move accordingly? That would be cool, but I can't figure it out :-(

I could do it manually by scaling every image myself and adjusting the coords based on the central zoom point, but this sounds like a job for a projection matrix where you want your virtual screen projected onto one BIGGER than the actual current resolution.

Any advice welcome, thanx!


tonyg(Posted 2008) [#2]
Here is some DX stuff hacked together a while back.

I do have some DX/OGL code from Indiepath but I remember it being provided by email request only. His code also adjust the mouse pos
<edit> In fact that last bits a lie. Tim's code doesn't scale. There's quite a few hits on gamedev.net though.


Grey Alien(Posted 2008) [#3]
Thanks. Why does everything disappear if you scale in at all?

The problem I was having was because I tested only with Yan's code which I assumed was the same as the rest but it was not for some reason, I was having to manually scale and reposition everything as if the projection matrix wasn't working. However, Mutley's code seemed to properly scale everything as I expected it too so all I do to zoom in is shrink the virtual screen each frame and decide if I want to shift the origin at all (otherwise it scales from the top left, and I may want to scale from the middle, or do some panning).

Here's Mutley's Freeware code: http://www.retroremakes.com/forum2/showthread.php?t=10040


tonyg(Posted 2008) [#4]
Why does everything disappear if you scale in at all?

Because the size of the projection matrix is being changed. You'll have to create a larger projection matrix and viewport to allow for more information to be displayed.
This is what Muttley's code does.
<edit> Btw :What exactly is it you're after that Muttley's code doesn't provide?
<edit2> I'm really confused now. Muttley's code is projectmatrix rotation.
<edit3> In fact, it's neither it simply creates a projmatrix a la Indiepath's projmatrix
<edit4> From a quick check on gd.net the advice is to change just the FOV


JoshK(Posted 2008) [#5]
http://www.sjbaker.org/steve/omniv/projection_abuse.html


Pinete(Posted 2008) [#6]
Hi Leadwerks,
Could you please read your email?
I bought your engine yesterday via paypal but I've not received any download link still.
How much time I need wait till that? I'm very impatient.
Thanks a lot.

PD. Sorry all for the offtopic.


TartanTangerine (was Indiepath)(Posted 2008) [#7]
This is my version : http://www.modules.indiepath.com/forum/viewtopic.php?t=19

Used it loads - works and stuff :)


tonyg(Posted 2008) [#8]
Angle and scale are not currently implemented

Isn't that what GA is after though?


Grey Alien(Posted 2008) [#9]
Leadwerks: That page only lists problems with 3D effects doesn't it? This projection matrix code is for 2D games.

Btw :What exactly is it you're after that Muttley's code doesn't provide?
It's fine, I added some stuff to it and it totally works for zooming in and out and even reversing the scale.

isn't that what GA is after though?
I'd love to spin it yeah, but the scaling can be achieved by simply resizing the viewport rapidly.


ImaginaryHuman(Posted 2008) [#10]
The essence of the page that Leadwerks pointed to is not to use the projection matrix for changing the position or orientation of the camera, and to use the modelview matrix for that, and it applies to 2D or 3D. However I don't think it hurts to use the projection matrix to scale the camera lens to make things zoom in and out - but really you should move the model itself towards or away from the camera. So instead of looking at the projection matrix try scaling the modelview matrix, or translating it in Z to push it away from/towards the camera. It's safer and more supported to move the model than to move the camera. Use the projection matrix for changing the field of view/shape of the viewing frustum, but not its location in space.


Yan(Posted 2008) [#11]
The problem I was having was because I tested only with Yan's code which I assumed was the same as the rest but it was not for some reason
I don't know what's happening there, it *should* be exactly the same as we've all cut'n'pasted the code researched material from the same source, Max2D. :o)

[edit]
Tell a lie...I seem to have introduced a spurious LoadIdentity() into the GL code. It is, however, after the matrix is switched to model view so I don't think it should've broken anything?

Were you only having problems with GL?
[/edit]

[edit]
Gone back and removed the extra LoadIdentity() from all instances of the proj matrix code I could find.
[/edit]


Yan(Posted 2008) [#12]
Hmmm...A quick hack (didn't bother sorting out the origin) and it appears to be working alright here...


...as expected, it seems to work fine with the extra LoadIdentity() too?

??

[edit]
Aha...The GL section of code I've previously posted differs from the code I have here (0 rather than -1 for nearVal), not sure how that happened but fixed wherever I found it. :o/

I'll stop talking to myself now. ;o)
[edit]


tonyg(Posted 2008) [#13]
@GA
It's fine, I added some stuff to it and it totally works for zooming in and out and even reversing the scale.

Can you post the adjusted code?


Grey Alien(Posted 2008) [#14]
Yan: Basically the code I had before from you on an old thread didn't rescale the coords or the images when you changed viewport size, which it should have done (Mutley's did). Don't know why. May have been the nearVal setting or I screwed it up somehow. Otherwise it looked the same.


ImaginaryHuman: OK thanks. All I'm doing is changing the view port size to simulate scaling not using the scale param so I'm pretty sure that's OK. I've tested it on my PC in DX and GL and on my mac in GL. It works fine on all in full-screen and windowed mode except for one case: GL Windowed Mode on the PC seems to be a little jerky when zooming in. I've no idea why, but my game won't support that driver anyway. Hopefully this will still be a valid approach when supporting widescreen but I haven't got to that bridge yet...

TonyG: I'd love to BUT because I'm contracting for BFG, any work I do I'm being paid for (and they own) and can't make public I'm afraid :-( But I can *maybe* talk about the general method I used (possibly my contract prohibits that too under proprietary information/secrets)...

Basically all I did was get Mutley's TProjectionMatrix and add in a Zoom field and OriginalWidth and OriginalHeight fields. Then I alter the Zoom value in a loop and work out the Width and Height based on the OriginalWidth/Height and zoom and the set up the projection matrix again. This has the effect of zooming in or out very nicely and doesn't involve using the scale parameter. Naturally I've added more methods to automate the zooming over a set time and to zoom to a certain point by shifting SetOrigin. When combined with my TSlowMotion type I get a wicked Matrix-style Bullet Time effect which you'll see in my next game.


Grey Alien(Posted 2008) [#15]
So should I really be using the Scale param then or is that the one that might cause a problem according to Imaginary Human?

At some point BFG will test this code on a lot of PCs and then we'll find out if it works or not...


Yan(Posted 2008) [#16]
Basically the code I had before from you on an old thread didn't rescale the coords or the images when you changed viewport size
I think it *was* scaling, the view was just being clipped, hence the disappearing act. ;o}


So you're basically doing the same as I did with the code above, except for moving the viewport about too?


I can't see how the problems highlighted above even apply to orthographic mode in the first place? Moving stuff on the Z axis wouldn't make any difference so how else would you zoom in?


MGE(Posted 2008) [#17]
Sounds cool, can't wait to see it in use!


Grey Alien(Posted 2008) [#18]
Yan: I don't know. It seems to work so I'm happy for now...


ImaginaryHuman(Posted 2008) [#19]
You should be okay with 2D. It's just that in 3D when you try to do lighting, if you have translated or rotated the projection matrix it may not calculate light results properly. I'm trying to write my engine with moving the model instead of moving the camera at all, just to be on the safe side, but that mainly applies to 3d.


GfK(Posted 2008) [#20]
Sorry to dig up an old thread.

I'm using Yan's code (above) to handle multiple resolutions and it all works fine. I'm setting tVirtualGraphics to 800x600, and the screen resolution to anything higher, i.e. 1280x1024.

If I press CTRL+ALT+DEL in Vista, then open Taskmanager, the game window is restricted to an 800x600 portion in the top left corner of the 1280x1024 window.

Why is this? Anybody know how to stop it happening? Simply calling tVirtualGraphics.set() again isn't an option as the error is still visible for a second or two.

[edit] Only does it in DirectX (Works fine in OpenGL but I prefer to use DirectX).


Muttley(Posted 2008) [#21]
I found that you need to recreate the projection matrix if you minimise from full-screen and back again.

IIRC it only occurs with DirectX, not OpenGL.


MGE(Posted 2008) [#22]
What's happening is the device is being lost when in full screen mode. This will happen when apps pop up, task manager, etc, etc. You should be checking for a "If AppSuspended" before you render anything. If the app is suspended, in window mode you can just loop (until app is not suspended) a "Pause" message or something. In full screen mode, I just loop (again, until app is not suspended) without rendering anything because the device seems to be lost 99% of the time anyway.

Usually in windowed mode you won't lose the device while the app is suspended, but in full screen mode the app always seems to lose the device so when the app is no longer suspended in full screen mode, I always just EndGraphics(), GCCollect() and reinitialize the graphics screen, proj matrix, etc, etc, and continue on with the game. Graphics do not have to be loaded again. :)

I've tested it 100's of times on xp,vista, and it works in both OGL and DX.


GfK(Posted 2008) [#23]
Well, it all works perfectly, even when the window loses focus, or is alt-tabbed etc.

The only problem is when I press CTRL+ALT+DEL in order to start Task Manager. It screws up even if my app is in Windowed mode.

I've tried resetting tVirtualGraphics and it sort of works, but there is then a visible border around my tiled images (which was seamless before), and I don't know why that should be, either.

But the bottom line is, it looks butt-ugly and therefore isn't acceptable.


MGE(Posted 2008) [#24]
"It screws up even if my app is in Windowed mode." Sounds like you are not handling the AppSuspended properly. Perhaps you should post some basic code to see how you are handling it?


GfK(Posted 2008) [#25]
I don't think its anything to do with that, as it works perfectly in OpenGL, and in DirectX too apart from when I want to start taskmanager.

The image on the left is how it should look. The one on the right is how it looks after opening taskmanager.


Even reloading the graphics doesn't make this go away.


Grey Alien(Posted 2008) [#26]
Those tiles look like they are rendered at sub-pixel coords. Has your origin shifted?


GfK(Posted 2008) [#27]
Those tiles look like they are rendered at sub-pixel coords. Has your origin shifted?
No. Nothing changes at all.

Trying to keep things in perspective, I guess its no massive deal. I don't think CTRL+ALT+DEL is all that commonly used by your average games player anyway.