The typical OpenGL projection matrix (what you get from glFrustum or gluPerspective) puts the camera point at the origin. The plane of projection is at (0, 0, -1): one unit in front of the camera.
So for a given vertex, what you need to find is the X and Y positions you would get for a projection onto the (0, 0, -1) plane. This is technically "ray tracing", but since it's an axis-aligned plane, and the camera is at the origin, it really is just simple arithmetic:
vec3 newPosition = oldPosition * (-1.0 / oldPosition.z);
Note that interpolating parameters under this perspective projection will be linear in window space, not eye/camera-space. That is, there will be no perspective correct interpolation.
Also, note that the above "simple arithemtic" does not take into account FOV. To handle that, you need to transform the X and Y of oldPosition
by the upper-left part of the perspective matrix. Or just extract the 0,0 and 1,1 values from the projection matrix and multiply them with the X and Y of oldPosition
. That takes care of the scaling.
One more note, since you did not state the overall goal of this.
OpenGL does not require you to render an entire scene with a single projection matrix. You can render some of a scene orthographically, while using a perspective matrix for the rest. This is often done in games, where the HUD and text elements are rendered orthographically, while the game itself is in a 3D perspective.
If this is what you're doing, all you need to do is something like the following:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(...);
glMatrixMode(GL_MODELVIEW);
//Render my perspective stuff here.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(...);
glMatrixMode(GL_MODELVIEW);
// Render my orthographic stuff here.
You may want to turn off depth tests during the orthographic rendering, if you have ortho objects that overlap the perspective ones.