Windows Menu & OpenGL

Started by
12 comments, last by JakeM 16 years, 1 month ago
Hello All I am using MFC with OpenGL to code multimedia application, I am using SDI architecture, and I found that when I open any menu item and select it, windows sometimes don’t erase the menu area immediately, and it appears like a shadow over the OpenGL window, until I do any repaint action it disappears It seems to me that it is windows issue, but I am not sure! i had posted this issue in another forum, but i still couldn't able to solve it http://www.codeproject.com/script/Forums/View.aspx?fid=1647&msg=2426136
Advertisement
Quote:
....until I do any repaint action it disappears


What does that mean?
Are you somehow suspending painting then sending the WM_PAINT message to windows to repaint?

or do you mean: as soon as you click you mouse somewhere in the app window/viewport, that this is when the menu disppears?
I mean after clicking on the menu item, it is not completely disappear, and it keeps a shadow of it on the client area, and this shadow disappears if any repaint had happened, like for example minimize and restore the window
And here is a piece of my code
void CChildView::OnPaint()
{
CPaintDC dc(this);
glClear(GL_COLOR_BUFFER_BIT);
RenderScene(); //My OpenGL Drawing function
glFlush();
SwapBuffers(m_pDC->GetSafeHdc());
}

void CChildView::RenderScene ()
{
glBegin(GL_TRIANGLES);
glColor3f(0.0f,1.0f,1.0f);
glVertex2f(-5.0f,4.0f);
glVertex2f(6.0f,2.0f);
glVertex2f(2.0f,0.0f);
glEnd();
}
I still don't feel as though you have provided enough info, but I also don't know what other info I would want from you?

So I'll take a stab in the dark( How's that for confidence!).

One thing seems obvious from your description though is: sometimes your CView/OpenGL viewport rendering is not being updated (which most likely is related to the windows message handling happening 'underneath' mfc). So, I'll assume that's what we want to investigate.

Do you only have one CView derived object instantiated?
i.e. do you only have one CView in which you do your OpenGL rendering?

Here are two or three suggestions ( if I were debugging it with the info I have):

(1) (a)Comment out all the contents of OnPaint() run you app and observe the effect.
(1)(b)Comment out all the contents of OnPaint() and replace it with a call to the base class function i.e.
void CChildView::OnPaint() {   // Do not call CPaintDC dc(this);     // CView::OnPaint() calls OnDraw()    CView::OnPaint();}


...and observe the effect. If you app can still run...do you still have your problem?

If that is too simple or if you have tried these already, here's another suggestion:

(2)For a CView derived class you'll normally draw in the OnDraw handler. See "Drawing in a View" in your VC++ documentation for details.

So another thing you could try ,is moving you rendering code into the CView's OnDraw() method. This will place your rendering code 'one step removed' from the windows message handlers.

i.e. Change

void CChildView::OnPaint() {   CPaintDC dc(this);    glClear(GL_COLOR_BUFFER_BIT);   RenderScene(); //calling my OpenGL drawing function   glFlush();   SwapBuffers(m_pDC->GetSafeHdc());}


to

void CChildView::OnPaint() {   // Do not call CPaintDC dc(this);     // CView::OnPaint() calls OnDraw()    CView::OnPaint();}void CChildView::OnDraw(CDC* pDC){   // if you haven't already done so, or if you have more than one    // viewport, you may have to set the context something like...   wglMakeCurrent( m_pDC->GetSafeHdc(), m_hRC );   glClear(GL_COLOR_BUFFER_BIT);   RenderScene(); //calling my OpenGL drawing function   glFlush();   SwapBuffers(m_pDC->GetSafeHdc());}// Optional code to store the viewport's render context, used in // your CView::OnDraw() function, as a class member variableint COpenGLWnd::OnCreate(LPCREATESTRUCT lpCreateStruct){   ...   ...   // usually you would init opengl in here and can    // Create Rendering Context and store it as class member    // variable HGLRC m_hRC    m_hRC = ::wglCreateContext( m_pDC->GetSafeHdc() );   ...   ...   ...}


let us know what happens.
The class CChildView is based on CWnd, and I couldn't find OnDraw message in it,
And I want to mention that I had build my MFC application using MFC Application wizard with type SDI and without support of document/view architecture
what do you think?

No wonder...it all makes sense now (well at least I like to think so)
Whatever possessed you to do such a thing?
Stop right now.
Go back and change it to document/view architecture.
Really, I don't care, do what you want(I have an attack of biploar disorder sometimes...no I don't ).

That's a good way to spend more time wrestling with your code (as in like now?) than actually trying to eke out whatever enjoyment you can out of making mfc work.

Even better try out the VS c++ express edtions: forms are even better to work with. It doesn't sound like you have too many lines of code you'll miss.

This is my uneducated opinion. Educated opinions are welcome.
Quote:Original post by AhmedSabry1975
The class CChildView is based on CWnd, and I couldn't find OnDraw message in it,
And I want to mention that I had build my MFC application using MFC Application wizard with type SDI and without support of document/view architecture
what do you think?


That's fine. I also do not use doc/view since this does not fit well with what I wanted to do. No one is forcing you to accept microsoft solutions like putting a m_ in front of everything and doing this-> everywhere or using DirectX, XNA, MDX, ActiveX, SuperSex.

I would just put a timer and redraw the entire window once in a while.
I think you are talking about the menu shadow effect. It's a minor problem.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
thx for all of you
actualy i did as you said V-Man,
and also used the documet/view archtecture as steven suggested
and both solution works good with me :)
Hello All
Sorry for the interrupt, but it seems that the problem is till exist, I tried to use a document/view architecture, but the problem is sometimes happened and sometimes not, then I added the timer on the Create message to invalidate the view
The problem disappeared but another problem had came, that was a flickering effect when clicking on a menu item,
I tried to diagnose the problem again, and I got the feel that GL drawing may be faster than the on erase background of the menu, I tried to do some delay in my render scene function if any menu item clicked

void CMFCOpenGLWindowView::RenderScene ()
{
if(MenuClicked)
{
for(long x=0;x<100000000;x++);
MenuClicked=false;
}
//GL drawing come here.......


}

This is working well without any flickering
I have seen the menu shadow flicker but I haven't seen the case with the menu flickering.

There should be a better way than looping. Why don't you detect that the menu has been clicked on and turn off the timer?
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

This topic is closed to new replies.

Advertisement