Direct-Qt - Qt4.x and Microsoft Direct3D

So Qt4.3 introduced a Windows Direct3D class to help D3D/Qt compatibility, Obviously a change of heart occurred at Nokia as the feature was removed in Qt4.6, preferring instead to promote OGL as their defacto standard. (#$!@%$#%@!%)

While OGL 3.2 is certainly catching up on some of legacy issues that have left it behind, D3D is just better optimized for consumer videocards and Windows users. The feature set and integration is far better with D3D than that of OGL.

OGL requires quite an investment in time to sort the messy setup. Glu, Glew, Glee, Glut, and then compiling them for the x64 Windows environment for which you need some headers from glew, some from Microsoft some from Kronos and then hope that the correct OGL3.2 compliant drivers play along, which currently are not available from Nvidia for my Asus laptop. (So i had to modify my nvdisp.inf use desktop drivers on my lappy.... Grrrr)

On top of that the one thing that kept OGL useful for myself is it's immediate mode that enables the less savvy programmers like myself, learn and see results before giving up hope... :) Now that these methods are being depreciated I've decided to test Direct3D and OGL and compare them. But of course the latest change to Qt from Nokia just makes this another step to overcome.

Currently we have a simple OGL windows painting a triangle using a more modern vertex array in OGL, my attempt will be to replace the OGL version with an identical D3D version... (Wish me luck!) (Good Luck Me!)

1) Make sure you are using Qt 4.5x and not 4.6x or later.
2) Download and install the Microsoft DirectX11 SDK from MSDN.
3) Qt needs to be compiled using "configure -direct3d" switch after setting the "dx_setenv.cmd" which is found in your DXSDK directory.

4) Make a standard Qt project either from QWidget or QMain.
5) You will need to really focus on 2 Direct3D functions (InitDevice & Draw or Render)
6)According to the Qt docs, if you want to use GDI or Direct3D on Windows with Qt, you need to:

A) Override QWidget::paintEngine to return NULL.

This is the example i was using to do so:

QPaintEngine* paintEngine()
{
return 0;
}

B) Call QWidget::setAttribute(Qt::WA_PaintOnScreen, true)

Ironically i don't seem to need to set either of them for D3D to work.

7)We did however need our own paintEvent.

void iD3D::paintEvent(QPaintEvent *p) // We made our own paintEvent

8) use "winId" to handle the usual Windows interface stuff.

A) For Direct3D9 i used it as follows:

"g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winId(),
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice );"

I also needed the following extra stuff for Direct3D 9 to show correctly:

D3DPRESENT_PARAMETERS d3dpp;
//d3dpp.EnableAutoDepthStencil = TRUE; // When Disabled Screen is Black
//d3dpp.AutoDepthStencilFormat = D3DFMT_D16; //When Disabled Screen is White

B)For Direct3D10 i used it as follows: Although i have my doubts on it's actual value on this one.

"sd.OutputWindow = winId(); " //DXGI Stuff

9)Compile and watch our lovely colored square! (Possible Resizing issues with buffers and depth)

10)You will need to set this Qt call to enable D3D when running the .exe file you create.

setAttribute(Qt::WA_MSWindowsUseDirect3D, true);

(Alternatively use the -direct3d switch at the command line. eg. "mytest.exe -direct3d"
I still need to make a simple triangle in Direct3D... :) But it's all looking good! I do have several QtD3D and QtOGL examples for x64 and MSVC-2008 if anyone ever needs them.

Comments

Popular posts from this blog

Qt and the Beast...

Microsoft and the DevIL