我试图根据https://www.khronos.org/opengl/wiki/Creating_an_OpenGL_Context_(WGL)的教程创建一个wgl上下文。无论出于何种原因,wglCreateContext
都会返回null
,GetLastError
会返回6
或无效句柄。我之前使用过该教程,但它工作得很好。
我试图为隐藏窗口创建一个虚拟上下文,以便我可以为用户窗口创建另一个上下文。发生了什么事?
Windows API通过winAPI
标识符引用,wgl
是一个包含OpenGL函数指针的全局结构。
struct WglContext
{
winAPI.HDC hdc;
winAPI.HGLRC handle;
}
__gshared Win32GL wgl;
///WGL-specific global data.
struct Win32GL
{
import oswald : OsWindow, WindowConfig, WindowError;
OsWindow helperWindow;
winAPI.HINSTANCE instance;
PFN_wglCreateContext createContext;
PFN_wglDeleteContext deleteContext;
PFN_wglGetProcAddress getProcAddress;
PFN_wglMakeCurrent makeCurrent;
PFN_wglCreateContextAttribsARB createContextAttribsARB;
PFN_wglGetExtensionStringARB getExtensionStringARB;
PFN_wglGetExtensionStringEXT getExtensionStringEXT;
bool extensionsAreLoaded;
static void initialize()
{
if (wgl.instance !is null)
return; //The library has already been initialized
WindowConfig cfg;
cfg.title = "viewport_gl_helper";
cfg.hidden = true;
auto windowError = OsWindow.createNew(cfg, &wgl.helperWindow);
if (windowError != WindowError.NoError)
{
import std.conv : to;
assert(false, "Failed to create helper window: " ~ windowError.to!string);
}
wgl.instance = winAPI.LoadLibrary("opengl32.dll");
if (wgl.instance is null)
assert(false, "Viweport failed to load opengl32.dll");
wgl.bind(cast(void**)&wgl.createContext, "wglCreateContext\0");
wgl.bind(cast(void**)&wgl.deleteContext, "wglDeleteContext\0");
wgl.bind(cast(void**)&wgl.getProcAddress, "wglGetProcAddress\0");
wgl.bind(cast(void**)&wgl.makeCurrent, "wglMakeCurrent\0");
}
static void terminate()
{
if (!wgl.instance)
return;
winAPI.FreeLibrary(wgl.instance);
wgl.helperWindow.destroy();
}
void bind(void** func, in string name)
{
*func = winAPI.GetProcAddress(this.instance, name.ptr);
}
}
struct WglContext
{
winAPI.HDC hdc;
winAPI.HGLRC handle;
}
WglContext wglCreateTmpContext()
{
assert(wgl.instance);
winAPI.PIXELFORMATDESCRIPTOR pfd;
pfd.nSize = winAPI.PIXELFORMATDESCRIPTOR.sizeof;
pfd.nVersion = 1;
pfd.dwFlags = winAPI.PFD_DRAW_TO_WINDOW | winAPI.PFD_SUPPORT_OPENGL | winAPI.PFD_DOUBLEBUFFER;
pfd.iPixelType = winAPI.PFD_TYPE_RGBA;
pfd.cColorBits = 24;
auto hdc = winAPI.GetDC(wgl.helperWindow.platformData.handle);
const pixelFormat = winAPI.ChoosePixelFormat(hdc, &pfd);
if (winAPI.SetPixelFormat(hdc, pixelFormat, &pfd) == winAPI.FALSE)
assert(false, "Failed to set pixel format for temp context");
writeln(hdc);
writeln(pixelFormat);
winAPI.HGLRC context = wgl.createContext(hdc);
if (context is null)
{
import std.conv: to;
assert(false, "Failed to create temp context: Error Code " ~ winAPI.GetLastError().to!string);
}
if (wgl.makeCurrent(hdc, context) == winAPI.FALSE)
{
wgl.deleteContext(context);
assert(false, "Failed to make temp context current");
}
return WglContext(hdc, context);
}
void main()
{
wgl.initialize(); //Fetches function pointers, and loads opengl32.dll
auto context = wglCreateTmpContext();
wglDeleteContext(context); //Delegates to wgl.deleteContext
wgl.terminate(); //Unloads opengl32.dll and nulls function pointers
}
答案 0 :(得分:0)
我对你使用的winAPI
一无所知。无论如何,我确信:
你必须:
HWND
句柄(Windows的定义)
HWND,见下文)。该窗口使用WS_CLIPCHILDREN | WS_CLIPSIBLINGS
样式;但请尝试使用链接中的WS_OVERLAPPEDWINDOW
帐。HWND
和有效的HDC
。 HWND
和HDC
定义为*void
。我不相信auto
。