# Formulas for glViewport may be not exact

On this link I found the formulas for glViewport.
<www.opengl.org/wiki/GLAPI/glViewport>

xw = (xnd + 1) (width / 2) + x;
yw = (ynd + 1) (height / 2) + y;

First test: Assume x=0 and width=800, then the window coordinates go from 0 to 799.
xnd = 1 should result in the rightmost pixel 799.
xw ( 1 ) = ( 1 + 1 ) * 800 / 2 + 0 = 800; And not 799.

I derivated the formula for normalized device to window coordinates and came to a slightly different result
to replace “width” by “(width - 1)”:

xw = (xnd + 1) ((width - 1) / 2) + x;
yw = (ynd + 1) ((height - 1) / 2) + y;

Can someone confirm or disprove that?

Here my derivation for glViewport( x, y, width, height ):
So the rectangle is from (x) to (x + width - 1), and from (y) to (y + height - 1).

Example: glViewport( 400, 200, 800, 600 ) has a rectangle from x: 400 to 1199, and y: 200 to 799.

Formula for x:
xw - x = xnd * a + b; // Linear equation, resolve a and b.

1. xnd = -1, and xw = x:
x - x = -1 * a + b; -> a = b;

2. xnd = +1, and xw = x + width - 1:
x + width - 1 - x = 1 * a + b; -> width - 1 = 2 a; -> a = ( width - 1 ) / 2;

Insert in formula for x:
xw - x = xnd * (width - 1) / 2 + (width - 1) / 2;
xw = ( xnd + 1 ) * (( width - 1 ) / 2 ) + x;

Test:

1. xnd = -1: xw = ( -1 + 1 ) * (( width - 1 ) / 2 ) + x = x; -> ok, 400 by the example.
2. xnd = +1: xw = ( 1 + 1 ) * (( width - 1 ) / 2 ) + x = width - 1 + x; -> ok, 1199 by the example.

Analogical for y.

No, the coordinates go from 0 to 800, 800 being the right-hand edge of the right-most pixel. 799 would be the left-hand edge of the right-most pixel, which is one pixel in from the right-hand edge of the window.

Hello GClements,

thanks for your answer. As I understand you, in OpenGL the edges between the pixels are counted? Then there are 800 edges between 801 pixels. Do you know a reference for that?

In the MacOS X API the pixels themselves are counted. Because the pixel on position zero has also a count, a window with width=800 goes here from 0 to 799.

Best regards

Read the rasterization rules. It depends what type of primitive you’re drawing.

No; there are 801 edges “around” 800 pixels. There is an edge before the first pixel, after the last pixel, and between each pair of adjacent pixels.

You’re conflating coordinates with row/column indices.

Consider an 800x600 window, which has 800 columns and 600 rows.

The bottom-left pixel has its bottom-left corner at (0,0) in window coordinates, while its top-right corner is at (1,1) and its centre is at (0.5,0.5). Similarly, the top-right pixel has its bottom-left corner at (799,599), its top-right corner at (800,600), and its centre at (799.5,599.5).

The bottom-left corner of the window is at (0,0) while the top-right corner is at (800,600).

Essentially, a pixel as a whole doesn’t have specific coordinates; particular points within a pixel (e.g. corners, centre, edge midpoints) have specific coordinates. The pixel spans a range of coordinates.