Bonjour,
J'aurais voulu savoir si l'on pouvait utiliser une fenêtre créée avec QT, pour afficher une application Directx ? En gros peut-on récupérer le handle de la fenêtre QT pour l'utiliser ensuite dans une application Directx ?
Merci.
Version imprimable
Bonjour,
J'aurais voulu savoir si l'on pouvait utiliser une fenêtre créée avec QT, pour afficher une application Directx ? En gros peut-on récupérer le handle de la fenêtre QT pour l'utiliser ensuite dans une application Directx ?
Merci.
Je ne sais pas si cela peut t'aider mais je crois que pour recuperer le HANDLE d'une fenetre Qt il faut utiliser la methode WId QWidget::winId().
Apres pour ce qui est de l'intégration directX je penses que cela devrait fonctionner mais je n'ai jamais essayé.
Merci pour ta réponse je teste ça des que possible.
Bonjour,
Je viens de voir et c'est bon je peux récupérer le handle de la fenêtre avec cette fonction.
Par contre j'ai vu qu'il y avait certaines choses a faire pour intégrer Ogre ou SDL à QT, et j'aurais voulu savoir si quelqu'un pouvait m'indiquer comment faire pour intégrer DirectX à Qt car je n'ai pas trouvé grand chose.
Merci
Quelqu'un qui a deja réussi a intégrer directx dans qt, peut il m'expliquer la marche à suivre ?
Merci.
Je suis en train de regarder comment fonctionne QT et en fait je me demande surtout comment j'effectue mon rendu Directx dans la fenêtre ?
Avec windows j'avais accés à la "pompe à message" comment faire la pour y avoir accés ?
Oui j'utilise visual studio 2008.
Salut.
es ce que ceci peut aider?
http://lists.trolltech.com/qt-intere...ad01272-0.html
Salut merci je l'avais déjà vu ce lien mais je ne comprend pas a quoi sert sa méthode virtuelle et ou et comment est fait le rendu direct3d
Je comprend pa trop le problème. Le lien de Yan semble repondre a ta question. Enfin j'ai pas tester mais cela a l'air correcte. D'apres ce liens tu créer un objet derivant de QWidget. Dans le constructeur tu fais toute l'initialisation de direct3D et apres tu te charges du rendu en redefinissant paintEvent.
Tu devrais essayer cette voie elle me semble interressante. ;)
Ok merci j'avais pas vu qu'il fallait redéfinir paintEvent ce sera donc dans paintEvent que j'effectue le rendu de direct3D.
Je vais tester ca dés que possible merci.
Tiens nous au courant de la suite. :ccool:
J'ai un problème que je n'arrive pas à comprendre, je vous met d'abord le code puis je vous explique mon problème :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 class MaFenetreDX : public QWidget { public: MaFenetreDX(QWidget *parent = 0); virtual ~MaFenetreDX(); private: virtual void paintEvent(QPaintEvent *e); virtual void showEvent(QShowEvent *e); QPushButton *m_bouton; D3D10_DRIVER_TYPE g_driverType; ID3D10Device* g_pd3dDevice; IDXGISwapChain* g_pSwapChain; ID3D10RenderTargetView* g_pRenderTargetView; ID3D10Effect* g_pEffect; ID3D10EffectTechnique* g_pTechnique; ID3D10InputLayout* g_pVertexLayout; ID3D10Buffer* g_pVertexBuffer; ID3D10Buffer* g_pIndexBuffer; ID3D10EffectMatrixVariable* g_pWorldVariable; ID3D10EffectMatrixVariable* g_pViewVariable; ID3D10EffectMatrixVariable* g_pProjectionVariable; D3DXMATRIX g_World; D3DXMATRIX g_View; D3DXMATRIX g_Projection; // Structures struct SimpleVertex { D3DXVECTOR3 Pos ; D3DXVECTOR4 Color; }; HRESULT InitDevice() ; void CleanupDevice() ; void Render() ; };
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 #include "MaFenetreDX.h" MaFenetreDX::MaFenetreDX(QWidget *parent) : QWidget(parent) { // Mise en place de quelques options pour autoriser le rendu direct dans le widget setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); setMinimumSize(640, 480); this->setWindowTitle("Test Fenêtre DirectX"); // Construction du bouton m_bouton = new QPushButton("Bouton 1", this); m_bouton->setFont(QFont("Comic Sans MS", 10)); m_bouton->setCursor(Qt::PointingHandCursor); m_bouton->move(10, 10); g_driverType = D3D10_DRIVER_TYPE_NULL ; g_pd3dDevice = NULL ; g_pSwapChain = NULL ; g_pRenderTargetView = NULL ; g_pEffect = NULL ; g_pTechnique = NULL ; g_pVertexLayout = NULL ; g_pVertexBuffer = NULL ; g_pIndexBuffer = NULL ; g_pWorldVariable = NULL ; g_pViewVariable = NULL ; g_pProjectionVariable = NULL ; } MaFenetreDX :: ~MaFenetreDX() { CleanupDevice() ; } void MaFenetreDX::showEvent(QShowEvent *e) { InitDevice(); QWidget::showEvent(e); } void MaFenetreDX::paintEvent(QPaintEvent *e) { Render(); }
Quand je lance l'application j'obtient un écran noir avec un bouton "Bouton 1" en haut à gauche de l'écran.Code:
1
2
3
4
5
6
7
8
9
10 int main(int argc, char *argv[]) { QApplication app(argc, argv); MaFenetreDX fenetre; fenetre.show(); return app.exec(); }
Et c'est lorsque je survole ce bouton que j'obtient mon rendu DirectX, en l'occurence un cube de couleur qui tourne.
Je voudrais donc savoir comment je peux faire pour avoir le rendu dans la fenêtre directement sans être obligé de survoler le bouton.
A mon avis, c'est seulement quand tu passes sur bouton1 que la fenetre se redessine (paintEvent). Tu peux verifier cela avec une debugger pour en etre sur. Par consequent je pense que c'est a toi de forcer peut etre le rendu dans ce cas là avec une Timer ou un Thread. Il faudrait tester. Apres peut etre que quelqu'un a une meilleur solution...
Bon courage pour la suite
Pas mieux.
L'appel d'un update à temps régulier
http://qt.developpez.com/doc/4.6/qwidget/#update
Tu veux dire que je doit utiliser un timer qui appele l'update de la fenêtre ?
Oui je pense que c'est ce que Yan veut dire. :D
Il faudrait aussi vérifier, mais il me semble que QOpenGl appel update après chaque paintevent.
Bonjour,
J'ai rajouté un timer et ça fonctionne je vois mon cube qui tourne.
Par contre ca fonctionne quand je le voit sur ma fenêtre qui contient le widget comme ceci :
(Le rectangle gris c'est mon widget "MaFenetreDX")
http://img199.imageshack.us/img199/6589/qtdirectx.jpg
C'est normal que ca m'affiche mon rendu dans la fenêtre qui contient le widget puisque j'ai fait ça dans mon code :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 int main(int argc, char *argv[]) { QApplication app(argc, argv); QFrame* MainFrame = new QFrame; MainFrame->setWindowTitle("Qt SFML"); MainFrame->resize(1024, 768); MainFrame->show(); MaFenetreDX* fenetre = new MaFenetreDX(MainFrame); fenetre->show(); return app.exec(); }
mais si à la place je fait ca :Code:
1
2 sd.OutputWindow = this->topLevelWidget()->winId();
Je me retrouve avec un écran gris et je vois apparaître par moment mon cube.Code:
1
2 sd.OutputWindow = this->winId();
Donc le rendu se fait et se raffraichit bien lorsqu'il est sur la fenêtre contenant le widget mais il ne se fait pas sur le widget lui-même.
J'aurais voulu savoir aussi quelle fréquence mettre pour mon timer j'ai mis 5 mais c'est peut être trop rapide ?
Tu peut mettre le code de ta widget??
Voila le code de mon widget :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 #ifndef DEF_MAFENETREDX #define DEF_MAFENETREDX #include <QApplication> #include <QWidget> #include <QPushButton> #include <QTimer> #include <windows.h> #include <d3d10.h> #include <d3dx10.h> class MaFenetreDX : public QWidget { public: MaFenetreDX(QWidget *parent = 0); virtual ~MaFenetreDX(); private: virtual void paintEvent(QPaintEvent *e); virtual void showEvent(QShowEvent *e); virtual void resizeEvent(QResizeEvent *e); virtual void moveEvent(QMoveEvent *e); QTimer myTimer; D3D10_DRIVER_TYPE g_driverType; ID3D10Device* g_pd3dDevice; IDXGISwapChain* g_pSwapChain; ID3D10RenderTargetView* g_pRenderTargetView; ID3D10Effect* g_pEffect; ID3D10EffectTechnique* g_pTechnique; ID3D10InputLayout* g_pVertexLayout; ID3D10Buffer* g_pVertexBuffer; ID3D10Buffer* g_pIndexBuffer; ID3D10EffectMatrixVariable* g_pWorldVariable; ID3D10EffectMatrixVariable* g_pViewVariable; ID3D10EffectMatrixVariable* g_pProjectionVariable; D3DXMATRIX g_World; D3DXMATRIX g_View; D3DXMATRIX g_Projection; // Structures struct SimpleVertex { D3DXVECTOR3 Pos ; D3DXVECTOR4 Color; }; HRESULT InitDevice() ; void CleanupDevice() ; void Render() ; bool initDevice; }; #endif
Si besoin je pourrais mettre le projet complet en .zip.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 #include "MaFenetreDX.h" MaFenetreDX :: MaFenetreDX(QWidget *parent) : QWidget(parent) { // Mise en place de quelques options pour autoriser le rendu direct dans le widget setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); setMinimumSize(320, 240); this->setWindowTitle("Rendu"); g_driverType = D3D10_DRIVER_TYPE_NULL ; g_pd3dDevice = NULL ; g_pSwapChain = NULL ; g_pRenderTargetView = NULL ; g_pEffect = NULL ; g_pTechnique = NULL ; g_pVertexLayout = NULL ; g_pVertexBuffer = NULL ; g_pIndexBuffer = NULL ; g_pWorldVariable = NULL ; g_pViewVariable = NULL ; g_pProjectionVariable = NULL ; initDevice = false; myTimer.setInterval(0); } MaFenetreDX :: ~MaFenetreDX() { CleanupDevice() ; } void MaFenetreDX :: showEvent(QShowEvent *e) { InitDevice(); QWidget::showEvent(e); connect(&myTimer, SIGNAL(timeout()), this, SLOT(update())); myTimer.start(); } void MaFenetreDX :: paintEvent(QPaintEvent *e) { if(initDevice) { QWidget::paintEvent(e); Render(); update(); } } void MaFenetreDX :: moveEvent(QMoveEvent *e) { QWidget::moveEvent(e); update(); } void MaFenetreDX :: resizeEvent(QResizeEvent *e) { QWidget::resizeEvent(e); update(); } /*----------------------------------------------------------------- Nom : InitDevice() Description : Création du Device et l'associe à une Swap Chain -----------------------------------------------------------------*/ HRESULT MaFenetreDX :: InitDevice() { HRESULT hr = S_OK ; //RECT rc ; //GetClientRect(hWnd, &rc) ; //UINT width = rc.right - rc.left ; //UINT height = rc.bottom - rc.top ; UINT width = 640 ; UINT height = 480 ; UINT createDeviceFlags = 0 ; #ifdef _DEBUG createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG ; #endif D3D10_DRIVER_TYPE driverTypes[] = { D3D10_DRIVER_TYPE_HARDWARE, D3D10_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = sizeof(driverTypes) / sizeof(driverTypes[0]) ; DXGI_SWAP_CHAIN_DESC sd ; ZeroMemory(&sd, sizeof(sd)) ; sd.BufferCount = 1 ; sd.BufferDesc.Width = width ; sd.BufferDesc.Height = height ; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM ; sd.BufferDesc.RefreshRate.Numerator = 60 ; sd.BufferDesc.RefreshRate.Denominator = 1 ; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT ; sd.OutputWindow = this->winId(); sd.SampleDesc.Count = 1 ; sd.SampleDesc.Quality = 0 ; sd.Windowed = TRUE ; for(UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++) { g_driverType = driverTypes[driverTypeIndex] ; hr = D3D10CreateDeviceAndSwapChain(NULL, g_driverType, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) ; if(SUCCEEDED(hr)) break ; } }
Merci.
et si tu vire cette ligne QWidget::paintEvent(e); ?
D'autre lien trouvé :
http://lists.trolltech.com/qt-intere...ad00316-0.html
http://www.krizka.net/2008/04/27/cus...ms-with-qt-44/
Regarde aussi les source de QGLWidget. Tu trouvera surement des choses.
ok merci je vais regarder tout ça et voir si j'arrive à régler ce problème.
Je viens de faire ca dans mon widget :
Code:
1
2
3
4 QPaintEngine *MaFenetreDX :: paintEngine() { return NULL; }
mais mon rendu clignote toujours dans le widget.
Si quelqu'un sait pourquoi qu'il me fasse signe :D.
Merci.
Bon voila ça fonctionne enfin.
En fait il ne fallait pas oublier de déclarer la fonction en constante :
Dans le .h :
Dans le .cpp :Code:
1
2 QPaintEngine *paintEngine() const;
Voila ce n'était pas grand chose en fin de compte.Code:
1
2
3
4
5 QPaintEngine *MaFenetreDX:: paintEngine() const { return 0; }
Merci à ceux qui m'ont aidé. (superjaja, Yan)
Ok. Super. Tu peux remettre le code source final de ton Widget. cela peut servir a beaucoup de monde je pense. Peut etre meme qu'on pourra en faire une question dans la FAQ si tu veux.
Merci par avance.
Oui pas de problème il faudrait que tu me dises comment faire et je le rédigerai.
Voila le code complet de mon widget.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 #ifndef DEF_MAFENETREDX #define DEF_MAFENETREDX #include <QApplication> #include <QWidget> #include <QPushButton> #include <QTimer> #include <windows.h> #include <d3d10.h> #include <d3dx10.h> class MaFenetreDX : public QWidget { public: MaFenetreDX(QWidget *parent = 0); virtual ~MaFenetreDX(); private: virtual void paintEvent(QPaintEvent *e); virtual void showEvent(QShowEvent *e); virtual void resizeEvent(QResizeEvent *e); virtual void moveEvent(QMoveEvent *e); virtual QPaintEngine *paintEngine() const; QTimer myTimer; HRESULT InitDevice() ; void CleanupDevice() ; void Render() ; bool initDevice; }; #endif
Voila, par contre il n'y a pas le code concernant DirectX il y a seulement le nom des fonctions utilisées.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 #include "MaFenetreDX.h" MaFenetreDX :: MaFenetreDX(QWidget *parent) : QWidget(parent) { // Mise en place de quelques options pour autoriser le rendu direct dans le widget setAttribute(Qt::WA_PaintOnScreen, true); setAttribute(Qt::WA_NoSystemBackground, true); setMinimumSize(320, 240); initDevice = false; this->setWindowTitle("Rendu"); myTimer.setInterval(0); } MaFenetreDX :: ~MaFenetreDX() { CleanupDevice() ; } void MaFenetreDX :: showEvent(QShowEvent *e) { InitDevice(); QWidget::showEvent(e); connect(&myTimer, SIGNAL(timeout()), this, SLOT(update())); myTimer.start(); } void MaFenetreDX :: paintEvent(QPaintEvent *e) { if(initDevice) { QWidget::paintEvent(e); Render(); update(); } } QPaintEngine *MaFenetreDX:: paintEngine() const { return 0; } void MaFenetreDX :: moveEvent(QMoveEvent *e) { QWidget::moveEvent(e); } void MaFenetreDX :: resizeEvent(QResizeEvent *e) { QWidget::resizeEvent(e); }
Si quelqu'un veut le code complet avec les sources je pourrais mettre un zip à disposition.