Dear all OpenGL experts:
I have a need to write a Graphics
application under Window2000 with MFC.
My problem is that I need split the graphics
window into 4 different sub windows (panes)
and let each panes shows different projection
model and views (for examples, one Perspective
projection and three Ortho2D with top, left and
right view). I struggled for almost one month,
and with some other people’s help, it did show
4 panes, but they are all with same Perspective
mode. Could anyone tell me how to achieve my
goal? I put some of the codes here, it is
lenghy, but hope to get some help from any of
your guys. Thanks.
In MainFrm.h, I have
protected:
CSplitterWnd m_wndSplitter;
and in MainFrm.cpp, I have
CView *p0, *p1, *p2, p3; //Globl Variable
:
:
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;
}
//Save the global variable – let call them as Pain ID
p0 = (CView *) m_wndSplitter.GetPane(0,0);
p1 = (CView *) m_wndSplitter.GetPane(0,1);
p2 = (CView *) m_wndSplitter.GetPane(1,0);
p3 = (CView *) m_wndSplitter.GetPane(1,1);
SetActiveView((CView*)m_wndSplitter.GetPane(1,1));
return TRUE;
}
CView * CMainFrame::ReturnActiveView()
{
return CFrameWnd::GetActiveView();
}
And in the View.cpp, I list the code segments as following:
void CGLSplitWndView::OnLButtonDown(UINT nFlags, CPoint point)
{
/*
if (p0 ==reinterpret_cast<CMainFrame*>(::AfxGetMainWnd())->ReturnActiveView())
AfxMessageBox(“Left Upper Pane (0,0) is selected”);
if (p1 ==reinterpret_cast<CMainFrame*>(::AfxGetMainWnd())->ReturnActiveView())
AfxMessageBox(“Right Upper Pane (0,1) is selected”);
if (p2 ==reinterpret_cast<CMainFrame*>(::AfxGetMainWnd())->ReturnActiveView())
AfxMessageBox(“Left Lower Pane (1,0) is selected”);
if (p3 ==reinterpret_cast<CMainFrame*>(::AfxGetMainWnd())->ReturnActiveView())
AfxMessageBox(“Right Lower Pane (1,1) is selected”);
*/
m_LButtonDown = TRUE;
m_LDownPos = point;
CView::OnLButtonDown(nFlags, point);
}
void CGLSplitWndView::OnLButtonUp(UINT nFlags, CPoint point)
{
m_LButtonDown = FALSE;
CView::OnLButtonUp(nFlags, point);
}
void CGLSplitWndView::OnMouseMove(UINT nFlags, CPoint point)
{
SetFocus();
CClientDC dc(this);
fastMakeCurrent(dc.GetSafeHdc(), m_hGLContext);
if (m_LButtonDown)
{
CGLSplitWndDoc* pDoc = GetDocument();
CSize rotate = m_LDownPos - point;
m_LDownPos = point;
m_yRotate -= rotate.cx/2;
m_xRotate -= rotate.cy/2;
GetDocument()->UpdateAllViews(NULL/*this*/);
}
CView::OnMouseMove(nFlags, point);
}
void CGLSplitWndView::OnPaint()
{
CPaintDC dc(this); // device context for painting
wglMakeCurrent(dc.GetSafeHdc(), m_hGLContext);
CGLSplitWndDoc* pDoc = GetDocument();
RenderScene();//Call the one in View ...
SwapBuffers(dc.m_ps.hdc);
}
void CGLSplitWndView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
GLsizei width, height;
GLdouble aspect;
width = cx;
height = cy;
if (cy==0)
aspect = (GLdouble)width;
else
aspect = (GLdouble)width/(GLdouble)height;
CClientDC dc(this);
wglMakeCurrent(dc.GetSafeHdc(), m_hGLContext);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//???How to specify each panes has its own projection model?? ???
gluPerspective(45, aspect, dClipNear, dClipFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDrawBuffer(GL_BACK);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}
void CGLSplitWndView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
Invalidate(false);
}
void CGLSplitWndView::RenderScene()
{
glClearColor(1.0f,1.0f,1.0f,0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
SetModelView();
double dZRatio = dClipFar/dClipNear;
//Dwaw the Background Grid
double dRange = min(5, dClipFar);
double dStep = dRange/20;
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glColor3f(0.9f, 0.9f, 0.3f);
glBegin(GL_LINES);
for (double dC = -dRange; dC <= dRange; dC += dStep)
{
glVertex3d(dC, 0, -dRange);
glVertex3d(dC, 0, dRange);
glVertex3d(-dRange, 0, dC);
glVertex3d( dRange, 0, dC);
}
glEnd();
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
GetDocument()->RenderScene();
glPopMatrix();
}
void CGLSplitWndView::SetModelView()
{
glTranslated(0,0,-8);
glRotated(m_xRotate, 1.0, 0.0, 0.0);
glRotated(m_yRotate, 0.0, 1.0, 0.0);
}
As your guys can see – in the OnLButtonDown routine,
if I took away those commends, then when I pick any of
the panes, it pops the right MessageBox. So I assume
that even there are 4 panes (sub windows), but they
use the same codes. NOW, MY PROBLEM IS::::::::::::
In the OnSize, there is one statement “gluPerspective”,
how can I do (what to change) so that the first pane
(ie, p0 = (CView *) m_wndSplitter.GetPane(0,0)
is ortho2d with top view (rotate x 90 degree) and
the second pane
(ie, p1 = (CView *) m_wndSplitter.GetPane(0,1)
is perspective view, and the third pane
(ie, p2 = (CView *) m_wndSplitter.GetPane(1,0)
is ortho2d with left view (rotate y 90 degree)
and the last pane
(ie p3 = (CView *) m_wndSplitter.GetPane(1,1)
is ortho2d with right view (rotate y -90 degree)???
Since your guys are experts, let me ask one more
question: How to add the displaylist to the code?
Does the displaylist handle differently in the split
window?
Thanks for all your helps,
Robert Yu tyyu@ksts.seed.net.tw