jueves, 24 de octubre de 2013

Qt 5 and SFML 2.0 Integration

Hi all!

Today, I'm gonna show you my last fight and victory (for now :)). The goal: integrating SFML with Qt. Yeah, too many abbreviations... ok, let's go step by step.

SFML, as mentioned in earlier posts, is an efficient, easy to learn library that wraps OpenGL as a set of higher-level classes and methods. As its main purpose is to draw (or technically, render) things on the screen, it is usually referred as a renderer library. But it doesn't go beyond that: it's not a framework that manages the screen by screen graphs or trees, such as Ogre3D, for example. It is just a nicer entry point to OpenGL.

On the other hand, Qt (pronounced 'cute'), is a framework for developing Graphical User Interfaces (GUI) applications. As such, it provides an API to let developers create buttons, windows, labels, etc in an easy manner. Its (very) complete API also allows developers to render things on the windows. 

The question is: why would it be a good idea to integrate these two libraries? Well, SFML is a very good renderer, but it lacks the capability to create complex GUIs, whereas Qt has the opposite pros and cons. Therefore, the integration yields the breeding ground for nice game tools development, for instance, a level editor. And this is actually the reason why I wanted this integration. I can take advantage of my current knowledge of SFML, and just need to learn some concrete parts of Qt, concretely, the parts for drawing windows stuff (toolbars, menus, etc) and for receiving interaction events from the user.

In addition, Qt brings a very complete IDE (Integrated Development Environment) for C++, which according to many people in forums, it is better if you want to work in C++ than XCode (the Mac OS default IDE), which is more fine-tuned to work with Objective-C. The Qt IDE is called Qt Creator.

First of all, the specification of the problem:
Operating System: Mac OS X 10.7.5
Qt: 5.5.1 (Clang 3.1, 64 bit) -> Clang is the name of the C++ compiler to be used and is installed automatically when you install Qt.
Qt Creator: 2.8.1
SFML: 2.0

Once you have downloaded everything you need (correct SFML and Qt packages), you must follow the following steps:

1) Open a new Qt Creator project. You have to let Qt Creator know where it can find the headers and libraries of SFML. You can copy the following lines and paste them in the .pro file of the Qt Creator project. IMPORTANT: Everything between '< >' must be set appropriately according to your installation settings.

