2008-09-23 16 views
21

Ich baue eine Physik-Simulations-Engine und Editor in Windows. Ich möchte den Editor-Teil mit Qt erstellen und ich möchte die Engine mit SDL mit OpenGL ausführen.Wie verwende ich Qt und SDL zusammen?

Meine erste Idee war, den Editor nur mit Qt zu erstellen und so viel Code mit der Engine zu teilen (der Ressourcenmanager, der Renderer, die Mathematik). Aber ich würde auch gerne die Simulation im Editor ausführen können. Das bedeutet, ich muss auch den Simulationscode freigeben, der SDL-Threads verwendet.

Also meine Frage ist das: Gibt es eine Möglichkeit, ein Render OpenGL zu einem Qt-Fenster mit SDL zu haben?

Ich habe im Internet gelesen, dass es möglich sein könnte, SDL mit einem Fensterhandle zu liefern, in dem gerendert werden soll. Hat jemand Erfahrung dong das?

Auch der Thread-Teil des Simulators könnte ein Problem darstellen, da er SDL-Threads verwendet.

+0

Dies ist ein Open-Source-Projekt, das ich jetzt fange. Ich werde meine Architektur/Lösung im Laufe des Projekts veröffentlichen. – bineteri

+0

Basierend auf der Aufgabe, die Sie erreichen möchten, glaube ich, dass Sie direkt für Qt gehen und SDL vollständig dumpen können. Qt hat eine ordentliche OpenGL-Unterstützung, bietet Eingabehandhabung, viel bessere Benutzeroberflächenfeatures (nichts für ungut, SDL-Leute) usw. Die Verwendung des OpenGL-Qt-Widgets ist trivial und die Threading-Modelle, die das Qt-Framework bietet, sind auch sehr einfach zu benutzen haben Standard-Threading, Parallelität usw. + das Signal/Slot-Konzept). Wenn das Threading-Modell nicht Ihren Vorstellungen entspricht, können Sie beispielsweise Boost verwenden. In beiden Fällen sehe ich keinen Grund, SDL + Qt in Ihrem Szenario zu verwenden. – rbaleksandar

Antwort

11

Während Sie es zur Arbeit wie die erste Antwort vorschlagen können, werden Sie wahrscheinlich auf Probleme aufgrund Threading stoßen. Es gibt keine einfachen Lösungen, wenn es um Threading geht, und hier würden Sie SDL Qt und OpenGL-Mainloop interagieren. Kein Spaß.

Die einfachste und klarste Lösung wäre, beide Teile zu entkoppeln. So dass SDL und Qt in separaten Prozessen laufen und sie eine Art von Messaging zur Kommunikation verwenden (ich würde hier D-Bus empfehlen). Sie können SDL in ein randloses Fenster rendern lassen und Ihr Editor sendet Befehle über Nachrichten.

+0

Danke, diese Information ist sehr wertvoll. Ich denke, ich muss die Arbeit in 2 Prozessen trennen. Die größte Hürde besteht darin, den OpenGL-Kontext zu teilen. Die Widgets von Qt spielen nicht gut mit OpenGL/SDL. Threading scheint gut zu funktionieren, da QT und SDL dieselbe Bibliothek verwenden (Pthreads, Win32-Threads). – bineteri

3

Rendern auf opengl von QT ist trivial (und funktioniert sehr gut) Keine direkte Erfahrung von SDL, aber es gibt eine Beispielanwendung hier über das Mischen von ihnen. http://www.devolution.com/pipermail/sdl/2003-January/051805.html

Es gibt einen guten Artikel über das Mischen QT widgewts direkt mit dem opengl hier http://doc.trolltech.com/qq/qq26-openglcanvas.html ein bisschen über das, was Sie unbedingt brauchen, sondern clever!

+0

OpenGL ist nicht das Problem hier. Ich weiß, es funktioniert gut mit Qt. Das Problem ist meist Threading. – bineteri

+0

Mein Fehler Ich dachte SDL war die Physik-Engine-Bibliothek! –

18

Dies ist eine Vereinfachung von dem, was ich in meinem Projekt mache. Sie können es verwenden, wie ein gewöhnlicher Widget, aber, wie Sie benötigen, können Sie mit ihr Objekt m_Screen ist auf die SDL Oberfläche zu ziehen, und es wird im Widget zeigen :)

#include "SDL.h" 
#include <QWidget> 

class SDLVideo : public QWidget { 
    Q_OBJECT 

public: 
    SDLVideo(QWidget *parent = 0, Qt::WindowFlags f = 0) : QWidget(parent, f), m_Screen(0){ 
     setAttribute(Qt::WA_PaintOnScreen); 
     setUpdatesEnabled(false); 

     // Set the new video mode with the new window size 
     char variable[64]; 
     snprintf(variable, sizeof(variable), "SDL_WINDOWID=0x%lx", winId()); 
     putenv(variable); 

     SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE); 

     // initialize default Video 
     if((SDL_Init(SDL_INIT_VIDEO) == -1)) { 
      std:cerr << "Could not initialize SDL: " << SDL_GetError() << std::endl; 
     } 

     m_Screen = SDL_SetVideoMode(640, 480, 8, SDL_HWSURFACE | SDL_DOUBLEBUF); 
     if (m_Screen == 0) { 
      std::cerr << "Couldn't set video mode: " << SDL_GetError() << std::endl; 
     } 
    } 

    virtual ~SDLVideo() { 
     if(SDL_WasInit(SDL_INIT_VIDEO) != 0) { 
      SDL_QuitSubSystem(SDL_INIT_VIDEO); 
      m_Screen = 0; 
     } 
    } 
private: 
    SDL_Surface *m_Screen; 
}; 

this helps

Hinweis: Normalerweise ist es sinnvoll, sowohl die minimale als auch die maximale Größe dieses Widgets auf die SDL-Oberflächengröße festzulegen.

+0

Funktioniert der Fenster-ID-Hack auf dem Mac? Es scheint nicht unter OSX zu funktionieren. Ich habe putenv und SDL_putenv ohne Glück versucht. –

+0

Ich weiß, das ist wirklich spät, aber könnte mir jemand erklären, wie mir das geht? – Whyrusleeping

Verwandte Themen