Как я могу использовать Qt и SDL вместе? - PullRequest
26 голосов
/ 23 сентября 2008

Я создаю движок и редактор для симуляции физики в Windows. Я хочу собрать часть редактора, используя Qt, и я хочу запустить движок, используя SDL с OpenGL.

Моей первой идеей было построить редактор, используя только Qt, и поделиться с ним как можно большим количеством кода (менеджер ресурсов, средство визуализации, математика). Но я также хотел бы иметь возможность запустить симуляцию внутри редактора. Это означает, что я также должен поделиться кодом симуляции, который использует потоки SDL.

Итак, мой вопрос таков: есть ли способ сделать OpenGL рендеринга в окно Qt с помощью SDL?

Я прочитал в Интернете, что возможно предоставить SDL дескриптор окна для рендеринга. У кого-нибудь есть опыт с этим?

Кроме того, резьбовая часть симулятора может создавать проблемы, поскольку она использует потоки SDL.

Ответы [ 4 ]

21 голосов
/ 28 сентября 2008

Это упрощение того, что я делаю в своем проекте. Вы можете использовать его как обычный виджет, но по мере необходимости вы можете использовать его объект m_Screen для рисования на поверхности SDL, и он будет отображаться в виджете:)

#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.

14 голосов
/ 06 октября 2008

Хотя вы можете заставить его работать, как в первом ответе, вы можете столкнуться с проблемами из-за многопоточности. Нет простых решений, когда дело доходит до многопоточности, и здесь у вас есть взаимодействие между SDL Qt и OpenGL mainloop. Не весело.

Самое простое и разумное решение - разделить обе части. Так что SDL и Qt работают в разных процессах и используют для обмена сообщениями какой-то тип сообщений (я бы порекомендовал здесь d-bus). Вы можете сделать рендеринг SDL в окне без полей, и ваш редактор отправляет команды через сообщения.

3 голосов
/ 23 сентября 2008

Рендеринг на opengl из QT тривиален (и работает очень хорошо) Прямого опыта SDL нет, но здесь есть пример приложения по их смешиванию. http://www.devolution.com/pipermail/sdl/2003-January/051805.html

Здесь есть хорошая статья о смешивании виджетов QT напрямую с opengl. http://doc.trolltech.com/qq/qq26-openglcanvas.html немного сверх того, что вам строго нужно, но довольно умно!

1 голос
/ 13 мая 2011

вы можете использовать эту библиотеку (см. Демонстрационный каталог):

https://github.com/kronat/libqsdl

Хорошего дня

...