【问题标题】:wglMakeCurrent fails on x64wglMakeCurrent 在 x64 上失败
【发布时间】:2013-10-07 22:38:15
【问题描述】:

我正在尝试在 x64 平台上创建一个 OpenGL 窗口。 我的初始化代码适用于 x86/Win32,但在“wglMakeCurrent”处对 x64 失败。我猜问题出在像素格式的设置或获取DC(getDC())中。我已经为我的 PIXELFORMATDESCRIPTOR 尝试了不同的设置(假设 OpenGL 的 x64 实现不支持我正在使用的那个),但在那里没有成功。调试器表明 hdc 可能已损坏 - (类似于 0xfffffffff10102e0) - 但是 wglCreateContext 然后返回一个看起来有效的 hglrc (即 0x0000000000010000)。但即使我将值从 hdc on-the-fly 更改为 0x0000000010102e0(使用调试器,在调用 wglCreateContext 之前)wglMakeCurrent 仍然失败。

我在装有 Visual Studio 12 RC 1 的 Windows 8 上。 有什么想法我在这里做错了吗?还是 x64 OpenGL 实现可能存在一些限制?

#include <windows.h>
#pragma comment(lib, "OpenGL32.lib")

static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
  switch (uMsg){
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  default:
    break;
  }
  return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
  WNDCLASSEX wc;
  ZeroMemory(&wc, sizeof(WNDCLASSEX));
  wc.cbSize = sizeof(WNDCLASSEX);
  wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  wc.lpfnWndProc = WindowProc;
  wc.hInstance = nullptr;
  wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
  wc.lpszClassName = "WindowClassTest";
  RegisterClassEx(&wc);
  DWORD dwStyle = WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;
  RECT WindowRect;
  WindowRect.left = (long)0;
  WindowRect.right = (long)640;
  WindowRect.top = (long)0;
  WindowRect.bottom = (long)480;
  AdjustWindowRect(&WindowRect, dwStyle, FALSE);
  HWND hWnd = CreateWindowEx(0,
    "WindowClassTest",
    "WindowTitle",
    dwStyle,
    0, 0,
    WindowRect.right - WindowRect.left,
    WindowRect.bottom - WindowRect.top,
    nullptr,
    nullptr,
    wc.hInstance,
    (LPVOID) nullptr);
  wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
  ShowWindow(hWnd, SW_SHOW);
  SetFocus(hWnd);
  HDC hdc = GetDC(hWnd);
  int         pf;
  PIXELFORMATDESCRIPTOR pfd;
  memset(&pfd, 0, sizeof(pfd));
  pfd.nSize = sizeof(pfd);
  pfd.nVersion = 1;
  pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
  pfd.iPixelType = PFD_TYPE_RGBA;
  pfd.cColorBits = 32;
  pf = ChoosePixelFormat(hdc, &pfd);
  if (pf == 0) {
    MessageBox(NULL, "ChoosePixelFormat() failed:  "
      "Cannot find a suitable pixel format.", "Error", MB_OK);
  }
  if (SetPixelFormat(hdc, pf, &pfd) == FALSE) {
    MessageBox(NULL, "SetPixelFormat() failed:  "
      "Cannot set format specified.", "Error", MB_OK);
  }
  DescribePixelFormat(hdc, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  HGLRC hglrc = wglCreateContext(hdc);
  if (!wglMakeCurrent(hdc, hglrc)){
    MessageBox(NULL, "wglMakeCurrent() failed:  "
      "Cannot make context current.", "Error", MB_OK);
  }

  /* left out other unnecessary code here*/
  return 0;
}

【问题讨论】:

  • 你查看GetLastError()返回的错误码是什么?
  • 在 ChoosePixelFormat() 之前 GetLastError() 返回 0x00000000 - 所以在那之前一切都很好。在 ChoosePixelFormat() GetLastError() 返回 0x0000007f - 在 wglCreateContext() 0x0000007a 和 wglMakeCurrent() 0x00000006 之后。第一个错误发生在 ChoosePixelFormat() 中,所以那里可能有问题...
  • 如果其他函数没有失败,那么GetLastError() 在它们之后返回的内容无关紧要,但如果wglMakeCurrent() 失败,则错误 6 == ERROR_INVALID_HANDLE 这表明 hdchglrc 无效。你确定wglCreateContext() 成功了吗?
  • 是的,wglCreateContext() 不返回 0,所以它很可能成功。
  • 附注:您不应该为 OpenGL 窗口设置背景画笔。如果有画笔,则窗口将在每个 WM_ERASEBACKGND 消息(通常发生在 WM_PAINT 之前)时在画笔和 OpenGL 绘图之间闪烁,这是您要避免的。

标签: c++ winapi opengl 64-bit wgl


【解决方案1】:

看起来这是在 Windows 8.x 虚拟机中运行 64 位 OpenGL 应用程序时在某些情况下触发的非常具体的错误。根据可用的报告(见下文),它发生在

  • 应用程序已使用 Visual Studio >= 2012 为 x64 编译
  • 它在运行于 VM (Parallels/VMWare) 内的 Windows 8.x 中执行

我在用于为 Windows 编译我的应用程序的 Parallels VM 中遇到了同样的问题。临时解决方法是使用 32 位构建或使用以前版本的 Visual Studio(我使用 2010)编译为 64 位。

重要的是,在非仿真硬件上运行的 Windows 8.x 似乎没有受到影响。

其他人提及此问题的链接:

【讨论】:

    猜你喜欢
    • 2015-04-24
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    相关资源
    最近更新 更多