Reputation: 41
So the default 2d clipping area of opengl is left -1.0 to right 1.0, and buttom -1.0 to top 1.0
And the window I created for an opengl program is 640 pixles in width and 480 pixels in height. The top left pixel is (0,0), the button right pixel is (640, 480)
I also wrote a function to retrive the coordinates when I click and drag and release the mouse button(When I click, it's (x1,y1) and when I release it's(x2,y2) )
So what should I do to convert (x1,y1) and (x2,y2) to the corresponding position in the clipping area?
Upvotes: 1
Views: 3457
Reputation: 54562
The answer given by @BDL might get you close enough for what you need, but the calculations are not really correct.
The division needs to be by the number of pixels in each coordinate direction, because you do have 640/480 pixels within the coordinate range.
One subtle detail to take into account is that, when you get a given position from your mouse input, these will be the integer coordinates of the pixels. If you simply apply the scaling based on the window size, the resulting OpenGL coordinate would map to the left/bottom edge of the pixel. But what you most likely want is the center of the pixel. To precisely transform this into the OpenGL coordinate space, you can simply apply a 0.5 offset to your input value, moving the value from the edge to the center of the pixel.
For example, the left most pixel would have x-coordinate 0, the right most 639. The centers of these two, after applying the 0.5 offset, are 0.5 and 639.5. Applying this correction, you can also see that they are now both a distance of 0.5 away from the corresponding edges of the area at 0 and 640, making the whole thing symmetrical.
So the correct calculation is:
float xClip = ((xPix + 0.5f) / 640.0f) * 2.0f - 1.0f;
float yClip = 1.0f - ((yPix + 0.5f) / 480.0f) * 2.0f;
Or slightly simplified:
float xClip = (xPix + 0.5f) / 320.0f - 1.0f;
float yClip = 1.0f - (yPix + 0.5f) / 240.0f;
This takes the y-inversion into account.
Upvotes: 3
Reputation: 22156
I assume that the rightmost pixel is 639 (otherwise your window would be 641 pixels large).
The transformation is quiet simple, we just need a linear mapping. To transform a point P from pixel coordinates to clipping coordinates one can use the following formula
319.5
P_clip = (P_pixel / [ ]) - 1.0
239.5
Let's go over it step by step for the x coordinate. First we transform the [0, 639] range to a [0, 1] range by dividing through the window width
P_01 = P_pixel_x / 639
Then we transform from [0, 1] to [-1, 1] by multiplying by 2 and subtracting 1
P_clip_x = P_01 * 2 - 1
When one combines these two calculations and extends it to the y coordinate one gets the equation given above.
Upvotes: 0