Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: [SFML2.0]Dessin avec Qt, problème avec sf::view  (Lu 4584 fois)

0 Membres et 1 Invité sur ce sujet

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
[SFML2.0]Dessin avec Qt, problème avec sf::view
« le: Février 04, 2013, 02:39:56 pm »
Salut, j'ai un soucis lorsque je veux dessiner une image en utilisant la SFML avec Qt, lorsque je n'utilise pas de vue l'image s'affiche bien par contre lorsque j'utilise une vue l'image ne s'affiche plus.

Voici mon code :

Les fichiers en tête :

#ifndef QSFMLCANVAS_HPP
#define QSFMLCANVAS_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics.hpp>
#include <Qt/qwidget.h>
#include <Qt/qtimer.h>


////////////////////////////////////////////////////////////
/// QSFMLCanvas allows to run SFML in a Qt control
////////////////////////////////////////////////////////////
class QSFMLCanvas : public QWidget, public sf::RenderWindow
{
public :

    ////////////////////////////////////////////////////////////
    /// Construct the QSFMLCanvas
    ///
    /// \param Parent :    Parent of the widget
    /// \param Position :  Position of the widget
    /// \param Size :      Size of the widget
    /// \param FrameTime : Frame duration, in milliseconds (0 by default)
    ///
    ////////////////////////////////////////////////////////////
    QSFMLCanvas(QWidget* Parent, const QPoint& Position, const QSize& Size, unsigned int FrameTime = 0);

    ////////////////////////////////////////////////////////////
    /// Destructor
    ///
    ////////////////////////////////////////////////////////////
    virtual ~QSFMLCanvas();

private :

    ////////////////////////////////////////////////////////////
    /// Notification for the derived class that moment is good
    /// for doing initializations
    ///
    ////////////////////////////////////////////////////////////
    virtual void onInit();

    ////////////////////////////////////////////////////////////
    /// Notification for the derived class that moment is good
    /// for doing its update and drawing stuff
    ///
    ////////////////////////////////////////////////////////////
    virtual void onUpdate();

    ////////////////////////////////////////////////////////////
    /// Return the paint engine used by the widget to draw itself
    ///
    ////////////////////////////////////////////////////////////
    virtual QPaintEngine* paintEngine() const;

    ////////////////////////////////////////////////////////////
    /// Called when the widget is shown ;
    /// we use it to initialize our SFML window
    ///
    ////////////////////////////////////////////////////////////
    virtual void showEvent(QShowEvent*);

    ////////////////////////////////////////////////////////////
    /// Called when the widget needs to be painted ;
    /// we use it to display a new frame
    ///
    ////////////////////////////////////////////////////////////
    virtual void paintEvent(QPaintEvent*);

    ////////////////////////////////////////////////////////////
    // Member data
    ////////////////////////////////////////////////////////////
    QTimer myTimer;       ///< Timer used to update the view
    bool   myInitialized; ///< Tell whether the SFML window has been initialized or not
};


#endif // QSFMLCANVAS_HPP

 

#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();
        ~MyCanvas();
    private :
        sf::Sprite tile;
        sf::Texture *text;
        sf::View view;
};
#endif
 

Et les fichier sources :

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include "qSFMLCanvas.h"

// Platform-specific headers
#ifdef Q_WS_X11
    #include <Qt/qx11info_x11.h>
    #include <X11/Xlib.h>
#endif


////////////////////////////////////////////////////////////
/// Construct the QSFMLCanvas
////////////////////////////////////////////////////////////
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);



    // Setup the widget geometry
    move(Position);
    resize(Size);

    // Setup the timer
    myTimer.setInterval(FrameTime);
}


////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
QSFMLCanvas::~QSFMLCanvas()
{
    // Nothing to do...
}


////////////////////////////////////////////////////////////
/// Notification for the derived class that moment is good
/// for doing initializations
////////////////////////////////////////////////////////////
void QSFMLCanvas::onInit()
{
    // Nothing to do by default...
}


