DirectX with Qt

Started by
34 comments, last by the_edd 13 years, 4 months ago
Quote:Original post by SeaBourne
What do you mean you cannot add it to the layout? Code looks fine. Btw if you have a parameter in the constructor you have to pass it to the base constructor. You passing 0 is not correct. Because if you was to pass this to that parameter it would cause a memleak. Due to you not deleting the Window since passing "this" would cause the Window to be correctly deleted.

Also you do not need to pass "this" to the ctor of the QD3DWidget since it's being added to a layout. As the layout takes ownership of the widget.


Sorry, we did not know of these errors on Qt (I'm new in programming with Qt) :)

As the window, I am creating in QtDesigner:


Using the ui, the code looks like, and the window when run like this:
Window::Window(QWidget* parent)	: QWidget(parent){	ui.setupUi(this);	ui.horizontalLayout->addWidget(new QD3DWidget());}



And when I create my QHBoxLayout the code looks like this:
Window::Window(QWidget* parent)	: QWidget(parent){	ui.setupUi(this);		QHBoxLayout *layout = new QHBoxLayout();	setLayout(layout);	layout->addWidget(new QD3DWidget());}



A note: The blue screen means that the code of DirectX is working, I configured it to clean the screen with the color blue

and using the code (last image), so if I do (wrong):
layout->addWidget(new QD3DWidget()); //not using this

it is white
and if I do so, it turns blue (correct):
layout->addWidget(new QD3DWidget(this)); //using this


Thanks
Advertisement
can you post the full code for your source of QD3DWidget?
Quote:Original post by SeaBourne
Btw if you have a parameter in the constructor you have to pass it to the base constructor. You passing 0 is not correct. Because if you was to pass this to that parameter it would cause a memleak. Due to you not deleting the Window since passing "this" would cause the Window to be correctly deleted.


Passing 0 is entirely correct for a top-level window. See the QWidget documentation.

Quote:Original post by the_edd
Quote:Original post by SeaBourne
Btw if you have a parameter in the constructor you have to pass it to the base constructor. You passing 0 is not correct. Because if you was to pass this to that parameter it would cause a memleak. Due to you not deleting the Window since passing "this" would cause the Window to be correctly deleted.


Passing 0 is entirely correct for a top-level window. See the QWidget documentation.


Yes I know. I have a certification for Qt.

For instance (this is an example)

void Foo::bar(){    QD3DWidget* newWidget = new QD3DWidget(this);}


Now if you kept it like it currently is, newWidget would cause a memory leak due to parent not being set. "Foo::Foo(QWidget* parent) : QWidget(0)".

Now if you pass parent to QWidget like you should, then there would be no memleak but then again that object would still persist through out the life of that class due to the way Qt does it's memory management.

So you are correct but it is wrong. If you aren't going to use the parent parameter you might as well remove it and not use it at all.
Quote:Original post by SeaBourne
can you post the full code for your source of QD3DWidget?

Yes guy :)

/** @file Defines the widget to display a Direct3D context */ #ifndef _QD3DWIDGET_H_ #define _QD3DWIDGET_H_ #include <QtGui/QWidget> struct IDirect3D9; struct IDirect3DDevice9; class QD3DWidget : public QWidget {   Q_OBJECT public:   /** Constructor */   QD3DWidget( QWidget* pParent = NULL);   /** Destructor */   ~QD3DWidget();   /** a hint to Qt to give the widget as much space as possible */   QSizePolicy sizePolicy() const { return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); }   /** a hint to Qt that we take care of the drawing for ourselves, thankyouverymuch */   QPaintEngine *paintEngine() const { return NULL; } protected:   /** Initialized the D3D environment */   void Setup();   /** Destroys the D3D environment */   void Close();   /** paints the scene */   void paintEvent( QPaintEvent* pEvent); private:   /** D3D stuff */   IDirect3D9*       mD3D;   IDirect3DDevice9* mDevice; }; #endif // _QD3DWIDGET_H_ 


