我有一個關於如何(正確)使用glewInit()
的問題。爲每個渲染上下文調用glewInit一次?或整個應用程序只有一次?
假設我有一個多窗口應用程序,我應該在應用程序(即全局)級別調用glewInit()
一次嗎?或者爲每個窗口調用glewInit()
(即每個OpenGL
渲染上下文)?
我有一個關於如何(正確)使用glewInit()
的問題。爲每個渲染上下文調用glewInit一次?或整個應用程序只有一次?
假設我有一個多窗口應用程序,我應該在應用程序(即全局)級別調用glewInit()
一次嗎?或者爲每個窗口調用glewInit()
(即每個OpenGL
渲染上下文)?
根據所使用的GLEW構造,水密方法是在每個上下文更改後調用glewInit
!
X11/GLX函數指針是不變的。
但是在Windows中,OpenGL函數指針是特定於每個上下文的。 GLEW的一些構建可以識別多個上下文,而另一些則不是。因此,爲了涵蓋這種情況,技術上你必須稱之爲,每當情況發生變化時。
(編輯:由於澄清要求)
爲每個窗口(即,每個OpenGL渲染上下文)?
首先要做的事情:OpenGL上下文並不依賴於窗口。具有單個窗口但具有多個渲染上下文是完全正確的。在Microsoft Windows中,與OpenGL相關的是與窗口關聯的設備上下文(DC)。但是它也可以用其他方式工作:您可以擁有單個OpenGL上下文,但使用它的多個窗口(只要該窗口的像素格式與OpenGL上下文兼容)。
因此,這是合法的:
HWND wnd = create_a window()
HDC dc = GetDC(wnd)
PIXELFORMATDESCRIPTOR pf = select_pixelformat();
SetPixelFormat(dc, pf);
HGLRC rc0 = create_opengl_context(dc);
HGLRC rc1 = create_opengl_context(dc);
wglMakeCurrent(dc, rc0);
draw_stuff(); // uses rc0
wglMakeCurrent(dc, rc1);
draw_stuff(); // uses rc1
,所以是這個
HWND wnd0 = create_a window()
HDC dc0 = GetDC(wnd)
HWND wnd1 = create_a window()
HDC dc1 = GetDC(wnd)
PIXELFORMATDESCRIPTOR pf = select_pixelformat();
SetPixelFormat(dc0, pf);
SetPixelFormat(dc1, pf);
HGLRC rc = create_opengl_context(dc0); // works also with dc1
wglMakeCurrent(dc0, rc);
draw_stuff();
wglMakeCurrent(dc1, rc);
draw_stuff();
這裏就是擴展進入圖片。像glActiveTexture
這樣的函數不是已經被固定到Windows應用程序二進制接口(ABI)中的OpenGL規範的一部分。因此你必須在運行時得到一個函數指針。這就是GLEW所做的。在內部看起來像這樣:
首先它定義了函數指針的類型,將它們聲明爲extern變量並使用一點預處理器魔法來避免名稱空間衝突。
typedef void (*PFNGLACTIVETEXTURE)(GLenum);
extern PFNGLACTIVETEXTURE glew_ActiveTexture;
#define glActiveTexture glew_ActiveTexture;
在glewInit
函數指針變量都設置爲使用wglGetProcAddress
(爲了便於閱讀起見予省略型鑄件)中獲得的值。
int glewInit(void)
{
/* ... */
if(openglsupport >= gl1_2) {
/* ... */
glew_ActiveTexture = wglGetProcAddress("glActiveTexture");
/* ... */
}
/* ... */
}
現在重要的部分:wglGetProcAddress
作品與在調用的時候當前的OpenGL渲染上下文。所以無論是最後的wglMakeCurrent
打電話。如前所述,擴展函數指針與OpenGL上下文綁定,不同的OpenGL上下文可能爲同一函數提供不同的函數指針。
所以,如果你這樣做
wglMakeCurrent(…, rc0);
glewInit();
wglMakeCurrent(…, rc1);
glActiveTexture(…);
它可能會失敗。所以一般來說,在GLEW中,每次撥打wglMakeCurrent
必須緊接着撥打glewInit
。 GLEW的一些構建可以識別多個上下文,並在內部執行此操作。其他人不是。然而,多次呼叫glewInit
是完全安全的,所以安全的方式就是調用它,只是爲了確保。
但我還是不完全明白。你能解釋一下關於「變化」的上下文嗎? –
@ChanggongZhang:看到我的更新。 – datenwolf
我剛剛注意到glew還提供了[glew32mx.lib,glew32mx.dll]。這是否意味着如果我想創建一個多窗口的應用程序,我應該使用glew32mx.dll而不是glew32.dll? 還有另一個後續問題。您能否爲多DC-single-RC和單DC-multiple-RC提供真正的應用示例x? –