I have an OpenGL MDI application that was written by someone else and which I have adapted to my own purposes.
While the application works fine on NVIDIA and Radeon Video Cards, there is a problem with the
Intel Graphics devices built-in to our motherboards.
One of the features that I have added to the application is more sophisticated layout of the child windows
than cascading or tiling. This layout causes problems with Intel graphics devices.
If all the child windows are the same size, everything is fine. If the child windows are a different size,
one or more of the windows will have a corrupted view.
One of the corruptions I see is a “phantom viewport”. The scene is rendered to match the window size but only the part
of the scene is rendered properly. This part is a rectangular area in the top left of the window that appears to have the same
size as viewport of the smallest window.
For example, I have three windows 300x300, 300x400, 500x500. Assuming for simplicity that the viewports are the same size as
the windows, the two larger windows have a “phantom viewport” of size 300x300. Inside this “phantom viewport” the scene is rendered
correctly. Outside of this rectangle, all sorts of corruption occurs.
If it were simply a case of using the wrong viewport, the view would be scaled to this wrong viewport but it is scaled correctly for the Window.
Secondly, one of the views has a HUD which is rendered correctly. This HUD is rendered immediately after the scene tree without
any intervening calls to glViewport or wglMakeCurrent.
Strangely, the corruptions can be remedied by manually adjusting the size of one or more windows ie by using mouse. This is a permanent
fix in that applying the layout again does NOT cause corruption. It is this fact that makes me think that there should be a workaround
for the problem.
There appears to be no difference between the opengl calls generated by the program when the views are corrupt than when the corruption has been remedied by manually resizing. The few differences are due to the viewport
being a few pixels wider or narrower. The glViewport commands have slightly different values and the PROJECTION
transformations have one element that is marginally different. All the other thousands of commands are identical.
Examining the opengl generated when resizing the windows manually and using MoveWindow, reveals no significant
difference.
All the glViewport commands are issued in the correct context and all succeed.
The layout code follows:
void CMyMainFrame::ArrangeViews(CViewLayout *layout)
{
CWinApp *pApp = AfxGetApp();
ASSERT_VALID(pApp);
// Iterate through App's document template list
POSITION posTemplate = pApp->GetFirstDocTemplatePosition();
while (posTemplate != NULL)
{
CDocTemplate *pTemplate = pApp->GetNextDocTemplate(posTemplate);
ASSERT_VALID(pTemplate);
ASSERT_KINDOF (CDocTemplate, pTemplate);
POSITION posDocument = pTemplate->GetFirstDocPosition();
while (posDocument!=NULL)
{
CDocument *pDoc = pTemplate->GetNextDoc(posDocument);
ASSERT_VALID(pDoc);
if (pDoc->IsKindOf(RUNTIME_CLASS(CMyMfcDoc)))
{
POSITION pos = pDoc->GetFirstViewPosition();
while (pos!= NULL)
{
CString fn = pDoc->GetTitle();
CView *pView = pDoc->GetNextView( pos );
ASSERT_VALID(pView);
CSingleViewLayout *vlo = layout->getLayout(std::string(fn.GetBuffer(10)));
if (vlo != NULL)
{
pView->GetParent()->MoveWindow(&vlo->rect,true);
}
}
}
}
}
}
I have tried using SetWindowPlacement and SetWindowPos instead of MoveWindow but with the same result.
I am fresh out of ideas, so I would be grateful for any suggestions.