Jump to content
  • Advertisement
Sign in to follow this  
alliedwarrior

DirectX with Qt

This topic is 2785 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I made a class that uses DirectX and Qt

/** @file Defines the widget to display a Direct3D context */ 
#ifndef _QD3DWIDGET_H_
#define _QD3DWIDGET_H_

#include <QtGui/QWidget>
#include "ui_Main.h"

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;
Ui::Form ui;
};

#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)
{
ui.setupUi(this);

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();
}


and got this window:


But I would leave the Direct3D rendering in just a portion of the window, something like a Viewport of 3D studio Max, how do this?

Thanks

Share this post


Link to post
Share on other sites
Advertisement
Put your QD3DWidget in a parent widget's layout. Off the top of my head, something like:


class Window : public QWidget
{
public:
Window() :
QWidget(0) // top-level, no parent
{
QHBoxLayout *layout = new QHBoxLayout;
setLayout(layout);
layout->addWidget(new QD3DWidget(this));
layout->addWidget(new QPushButton("hello", this));
}
};


This will create a window with your D3D widget on the left and a button on the right (if I've done everything correctly).

There are a bunch of other layouts you might wnt to use rather than a QHBoxLayout, but that's the general idea.

EDIT: or, presumably D3D has an equivalent to glViewport. You could use that if you want to split the D3D widget itself.

Share this post


Link to post
Share on other sites
the_edd, thank you very much!
now working :)

Taking this thread, I have another doubt (idiot):

I have an abstract class:
class IObserver
{
public:
virtual void handle_Event(const std::string &msg) = 0;
};





And I have my class that inherits QWidget
class server_control : public QWidget
{
Q_OBJECT

public:
server_control(Server* s, QWidget *parent = 0);
~server_control();

private:
Ui::server_control ui;

Server* server;

std::string text_map;
std::string text_server;
std::string text_type_net;
std::string text_password;
int max_players;
int port;

QTextTableFormat tableFormat;

public slots:
void Submit();
};




But when I try to make my class inherit the abstract class IObserver, it shows the following error:
1>dedicatedserver.cpp(142): error C2259: 'server_control' : cannot instantiate abstract class
1> due to following members:
1> 'void IObserver::handle_Event(const std::string &)' : is abstract
1> d:\projetos\dedicatedserver\dedicatedserver\Observer.h(15) : see declaration of 'IObserver::handle_Event'


And it points to that line when instantiate the object (the class that I'm trying to inherit)
s_control = new server_control(server);




Why? :(

[Edited by - alliedwarrior on December 4, 2010 7:25:03 AM]

Share this post


Link to post
Share on other sites
Because you haven't implemented the pure-virtual handle_Event method in your derived class. The error message is quite helpful in this case, actually.

Share this post


Link to post
Share on other sites
class server_control : public QWidget, public IObserver
{
Q_OBJECT

public:
server_control(Server* s, QWidget *parent = 0);
~server_control();

virtual void handle_Event(const std::string &msg);
private:
//....

}


Now that I have implemented the following error appears:
Quote:
server_control.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall server_control::handle_Event(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?handle_Event@server_control@@UAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)


[crying]

Share this post


Link to post
Share on other sites
The object file or library that contains your definition of server_control::handle_Event has not been linked in to the binary.

Share this post


Link to post
Share on other sites
The compiler turns C++ source files in to object files (typically .obj extension for Visual C++). For convenience, object files can optionally be bundled in to what's called a static library (typically a .lib extension for Visual C++). The linker then takes these object files and/or static libraries and glues them together in to an executable or dynamic library.

You are getting an error at the linking stage. Your code mentions a server_control::handle_Event function but the linker cannot find the object file/static library that contains the compiled definition of this method ("unresolved external symbol").

So, check that the source file that contains the definition of server_control::handle_Event is mentioned in your Visual C++ solution/project or your Qt .pro file.

I empathise with your desire to jump in to creating GUIs and visuals at an early stage, but I'd recommend learning a little more about the basics of C++ before continuing too much further. The last two questions are C++ 101 (and actually the first question can be answered by following any Qt tutorial, including the ones found inside Qt Assistant).

Share this post


Link to post
Share on other sites
The strange thing is that this happens even I trying something very simple and in the same header:

server_control.h
class AbstractClass {
public:
virtual void AbstractMemberFunction() = 0; //pure virtual function makes this class Abstract class
};

class server_control : public QWidget, public AbstractClass
{
Q_OBJECT

public:
server_control(Server* s, QWidget *parent = 0);
~server_control();

void AbstractMemberFunction();
private:
Ui::server_control ui;

Server* server;

std::string text_map;
std::string text_server;
std::string text_type_net;
std::string text_password;
int max_players;
int port;

QTextTableFormat tableFormat;

public slots:
void Submit();
};




Quote:
error LNK2001: unresolved external symbol "public: virtual void __thiscall server_control::AbstractMemberFunction(void)" (?AbstractMemberFunction@server_control@@UAEXXZ)


I tested in another class that does not inherit QWidget, and it worked perfectly:
class AbstractClass {
public:
virtual void AbstractMemberFunction() = 0; //pure virtual function makes this class Abstract class
};

class Test : public AbstractClass
{
public:
Test() { }
~Test() { }
void AbstractMemberFunction();
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!