Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 9 of 9

Thread: Display List sharing between contexts, disapearing

  1. #1
    Junior Member Newbie
    Join Date
    Dec 2009
    Posts
    2

    Display List sharing between contexts, disapearing

    Hello,
    I'm using wglShareLists() to share display lists between contexts. My problem is that when I dynamically create a context (a sub window) and use one of the display lists in it, the display list stops displaying on the parent window.

    Note: Both contexts have the same pixel format. (they are instances of the same class)

    I'ma lost. Any help is much appreciated.

    Frank V.

  2. #2
    Advanced Member Frequent Contributor yooyo's Avatar
    Join Date
    Apr 2003
    Location
    Belgrade, Serbia
    Posts
    883

    Re: Display List sharing between contexts, disapearing

    You dont need to create new contex for each subwindow... just set same pixelformat for all windows that need to host OpenGL rendering contex. When you need to repaint some subwindow in WM_PAINT call:
    - wglMakeCurrent(win_dc, global_rc);
    - draw stuff,
    - swap buffers and
    - wglMakeCurrent(win_dc, NULL);
    Using this way you just move rendering contex between subviews. All textures, buffers, vertices, states, etc. remain same in all views.

  3. #3
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,793

    Re: Display List sharing between contexts, disapearing

    You dont need to create new contex for each subwindow...
    I'm pretty sure that you do. Just changing the pixel format of the window doesn't initialize OpenGL to render to those windows. The default framebuffer of your "global_rc" will only go to the first window you created.

  4. #4
    Senior Member OpenGL Pro
    Join Date
    Sep 2004
    Location
    Prombaatu
    Posts
    1,401

    Re: Display List sharing between contexts, disapearing

    IMO it'll work iff you set the pixel format on each subwindow you draw to. E.g. you could create an invisible root window for the app with the desired PF then SetPixelFormat on each window touched thereafter. There may be a multithreading consequence or two in such an approach, and AFAIK WPF will flat out refuse to work owing to some top-level window-handle monkey business.

  5. #5
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,793

    Re: Display List sharing between contexts, disapearing

    But it's not supposed to work. There is nothing that says it should work, and nothing that guarantees that it will work on other OS's. Have you tried this on Vista/Win7, for example?

  6. #6
    Senior Member OpenGL Pro
    Join Date
    Sep 2004
    Location
    Prombaatu
    Posts
    1,401

    Re: Display List sharing between contexts, disapearing

    Well, as far as I can comprehend wglMakeCurrent only mandates that hdc exist on the same device and have the same pixel format - which seems to imply basic goodness overall.

  7. #7
    Junior Member Newbie
    Join Date
    Dec 2009
    Posts
    2

    Re: Display List sharing between contexts, disapearing

    Following is my open gl window class. when I try and create multiples of the class, to share the textures loaded, only one of the windows displays the textures correctly. Sometimes my textures get moved around. Could someone point out my error, perhaps in the init or the create functions?

    Thanks in advanced.



    My code:
    class OpenGLDisplayClass : public CWnd
    {
    public:
    OpenGLDisplayClass();
    virtual BOOL Create(CWnd*, const RECT&, int TypeOfWindow = 0);
    virtual void Update();

    virtual void Display(){};

    void ChangeViewPort(double angle, int x1, int y1, int width, int height, int projection = 0);

    void MakeContextCurrent(BOOL onOff);

    ~OpenGLDisplayClass();

    protected:
    // declare event functions
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    afx_msg void OnSize (UINT, int, int);
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    DECLARE_MESSAGE_MAP ()

    void CreateViewPort(double angle, int x1, int y1, int width, int height);

    static HGLRC m_first_hRC ; //OpenGL Rendering Context
    static CDC* m_first_pDC; //Device Context
    HGLRC m_hRC ; //OpenGL Rendering Context
    CDC* m_pDC; //Device Context
    HDC m_hdc;
    CRect m_window_area;

    ViewType m_view;

    BOOL SetupPixelFormat();
    BOOL InitOpenGL();

    static int m_objects;
    static bool m_initialized;

    private:
    };


    int OpenGLDisplayClass::m_objects = 0;
    bool OpenGLDisplayClass::m_initialized = false;
    HGLRC OpenGLDisplayClass::m_first_hRC = NULL; //OpenGL Rendering Context
    CDC* OpenGLDisplayClass::m_first_pDC = NULL;
    //CDC* OpenGLDisplayClass::m_pDC; //Device Context

    BEGIN_MESSAGE_MAP (OpenGLDisplayClass, CWnd)
    ON_WM_CREATE()
    ON_WM_SIZE()
    ON_WM_ERASEBKGND()
    END_MESSAGE_MAP ()



    //-----------------------------------------------------------------------------
    OpenGLDisplayClass::OpenGLDisplayClass()
    {
    m_view = view_chase;
    m_objects++;
    };



    //-----------------------------------------------------------------------------
    OpenGLDisplayClass::~OpenGLDisplayClass()
    {
    wglMakeCurrent(0,0);
    wglDeleteContext(m_hRC);
    if(m_pDC)
    {
    delete m_pDC;
    }
    m_pDC = NULL;
    m_objects--;

    if (m_objects<= 0)
    {
    m_initialized = false;
    m_objects = 0;
    }
    };


    //-----------------------------------------------------------------------------
    BOOL OpenGLDisplayClass::SetupPixelFormat()
    {
    static PIXELFORMATDESCRIPTOR pfd =
    {
    sizeof(PIXELFORMATDESCRIPTOR), // Size of this pixel format descriptor.
    1, // Version number
    PFD_DRAW_TO_WINDOW | // Format must support windows
    PFD_SUPPORT_OPENGL | // Use OpenGL
    PFD_DOUBLEBUFFER | // Use double buffer
    PFD_GENERIC_ACCELERATED |
    PFD_GENERIC_FORMAT, // Pixel format is for a window.
    PFD_TYPE_RGBA, // Request A RGBA Format
    24, // Select Our Color Depth
    0, 0, 0, 0, 0, 0, // Color Bits Ignored
    0, // No Alpha Buffer
    0, // Shift Bit Ignored
    0, // No Accumulation Buffer
    0, 0, 0, 0, // Accumulation Bits Ignored
    32, // 32bit Z-buffer (depth buffer)
    1, // 1 Stencil Buffer
    0, // No Auxiliary Buffer
    PFD_MAIN_PLANE, // Main Drawing Layer
    0, // Reserved
    0, 0, 0 // Layer Masks Ignored
    };

    //int m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &amp;pfd);
    int m_nPixelFormat = ::ChoosePixelFormat(m_hdc, &amp;pfd);
    if (m_nPixelFormat == 0)
    return FALSE;

    // return ::SetPixelFormat(dc.m_hDC, nPixelFormat, &amp;pfd);
    // return ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &amp;pfd);
    return ::SetPixelFormat(m_hdc, m_nPixelFormat, &amp;pfd);

    };


    //-----------------------------------------------------------------------------
    BOOL OpenGLDisplayClass::InitOpenGL()
    {
    //Get a DC for the Client Area
    m_pDC = new CClientDC(this);

    //Failure to Get DC
    if(m_pDC == NULL)
    return FALSE;

    // Get device context only once.
    m_hdc = GetDC()->m_hDC;
    // m_hdc = m_pDC->GetSafeHdc();

    if(!SetupPixelFormat())
    return FALSE;

    //Create Rendering Context
    m_hRC = wglCreateContext(m_hdc);//m_pDC->GetSafeHdc());

    //Failure to Create Rendering Context
    if(m_hRC == 0)
    return FALSE;

    //Make the RC Current
    //if(::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE)
    // return FALSE;
    if(wglMakeCurrent(m_hdc, m_hRC) == FALSE)
    return FALSE;

    // set material values.
    GLfloat mat_specular[] = {0.5f, 0.5f, 0.5f, 1.0};
    GLfloat mat_shininess[] = {30.0f};

    // set the light values.
    GLfloat diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f };
    GLfloat specular[] = {1.0f, 1.0f, 1.0f, 1.0f };
    GLfloat ambient[] = {0.3f, 0.3f, 0.3f, 1.0f };
    GLfloat lightPos[] = {10000.0, 0.0, 1000.0, 0.0};


    // setup lights and material
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
    glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
    // glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_COLOR_MATERIAL);

    glEnable(GL_DEPTH_TEST);

    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);


    glShadeModel(GL_SMOOTH); // Enable Smooth Shading
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
    glClearDepth(1.0f); // Depth Buffer Setup
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); // Really Nice Perspective Calculations
    glHint(GL_POLYGON_SMOOTH_HINT , GL_FASTEST);
    glHint(GL_POINT_SMOOTH_HINT , GL_FASTEST);
    glHint(GL_LINE_SMOOTH_HINT , GL_FASTEST);


    return true;
    };


    //-----------------------------------------------------------------------------
    BOOL OpenGLDisplayClass::Create(CWnd *pParentWnd, const RECT &amp;rect, int TypeOfWindow)
    {
    if (CWnd::Create(NULL, "", WS_CHILD | WS_VISIBLE, rect, pParentWnd, 0, NULL) == -1)
    return false;

    GetClientRect(&amp;m_window_area);

    if (!InitOpenGL())
    {
    MessageBox("Error setting up OpenGL!",
    "Init Error!",
    MB_OK | MB_ICONERROR );
    return -1;
    }

    if (m_initialized == false)
    {
    BuildFont(m_hdc);//m_pDC->GetSafeHdc());
    LoadCommonTextures();
    DrawCommonShapes(TypeOfWindow);
    m_first_hRC = m_hRC;

    m_initialized = true;
    }
    else
    {
    wglShareLists(m_first_hRC, m_hRC);
    };

    return true;
    };


    //-----------------------------------------------------------------------------
    BOOL OpenGLDisplayClass::PreCreateWindow(CREATESTRUCT&a mp; cs)
    {
    cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_OWNDC;
    return CWnd::PreCreateWindow(cs);
    }


    //-----------------------------------------------------------------------------
    BOOL OpenGLDisplayClass::OnEraseBkgnd(CDC* pDC)
    {
    //return CView::OnEraseBkgnd(pDC);
    return TRUE ;
    }


    //-----------------------------------------------------------------------------
    void OpenGLDisplayClass::CreateViewPort(double angle, int x1, int y1, int width, int height)
    {
    glScissor(x1, y1, width,height);
    glEnable(GL_SCISSOR_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDisable(GL_SCISSOR_TEST);

    glViewport(x1, y1, width, height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(angle, (float) width / (float)height, 1.0, 3000000.0);

    glMatrixMode(GL_MODELVIEW);
    // glLoadIdentity();
    }


    void OpenGLDisplayClass::ChangeViewPort(double angle, int x1, int y1, int width, int height, int projection)
    {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    int left = x1,
    right = width,
    bottom = y1,
    top = height;

    glViewport(x1, y1, width, height);

    if (projection == 0)
    {
    // glTranslated(x1, y1, 0);
    gluPerspective(angle, (float) width / (float)height, 1.0, 3000000.0);
    }
    else
    {
    glOrtho(left, right, bottom, top, -1000, 3000);
    };

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    };


    //-----------------------------------------------------------------------------
    void OpenGLDisplayClass::OnSize(UINT nType, int cx, int cy)
    {
    CClientDC dc(this);
    wglMakeCurrent(dc.m_hDC, m_hRC);
    m_window_area = CRect(0, 0, cx, cy);

    CreateViewPort(30.0, 0, 0, cx, cy);
    wglMakeCurrent(NULL, NULL);
    }


    //-----------------------------------------------------------------------------
    void OpenGLDisplayClass::MakeContextCurrent(BOOL onOff)
    {
    if (onOff)
    {
    // ::wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
    ::wglMakeCurrent(m_hdc, m_hRC);
    }
    else
    {
    ::wglMakeCurrent(NULL, NULL);
    };
    }


    //-----------------------------------------------------------------------------
    void OpenGLDisplayClass::Update()
    {
    Invalidate(FALSE);
    UpdateWindow();
    };

  8. #8
    Member Regular Contributor
    Join Date
    Dec 2007
    Posts
    250

    Re: Display List sharing between contexts, disapearing

    normally the contexts need to be completely empty before you can share display list space. You might be able to get away with just having 1 empty. I can't remember the details exactly, but if you have already uploaded content and do the same with the second, display list sharing will fail.

  9. #9
    Advanced Member Frequent Contributor
    Join Date
    Apr 2003
    Posts
    652

    Re: Display List sharing between contexts, disapearing

    Just to clear up the confusion here a bit.
    1. Its perfectly legal and possible to use one context to draw into multiple windows (DC's). To quote MSDN about wglMakeCurrent:
    The hdc parameter must refer to a drawing surface supported by OpenGL. It need not be the same hdc that was passed to wglCreateContext when hglrc was created, but it must be on the same device and have the same pixel format.
    2. wglShareLists accepts two RCs. The first one (RC1) is the one that already might have objects in it. The second (RC2) is the one that will "take over" the list of RC1. RC2 must not have any objects in at this moment.
    BOOL wglShareLists(
    HGLRC hglrc1, // OpenGL rendering context with which to share display lists
    HGLRC hglrc2 // OpenGL rendering context to share display lists
    );
    hglrc1
    Specifies the OpenGL rendering context with which to share display lists.
    hglrc2
    Specifies the OpenGL rendering context to share display lists with hglrc1. The hglrc2 parameter should not contain any existing display lists when wglShareLists is called.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •