public class Viewport extends Object
Vertex
of a LineSegment
from
projected camera coordinates (i.e., image plane coordinates)
to viewport coordinates.
The image plane contains a view rectangle with
-1 <= x <= 1,
-1 <= y <= 1,
The view rectangle has the important job of determining what part of the scene is visible to our renderer.
In the previous pipeline stage, every line segment from the scene was projected onto the image plane. We want only that part of each projected line segment contained in the view rectangle to be visible to our renderer and rasterized into the framebuffer's viewport. To prepare for the rasterization step, we need to convert each vertex's x and y coordinates
(w+1/2,h+1/2)
y-axis +----------------------------------------+
| | |
| (+1,+1) | |
+-----|-----+ | |
| | | | |
| | | | |
----------+----------- x-axis | |
| | | | |
| | | | |
+-----|-----+ | |
(-1,-1) | | |
| | |
| |
View Rectangle +----------------------------------------+
(in the view plane) (1/2,1/2)
Logical Viewport
Notice how the view rectangle is a square but the logical viewport is a reactangle (though it may be a square).
The view rectangle always has -1.0 <= x <= 1.0 and -1.0 <= y <= 1.0.
The logical viewport always has 0.5 <= x <= w+0.5 and 0.5 <= y <= h+0.5 where w and h are the width and height of the FrameBuffer's current viewport.
If the aspect ratio, w/h, of the logical (and FrameBuffer) viewport is not 1, then the image in the view rectangle will be distorted when it is transformed to the logical viewport. (NOTE: Starting with Renderer 7, the aspect ratio of the viewport will usually match the aspect ratio of the renderer's view volume, so the distortion caused by the viewport transformation will undo the distortion caused by the normalization transformation. If the view volume and viewport aspect ratios do not match, then the final image in the framebuffer's viewport will be a distortion of the image in the view volume's view rectangle.).
For each Vertex
object in each LineSegment
object,
transform the Vertex object from image plane coordinates to viewport
coordinates so that the view rectangle in the image plane with
-1 <= x <= 1,
-1 <= y <= 1,
transforms into a viewport where
0.5 <= x < w + 0.5,
0.5 <= y < h + 0.5,
where
w = number of horizontal pixels in the viewport,
h = number of vertical pixels in the viewport.
The goal of this transformation is to put a logical pixel with integer coordinates at the center of each square physical pixel. The logical pixel with integer coordinates (m, n) represents the square pixel with
m - 0.5 <= x < m + 0.5,
n - 0.5 <= y < n + 0.5.
Notice that logical pixel integer coordinates (m.n) have
1 <= m <= w
1 <= n <= h.
Let us derive the formulas for the viewport transformation (we will derive the x-coordinate formula; the y-coordinate formula is similar).
Let x_p denote an x-coordinate in the image plane and let x_vp denote an x-coordinate in the viewport. If a vertex is on the left edge of the view rectangle (with x_p = -1), then it should be transformed to the left edge of the viewport (with x_vp = 0.5). And if a vertex is on the right edge of the view rectangle (with x_p = 1), then it should be transformed to the right edge of the viewport (with x_vp = w + 0.5). These two facts are all we need to know to find the linear function for the transformation of the x-coordinate.
We need to calculate the slope m and intercept b of a linear function
x_vp = m * x_p + b
that converts image plane coordinates into viewport coordinates. We know,
from what we said above about the left and right edges of the view
rectangle, that
0.5 = (m * -1) + b,
w + 0.5 = (m * 1) + b.
If we add these last two equations together we get
w + 1 = 2*b
or
b = (w + 1)/2.
If we use b to solve for m we have
0.5 = (m * -1) + (w + 1)/2
1 = -2*m + w + 1
2*m = w
m = w/2.
So the linear transformation of the x-coordinate is
x_vp = (w/2) * x_p + (w+1)/2
= 0.5 + w/2 * (x_p + 1).
The equivalent formula for the y-coordinate is
y_vp = 0.5 + h/2 * (y_p + 1).
Constructor and Description |
---|
Viewport() |
Modifier and Type | Method and Description |
---|---|
static void |
viewport(LineSegment ls,
FrameBuffer fb)
For each
LineSegment , transform each Vertex
from image plane coordinates to viewport coordinates. |
public Viewport()
public static void viewport(LineSegment ls, FrameBuffer fb)
LineSegment
, transform each Vertex
from image plane coordinates to viewport coordinates.ls
- LineSegment to transform into viewport coordinatesfb
- FrameBuffer that holds the current viewport