Solved

OpenGL Multiple Views (Animations) Rendered in Different Windows

Posted on 2003-10-21
2
3,821 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
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

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Artificial Intelligence comes in many forms, and for game developers, Path-Finding is an important ability for making an NPC (Non-Playable Character) maneuver through terrain.  A* is a particularly easy way to approach it.  I’ll start with the algor…
Recently, in one of the tech-blogs I usually read, I saw a post about the best-selling video games through history. The first place in the list is for the classic, extremely addictive Tetris. Well, a long time ago, in a galaxy far far away, I was…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

746 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now