Setting up a simple view matrix

Started by
8 comments, last by Sandra-24 18 years, 7 months ago
I think a view matrix is what I need, but I'll explain the problem first. I made an OrthoOffCenter projection with a width of 3500 and a height of 2400. I then setup a bunch of quads and textures (35) to render a 3500x2400 image in 2d. This seems fine to me. But when I draw the first of the quads at the 0,0 position, it's way smaller than it should be. It seems like the entire 3500x2400 region is being scaled to fit inside the backbuffer (which I made 800x600). I only want to display 800x600, but I don't want the 3500x2400 area scaled to fit, I want everything outside the 800x600 view to be clipped instead. How do I accomplish this? Do I use a view? I tried setting up a view last night but had no success. I need some help with this. Thanks a bundle, -Sandra
Advertisement
I can't say for sure, but I doubt the problem is related to the view matrix. Here's the way it works in OpenGL (I think it's similar in D3D). The projection matrix maps the view volume (3500x2400x? in your case) to canonical clip space. (There's also a divide by w in there, but it doesn't have any effect for orthographic projection). Canonical clip space is in the range [-1,1] for x and y, while z is in the range [0,1] in D3D, and [-1,1] in OpenGL.

Coordinates in this space are called normalized device coordinates. From here they are mapped to the viewport. For example, an x value on the left side of your view frustum would map to -1 in NDC, which would map to the left edge of the viewport. An x value on the right side of the view volume would map to +1, and then to the right edge of the viewport. So what you describe - the 3500x2400 area being scaled to fit the 800x600 viewport - is, I think, what you should expect given the series of transformations that are being applied.

Beyond that, since I'm not positive what you're trying to do, I don't have any particular advice. I know there are techniques for, say, rendering images in higher resolutions; perhaps these are what you're looking for...
Actually I just want my 3500x2400 region to render without any scaling. The 800x600 viewport will only allow a small part of it to be visible at once, but that part should be at full size. Then I can move the viewport around so I can see different parts of the 3500x2400 region.

The only way I know how to do this is to actually render only a 800x600 region and render a different part of the larger region as an 800x600 region every time someone scrolls. That seems very complex and completely the wrong way of doing things. I should imagine that directx allows one to leave the rendered things as they are and just move the view over a bit. You guys are the experts though, please just give me an idea of what to do, because I don't even know where to start.

-Sandra
I think what Sandra-24 is trying to accomplish is like you have a big image and you're looking at a portion of that image. So you see only that portion not the whole image shrink down so you can see the whole image.

If that's the case, then what you can do is manage the big image in memory, and then decide which portion of it to render then render that portion of it.
Quote:I think what Sandra-24 is trying to accomplish is like you have a big image and you're looking at a portion of that image.


Bingo.
This is an unusual request. Why would you not just render the visible part of your large image each frame? Each frame you should be writing the 800x600 pixels you care about. What is the need for storing all the invisible stuff in any memory?

In other words, why not just store a "camera" x and y which range from (0,0) to (3500 - 800, 2400 - 600) and then render with that x and y representing the top left corner of the screen? Not only do you not use excessive memory, but if your scene is dynamic you don't have to worry about it.
Well, maybe I was wrong about the view matrix not being involved. One way to do what you want might be as follows. Build your 3500x2400 'wall of quads'. Set your viewport to 800x600, and set your orthographic projection matrix to 800x600 as well. Then use the view matrix to move your camera around, keeping it in a plane parallel but some distance away from the quad plane. Since all you'll be doing is translating, the view matrix will just be an identity matrix with the negatives of your camera translation loaded into the bottom row.

Another way you could do it might be to adjust your frustum parameters so as to view different parts of the image. In this case, the view matrix would not be involved.

That said, if this is only ever going to be a 2d application, there might be more direct ways of approaching the problem.
Quote:Why would you not just render the visible part of your large image each frame?


Yes that can work masterworks, but it is not required. By culling any quads that don't appear in the viewing window I can reduce the amount rendered to reasonable levels. I'll probably be rendering a region about 3 times the size of the viewing window, but it hardly matters since the game is so simple anyway.

I don't see any way of implementing it that would be lighter on the memory asside from using the harddrive. I'm not hitting the hard drive for 20mb of bitmap data every frame though, that's crazy.

I seem to have figured it out though. By modifying the Matrix.OrthoOffCenterLH parameters I can acheive the effect I want. Adding +800 to the min and max x params for example will move the viewing region over by 800 pixels. No need to fiddle with View or World matrices.
That's cool if you figured it out, I just don't understand why you need to render an area larger than the area that can be viewed. If you can't see it, why render it?
Quote:If you can't see it, why render it?


Since the image is broken down into 512x512 textures, rendering an area of the screen thats about 800x600 - 1024x768 will involve many 512x512 regions that are viewable (probably 6-9 most of the time) So to draw only what needs to be visible I would have to create all the vertices every frame and go through somewhat complex code to show the right size triangles with the right parts of the textures on them. I doubt it would perform much better than just rendering the 6-9 quads. Besides which, I'm under the impression even ancient video cards sneeze at the idea of rendering 12-18 triangles so it's all a moot point.

Sure one could figure out what part of the image to display on the screen, load it into the texture and render it in 4 neat quads every frame, but that's way more expensive (although cheaper on memory.) I don't think it's worth it. Copying a section of a 3500x2400 jpeg every frame into a bitmap and then into a texture taxes even my computer to the limits.

-Sandra

This topic is closed to new replies.

Advertisement