It’s funny. I already noticed on my own yesterday evening, shortly after I posted this thread, that I had forgotton to release the gl context.
The destructor of the OpenGL-Control-Class looks now like this:
OpenGLControl::~OpenGLControl ()
{
glDeleteLists(mglfont, 91);
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hrc);
ReleaseDC(CDC::FromHandle (hdc));
}
But: Now I have no more 3 MB memory-leak per result-window-call, but still about 200 kb !
If I cancel the wglMakeCurrent and ReleaseDC-command from the destructor, there are still 200 kb, if I cancel also the wglDeleteContext-command, I have again the 3 MB.
I watched the code, but there is nothing I can find, that causes the additional memory (the 200 kb).
So the best would be, I post the code here, so that any expert will see hopefully more than I can see there inside:
void OpenGLControl::OnPaint ()
{
ValidateRect(NULL);
} // OnPaint
void OpenGLControl::OnSize (UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
if (0 >= cx || 0 >= cy || nType == SIZE_MINIMIZED)
{
return;
}
glViewport(0, 0, cx, cy);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-frustumPlanes, frustumPlanes, -frustumPlanes, frustumPlanes, 10.0, frustumFar);
glMatrixMode(GL_MODELVIEW);
} // OnSize
int OpenGLControl::OnCreate (LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
{
return -1;
}
oglInitialize();
return 0;
} // OnCreate
void OpenGLControl::OnDraw (CDC *pDC)
{
glLoadIdentity();
glTranslated(drawBase1, 0.0, mfZoom);
glTranslated(drawBase2, heightDiff, 0.0);
glRotated(mfRotX, 1.0, 0.0, 0.0);
glRotated(mfRotY, 0.0, 1.0, 0.0);
} // OnDraw
void OpenGLControl::OnMouseMove (UINT nFlags, CPoint point)
{
int diffX = (int)(point.x - mfLastX);
int diffY = (int)(point.y - mfLastY);
mfLastX = (double)point.x;
mfLastY = (double)point.y;
if (nFlags & MK_LBUTTON)
{
mfRotX += (double)0.5 * diffY;
if ((mfRotX > 360.0) || (mfRotX < -360.0))
{
mfRotX = 0.0;
}
mfRotY += (double)0.5 * diffX;
if ((mfRotY > 360.0) || (mfRotY < -360.0))
{
mfRotY = 0.0;
}
OnDraw(NULL);
} // if
startflag = FALSE;
CWnd::OnMouseMove(nFlags, point);
} // OnMouseMove
void OpenGLControl::oglCreate (CRect rect, CWnd *parent)
{
CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_OWNDC, NULL, (HBRUSH)GetStockObject(BLACK_BRUSH), NULL);
CreateEx(0, className, "OpenGL", WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, rect, parent, 0);
hWnd = parent;
} // oglCreate
void OpenGLControl::DisplayText (CString str)
{
glPushAttrib(GL_LIST_BIT);
glListBase(mglfont - 32);
glCallLists(str.GetLength(), GL_UNSIGNED_BYTE, str);
glPopAttrib();
} // DisplayText
void OpenGLControl::oglInitialize ()
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16,
0, 0, 0, 0, 0, 0, 0,
};
hdc = GetDC()->m_hDC;
mnPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, mnPixelFormat, &pfd);
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
glClearColor(1.0, 1.0, 1.0, 1.0);
glClearDepth(1.0);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
HFONT hFont;
HFONT oldFont;
mglfont = glGenLists(91); // Generate the list for the font
hFont = ::CreateFont(
18, // Our desired HEIGHT of the font
0, // The WIDTH (If we leave this zero it will pick the best width depending on the height)
0, // The angle of escapement
0, // The angle of orientation
FW_BOLD, // The font's weight (We want it bold)
FALSE, // Italic - We don't want italic
FALSE, // Underline - We don't want it underlined
FALSE, // Strikeout - We don't want it strikethrough
ANSI_CHARSET, // This is the type of character set
OUT_DEFAULT_PRECIS, // The Output Precision
CLIP_DEFAULT_PRECIS, // The Clipping Precision
DEFAULT_QUALITY, // The quality of the font - We want anitaliased fonts
FF_DONTCARE|DEFAULT_PITCH, // The family and pitch of the font. We don't care.
"Arial"); // The font name (Like "Arial", "Courier", etc...)
oldFont = (HFONT)SelectObject(hdc, hFont);
wglUseFontBitmaps(hdc, 32, 91, mglfont);
SelectObject(hdc, oldFont);
DeleteObject(hFont);
glNewList( (GLint) PACKSTUECK, GL_COMPILE);
glBegin(GL_QUADS);
// Grundfläche
glVertex3d(0, 0, 0);
glVertex3d(0, 1.0, 0);
glVertex3d(1.0, 1.0, 0);
glVertex3d(1.0, 0, 0);
// Deckel
glVertex3d(0, 0, 1.0);
glVertex3d(0, 1.0, 1.0);
glVertex3d(1.0, 1.0, 1.0);
glVertex3d(1.0, 0, 1.0);
// Mantel
glVertex3d(0, 0, 0);
glVertex3d(1.0, 0, 0);
glVertex3d(1.0, 0, 1.0);
glVertex3d(0, 0, 1.0);
glVertex3d(0, 0, 0);
glVertex3d(0, 1.0, 0);
glVertex3d(0, 1.0, 1.0);
glVertex3d(0, 0, 1.0);
glVertex3d(0, 1.0, 0);
glVertex3d(0, 1.0, 1.0);
glVertex3d(1.0, 1.0, 1.0);
glVertex3d(1.0, 1.0, 0);
glVertex3d(1.0, 1.0, 0);
glVertex3d(1.0, 1.0, 1.0);
glVertex3d(1.0, 0, 1.0);
glVertex3d(1.0, 0, 0);
glEnd();
glEndList();
OnDraw(NULL);
} // oglInitialize
void OpenGLControl::OnTimer(UINT nIDEvent)
{
switch (nIDEvent)
{
case 1:
{
// Clear color and depth buffer bits
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw OpenGL scene
oglDrawScene();
// Swap buffers
SwapBuffers(hdc);
break;
}
default:
break;
}
CWnd::OnTimer(nIDEvent);
}