PDA

View Full Version : bad projection with gluUnProject



grodslukaren
07-04-2001, 04:57 AM
What might be the error if I get really strange convertions with the use of gluUnproject??

I have a OpenGL window with the dimensions 250*250 and a coordinate sytem in my OpenGL space defined as:

// create the coordinate system
glOrtho(-180.0,180,-180.0,180.0,-256.0,256.0);

When I use the screen coordinates I get from a mouse click, I receive the "un"-projected coordinates as:

screenX = 96 => objectX = -72
screenY = 182 => objectY = 357
screenZ = 0.36 => objectZ = 103

Itīs strange, because I make a mouse click at an object placed almost in the center of my coordinate system that has the radius of 130 and is not rotated. After the projection my "clicked" point is outside my coordintae system and my object... ????

Is there anything wrong to do gluUnProject with the use of glOrtho??


some code when converting:
// get the mouse coordinates
event.GetPosition(&x,&y);
winx = (GLdouble) x;
winy = (GLdouble) 250-y; // window height - y
glReadPixels(x,y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&depth);
winz = (GLdouble) depth;
// here we get the object coordinates from the screen coordinates
glMatrixMode(GL_MODELVIEW);
glGetDoublev(GL_MODELVIEW_MATRIX, modelviewMatrix);
glMatrixMode(GL_PROJECTION);
glGetDoublev(GL_PROJECTION_MATRIX , projectionMatrix);
glGetIntegerv(GL_VIEWPORT,viewport);
gluUnProject(winx,winy,winz,modelviewMatrix,projec tionMatrix,viewport,&objx,&objy,&objz);

DFrey
07-04-2001, 06:50 AM
Since you are using a orthographic projection, it should be easy enough to just map the viewport to the bounds of the projection, and use that mapping to convert the mouse coordinates.

DFrey
07-04-2001, 06:54 AM
Or wait, if I read between the lines, it looks like you may be drawing a 3D object using a orthographic projection, and wanting to determine which part of the object was clicked. Is this correct? Or are you drawing a 2D object and just want to determine if it was clicked on (like a GUI button)?

grodslukaren
07-04-2001, 07:07 AM
Thatīs it, I have a 3D object ( a head ) and Iīd like to insert small objects ( dipoles ) at the point I give to the program with a mouse click...

/grodslukaren

DFrey
07-04-2001, 10:03 AM
I'm confused then. Are you using the orthographic projection to draw the head, or are you using a perspective projection? Is this some kind of 3D editor you are working on? That's what it sounds like to me anyway.
So if I understand correctly, you have a parallel projection of a 3D head which you can rotate, and you want to find the point on the front side of the head (front as rotated) that was clicked. So that you can then draw the dipole at that coordinate. Am I getting close to understanding what you want?

grodslukaren
07-04-2001, 10:21 AM
Well, you are close... ; )

Iīm using my OpenGL to show a head in 3D. The head is shown in orthographic projection and Iīd like to be able to place a dipole at the point I specify with the mouse. The thing is that I can ( as you wrote) rotate the head with the mouse to look at diferent parts of the head.

It is not that important to place it right in z-position, because I have three different windows, one where I can rotate the head and two other where I can see the head from the side and from above, and from there change the z-position to desired location.

I hope you get it...
Iīd like to say thanks for the help so far!!!

/grodslukaren

dUckmAnn
07-04-2001, 10:34 AM
AFAIK you should use the same coordinate-system for both glReadpixels and gluUnproject.
you give a different value for the y-coordinate in gluUnproject. i think gluUnproject(x, y, winZ, ...) should work.

Carl

grodslukaren
07-04-2001, 11:48 AM
Thanks Duck!
That made it much better, but itīs still not good. As I mentioned before, I have three windows, th main window which I rotate with the mouse, and two others, the first rotated 90 degrees on the the x-axis and the second 90 degrees on the y-axis. With the last advice, it works fine when I click in the window where I rotated the head 90 degrees on the y-axis. And the dipoles are inserted as I wish. But why doesnīt it work in the other two windows??? Even if I rotate the head to an angle I havnīt got a clue of, gluUnProject takes care of that???

dUckmAnn
07-05-2001, 05:23 AM
do you use the correct modelview/projection matrix??? each time you call glRotatef/glTranslatef you modify the modelview-matrix. draw the front view, save front MV-matrix, draw left-view, save left MV-matrix,etc... when you click, determine on which view you clicked and pass the correct MV-matrix to gluUnproject.

Carl

grodslukaren
07-05-2001, 06:02 AM
The thing is that I have a class that is used for the three different views, as you can see in the code below. So the MV-matrix doesnīt change between the three views... I mean, they are in three different objects...

Or is it really stupied to use the same class?? This is the only difference and I thought that it wouldnīt be any problem with this...

???

/grodslukaren

void CDirectCanvas::Render()
{
int dipole;

wxPaintDC dc(this);
// sets this canvas as the current recipient of OpenGL calls
SetCurrent();
// init OpenGL once, but after SetCurrent
if (!m_bInit)
{
InitGL();
m_bInit = true;
}

// clear color and depth buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);

// the same class is used to show three different views/angles
// view from above
if (m_numWindowType == UPPER)
{
glLoadIdentity();
glRotatef(90, 1.0f, 0.0f, 0.0f );
}
// side view of the head
else if (m_numWindowType == LOWER)
{
glLoadIdentity();
glRotatef( 90, 0.0f, 1.0f, 0.0f );
}
else // view from the front, allow to rotate the head
{
// rotate the head
glRotatef( m_dXAngle, 1.0f, 0.0f, 0.0f );
glRotatef( m_dYAngle, 0.0f, 1.0f, 0.0f );
}
// draw dipoles if exist any, opaque
if (m_bDipoles)
glDisable(GL_BLEND);
{
for (dipole=0; dipole<m_numNbrOfDipoles; dipole++)
{
glPushMatrix();
glTranslatef(m_pDipoles[dipole]->posX,m_pDipoles[dipole]->posY,m_pDipoles[dipole]->posZ);
glPushName(dipole);
glColor3f(0.3f, 0.3f, 1.0f); // dipoles drawn blue
glCallList(DIPOLE); // draws a dipole
glPopName();
glPopMatrix();
}
}

glEnable(GL_BLEND);
// draw the brain, the scalp and the face from the displaylists blended to 33%
glPushMatrix();
glTranslatef(-0.00950363f, 84.0311f,-16.7920f);
glColor4f(0.3f, 1.0f, 0.3f, 0.33f);
glCallList(BRAIN);
glPopMatrix();
glColor4f(1.0f, 0.4f, 0.3f, 0.33f);
glCallList(DISP_FACE); // draws the face
glCallList(DISP_REAL_SCALP); // draws the scalp with the same color as the face

glFlush();
SwapBuffers();
}