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 = ySize9/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