# doing a 3D lensflare

Ok, so we are doing a rendering engine and want to add lensflares (not very original, yeah). I know how to do them in 2D space (put the light wherever it is, trace a line from there thru the center of the screen and put the nice translucent polygons there).
Problem comes if we try to do this in 3D: we have a sun in a 3D position, and need ot be able to paint the trailing flares aligned.

Any help? (source code preferred)

I would imagine that if you get the screen coordinates of your sun w/ gluProject, then change the projection matrix to an orthogonal projection (and use glPushMatrix to save your perspective matrix) w/ a pixel separation of 1 unit, then you can do your lens flare as if you where working in 2D and in screen coordinates and return to your perspective projection w/ glPopMatrix.

here is the source actually :

proto of gluProject :
int gluProject(GLdouble objx, GLdouble objy, GLdouble objz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *winx, GLdouble *winy, GLdouble *winz);
Map the specified object coordinates (objx, objy, objz) into window coordinates, using transformations defined by a modelview matrix (modelMatrix), projection matrix (projMatrix), and viewport (viewport). The resulting window coordinates are returned in winx, winy, and winz. The function returns GL_TRUE, indicating success, or GL_FALSE, indicating failure.
(taken from somewhere at http://helios.scripps.edu/cgi-bin/infosr…OpenGL_PG/6635))

The code would be:

GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport); // for use in gluProject
gluProject(…);
GLint saved_matrix_mode[1];
glGetIntegerv(GL_MATRIX_MODE, saved_matrix_mode);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
gluOrtho2D(0.0, (GLfloat) viewport[2], 0.0, (GLfloat) viewport[3]);
// do your 2D lens flare here using winx, winy, winz for the screen coord of the sun !
glPopMatrix();
glMatrixMode(saved_matrix_mode[0]);

See what I mean ?

Moz

Another idea:
winz is the depth value of the “virtual fragment” returned by gluProject and is scaled the same way as the values in the depth buffer.
With that you can figure out if an object is masking the sun. Just read the depth buffer at the winx, winy coords returned by gluProject if winz is greater than the value in the depth buffer then don’t do the lens flare since the sun is masked.

Moz

Originally posted by Moz:
[…]Just read the depth buffer at the winx, winy coords returned by gluProject if winz is greater than the value in the depth buffer then don’t do the lens flare since the sun is masked.

I actually wanted to do something like this, but had serious problems with glReadPixels, using a Matrox G400 and Win2000.
I still don’t know if it’s a Matrox bug, so I’d like to know there are specific rules to make glReadPixels work fine… Things to avoid and so on.

Thanks

Moz, I notice that you are reading GL_MATRIX_MODE into a one element array. You can do this more nicely if you do

``````GLint saved_matrix_mode;
glGetIntegerv(GL_MATRIX_MODE, &saved_matrix_mode);
``````

and after that you can use saved_matrix_mode instead of saved_matrix_mode[0]