////////////////////////////////////////////////////////////
/// Notification for the derived class that moment is good
/// for doing its update and drawing stuff
////////////////////////////////////////////////////////////
void QSFMLCanvas::onUpdate()
{
    // Nothing to do by default...
}


////////////////////////////////////////////////////////////
/// Return the paint engine used by the widget to draw itself
////////////////////////////////////////////////////////////
QPaintEngine* QSFMLCanvas::paintEngine() const
{
    return 0;
}


////////////////////////////////////////////////////////////
/// Called when the widget is shown ;
/// we use it to initialize our SFML window
////////////////////////////////////////////////////////////
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
        sf::Window::create(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;
    }
}


////////////////////////////////////////////////////////////
/// Called when the widget needs to be painted ;
/// we use it to display a new frame
////////////////////////////////////////////////////////////
void QSFMLCanvas::paintEvent(QPaintEvent*)
{
    // Let the derived class do its specific stuff
    onUpdate();

    // Display on screen
    display();
}

 
#include "mycanvas.h"
#include <iostream>
using namespace sf;
using namespace std;
MyCanvas::MyCanvas(QWidget *parent, const QPoint& position, const QSize& size) : QSFMLCanvas (parent, position, size) {
}
void MyCanvas::onInit() {
    view.setViewport(FloatRect(0, 0, getSize().x, getSize().y));
    text = new Texture();
    if (!text->loadFromFile("herbe.png"))
        cout<<"Erreur while loading texture."<<endl;
    tile = Sprite(*text);
    tile.setPosition(0, 0);
    setView(view);
}
void MyCanvas::onUpdate() {
    clear();
    draw(tile);
}
MyCanvas::~MyCanvas() {
    delete text;
}
 
Le main :
#include "mycanvas.h"
#include <QApplication>
#include <QMainWindow>
int main (int argc, char* argv[]) {

    QApplication app (argc, argv);
    QMainWindow* frame = new QMainWindow();
    MyCanvas *canvas = new MyCanvas (frame, QPoint(0, 0), QSize (500, 500));
    frame->setCentralWidget(canvas);
    frame->show();
    return app.exec();
}
 

Voila quand je n'utilise pas de vue ça marche, avec la vue je n'avais pas de problème avec la SFML 1.6 mais là. :/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #1 le: Février 04, 2013, 02:56:56 pm »
Ce n'est pas le viewport que tu dois utiliser. Relis bien la doc et le tutoriel sur le wiki.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #2 le: Février 05, 2013, 10:12:12 am »
Heu... oui tu as raison, j'ai regardé un coup le wiki, j'ai enlever le setViewport et j'ai fait ça :
MyCanvas::MyCanvas(QWidget *parent, const QPoint& position, const QSize& size) : QSFMLCanvas (parent, position, size), view (Vector2f(0, 0), Vector2f(size.width(), size.height())) {

}

On voit la texture mais il y a 2 problèmes plutôt étranges :

-La texture n'apparait pas au bonne endroit. (Elle apparait au milieu de la fenêtre et non pas dans le coin supérieur gauche de la fenêtre.)
-La taille de la texture n'est pas bonne.
J'ai essayé avec un view.setCenter mais ça ne résoud pas le problème. :/




La taille de mon image est de 100*50 pixels, je doute fort que sur le screen elle fasse cela vu qu'elle est fort aplatie, surtout en hauteur.
« Modifié: Février 05, 2013, 10:15:21 am par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #3 le: Février 05, 2013, 10:34:05 am »
Relis la documentation attentivement.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #4 le: Février 05, 2013, 11:34:09 am »
Bah j'ai regardé les constructeurs de la classe sf::View quand je construit la vue avec un FloatRect, ma texture se met au bonne endroit car l'autre constructeur construit la vue à partir de son centre mais ma texture est toujours écrasée, que ça soit avec un constructeur ou l'autre.

PS : et avec mon projet perso, je me retrouve avec un affichage vraiment bizarre (textures trop petites et pas toujours au bonne endroit), pourtant je n'ai rien changé du tout, à part évidement utiliser les classes et méthodes de la SFML 2.0 et plus celles de la version 1.6.
Bref je vais poster un screen.

