Two OpenGL questions need your help!

Hello, everyone:

I have two questions and would like to
get some helps from your guys.

1> First question: How to get the cursor position
in the OpenGL 3D projection mode?

I am trying to get the cursor position
in a 3D OpenGL projection mode (like the
glOrtho(-5,5,-5,5,-100,100)) by using the
gluUnProject function. I know the answer
is not unique – but I want the point in
the xy plane – which means the z value
should be zero (world coordinates). How
can I achieve this goal?
I have the code segment like the following:

float x,y,z;
  
x = (float) point.x; 
y = (float) point.y;
z = 0.0f; 	   
MapDeviceToWorld(x,y,z); 
      :
      :
      and 

void CGLSplitWndView::MapDeviceToWorld(float &x, float &y, float &z)
{
CRect rectClient;
GetClientRect(rectClient);

GLdouble objx, objy, objz; 

glPushMatrix();
    SetModelView(); //Just set the right modelView matrix
    glGetDoublev(GL_MODELVIEW_MATRIX,modelMatrix);
glPopMatrix();

glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
glGetIntegerv(GL_VIEWPORT,viewport);

y = rectClient.Height() - y; 

gluUnProject((GLdouble)x,(GLdouble)y,(GLdouble)z,
          modelMatrix, projMatrix, viewport,
          &objx, &objy, &objz);

x = (float) objx; 
y = (float) objy; 
z = (float) objz;

}

and when I do this, the model view has rotate x and y
axis with 45 degree. The Projection Matrix is
glOrtho(-5,5,-5,5,-100,100);

The return answer is not correct – since the x,y are very
large, and the z value is not zero. I then try the following:
(assume p0=MapDeviceToWorld(x,y,0) and
p1=MapDeviceToWorld(x2,y2,1) and let the p0p1 form
a straight line and let this line intersect with z=0 plane
and find out the intersection point. The line is formed as
(x=x+t*(x2-x), y=y+t(y2-y), z=z+t(z2-z)), since z should be
zero, then t = z/(z-z2), then we should have our x and y)

float x,y,z;
float x2,y2,z2,t;
  
x = (float) point.x; 
y = (float) point.y;
z = 0.0f; 	   
MapDeviceToWorld(x,y,z); 
	
x2 = (float) point.x; 
y2 = (float) point.y;        
z2 = 1.0;
MapDeviceToWorld(x2,y2,z2);
if (fabs(z - z2) < fabs(0.00001)) //if there is no intersection
        t = 0.5;   //I am not sure if this is correct!
else
    t = z/(z-z2);
x= x + t * (x2 -x);
y= y + t * (y2 -y);
    z= z + t * (z2-z);		        

SomeHow this implement is still not right! When I get a value,
I polt that point location, it is not the location of the cursor
position. Can anyone help me with this quesiton?

2>Second Question: How to get the splitted windows have the
same size (all the same width and heigh)?

I have an OpenGL window, and I split it into 4 sub windows (panes)
with the following code segment:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
if (!m_wndSplitter.CreateStatic(this, 2, 2)) return FALSE;

int nSizeX = (lpcs->cx)/2;
int nSizeY = (lpcs->cy)/2;

if ( !(m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CGLSplitWndView), CSize(nSizeX, nSizeY), pContext) &&
m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CGLSplitWndView), CSize(nSizeX, nSizeY), pContext) &&
m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CGLSplitWndView), CSize(nSizeX, nSizeY), pContext) &&
m_wndSplitter.CreateView(1, 1, RUNTIME_CLASS(CGLSplitWndView), CSize(nSizeX, nSizeY), pContext)) )
{
m_wndSplitter.DestroyWindow();
return FALSE;
}

p0 = (CGLSplitWndView *) m_wndSplitter.GetPane(0,0);//Save the global variable – the Pain ID
p1 = (CGLSplitWndView *) m_wndSplitter.GetPane(0,1);
p2 = (CGLSplitWndView *) m_wndSplitter.GetPane(1,0);
p3 = (CGLSplitWndView *) m_wndSplitter.GetPane(1,1);

SetActiveView((CView*)m_wndSplitter.GetPane(0,0));
m_wndSplitter.RecalcLayout();

return TRUE;
}

When the program run, the heigh of p0 and p1 are not the same of
that of p2 and p3. I have to subtract 50 to nSizeY of p1 & p0
and add 50 to nSizeY of p2 & p3 so that the final panes look
like the same size. Why this happen? Is this a MFC bug?
Or do I mess it somewhere? I have make the initial screen
larger with the following code:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
int xSize = ::GetSystemMetrics(SM_CXSCREEN);
int ySize = ::GetSystemMetrics(SM_CYSCREEN);
cs.cx = xSize9/10;
cs.cy = ySize
9/10;
cs.x = (xSize - cs.cx) /2 ;
cs.y = (ySize - cs.cy) /2 ;
cs.style &= ~FWS_ADDTOTITLE;

return CFrameWnd::PreCreateWindow(cs);

}

Does the above code effect the size of the splitted windows?

Thanks for all your helps. I appreciate.

Robert Yu tyyu@ksts.seed.net.tw

  1. gluUnProject gives you for z=0 the worldcoordinates of the near clipping plane and for z=1 of the far clipping plane.

Your calculations seem correct to me, so there must be anothermistake, my best guess would be that you are setting the Modelviewmatrix wrong.

  1. i have no idea