Jean-Milost Reymond
Jean-Milost Reymond

Reputation: 1943

OpenGL glCreateProgram() always return 1 and erase previous programs

Using RAD Studio C++ Builder XE7 and OpenGL, I'm creating an application on which several TPanel objects are used as render target. Each of these panels use their own render context. With OpenGL Direct Mode, I'm able to draw a scene on each of them without problems.

Now I want to each scene have their own shader program. If only one panel in my app exploits a shader, all is running fine. However, as soon as I select a new render context, to generate and link a new program, the programs generated with the previous context seems to be erased, and the glCreateProgram() function returns the same identifiers as generated in the previous context, as if the new programs take the place of the existing ones.

I cannot figure out why OpenGL behaves this way, but this issue generates a serious confusion in my rendering. It seems that only the shader programs are concerned, all the other values belonging to a context seem conserved while I select another context. Should I save and restore my contexts every time I select another one? Somebody can explain what I'm doing wrong?

Here is a simplified code sample illustrating the issue I face. (I call a such function for each of my target panels)

bool TMainForm::InitGL(HWND hWnd, HDC& hDC, HGLRC& hRC)
{
    // get the device context (DC)
    hDC = ::GetDC(hWnd);

    // failed to get device context?
    if (!hDC)
        return false;

    ::PIXELFORMATDESCRIPTOR pfd =
    {
        sizeof(::PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,
        24,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        0,
        32,
        0,
        0,
        PFD_MAIN_PLANE,
        0,
        0,
        0,
    };

    // get best available pixel format
    const int pixelFormat = ::ChoosePixelFormat(hDC, &pfd);

    // set pixel format to use
    if (!::SetPixelFormat(hDC, pixelFormat, &pfd))
        return false;

    // create OpenGL render context
    hRC = wglCreateContext(hDC);

    // succeeded?
    if (!hRC)
        return false;

    // enable OpenGL render context
    if (!wglMakeCurrent(hDC, hRC))
        return false;

    glewExperimental = GL_TRUE;

    // (re)initialize GLEW, as described here:
    // https://stackoverflow.com/questions/35683334/call-glewinit-once-for-each-rendering-context-or-exactly-once-for-the-whole-app
    if (glewInit() != GLEW_OK)
        return false;

    GLuint programID = glCreateProgram();

    // here the returned programID is always equal to 1!!!
    ::OutputDebugString((L"==> Newly generated shader ID - " + ::IntToStr((int)programID)).c_str());
}

Regards

Upvotes: 0

Views: 1118

Answers (1)

Ripi2
Ripi2

Reputation: 7198

Every gl-context owns its objects, gl-programs included. See https://www.khronos.org/opengl/wiki/OpenGL_Context

If you want to share among several contexts, you can set so at gl-context creation.

Upvotes: 3

Related Questions