PDA

View Full Version : Drawing in two windows



glsqyj
11-13-2005, 06:02 AM
I split the window into two,and I want to draw different scenes in this two windows.
But when I initialized the two windows,problem occured,one of them cannot be clear to backgroud color.
I don't know how can it happens?Is it possible that OpenGL cannot be initialized in two splitted windows?
Please help me.Thanks.

dorbie
11-14-2005, 03:52 PM
It seems you may be confused when you use the word window. Please be precise and clear when discusisng this stuff. If you have a single window and two regions in that window you need to make sure your viewport and scissor calls are set correctly when you issue the clear call for each region.

If you really have two windows then you'll have two contexts and in that case make sure you have the correct context active when drawing to the desired window, drawing includes the clear call and all other OpenGL calls that apply to that context.

glsqyj
11-14-2005, 07:27 PM
Thank you upstairs.
The code works well before I split the window.I split one window into two region,that means,two view.In each view, I add the same opengl basecode and do nothing else.But then the problem occured:one view cannot be clear to its background color.
I think it's the context problem,is it?But how can I do with it?
Please help me,thanks.

dorbie
11-14-2005, 11:33 PM
When you say you split the window into two views what do you mean. Do you have two eparate windows or one window with viewport calls. Be very clear about what you're doing or you're wasting your time and mine.

glsqyj
11-15-2005, 03:32 AM
I am sorry about my English.I will try to express my problem clearly.
I start my code in SDI(VC++6.0).Then I split the window into two parts with CSplitterWnd.In each part I want to do some drawing irrelevantly.What can I do?
I don't know whether it is clear. I have the code,but I don't know how to upload to this forum.Can we talk through E-mail?Mine is glsqyj@163.com
Thank you.

glsqyj
11-15-2005, 07:22 PM
I start a project named "1".
this is the code of "My1View.cpp"

void CMy1View::OnDraw(CDC* pDC)
{
CMy1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

if (!SwapBuffers( m_pDC->GetSafeHdc() ) )
{
AfxMessageBox("SwapBuffers failed",MB_OK|MB_ICONEXCLAMATION);
}
}

int CMy1View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

InitializeOpenGL();
return 0;
}

void CMy1View::OnDestroy()
{
CView::OnDestroy();

if ( FALSE == ::wglDeleteContext( m_hRC ) )
{
AfxMessageBox("wglDeleteContext failed",MB_OK|MB_ICONEXCLAMATION);
}

if ( m_pDC )
{
delete m_pDC;
}
}

BOOL CMy1View::InitializeOpenGL()
{
m_pDC =new CClientDC(this);
if ( NULL == m_pDC ) // failure to get DC
{
AfxMessageBox("Unable to get a DC",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if (!SetupPixelFormat())
{
return FALSE;
}
if ( 0 == (m_hRC = ::wglCreateContext( m_pDC->GetSafeHdc() ) ) )
{
AfxMessageBox("wglCreateContext failed",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}

if ( FALSE == ::wglMakeCurrent( m_pDC->GetSafeHdc(), m_hRC ) )
{
AfxMessageBox("wglMakeCurrent failed",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
::glClearColor( 0.0f, 0.0f, 0.0f, 1.0f);clear depth
::glClearDepth( 1.0f );
::glEnable( GL_DEPTH_TEST );
return TRUE;
}

BOOL CMy1View::SetupPixelFormat()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
// 32, // 32-bit z-buffer
16, // NOTE: better performance with 16-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelformat;
if ( 0 == (pixelformat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) )
{
AfxMessageBox("ChoosePixelFormat failed",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
if ( FALSE == ::SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) )
{
AfxMessageBox("SelectPixelFormat failed",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
return TRUE;
}
void CMy1View::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);

if ( 0 >= cx || 0 >= cy )
{
return;
}
::glViewport(0, 0, cx, cy);

::glMatrixMode( GL_PROJECTION );
::glLoadIdentity();
aspect_ratio = (GLdouble)cx/(GLdouble)cy;
::gluPerspective( 45.0f, aspect_ratio, 0.1f, 100.0f );
::glMatrixMode( GL_MODELVIEW );
::glLoadIdentity();
}

glsqyj
11-15-2005, 07:25 PM
And this is my new dialog,its "CV1.CPP":
void CCV1::OnDraw(CDC* pDC)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
if (!SwapBuffers( m_pDC->GetSafeHdc() ) )
{
AfxMessageBox("SwapBuffers failed",MB_OK|MB_ICONEXCLAMATION);
}
}

int CCV1::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFormView::OnCreate(lpCreateStruct) == -1)
return -1;

InitializeOpenGL();
return 0;
}

void CCV1::OnDestroy()
{
CFormView::OnDestroy();

if ( FALSE == ::wglDeleteContext( m_hRC ) )
{
AfxMessageBox("wglDeleteContext failed",MB_OK|MB_ICONEXCLAMATION);
}

if ( m_pDC )
{
delete m_pDC;
}
}

BOOL CCV1::InitializeOpenGL()
{
m_pDC =new CClientDC(this);

if ( NULL == m_pDC ) // failure to get DC
{
AfxMessageBox("Unable to get a DC",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}

if (!SetupPixelFormat())
{
return FALSE;
}

if ( 0 == (m_hRC = ::wglCreateContext( m_pDC->GetSafeHdc() ) ) )
{
AfxMessageBox("wglCreateContext failed",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}

if ( FALSE == ::wglMakeCurrent( m_pDC->GetSafeHdc(), m_hRC ) )
{
AfxMessageBox("wglMakeCurrent failed",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}

::glClearColor( 0.0f, 0.0f, 0.0f, 1.0f);

::glClearDepth( 1.0f );

::glEnable( GL_DEPTH_TEST );

return TRUE;
}

BOOL CCV1::SetupPixelFormat()
{

static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
// 32, // 32-bit z-buffer
16, // NOTE: better performance with 16-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelformat;

if ( 0 == (pixelformat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) )
{
AfxMessageBox("ChoosePixelFormat failed",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}

if ( FALSE == ::SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd) )
{
AfxMessageBox("SelectPixelFormat failed",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
return TRUE;
}

void CCV1::OnSize(UINT nType, int cx, int cy)
{
CFormView::OnSize(nType, cx, cy);

if ( 0 >= cx || 0 >= cy )
{
return;
}
::glViewport(0, 0, cx, cy);

// select the projection matrix and clear it
::glMatrixMode( GL_PROJECTION );
::glLoadIdentity();

aspect_ratio = (GLdouble)cx/(GLdouble)cy;

::gluPerspective( 45.0f, aspect_ratio, 0.1f, 100.0f );

::glMatrixMode( GL_MODELVIEW );
::glLoadIdentity();

}

glsqyj
11-15-2005, 07:29 PM
1. the viarible in the "1View.h"

public:
HGLRC m_hRC;
CDC* m_pDC;
private:
GLdouble aspect_ratio;

2.this is the viarible in the "CV1.h"

public:
HGLRC m_hRC;
CDC* m_pDC;
private:
GLdouble aspect_ratio;

dorbie
11-17-2005, 12:52 PM
You need to create another context for the other window. Hmm but you seem to be doing this already.

You shouldn't really have to split this like that, a glViewport and glScissor could render two regions with a single context, but if you insist on using MFC stuff for this then contexts are the way to go.

You may want to double check what's going on when those objects get created, make sure you are entering those routines etc.

I think I see your problem, it looks like you only make the context current after creation. You ned to make current in the onDraw also. You may want to ensure that make Current is called before all OpenGL stuff. Something like a viewport call in a resize callback other similar faux pas could really screw you up, so makecurrent sould not just happen in the OnDraw unless that's the ONLY callback you issue OpenGL calls from. In your case it isn't so you need to add it to the OnSize callbacks and any other entry points from callbacks to your OpenGL code.

Remember that MakeCurrent is a context switch, you don't have multiple contexts current simultaneously. It's strictly either one or the other.