【问题标题】:Crash During ChoosePixelFormat in VB6在 VB6 中选择像素格式期间崩溃
【发布时间】:2012-03-29 20:03:31
【问题描述】:

我的任务是维护一个 VB6 应用程序;我有一些 OpenGL 经验,但都使用 SDL,而且这个似乎手动处理它的所有上下文。

程序似乎在调用 ChoosePixelFormat 时崩溃。我正在传递一个非空句柄。它适用于大多数系统,所以我猜测它是图形驱动程序问题,但它似乎是最新的。

有谁知道为什么这个函数会崩溃而不是返回错误代码?我了解 PIXELFORMATDESCRIPTOR 可能具有给定系统上不存在的值:

  .nSize = Len(glPFD)
  .nVersion = 1
  .dwFlags = PFD_DRAW_TO_BITMAP Or PFD_SUPPORT_OPENGL Or PFD_SUPPORT_GDI
  .iPixelType = PFD_TYPE_RGBA
  .cColorBits = 32
  .cDepthBits = 16
  .iLayerType = PFD_MAIN_PLANE

但这会让它崩溃吗?

编辑:在失败的系统上,它可以与此代码相同的先前版本一起使用。我在某处读过一个论坛,上面说加载/卸载 opengl32.dll 会导致 gdi32.dll 破坏。可能就是这种情况。

编辑:我在下面附上了完整的代码(它有点难看,但它帮助我缩小了崩溃的范围)。在 ChoosePixelFormat 崩溃之前没有函数返回 0。

hDCdib = CreateCompatibleDC(0) 'DC compatible with screen

Call MsgBox("Create Compatible DC " + CStr(hDCdib))


'Setup a Device Independent Bitmap Section
With bmInfo.bmiHeader
  .biSize = Len(bmInfo)
  If lngWidth = 0 Then
     .biHeight = objDest.ScaleY(objDest.Height, vbTwips, vbPixels)
     .biWidth = objDest.ScaleX(objDest.Width, vbTwips, vbPixels)
  Else
     .biHeight = objDest.ScaleY(lngHeight, vbTwips, vbPixels)
     .biWidth = objDest.ScaleX(lngWidth, vbTwips, vbPixels)
  End If

  .biPlanes = 1
  .biBitCount = 32
  .biCompression = BI_RGB 'No Compression
  .biSizeImage = 0
  .biClrImportant = 0
  .biClrUsed = 0
  .biXPelsPerMeter = 0
  .biYPelsPerMeter = 0
End With
Call MsgBox("after header")
hDIBSection = CreateDIBSection(hDCdib, bmInfo, DIB_RGB_COLORS, hBitMapData, _
              &O0, &O0)
Call MsgBox("CreateDIBSection" + CStr(hDIBSection))
'Select the DIB into a device context
hBitMapOld = SelectObject(hDCdib, hDIBSection)
Call MsgBox("SelectObject " + CStr(hBitMapOld))
'Create an OpenGL drawing area in that DIB
With glPFD
  .nSize = Len(glPFD)
  .nVersion = 1
  .dwFlags = PFD_DRAW_TO_BITMAP Or PFD_SUPPORT_OPENGL Or PFD_SUPPORT_GDI
  .iPixelType = PFD_TYPE_RGBA
  .cColorBits = 32
  .cDepthBits = 16
  .iLayerType = PFD_MAIN_PLANE
End With
Call MsgBox("glPFD ")
'Ignacio issue is in the next line about ChoosePixelFormat
lngFormat = ChoosePixelFormat(hDCdib, glPFD)
   Call MsgBox("ChoosePixelFormat " + CStr(lngFormat))
Htemp = SetPixelFormat(hDCdib, lngFormat, glPFD)
Call MsgBox("SetPixelFormat " + CStr(Htemp))
hGLrc = wglCreateContext(hDCdib)
Call MsgBox("wglCreateContext " + CStr(hGLrc))
wglMakeCurrent hDCdib, hGLrc
Call MsgBox("wglMakeCurrent ")

【问题讨论】:

  • ChoosePixelFormat 的调用在哪里?
  • 我已将其附加到原始问题中,现在。

标签: windows opengl graphics vb6


【解决方案1】:

DIB 上的 OpenGL 上下文没有加速,因此您将获得一个软件渲染器(至少几年前就是这种情况,我怀疑它已经改变了,尽管我可能是错的)。如果您想进行硬件加速渲染,请创建一个窗口并使用它来生成您的 GL 上下文。如果需要,请隐藏窗口。

【讨论】:

  • 我实际上负责对系统进行现代化改造(这将是一个具有实际硬件加速的 Java 重写),但我还负责维护旧版本直到它完成。所以,我不需要担心这个版本的速度;它不能像现在一样崩溃。我读的越多,崩溃听起来越像图形驱动程序问题(我听说 gdi32.dll 和 opengl32.dll 不能很好地结合在一起并导致这样的事情)。
  • 当然。我不羡慕你必须保持这一点。我们仍然有一个我们在工作中支持的 VB6 应用程序,幸运的是我不是那个人:-)。不过,正如我所说,您的问题的解决方案可能是创建一个不可见的窗口来获取上下文,对其进行渲染,然后从后台缓冲区中获取位。我不应该认为这会是大量的代码。
  • @Robinson:在隐藏窗口中进行渲染以产生有用的东西,必须使用帧缓冲区对象,或者使用该窗口作为 PBuffer 的代理。
  • 是的。考虑到应用的年龄,这本身可能就是一个问题。
猜你喜欢
  • 1970-01-01
  • 2020-07-10
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
相关资源
最近更新 更多