I need to show the same object in OpenGL in two different viewports, for instance, one using ortographic projection and the other using perspective. In order to do this, do I need to draw again the object after each call to glViewport()?
How to use multiple viewports in OpenGL
openglviewport
Related Solutions
Cross-browser @media (width)
and @media (height)
valuesÂ
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
window.innerWidth
and window.innerHeight
- gets CSS viewport
@media (width)
and@media (height)
which include scrollbars initial-scale
and zoom variations may cause mobile values to wrongly scale down to what PPK calls the visual viewport and be smaller than the@media
values- zoom may cause values to be 1px off due to native rounding
undefined
in IE8-
document.documentElement.clientWidth
and .clientHeight
- equals CSS viewport width minus scrollbar width
- matches
@media (width)
and@media (height)
when there is no scrollbar - same as
jQuery(window).width()
which jQuery calls the browser viewport - available cross-browser
- inaccurate if doctype is missing
Resources
- Live outputs for various dimensions
- verge uses cross-browser viewport techniques
- actual uses
matchMedia
to obtain precise dimensions in any unit
When using an onthogonal projection, you can simply think of the ortho matrix as defining some axis-aligned 2D rectangle in the xy-plane, which describes the area of the scene which is mapped to the viewport. If the aspect ratio of that rectangle does not match the aspect ratio of the viewport, the image will be distored accordingly.
Let us use the following definitions:
V: aspect of the viewport:
V = viewport_width / viewport_height
P: aspect of the ortho projection:
P = (right - left) / (top - bottom)
O: aspect of some axis-aligned rectangle which is drawn
O = (x_max - x_min) / (y_max - y_min)
When the transformations are applied, the object will appear with aspect ratio O / P * V
on the screen.
Usually, when speaking of "keeping aspect ratio", we set P == V
so that V / P
cancels each other out in the above formula, and objects appear with exactly that aspect ratio they are drawn in eye space.
And this is already exactly what you get with your code.:
Then I create a quad going from
-1,-1 to 1, 1
so that it's origin is at the center.
That is a square, and I wonder how you ever can expect this to come out as a rectangle when the aspect ratio is preserved.
From your images, it is clear that your object of interest is a rectangle with aspect ratio 2/3. So you should also draw it as a rectangle with such an aspect ratio. There are multiple ways to achieve this. Since the viewport size seems to be a given, you can sill tweak O
or P
or both.
However, to me it seems like you are completely overcomplicating things. If I got you right, you have some "design space" of 320x480 pixels, which is your "region of interest" which you always want to be visible on the screen, no matter what the viewport size is. To achieve that, you could do the following:
float target_width = 320.f;
float target_height = 480.f;
float A = target_width / target_height; // target aspect ratio
// ... calculate V as above
if (V >= A) {
// wide viewport, use full height
ortho(-V/A * target_width/2.0f, V/A * target_width/2.0f, -target_height/2.0f, target_height/2.0f, ...);
} else {
// tall viewport, use full width
ortho(-target_width/2.0f, target_width/2.0f, -A/V*target_height/2.0f, A/V*target_height/2.0f, ...);
}
Now, you can work in your "design range" in pixels. In that example, the always visible range will be from (-160, -240)
to (160, 240)`, and if you draw an rectangle exactly with that coordinates, it will match the blue box in your image, in any of the viewports. If you don't want the origin in the center, you can of course translate it.
Best Solution
Nehe has a good tutorial on how to do this, and his site is generally a good resource for OpenGL questions.