IDirect3D9 :: CreateDevice阻止了GTK + 2 Cairo渲染

时间:2017-02-01 17:35:59

标签: visual-c++ gtk direct3d cairo direct3d9

我需要调用Cairo Graphics API(包含在GTK + 2.24.10包中),同时还使用Direct3D 9 API(DirectX SDK 2009年3月)。

为了测试,我按如下方式进行基本的开罗函数调用:

#include <cairo\cairo.h>

...

cairo_surface_t *surface;
cairo_t *cr;
cairo_status_t status;

surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 390, 60);
status = cairo_surface_status(surface);

cr = cairo_create(surface);
status = cairo_status(cr);

cairo_set_source_rgba(cr, 0, 0, 0, 1);
status = cairo_status(cr);

cairo_rectangle(cr, 175, 10, 40, 40);
status = cairo_status(cr);

cairo_fill(cr);
status = cairo_status(cr);

cairo_surface_flush(surface);
status = cairo_surface_write_to_png(surface, "c:\\cairo_test.png");

cairo_destroy(cr);
cairo_surface_destroy(surface);

...

如果在调用IDirect3D9 :: CreateDevice之前进行了这些Cairo API调用,则输出以下.PNG:

PNG of black square created with Cairo API

在调用IDirect3D9 :: CreateDevice之后,相同的Cairo API调用会创建一个空白的.PNG:

Blank PNG created with Cairo API when it should contain a black square

IDirect3D9 :: CreateDevice调用参数化如下:

Direct3DCreate9(D3D_SDK_VERSION)->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, WindowHandle, D3DCREATE_HARDWARE_VERTEXPROCESSING, &PresentParameters, &PDevice);

对象参数包含以下成员变量:

WindowHandle    0x001b07f8 {unused=13111204 }   HWND__ *
    unused  13111204    int

PresentParameters   {BackBufferWidth=0 BackBufferHeight=0 BackBufferFormat=D3DFMT_UNKNOWN (0) ...}  _D3DPRESENT_PARAMETERS_
        BackBufferWidth 0   unsigned int
        BackBufferHeight    0   unsigned int
        BackBufferFormat    D3DFMT_UNKNOWN (0)  _D3DFORMAT
        BackBufferCount 1   unsigned int
        MultiSampleType D3DMULTISAMPLE_NONE (0) _D3DMULTISAMPLE_TYPE
        MultiSampleQuality  0   unsigned long
        SwapEffect  D3DSWAPEFFECT_DISCARD (1)   _D3DSWAPEFFECT
+       hDeviceWindow   0x001b07f8 {unused=13111204 }   HWND__ *
        Windowed    1   int
        EnableAutoDepthStencil  0   int
        AutoDepthStencilFormat  D3DFMT_UNKNOWN (0)  _D3DFORMAT
        Flags   1   unsigned long
        FullScreen_RefreshRateInHz  0   unsigned int
        PresentationInterval    0   unsigned int

PDevice 0x00000000 <NULL>   IDirect3DDevice9 *
+       IUnknown    <struct at NULL>    IUnknown

问题是:

  • 如何在没有错误的情况下编译代码,并且在运行时不返回任何错误状态,但是Cairo API调用的行为会有很大差异?
  • 有没有办法参数化IDirect3D9 :: CreateDevice调用以防止这种情况,或者通过后续函数调用恢复Cairo API的预期行为?

1 个答案:

答案 0 :(得分:0)

此行为是Direct3D 9 API(DirectX SDK 2009年3月)与Cairo Graphics API(1.10.2)之间不兼容的结果。

2006-10-16的以下邮件列表主题详细说明了创建Direct3D 9设备如何改变FPU to single-precision mode,并且此版本的Cairo API在进行颜色计算时采用了更高的精度: / p>

http://cairo.cairographics.narkive.com/L9XYWFkQ/cairo-direct3d-interaction-bug-and-fix-x86-fpu-precision

立即引入了针对此错误的修复程序:

https://bugs.freedesktop.org/show_bug.cgi?id=7497

开罗v1.10.2于2010年12月25日发布,该修正案在4年后发布,但错误的行为仍然存在。

但是,修复程序必须在某些时候进入Cairo代码库,因为没有证据证明Cairo v1.14.6中的错误可以从HexChat项目下载:

https://github.com/hexchat/gtk-win32

N.B。此项目的发行版中的库不兼容Windows XP。如果您的目标是Windows XP,则需要构建自己的二进制版本。

非常感谢神秘的朋友,他们使用他们的搜索功能找到了关于开罗虫的原始线索。