2008-09-23 147 views
21

我在Windows中構建了一個物理模擬引擎和編輯器。我想用Qt構建編輯器部分,我想用OpenGL使用SDL來運行引擎。我如何一起使用Qt和SDL?

我的第一個想法是隻使用Qt構建編輯器,並與引擎(資源管理器,渲染器和數學)共享盡可能多的代碼。但是,我也希望能夠在編輯器中運行模擬。 這意味着我也必須共享使用SDL線程的模擬代碼。

所以,我的問題是這樣的:有沒有辦法使用SDL渲染OpenGL到Qt窗口?

我已經在網上閱讀過,有可能向SDL提供一個窗口句柄來渲染。有人有經驗的那個?

此外,由於模擬器使用SDL線程,因此模擬器的線程部分可能會造成問題。

+0

這對於我開始,現在一個開源項目。隨着項目的進展,我會發布我的架構/解決方案。 – bineteri 2008-09-23 01:43:47

+0

基於你想完成的任務,我相信你可以直接去Qt並完全轉儲SDL。 Qt具有良好的OpenGL支持,提供輸入處理,更好(沒有攻擊,SDL人員)用戶界面功能等。使用OpenGL Qt小部件是微不足道的,Qt框架提供的線程模型也非常易於使用(您具有標準線程,併發等+信號/時隙概念)。如果線程模型不符合你的喜好,你可以使用類似boost的東西。無論哪種方式,我真的沒有看到在您的方案中使用SDL + Qt的理由。 – rbaleksandar 2015-10-30 23:28:17

回答

11

雖然您可能會像第一個答案那樣工作,但建議您可能由於線程而遇到問題。談到線程時,沒有簡單的解決方案,在這裏您將擁有SDL Qt和OpenGL mainloop交互。不好玩。

最簡單和最簡單的解決方案是解耦這兩個部分。因此,SDL和Qt運行在不同的進程中,並讓它們使用某種消息傳遞進行通信(我在此推薦d-bus)。您可以將SDL渲染到無邊框窗口中,並且編輯器通過消息發送命令。

3

從QT渲染到opengl是微不足道的(並且效果很好) 沒有SDL的直接體驗,但這裏有一個關於混合它們的示例應用程序。 http://www.devolution.com/pipermail/sdl/2003-January/051805.html

有一個關於混合QT的好文章直接與此 http://doc.trolltech.com/qq/qq26-openglcanvas.html有點超出你所需要的嚴格,而是聰明瞭OpenGL widgewts!

+0

OpenGL在這裏不是問題。我知道它與Qt很好地合作。問題主要在於線程。 – bineteri 2008-09-23 02:02:18

+0

我的錯誤我以爲SDL是物理引擎庫! – 2008-09-23 04:03:50

18

這是我在我的項目中做的簡化。您可以使用它就像一個普通的小部件,但你有需要,你可以用它m_Screen對象提請SDL的表面,它會在widget :)

#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; 
}; 

希望這有助於

顯示

注意:通常將此小部件的最小和最大大小都設置爲SDL表面大小是有意義的。

+0

窗口ID黑客工作在Mac?它似乎不適用於OSX。我已經嘗試putenv和SDL_putenv沒有任何運氣。 – 2012-06-26 17:54:51