#include "QD3DWidget.h" #include <QMessageBox>#define WIN32_LEAN_AND_MEAN #include <d3d9.h> #include <d3dx9.h> // Constructor QD3DWidget::QD3DWidget( QWidget* pParent)   : QWidget( pParent) { 	mD3D = NULL; 	mDevice = NULL; 	setMinimumSize( 400, 400); 	setAttribute( Qt::WA_OpaquePaintEvent, true);  	setAttribute( Qt::WA_PaintOnScreen, true); 	Setup(); } // Destructor QD3DWidget::~QD3DWidget() { 	Close(); } // Initialized the D3D environment void QD3DWidget::Setup() { 	HWND windowHandle = winId(); 	// create Direct3D9 object 	mD3D = Direct3DCreate9( D3D_SDK_VERSION); 	if( NULL == mD3D) 	        QMessageBox::critical(this,                              "ERROR",                              "Failed to create D3D object",                              QMessageBox::Ok);	// create D3D device 	// pack hier deine eigenen PresentationParams rein     D3DPRESENT_PARAMETERS d3dpp;    // create a struct to hold various device information    ZeroMemory(&d3dpp, sizeof(d3dpp));    // clear out the struct for use    d3dpp.Windowed = TRUE;    // program windowed, not fullscreen    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    // discard old frames    d3dpp.hDeviceWindow = windowHandle;    // set the window to be used by Direct3D	HRESULT hr = mD3D->CreateDevice(D3DADAPTER_DEFAULT,                      D3DDEVTYPE_HAL,                      windowHandle,                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,                      &d3dpp,                      &mDevice);	if( FAILED( hr)) 	        QMessageBox::critical(this,                              "ERROR",                              "Failed to create D3D device",                              QMessageBox::Ok);} // Destroys the D3D environment void QD3DWidget::Close() { 	if( mDevice) 		mDevice->Release(); 	if( mD3D) 		mD3D->Release(); } // paints the scene void QD3DWidget::paintEvent( QPaintEvent* pEvent) {   // clear render buffer   HRESULT hr = mDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);  if( FAILED( hr)) 	        QMessageBox::critical(this,                              "ERROR",                              "Failed to clear backbuffer.",                              QMessageBox::Ok);  mDevice->BeginScene();    // begins the 3D scene  mDevice->EndScene();    // ends the 3D scene  // and show the result   hr = mDevice->Present(NULL, NULL, NULL, NULL);   // displays the created frame on the screen  if( FAILED( hr)) 	        QMessageBox::critical(this,                              "ERROR",                              "Failed to Present().",                              QMessageBox::Ok);  // trigger another update as soon as possible   update(); } 


Thanks :)
This is really confusing. The only thing I can possible think of that the reason why it is working is due to that the QD3DWidget is not getting a valid winId() unless it is parented, hence why you are getting it to work when you pass the "this" to the constructor. My best bet is not to call setup() inside of the constructor, but rather outside of it. But that's the only thing I can guess, that could be the issue. You might want to ask on irc.freenode.net #Qt and ask some people who do know about Windows specific stuff, because might be able to help more and give you a definite answer. But, try my suggestion first and then go there if it doesn't work.

Also you don't need to setLayout() it's already done for you when you passed "this" to setupUi(). Here is why you are getting the thick border around the DirectX render. Clear your form, drop the DirectX render back on the form and right click and set it as a grid layout. Then if you want you can drop a QHBoxLayout on to it and do it that way and if you need to dynamically add (rarely) then you can easily do it. Maybe sure you name the layout something unique. Also, l suggest you read this guide: http://doc.qt.nokia.com/latest/designer-using-custom-widgets.html and drop a QWidget on to the form, then up cast it to your name (tells you how on the page) and then you won't need to dynamically add it to the layout.

Also you might want to read on the styling guide for Qt. Because we don't use Windows pascal casting (I think that's the name) and we don't use Hungarian notation. http://doc.trolltech.com/qq/qq13-apis.html (Suggestion because mixing styles is bad idea). It's just a suggestion, don't get mad :).

you know any example of OpenGL that uses QtDesigner to create and QHBoxLayout?
I think you could help me

The examples that come with Qt, do not use QtDesigner
Quote:Original post by alliedwarrior
you know any example of OpenGL that uses QtDesigner to create and QHBoxLayout?
I think you could help me

The examples that come with Qt, do not use QtDesigner


Well just do

Drop QGLWidget as the central widget (setCentralWidget) that will make it the main window widget then just add your menus.

else just call show on your QD3DWidget and it will be displayed in a window.
I found this tutorial:
http://blog.lugru.com/2009/03/qtdesigner-and-qglwidget/

oddly enough, also did what he said and does not work.

I wish I could use QtDesigner and not take the trouble to get positioning buttons, etc. with the code
The problem must be something I'm doing wrong in my QD3DWidget I asked on irc.freenode.net #Qt but nobody could help me

:(


seabourne, thanks anyway for the attention and help
Are you just wanting the scene only on the main window?

This topic is closed to new replies.

Advertisement