5
\$\begingroup\$

My Camera class handles zoom, rotation, and of course panning. It's invoked through SpriteBatch.Begin, like so many other XNA 2D camera classes. It calculates the view Matrix like so:

public Matrix GetViewMatrix() {
    return Matrix.Identity
        * Matrix.CreateTranslation(new Vector3(-this.Spatial.Position, 0.0f))
        * Matrix.CreateTranslation(-( this.viewport.Width / 2 ), -( this.viewport.Height / 2 ), 0.0f)
        * Matrix.CreateRotationZ(this.Rotation)
        * Matrix.CreateScale(this.Scale, this.Scale, 1.0f)
        * Matrix.CreateTranslation(this.viewport.Width * 0.5f, this.viewport.Height * 0.5f, 0.0f);
}

I was having a minor issue with performance, which after doing some profiling, led me to apply a culling feature to my rendering system. It used to, before I implemented the camera's zoom feature, simply grab the camera's boundaries and cull any game objects that did not intersect with the camera.

However, after giving the camera the ability to zoom, that no longer works. The reason why is visible in the screenshot below. The navy blue rectangle represents the camera's boundaries when zoomed out all the way (Camera.Scale = 0.5f). So, when zoomed out, game objects are culled before they reach the boundaries of the window. The camera's width and height are determined by the Viewport properties of the same name (maybe this is my mistake? I wasn't expecting the camera to "resize" like this).

screenshot

What I'm trying to calculate is a Rectangle that defines the boundaries of the screen, as indicated by my awesome blue arrows, even after the camera is rotated, scaled, or panned.

Here is how I've more recently found out how not to do it:

public Rectangle CullingRegion {
    get {
        Rectangle region = Rectangle.Empty;

        Vector2 size = this.Spatial.Size;
        size *= 1 / this.Scale;

        Vector2 position = this.Spatial.Position;
        position = Vector2.Transform(position, this.Inverse);

        region.X = (int)position.X;
        region.Y = (int)position.Y;
        region.Width = (int)size.X;
        region.Height = (int)size.Y;

        return region;
    }
}

It seems to calculate the right size, but when I render this region, it moves around which will obviously cause problems. It needs to be "static", so to speak. It's also obscenely slow, which causes more of a problem than it solves.

What am I missing?

\$\endgroup\$
1
  • \$\begingroup\$ I should add that no matter what the zoom level, the top-left corner of the camera's bounds (the blue box) is (0,0). \$\endgroup\$
    – Cypher
    Commented Oct 7, 2012 at 19:00

1 Answer 1

3
\$\begingroup\$

Ask your Game class what the properties of Window.ClientBounds.Width and Window.ClientBounds.Height are.

\$\endgroup\$
1
  • \$\begingroup\$ This answer is "sort of" right. Just be careful about introducing dependencies / static / global-state when you implement this. \$\endgroup\$
    – ashes999
    Commented Dec 21, 2012 at 16:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .