# Algorithm for gluProject

I need to know if anyone has an algorithm for converting a 3D location to 2D coordinates. I tried to implement my own, but I couldn’t get it to work. gluProject works fine, but is rather slow. I have the matrix from the Object I wish to draw. There has to be a way to do this, anyone have an algorithm?

A simple algorithm

x’ = xfactor * x/(z + bias)
y’ = yfactor * y/(z + bias)

xfactor/yfactor create an aspect ratio

errrm, are xfactor,yfactor,bias trial and error values or is there some relationship to the FOVY and the Viewport. I guess I don’t understand how to utilize that.

xfactor and yfactor represent a distance from the eye to the focus. There’s some more math needed to get a FOVY equivalent for them. bias is supposed to be a fairly small number to prevent a division by zero.

tan(FOVY/2) * (focus length) should get you your max abs(y’) denoted by [-h,h].

y’ = yfactor * (y/z), in this sense will get you a value in [-h,h] if visible. Same goes with x’

Of course, this is all assuming you translated first and scale your (x’,y’) from [-h,h] to your actual window coords afterwards.

I’ll quote the OpenGL Reference Manual v1.1:

To compute the coordinates, let v=(objX,objY,objZ,1.0) represented as a matrix with 4 rows and 1 column. Then gluProject computes v’ as follows:

v’ = P x M x v

where P is the current projection matrix proj, M is the current modelview matrix model (both represented as 4x4 matrices in column-major order) and ‘x’ represents matrix multiplication.

(Then v’ = v’ / v’(3) is performed, where v’(3) is the fourth coordinate - w - of v’. This is missing in the text, but AFAIK is needed for a correct implementation. ET.)

The window coordinates are the computer as follows:

winX = view(0) + view(2) * (v’(0) + 1) / 2
winY = view(1) + view(3) * (v’(1) + 1) / 2
winZ = (v’(2) + 1) / 2

(I agree with you that glProject is slow. I implemented my own projection in Java, and it was faster. The implementation was based on the above description, with the correction I mentioned.)

[This message has been edited by ET3D (edited 04-30-2001).]

Looks complicated but thank you. I’ll try to get that working somehow.

I guess I thought there might be an easier was of doing it.

It’s not that complicated. You just have to be able to do matrix/vector multiplication (and matrix/matrix multiplication, but you should do this only once, not for every vertex you project).

winX = view(0) + view(2) * (v’(0) + 1) / 2

NeHe has just posted a new article. I think it explains exactly the thing you are asking for, but i´m not sure, haven´t read it, yet.

Jan.