Manual world-to-screen conversion

Hi, I’m writing a painterly renderer along the lines of various papers by others. I’m doing this by placing particles on geometry and then I need to transform those particles co-ordinates to screen space in order to paint strokes.
I’ve got as far as:

MatrixMultiply(particleposition * GL_MODELVIEW_MATRIX);
MatrixMultiply(particleposition * GL_PROJECTION_MATRIX);

but then I’m stuck. If I’ve got say a sphere going backwards and forwards across a 500 pixel wide screen, I get values roughly between -10 and 10 in the x part of the resulting vector. Can I assume that scaling this figure to 0 - 499 will give me the right answer in screen co-ordinates? I’m not sure…or is there some other transformation I need to do?



After multiplying by the modelview and projection matrix, you have your coordinate in clip space. To get screen coordinates, you need to “de-homogenize” (don’t know if this is this word is correct) the vector, and make a viewport transform.

De-homogenizing is when you divide the three first components by the fourth.

V = vector to be de-homogenized
V.x = V.x / V.w;
V.y = V.y / V.w;
V.z = V.z / V.w;
V.w = 1;

You now have normalized device coordinates, and you need to do a viewport transform.

X = viewport[0] + (1 + V.x) * viewport[2] / 2;
Y = viewport[1] + (1 + V.y) * viewport[3] / 2;
Z = (1 + V.z) / 2;

X and Y is the viewport coordinates.
Z is the value that goes into the Z-buffer.

Oh, and viewport is the four values returned by glGetIntegerv(GL_VIEWPORT, viewport);

Thanks for your reply Bob,
I tried the method you suggested but I’m still getting weird values, x between roughly -1000 and +1400!
I set up the program by calling glutInitWindowSize(500, 500);
and then
gluPerspective(45, 1.0, 0.1, 200);

so surely I should be getting like between -250 and +250 or something? Do I need to call glFrustrum instead?