?
Solved

OpenGL Multiple Views (Animations) Rendered in Different Windows

Posted on 2003-10-21
2
Medium Priority
?
3,859 Views
Last Modified: 2013-12-06
Ok, I have an SDI MFC application which is using OpenGL to display one of several graphs or animations in a single window dedicated to the OpenGl rendering.  I also have another window which allows me to change what's being drawn in the OpenGL window.  For example, in the OpenGL window I could be displaying a graph, or an animated model of the same data, depending on what I select in the other window.  Each view being displayed in the OpenGL window is based on the same data (stored in the document) so the only difference between a view is how the data is being interpreted and displayed in the OpenGL window.  I can even start an animation process, and while in the animation loop I can switch between views in the OpenGL window without disturbing the flow of the animation.  

What I would like to do is have the ability to create multiple OpenGL windows that each render a different view of the data during the animation.  Since each view would be using the same data, I'm not worried about synchronizing the views during the animation (they are already synchronized).  I'm having problems getting OpenGl to render things in different windows at the same time.  I'm trying to create several OpenGL windows, based on the same class.

In my view class, I create child windows (of base class CWnd) to be used to render OpenGL in:

//Creating a graph in one window
p_GraphWindow = new CGlWindow(m_hWnd, this);    
p_GraphWindow->m_pclGLView->myCam->View(1);      //View 1 means to draw a graph

//Creating an animation in another window
p_Animation = new CGlWindow(m_hWnd, this);    
p_GraphWindow->m_pclGLView->myCam->View(2);  //View 2 means to draw a model

You can see that each of these views is creating a new instance of the same class (CGlWindow).  As you will see in the CGlWindow constructor, m_pclGLView is a pointer to an additional class (a new instance of which is created inside the constructor) which takes care of the OpenGL rendering.  So each window is the same, however each window looks to its own camera object (myCam) to decide on the way it's going to interpret and display the data.  

Here is part of the CGlWindow constructor (I simplified it a bit by taking out some unrelated stuff)...

CGlWindow::CGlWindow(HWND pWin, CWnd *pclWnd)
{            
    m_Pwnd = pclWnd;  //Pointer to parent window
    CString szClassName = AfxRegisterWndClass( NULL,0,NULL,0);
   
      DWORD windowStyle = WS_VISIBLE | WS_CAPTION | WS_POPUPWINDOW |    THICKFRAME | WS_VSCROLL;
      CreateEx( 0, szClassName, "VBN", windowStyle, 0, 0, 700, 700, pWin, NULL );
      m_pclGLView = new CGlView(this);  /*Create an instance of the OpenGl
rendering class, passing it a pointer to this window so it knows which window to render in.*/
}

Here is a simplified constructor for CGlView, which is the class that is handeling all the OpenGl rendering for each window...

CGlView::CGlView(CWnd *pclWnd)
{
      myCam = new CCamera();  //Create a camera object to associate with this view
      m_hDC  = ::GetDC(pclWnd->m_hWnd);  //Get window handle of window we want to
                                                                         //render in
      
      BOOL bSuccess;
      RECT rect;
      pclWnd->GetClientRect(&rect);
      int iWidth = rect.right - rect.left;
      int iHeight = rect.top - rect.bottom;
      bSuccess = bSetWindowPixelFormat(m_hDC);
      ASSERT(&bSuccess);
      bSuccess = bCreateViewGLContext(m_hDC);
      ASSERT(&bSuccess);
      vInitGl(iWidth, iHeight);
}

So, lets say I have created to instances of my own CWnd class.  Each window creates an instance of my opengl rendering class, and keeps a pointer to this instance.  That rendering class also has a pointer to the window, so it knows which window to render in.  Each instance also has it's own camera object, which tells it how to interpret and draw the data (since each window is essentially the same, the only difference is which view mode the camera is set to).

Here is how I am currently rendering each scene in the main application loop

if (p_GlWindow){
            p_GlWindow->m_pclGLView->vRenderScene();
      }
      if (p_AnimationWindow){
            p_AnimationWindow->m_pclGLView->vRenderScene();
      }
}

So for each different view in turn, I execute that views vRenderScene(); Here is a simple version of one of the views vRenderScene();

void CGlView::vRenderScene(){
      
            float colour[3];            
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);      // Clear Screen And Depth Buffer
            glLoadIdentity();
            glPopMatrix();
            glTranslatef(myCam->x(), myCam->y(), myCam->z());

            if (myCam->View()==1){ //View 1 = Normal View
//etc
}
            else if (myCam->View()==2){ //View 1 = Model View
//etc
}
      SwapBuffers(m_hDC);  //m_hDC is the pointer to the window handle which this view is supposed to be rendered in
}


Now what seems to be happening is that OpenGl is only rendering in the last window I create, and not updating the other windows at all.  I can create 3 different windows, each with a different view, and it looks fine until I start playing around with the windows.  At that point, I can tell that it initializes each window fine but is only continuously refreshing the last window I created.  If I start resizing the other windows, it will actually resize the object being rendered inside the latest window at the same time (so all windows seem to be calling the same instance of the rendering classes resize method).  

I've tried testing to see if each window is pointing to a unique instance of the myCam class, and also a unique instance of my opengl rendering class GlView by giving those classes a member called "name", giving each instance a different name, running the program in debug mode and following each windows pointers to check the "name" members and make sure they are all unique.  It seems like this is the case.  Does this have something to do with viewports?  Maybe I need to do something special to create multiple viewports?

I'm sure I've made this a lot more complicated then it needs to be in my explanation, so I apologize in advance (I think I tend to overcomplicate things a lot).  I greatly appreciate any help the experts in this forum can give me.  

Thanks in advance
0
Comment
Question by:nexisvi
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 

Accepted Solution

by:
nexisvi earned 0 total points
ID: 9592731
I ended up answering my own question.  I guess when you have to sit down and think about how to explain your problem, you often end up bringing up something you hadn't though of.  For anyone who ever runs into a similar problem,  what I was missing was a line that sets the rendering context to the current window that I want to render.  like this...

wglMakeCurrent(m_hDC,m_hGLContext);

m_hDC is a handle to the current window, and m_hGLContext is that windows context (I stored both of these as members of each instance of my Glwindow class.  Basically, when each window is going thorugh it's rendering, it sets the context to itself using the above line, then at the end of everything I do a SwapBuffers(m_hDCarray[i]) in a loop.  The m_hDCarray is basically just an array of pointers to each windows handle, and it goes through the array updating each window.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is RenderMan: RenderMan is a not any particular piece of software. RenderMan is an industry standard, defining set of rules that any rendering software should use, to be RenderMan-compliant. Pixar's RenderMan is a flagship implementation of …
As game developers, we quickly learn that Artificial Intelligence (AI) doesn’t need to be so tough.  To reference Space Ghost: “Moltar, I have a giant brain that is able to reduce any complex machine into a simple yes or no answer. (http://www.youtu…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question