PS 2 : à moins que j'ai du vraiment loupé quelque chose. :/
« Modifié: Février 05, 2013, 11:41:12 am par Lolilolight »

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #5 le: Février 06, 2013, 10:36:17 am »
Bon j'ai 2 problèmes :
-Le 1er est le fait que pour des raisons que j'ignore, la taille de la vue est plus petite que celle de la fenêtre.
-Le view.move ne marche pas, ma vue ne bouge pas d'un poil.  :-\

La SFML 2.0 est toujours bien compatible avec QT ?
« Modifié: Février 06, 2013, 10:38:42 am par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #6 le: Février 06, 2013, 10:47:25 am »
Citer
La SFML 2.0 est toujours bien compatible avec QT ?
Ce genre de problème n'a rien à voir avec Qt (pas QT ;)).

Il faudrait voir ton code.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #7 le: Février 06, 2013, 10:55:19 am »
Bah je n'ai rien changé comparé à la SFML 1.6 avec le tutoriel sur utiliser la SFML avec Qt, au niveau du code, à part certains noms de classe et certaines méthode qui ont changées bien évidement.
Sinon voici ma classe qui utilise la vue.

#include "mycanvas.h"
#include <iostream>
using namespace sf;
using namespace std;
MyCanvas::MyCanvas(QWidget *parent, const QPoint& position, const QSize& size) : QSFMLCanvas (parent, position, size), view (FloatRect(0, 0, size.width(), size.height())) {

}
void MyCanvas::onInit() {

    text = new Texture();
    if (!text->loadFromFile("murs.png"))
        cout<<"Erreur while loading texture."<<endl;
    tile = Sprite(*text);
    tile.setTextureRect(IntRect(100, 100, 100, 100));
    setView(view);
    view.move(100, 100);
}
void MyCanvas::onUpdate() {
    clear();
    draw(tile);
}
MyCanvas::~MyCanvas() {
    delete text;
}
 
Dans la classe QSFMLCanvas j'ai du rajouté sf::Window.create(winId()) parce que sinon j'avais un problème d'appel de méthodes ambigüe.

Mais bon ma vue ne bouge pas et la taille de la fenêtre et de la vue ne correspondent pas. :-/

Ha oui et un autre truc, quand je redimensionne la fenêtre en hauteur, la texture bouge vers le haut ou vers le bas.

Sinon, voici ce que ça fait sur mon projet personnel comme si j'avais fait un zoom hors que je n'ai pas fais de zoom. :/

« Modifié: Février 06, 2013, 11:07:48 am par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #8 le: Février 06, 2013, 11:27:10 am »
Deux choses :
- que vaut "size" dans le constructeur ? (vérifie, parfois les valeurs ne sont pas celles auxquelles on s'attend)
- si tu appelles view.move après setView(view), aucune chance pour que le déplacement soit pris en compte ;)
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #9 le: Février 06, 2013, 02:09:21 pm »
En ce qui concerne la taille, je vais regarder parce que en effet c'est pas la taille que j'attendais, je m'attendais à avoir la même taille que avec la SFML 1.6 mais là ça me fait un zoom.

Au sujet du view.move j'ai essayé aussi de le mettre dans une méthode qui traite les évènements, qui est appelée par ma méthode qui remet à jour l'affichage, donc, la méthode onUpdate.

void MyCanvas::processEvents () {
   Event event;
   while (pollEvent(event)) {
        if (Keyboard::isKeyPressed(Keyboard::Right)) {
            view.move(10, 0);
        } else if (Keyboard::isKeyPressed(Keyboard::Left)) {
            view.move(-10, 0);
        } else if (Keyboard::isKeyPressed(Keyboard::Up)) {
            view.move(0, -10);
        } else if (Keyboard::isKeyPressed(Keyboard::Down)) {
            view.move(0, 10);
        } else if (event.type == Event::Closed) {
            sf::Window::close();
        }
    }
}
void MyCanvas::onUpdate() {
    clear();
    draw(tile);
    processEvents();
}
 

