Kullanılan GLEW yapısına bağlı olarak, su geçirmez yöntem, her bir içerikten sonra'u aramaktır. ,'u değiştirin! X11/GLX fonksiyonları işaretçiler ile
değişmez bulunmaktadır.
Ancak Windows OpenGL işlev işaretçileri içinde
her bağlamda özeldir. GLEW'in bazı yapıları çok bağlamlıdır, diğerleri ise değildir. Bu durumda, bağlamı değiştirmek için teknik olarak her zaman onu aramak zorundasınız.
: her bir pencere için
(DÜZENLEME nedeniyle açıklama talebine) (diğer bir deyişle, her bir OpenGL bağlamı)?
İlk şeyler ilk: OpenGL içerikleri Windows'a bağlı değildir. Tek bir pencereye sahip olmak ancak çok sayıda görüntü oluşturma bağlamına sahip olmak çok iyidir. Microsoft Windows bir pencere ile ilişkili cihaz bağlam (DC) OpenGL ne önemli olan. Fakat aynı zamanda başka bir şekilde de çalışır: Tek bir OpenGL içeriğine sahip olabilirsiniz, ancak bunu kullanarak birden çok pencere kullanabilirsiniz (pencerenin pixelformat'ı OpenGL bağlamıyla uyumlu olduğu sürece).
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
Ve böylece İşte bu
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();
olan uzantıları resmi girmek nerede:
Yani bu yasaldır. glActiveTexture
gibi bir işlev Windows Uygulama İkili Arayüzü (ABI) içine sıkışıp edilmiştir OpenGL şartnamenin bir parçası değildir. Bu nedenle, çalışma zamanında bir işlev gösterici almak zorunda. GLEW'in yaptığı şey bu. Dahili olarak şuna benzer:
Öncelikle, işlev işaretçileri için tiplerini tanımlar extern değişkenler olarak bunları beyan ve ad çakışmaları önlemek için önişlemci büyü biraz kullanır.
typedef void (*PFNGLACTIVETEXTURE)(GLenum);
extern PFNGLACTIVETEXTURE glew_ActiveTexture;
#define glActiveTexture glew_ActiveTexture;
glewInit
olarak işlev işaretçisi değişkenleri wglGetProcAddress
(Okunabilmesi I tipi döküm atın) kullanılarak elde edilen değerlere ayarlanır.
int glewInit(void)
{
/* ... */
if(openglsupport >= gl1_2) {
/* ... */
glew_ActiveTexture = wglGetProcAddress("glActiveTexture");
/* ... */
}
/* ... */
}
Şimdi önemli bir parçası: çağıran sırasında geçerli olan OpenGL render bağlam wglGetProcAddress
çalışır. Yani her ne kadar önceki wglMakeCurrent
numaralı çağrı yapıldı. Daha önce açıklandığı gibi, genişletme fonksiyonu işaretçileri OpenGL bağlamlarına bağlıdır ve farklı OpenGL içerikleri aynı işlev için farklı işlev göstergeleri verebilir.
bu
wglMakeCurrent(…, rc0);
glewInit();
wglMakeCurrent(…, rc1);
glActiveTexture(…);
başarısız olabilir yapmak Yani eğer. Yani genel olarak, Glew ile wglMakeCurrent
her çağrı derhal glewInit
tarafından takip edilmelidir. Bazı GLEW yapıları çok bağlamlıdır ve bunu dahili olarak yapar. Diğerleri değil. Ancak, glewInit
'u birden çok kez çağırmak tamamen güvenlidir, bu yüzden emin olmak için güvenli yol aramaktır.
Ama hala tam olarak anlamıyorum. "Değişim" bağlamında biraz daha açıklayabilir misiniz? –
@ChanggongZhang: güncellemeye bakın. – datenwolf
Sadece glew ayrıca [glew32mx.lib, glew32mx.dll] sağlar dikkat edin. Bu çok pencere uygulaması oluşturmak istiyorsanız glew32.dll yerine glew32mx.dll kullanmalıyım anlamına mı geliyor? Ve başka bir takip eden soru. @datenwolf, çoklu-DCs-single-RC ve single-DC-multiple-RCs için gerçek uygulama examplex sağlayabilir misiniz? –