猫の下には、Direct3DとQtの「rapprochement」命令、およびそのまま使用できるウィジェットコードがあります。
この記事を書くとき、次のツールが使用されました。
- Qt 4.5.0
- VS2008 SP1
- DirectX SDK 2008年8月
別のものを使用している場合。 IDEの場合、ビルド時間はわずかに異なります。 VS2008のみのアセンブリ例を示します。 ビルドがdirect3dエンジンをサポートしていることが確実な場合は、Qtの構成とビルドのステップをスキップしてください。
Qtの構成と構築
- 最初の手順は、DirectXの環境変数を構成することです。そのためには、コンソールで次のコマンドを実行します。
> "%DXSDK_DIR%\ Utilities \ Bin \ dx_setenv.cmd" -
Qtディレクトリに移動して構成します。 私の場合、このように見えました> configure -direct3d -platform win32-msvc2008
-direct3dは省略できます。このパラメーターはコンフィギュレーターが計算する必要があります。
すべてがうまくいった場合、コンフィギュレーターの出力では次のようになります: Direct3Dサポート...はい
- nmakeを作成し、問題がなければ、アセンブリが終了するまで待機します。 問題が発生しました。アセンブリ中にDirect3Dに関連する未解決の外部エラーがありました。 修正するには、 %QTDIR%\ src \ gui \に移動し、両方のMakefile(リリースおよびデバッグ)でdxguid.libを「%DXSDK_DIR%\ Lib \ x86 \ dxguid.lib」に変更します (またはx64どのプラットフォーム用に構築するのか。)その後、問題は解消されるはずなので、構築が完了するまで待ちます。
ウィジェットコード
Direct3DWidget.h
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
#ifndef DIRECT3DWIDGET_H #define DIRECT3DWIDGET_H #include <QtGui/QWidget> #include <d3d9.h> #include <atlbase.h> class Direct3DWidget : public QWidget { Q_OBJECT CComPtr < IDirect3D9 > m_pD3D ; CComPtr < IDirect3DDevice9 > m_pd3dDevice ; public : Direct3DWidget ( QWidget * parent = 0 ) ; ~Direct3DWidget ( ) ; bool InitDirect3D ( ) ; public slots : bool Rendering ( ) ; private : void paintEvent ( QPaintEvent * pEvent ) ; } ; #endif
Direct3DWidget.cpp
- #include "Direct3DWidget.h"
- Direct3DWidget :: Direct3DWidget ( QWidget * parent / * = 0 * / ) : QWidget ( parent )
- {
- setAttribute ( Qt :: WA_PaintOnScreen ) ;
- }
- Direct3DWidget :: 〜Direct3DWidget ( )
- {
- }
- bool Direct3DWidget :: InitDirect3D ( )
- {
- m_pD3D = Direct3DCreate9 ( D3D_SDK_VERSION ) ;
- if ( ! m_pD3D )
- falseを返します。
- D3DPRESENT_PARAMETERS d3dpp = { 0 } ;
- d3dpp。 ウィンドウ化 = TRUE ;
- d3dpp。 SwapEffect = D3DSWAPEFFECT_DISCARD ;
- d3dpp。 BackBufferFormat = D3DFMT_UNKNOWN ;
- d3dpp。 FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT ;
- d3dpp。 PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE ;
- d3dpp。 SwapEffect = D3DSWAPEFFECT_DISCARD ;
- d3dpp。 EnableAutoDepthStencil = TRUE ;
- d3dpp。 AutoDepthStencilFormat = D3DFMT_D16 ;
- HRESULT hrResult = m_pD3D- > CreateDevice ( D3DADAPTER_DEFAULT 、 D3DDEVTYPE_HAL 、 winId ( ) 、
- D3DCREATE_HARDWARE_VERTEXPROCESSING 、
- & d3dpp 、 & m_pd3dDevice ) ;
- if (失敗( hrResult ) )
- falseを返します。
- trueを返します。
- }
- bool Direct3DWidget :: レンダリング ( )
- {
- if ( m_pd3dDevice == 0 )
- falseを返します。
- m_pd3dDevice- > Clear ( 0、0 、 D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER 、 D3DCOLOR_XRGB ( 255、255、0 ) 、 1.0f 、 0 ) ;
- if ( SUCCEEDED ( m_pd3dDevice- > BeginScene ( ) ) ))
- {
- m_pd3dDevice- > EndScene ( ) ;
- }
- m_pd3dDevice- > Present ( 0、0、0、0 ) ;
- trueを返します。
- }
- void Direct3DWidget :: paintEvent ( QPaintEvent * pEvent )
- {
- Q_UNUSED ( pEvent ) ;
- レンダリング( ) ;
- }
使用例:
- #include <QtGui / QWidget>
- #include <QtGui / QApplication>
- #include <QtGui / QHBoxLayout>
- #include "Direct3DWidget.h"
- int main ( int argc 、 char * argv [ ] )
- {
- // ------------------------------初期化を開始
- //追加のパラメータ、カンマで区切られたパラメータを追加するだけ
- std :: string aAdditionalParameters [ ] = { "-direct3d" } ;
- int iRealArgumentAmount = argc + sizeof ( aAdditionalParameters ) / sizeof ( std :: string ) ;
- //このダブルポインターには、argvからのパラメーターが含まれます。
- //このアプリケーションに必要な静的パラメータ
- char ** pArguments = new char * [ iRealArgumentAmount ] ;
- //すべてのソース(コマンドラインから)パラメーターをコピーします
- for ( int i = 0 ; i < argc ; ++ i )
- {
- * ( pArguments + i ) = new char [ strlen ( argv [ i ] ) + 1 ] ;
- strcpy ( * ( pArguments + i ) 、 argv [ i ] ) ;
- }
- //追加するパラメーターを追加します
- for ( int i = argc 、 j = 0 ; i < iRealArgumentAmount ; ++ i 、 ++ j )
- {
- * ( pArguments + i ) = new char [ aAdditionalParameters [ j ] 。 サイズ ( ) + 1 ] ;
- strcpy ( * ( pArguments + i ) 、 aAdditionalParameters [ j ] .c_str ( ) ) ;
- }
- QApplication xApplication ( iRealArgumentAmount 、 pArguments ) ;
- for ( int i = 0 ; i < iRealArgumentAmount ; ++ i )
- delete [ ] * ( pArguments + i ) ;
- delete [ ] pArguments ;
- // --------------------------------初期化完了
- QWidget xMainWindow ;
- Direct3DWidget * xScene = 新しい Direct3DWidget ( & xMainWindow ) ;
- QHBoxLayout * xMainLayout = new QHBoxLayout ;
- xMainLayout- > addWidget ( xScene ) ;
- xMainWindow。 setLayout ( xMainLayout ) ;
- //ウィジェットがウィンドウに埋め込まれた後にDirect3dを初期化することが重要です
- xScene- > InitDirect3D ( ) ;
- xMainWindow。 show ( ) ;
- xApplicationを返します。 exec ( ) ;
- }
このコードの実行結果は、そのようなウィンドウになります(ストレッチした場合)。
優れたQtフレームワークでdirect3dを静かに使用するためのすべてがあるように思えますが、残念ながら、いくつかの落とし穴を発見しました。
一部のコンピューターでは、Direct3dで描画した画像の代わりにDirect3dを使用し始めた後、背景色でペイントされた画面がありました。 属性のすべての組み合わせを試しましたが、この欠陥を取り除くことができませんでした。 一部のマシンでは、direct3dエンジンの誤動作の原因を特定することもできませんでした。 Qtのドキュメントには「 この機能は実験的なものです。 "、問題はdirect3dサポートの素朴さであると仮定できます。
しかし、この欠点がDirect3Dを使用しない理由にはなりません:)。 trolltechがdirect3dを安定状態に完了する間、次の回避策を使用できます。
paintEventのRendering()の呼び出しをコメントアウトします。
- void Direct3DWidget :: paintEvent ( QPaintEvent * pEvent )
- {
- Q_UNUSED ( pEvent ) ;
- //レンダリング();
- }
使用場所に次のコードを追加します。
- ...
- //ウィジェットがウィンドウに埋め込まれた後にDirect3dを初期化することが重要です
- xScene- > InitDirect3D ( ) ;
- xMainWindow。 show ( ) ;
- QTimer xTimer ;
- QWidget :: connect ( & xTimer 、 SIGNAL ( timeout ( ) )) 、 xScene 、 SLOT ( Rendering ( ) ) )) ;
- xTimer。 開始 ( 100 ) ;
- xApplicationを返します。 exec ( ) ;
- ...
このコードを上記の例のコードに追加しました。
また、 QTimerヘッダーを含めることを忘れないでください
QtでDirect3d APIの使用をお楽しみください。 -direct3dオプションを使用してアプリケーションを起動することを忘れないでください。このオプションを使用例のコードに含めました。