### TO ALLOW SFML LIBRARY ###
CONFIG_APP_NAME = <Name of your application (in Qt Creator)>
INCLUDEPATH += <Path of installation of SFML>/SFML/include
DEPENDPATH += <Path of installation of SFML>/SFML/include
CONFIG(release, debug|release): 
LIBS += -L/<Path build of SFML>/SFML-build/lib -lsfml-audio 
-lsfml-graphics -lsfml-network -lsfml-window -lsfml-system
CONFIG(debug, debug|release): 
LIBS += -L<Path build of SFML>/SFML-build/lib -lsfml-audio-d 
-lsfml-graphics-d -lsfml-network-d -lsfml-window-d -lsfml-system-d
macx {
    QMAKE_POST_LINK += $(MKDIR) 
$${CONFIG_APP_NAME}.app/Contents/Frameworks &&
    QMAKE_POST_LINK += $${QMAKE_COPY} -r 
<Path build of SFML>/SFML-build/lib/* 
$${CONFIG_APP_NAME}.app/Contents/Frameworks
}

Before macx, we're simply doing what I explained: more precisely, we are telling to the compiler where it can find the SFML headers, and to the linker where it can find the SFML libraries. The instructions after the macx (which are QMake instructions), make the following: first, it creates a directory called Framework under <Application path>.app/Contents/, and then, it copies the SFML libraries in this directory. Why? Because the Mac OS loader reads the binaries of these libraries from this location. As simple as that. If you want to avoid problems, I suggest you at this point disallowing 'Shadow build' in Qt Creator (more information here).

2) Once these configuration issues are solved, let's perform the actual integration. As explained here, Qt extensions are done by means of extending QWidget class. So, we have to create a new QWidget, which is the SFML RenderWindow. The code changes a bit with respect to the SFML 1.6 tutorial. I'm simply going to paste here the raw code you will need for the different files. For a proper explanation though, I suggest you to read the aforementioned tutorial. 

QSFMLCanvas.h
#ifndef QSFMLCANVAS_H
#define QSFMLCANVAS_H
#include <QWidget>
#include <SFML/Graphics.hpp>
#include <QTimer>
class QSFMLCanvas : public QWidget, public sf::RenderWindow
{
//Q_OBJECT
public:
explicit QSFMLCanvas(QWidget *parent, const QPoint& Position, const QSize& Size, unsigned int FrameTime = 0);
virtual void showEvent(QShowEvent*);
virtual QPaintEngine* paintEngine() const;
virtual void paintEvent(QPaintEvent*);
virtual ~QSFMLCanvas();
virtual void OnInit();
virtual void OnUpdate();
private:
QTimer myTimer;
bool myInitialized;
};
#endif // QSMLCANVAS_H


QSFMLCanvas.cpp
#include "qsfmlcanvas.h"
#ifdef Q_WS_X11
#include <Qt/qx11info_x11.h>
#include <X11/Xlib.h>
#endif
#include <iostream>
QSFMLCanvas::QSFMLCanvas(QWidget* Parent, const QPoint& Position, const QSize& Size, unsigned int FrameTime) : QWidget(Parent),
myInitialized (false)
{
// Setup some states to allow direct rendering into the widget
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_NoSystemBackground);
// Set strong focus to enable keyboard events to be received
setFocusPolicy(Qt::StrongFocus);
// Setup the widget geometry
move(Position);
resize(Size);
// Setup the timer
myTimer.setInterval(FrameTime);
}
QSFMLCanvas::~QSFMLCanvas() {}
void QSFMLCanvas::showEvent(QShowEvent*)
{
if (!myInitialized)
{
// Under X11, we need to flush the commands sent to the server to ensure that
// SFML will get an updated view of the windows
#ifdef Q_WS_X11
//XFlush(QX11Info::display());
#endif
// Create the SFML window with the widget handle
RenderWindow::create((void *) winId());
// Let the derived class do its specific stuff
OnInit();
// Setup the timer to trigger a refresh at specified framerate
connect(&myTimer, SIGNAL(timeout()), this, SLOT(repaint()));
myTimer.start();
myInitialized = true;
}
}
QPaintEngine* QSFMLCanvas::paintEngine() const
{
return 0;
}
void QSFMLCanvas::paintEvent(QPaintEvent*)
{
// Let the derived class do its specific stuff
OnUpdate();
// Display on screen
RenderWindow::display();
}
void QSFMLCanvas::OnInit() {}
void QSFMLCanvas::OnUpdate() {}


MyCanvas.h 
 #ifndef MYCANVAS_H
#define MYCANVAS_H
#include "qsfmlcanvas.h"
#include <SFML/Graphics.hpp>
class MyCanvas : public QSFMLCanvas
{
public :
MyCanvas(QWidget* Parent, const QPoint& Position, const QSize& Size);
void OnInit();
void OnUpdate();
private :
sf::Clock myClock;
sf::Texture myImage;
sf::Sprite mySprite;
};
#endif // MYCANVAS_H


MyCanvas.cpp
#include "mycanvas.h"
#include <iostream>
#include <string>
#include <QDir>
MyCanvas::MyCanvas(QWidget* Parent, const QPoint& Position, const QSize& Size) : QSFMLCanvas(Parent, Position, Size)
{
}
void MyCanvas::OnInit()
{
// Load the image
std::cout << "onInit" << std::endl;
QString dir = QDir::currentPath();
std::string utf8_text = dir.toUtf8().constData();
std::cout << "HELLO: " << utf8_text << std::endl;
if (!myImage.loadFromFile(utf8_text + "/chef.png")) {
std::cout << "Loading error"<< std::endl;
} else {
std::cout << "Image was loaded fine" << std::endl;
}
// Setup the sprite
mySprite.setTexture(myImage);
mySprite.setPosition(150, 150);
std::cout << "setting the texture of the sprite" << std::endl;
//mySprite.setCenter(mySprite.GetSize() / 2.f);
myClock.restart();
}
void MyCanvas::OnUpdate()
{
// Clear screen
RenderWindow::clear(sf::Color(0, 128, 0));
// Rotate the sprite
mySprite.rotate(myClock.getElapsedTime().asSeconds() * 100.f);
// Draw it
RenderWindow::draw(mySprite);
myClock.restart();
}


main.cpp 
#include <QApplication>
#include "mycanvas.h"
#include <QFrame>
int main(int argc, char *argv[])
{
QApplication App(argc, argv);
// Create the main frame
QFrame* MainFrame = new QFrame;
MainFrame->setWindowTitle("Qt SFML");
MainFrame->resize(400, 400);
MainFrame->show();
// Create a SFML view inside the main frame
MyCanvas* SFMLView = new MyCanvas(MainFrame, QPoint(20, 20), QSize(360, 360));
SFMLView->show();
return App.exec();
}

There is an important consideration. Qt Creator uses a special way to declare the resources (e.g. images) that your application will use. It does so in order to comply with the cross-platform requirement, but it can be quite weird for someone who is not used to it. Basically, you would need to create a Resource file. However, SFML does not understand this, and when you try to execute loadFromFile in the MyCanvas::OnInit method by using this approach, SFML does not find the image. The solution, at least temporal and for testing purposes, is that you place you image inside the <Path application>.app/Contents/MacOS directory, and that you use the piece of code that I have provided above, which will search the image in that directory.

Figure 1. Output of the program. Basically, it's a Qt frame with a SFML renderer window inside the frame. It is showing the chef, which is a sprite (which as usual has been designed by Manuela) that I'm using for an iOS game that will come out very soon :).

I think that's all. If I forgot something or you need more explanations, just let me know and I'll update the post.

EDIT: Some people following this tutorial have encountered the following error: "error: invalid conversion from 'void*' to 'sf::WindowHandle {aka HWND__*}' [-fpermissive] RenderWindow::create((void *) winId());^". This error occurs in the line RenderWindow::create((void *) winId());

The solution, which was posted here, is to change the aforementioned line to this one: RenderWindow::create(reinterpret_cast<sf::WindowHandle>(winId())); (Thanks to delio and hyde for raising the problem and the fix)

Good luck!

34 comentarios:

  1. I've try to copy your source code that can create SFML widget in qt.
    But it gives many errors.

    I have no idea how can I do
    Please suggest me

    Thanks!

    ResponderEliminar
  2. Are you using the same versions of SFML and Qt? Can you post the error messages that you get?

    ResponderEliminar
  3. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  4. what do you mean by "path build of sfml" I mean which directory should I write here. it's not sfml installation path, then what it is?

    ResponderEliminar
  5. Hi,

    By the time of this post, I had two different directories: one called SFML, where you could find the sources, headers, external libraries, and tools (like SFML templates for Xcode); the other directory was SFML-build, where you could find the libraries (e.g. libsfml-audio.dylib). It's been a while since then, and maybe the current installation of SFML creates different directories.

    In any case, the important thing here is that you navigate through the installed SFML folder, and look for where the headers (include folder) and the libraries (lib folder) are located. These would be the paths that you have to write in the .pro file.

    Hope you find the solution and ask me if you have further questions.

    ResponderEliminar
  6. Works perfectly for me, n-th clone of 2048 is comming! ;-)

    ResponderEliminar
  7. Mcafee.com/activate have the complete set of features which can protect your digital online life the computing devices, and it not only help you to protect it but also it can maintain the stability of your computer, increase the speed with inbuilt PC Optimisation tool.

    Mcafee install

    install mcafee

    install mcafee with activation code

    enter mcafee activation code

    mcafee activate product key

    mcafee product activation

    mcafee activate

    ResponderEliminar
  8. Online Help – Step by Step guide for Norton Setup, Download & complete installation online. We are providing independent support service if in case you face problem to activate or Setup Norton product. Just fill the form and will get in touch with you as quick as possible.

    norton.com/setup

    norton setup enter product key

    norton setup product key

    norton setup with product key

    ResponderEliminar
  9. Install Webroot for complete internet browsing & web Security in your computer. It will save you from all the cyber attacks.
    The webroot antivirus is a very renowned security tool that protect the computer software and malware & firewall.

    webroot.com/safe

    webroot install key code

    install webroot

    webroot.com/safe

    webroot.com/safe

    webroot.com/safe

    webroot geek squad

    webroot geek squad dowload

    webroot download

    secure anywhere

    ResponderEliminar
  10. Hey, Loved it. Thanks For sharing this post with us.
    Fix Your Technical Problem With us. We are a team of the tech geeks. problem with Router, antiviruses, Windows, printer etc. Visit
    norton.com/setup
    Norton Activation

    ResponderEliminar
  11. Great efforts to collect genuine information.
    wireless router setup contains the router tech information which provides to the user to get resolve their router technical issues.

    ResponderEliminar
  12. Antivirus Guides are providing the helpful solution for problems Related to antivirus. We are giving a proper guidance how to fix your Gadgets Security.

    ResponderEliminar
  13. To avoid any software conflict issue before you do download, install and activate the Norton Setup.
    Check out the quick guide for activation and setup
    norton.com/activation or
    Norton setup
    To be Secure and be Aware

    ResponderEliminar
  14. If you are from different country and need online help with Norton Setup and Installation, then please start a live chat online. Currently our Toll Free Helpline available only in USA, Canada, United Kingdom and Australia Customers. http://nortonsetup.ca

    ResponderEliminar
  15. Microsoft Office 365 is an integral part of complete package which is widely used by professionals and non-professionals. There is a simple activation process of activation by entering account credentials and product key. Our technical team can help in complete process if there is any issue while activation of application.http://www.officeecomsetup.com

    ResponderEliminar
  16. Gmail users can directly connect with us at Gmail customer service number 1-844-777-7886 toll free. We, being a team of dedicated professionals, handle and impart solution for all the email account difficulties. Gmail users can just reach us whenever they want. http://gmail-gmail.com

    ResponderEliminar

  17. Install norton antivirus with the best support team and keep your computer virus free

    norton.com/setup

    ResponderEliminar
  18. Antivirus is the need of computers that makes them virus free and we are going to give you full support to get the best antivirus installed in your computers and laptops. Download norton antivirus package with us.

    www.norton.com/setup

    ResponderEliminar

  19. Install mcafee antivirus in your computer with high class professionals and best tech team. Just ring us and we are ready to assist you till the last minute of installation

    www.mcafee.com/activate

    ResponderEliminar
  20. Setup microsoft office 365 package with us. We are the team of technical professionals and give the best technical support to our clients even after the installation process

    office.com/setup

    ResponderEliminar
  21. Install full microsoft office setup 365 with our support. Now setting up your account will be a cakewalk with us

    microsoft office setup

    ResponderEliminar
  22. Download Microsoft office setup 365 with the best tech support team and make your computer working with Microsoft office package

    install office

    ResponderEliminar
  23. are you interested in using microsoft office 365 products here we are providing full support to make your computer working with Microsoft office. you dont need to work on anything as we will help you to setup your Microsoft product

    office.com/setup

    ResponderEliminar

  24. Microsoft office it the package of office tools to make your working smooth and effective.Get it downloaded in your computer with the fast support

    office.com/setup

    ResponderEliminar
  25. Step by step instructions to install Microsoft office 365 in your computer. For any help, Call us and we are here to help you

    install office

    ResponderEliminar

  26. Get your Office Setup Installed with the help of the best support team. You may install the complete microsoft office 365 package without any complicated work.

    www.office.com/myaccount

    ResponderEliminar
  27. Exceptional technical assistance for setting up microsoft office 365 in your computer or laptop.just give us a call on our number and we are ready to give you the best support

    www.office.com/myaccount

    ResponderEliminar
  28. Printer Tech Support Number gives an enterprise-level multi-brand support and dedicated solutions for various problems of printer brands like Canon, Epson, Dell, Hp, Brother, Lexmark, Toshiba etc. Our vast network of technicians and printer experts can resolve any issues of your printers

    HP Printer Tech Support Number
    Canon Printer Tech Support Number
    Brother Printer Tech Support Number
    Lexmark Printer Tech Support Number
    epson Printer Tech Support Number
    Dell Printer Tech Support Number
    toshiba Printer Tech Support Number
    Samsung Printer Tech Support Number
    Kindle Support Number

    ResponderEliminar
  29. kindle-help.org is an independent provider of phone support services for software, hardware, and peripherals. We are unique because we have expertise in products from a wide variety of third-party companies. Kindle Support Number Support has no affiliation with any of these third-party companies unless such relationship is expressly specified. Phone support may also be provided by such third parties. Kindle Support Number hereby disclaims its sponsorship, partnership, affiliation or endorsement regarding any such third party trademarks and brand names and also proclaims that the use of such terms including third party trademarks and brand names

    Netgear Externder Setup
    install Canon printer
    Canon Wireless Printer Setup
    Norton Tech Support
    Mcafee Support
    Kindle Support
    Norton Phone Number
    mcafee Phone Number

    ResponderEliminar
  30. kindle-help.org is an independent provider of phone support services for software, hardware, and peripherals. We are unique because we have expertise in products from a wide variety of third-party companies. Kindle Support Number Support has no affiliation with any of these third-party companies unless such relationship is expressly specified. Phone support may also be provided by such third parties. Kindle Support Number hereby disclaims its sponsorship, partnership, affiliation or endorsement regarding any such third party trademarks and brand names and also proclaims that the use of such terms including third party trademarks and brand names
    Geek Squad
    Netgear Genie Setup
    Netgear Router login
    reset Netgear password
    Geek Squad Best Buy
    Geek Squad Phone Number

    ResponderEliminar
  31. kindle-help.org is an independent provider of phone support services for software, hardware, and peripherals. We are unique because we have expertise in products from a wide variety of third-party companies. Kindle Support Number Support has no affiliation with any of these third-party companies unless such relationship is expressly specified. Phone support may also be provided by such third parties. Kindle Support Number hereby disclaims its sponsorship, partnership, affiliation or endorsement regarding any such third party trademarks and brand names and also proclaims that the use of such terms including third party trademarks and brand names
    Linksys Router Setup
    Netgear Router Setup
    Dlink Router Setup
    asus Router Setup
    Netgear Externder Setup
    Linksys Externder Setup
    Linksys Router Login

    ResponderEliminar
  32. kindle-help.org is an independent provider of phone support services for software, hardware, and peripherals. We are unique because we have expertise in products from a wide variety of third-party companies. Kindle Support Number Support has no affiliation with any of these third-party companies unless such relationship is expressly specified. Phone support may also be provided by such third parties. Kindle Support Number hereby disclaims its sponsorship, partnership, affiliation or endorsement regarding any such third party trademarks and brand names and also proclaims that the use of such terms including third party trademarks and brand names
    Belkin Router Setup
    Belkin Router Login
    Asus Router Login
    Dlink Router Login
    Netgear Router Login
    Hp printer Assistant

    ResponderEliminar