glViewport
is a completely different transformation than you think it is. What glViewport
actually does is re-map the scene after projection.
In OpenGL, the scene always projects to a special coordinate space where the viewing volume is defined by a cube: [-1,1] (following division by W
). The location (-1,-1,-1) is the bottom-left of your viewport at the near clip plane. The location (1,1,1) is the top-right of your viewport at the far clip plane. Your projection matrix produces coordinates in a special coordinate space called clip-space, and the clip-space coordinates are divided by W
to produce the NDC coordinates described above.
Thus, the only thing that glViewport
actually does is define where within your window that your projected image is displayed. It will effectively stretch the scene, and I do not think that is what you want. To display a 400x200 area, you need to alter your projection matrix as well so that you do not simply compress your projected scene into a smaller area.
Consider the following instead:
glOrtho (0, 400, 200, 0, -1, 1);
glViewport (0, 0, 400, 200);