Mais ma vue ne bouge toujours pas.  :o

PS : Attend mais je crois savoir pourquoi, à mon avis c'est Qt qui intercepte les évènements clavier et pas la SFML, comment dire à Qt de na pas intercepter les évènements clavier ?
J'ai essayé setFocusPolicy(Qt::NoFocus) mais ça ne marche toujours pas.  :-\
« Modifié: Février 06, 2013, 02:25:55 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #10 le: Février 06, 2013, 02:26:17 pm »
Les évènements peuvent en effet ne pas marcher à 100% côté SFML, c'est pourquoi il vaut mieux utiliser les évènements Qt.

Mais bon, toujours le même problème : tant que tu n'appelles pas setView(view), ta vue ne se mettra pas à jour. Ca ne marche plus comme avec SFML 1.6, maintenant les vues sont copiées. En d'autres termes, la fenêtre ne garde plus un pointeur sur ta propre vue, et ne peut donc pas réagir automatiquement lorsque tu modifies celle-ci. Il faut le lui dire explicitement, à chaque fois que tu fais une modif.
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #11 le: Février 06, 2013, 02:35:05 pm »
Erf dommage pour les évènements avec la SFML 1.6 ça marchait bien pourtant bref..., tant pis je vais les gérer avec QT. ^^

Je ne sais pas si QT à une façon de faire équivalente à la SFML pour faire une vérification si une touche est enfoncée ou non ou si il faut créer soi même ses propres variables booléenne bref si il faut créer soi même ses propres variables booléennes c'est pour ça que je dis que c'est dommages bref...

Sinon oui quand je refais un setView après un view.move ça marche. ^^ (Je ne savais pas que ça avait changé à ce point. :-\)
Le pointeur sur la view ça me semblait bien, mais bon. ^^


Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #12 le: Février 06, 2013, 02:58:15 pm »
Citer
Erf dommage pour les évènements avec la SFML 1.6 ça marchait bien pourtant bref...
Ca marche autant avec 2.0 que 1.6, pas de changement sur ce point. Donc si ça marchait pour toi en 1.6, il n'y a aucune raison pour que tu changes (teste bien quand même sur tous les OS que tu cibles).

Citer
Je ne sais pas si QT à une façon de faire équivalente à la SFML pour faire une vérification si une touche est enfoncée ou non ou si il faut créer soi même ses propres variables booléenne bref si il faut créer soi même ses propres variables booléennes c'est pour ça que je dis que c'est dommages bref...
Les entrées temps-réel (sf::Keyboard, sf::Mouse, sf::Joystick) marchent sans problème, elles ne sont pas connectées aux évènements, elles lisent l'état des périphériques directement.

Citer
Le pointeur sur la view ça me semblait bien, mais bon. ^^
C'était merdique, ça causait plein de problèmes :)
Laurent Gomila - SFML developer

Lolilolight

  • Hero Member
  • *****
  • Messages: 1232
    • Voir le profil
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #13 le: Février 06, 2013, 03:05:58 pm »
Voila ça marche et les déplacements ne sont plus aussi saccadés, mais j'ai encore quelques petites choses à régler, vu que il y a pas mal de choses qui ont changées, de ce fait mes ombres ne s'affichent plus bien, mon système de collision ne marche plus non plus, bref..., ce problème de zoom également car ça ne m'a pas donné du tout ce à quoi je m'attendais, bref...

Ca m'étonne cependant que ça ne soit pas plus performant avec un pointeur que avec une copie de la vue à chaque déplacement, ou alors, c'est que ça t'a posé des problèmes au niveau de la codification.
« Modifié: Février 06, 2013, 03:07:48 pm par Lolilolight »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML2.0]Dessin avec Qt, problème avec sf::view
« Réponse #14 le: Février 06, 2013, 03:15:46 pm »
Ce n'est pas une question de performances, c'est une question de conception. Les considérations de performances interviennent en fait extrêmement rarement dans les choix de l'API. Ce genre de détail est insignifiant par rapport aux performances globales.
Laurent Gomila - SFML developer

 

anything