使用RAD Studio C ++ Builder XE7和OpenGL,我创建了一个应用程序,其中有几个TPanel对象用作渲染目标。每个面板都使用自己的渲染上下文。使用OpenGL直接模式,我能够毫无问题地在每个模式上绘制场景。
现在我希望每个场景都有自己的着色器程序。如果我的应用中只有一个面板使用着色器,则一切正常。但是,只要我选择一个新的渲染上下文,生成并链接一个新程序,使用前一个上下文生成的程序似乎被擦除,并且glCreateProgram()函数返回与前一个上下文中生成的相同的标识符,如如果新程序取代现有程序。
我无法弄清楚为什么OpenGL会以这种方式运行,但是这个问题在我的渲染中会产生严重的混乱。似乎只关注着色器程序,当我选择另一个上下文时,属于上下文的所有其他值似乎都是守恒的。每次选择另一个时,我应该保存和恢复我的上下文吗?有人可以解释我做错了什么吗?
这是一个简化的代码示例,说明了我面临的问题。 (我为每个目标面板调用了这样的函数)
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());
}
此致
答案 0 :(得分:3)
每个gl-context都拥有它的对象,包括gl-programs。见https://www.khronos.org/opengl/wiki/OpenGL_Context
如果你想在几个上下文之间共享,你可以在gl-context创建时设置。