OpenSceneGraph и несколько средств просмотра

Я использую OpenSceneGraph и Qt для разработки программного обеспечения для моделирования. Симуляции могут включать несколько ботов в один и тот же виртуальный мир. Мои требования к представлениям следующие:

  • Возможность показывать статичные камеры мира
  • Возможность показывать камеры ботов
  • Возможность перемещать эти виды и/или складывать их

Для выполнения этих задач я создал «OSGWidget», который использует Osg Viewer для рендеринга сцены внутри QGLWidget. Этот OSGWidget, в свою очередь, помещается внутрь QDockWidget, который можно перемещать и/или складывать, выполняя это требование.

Проблема в том, что при использовании нескольких отдельных средств просмотра для рендеринга одной и той же сцены в разных виджетах я получаю странное поведение рендеринга. А именно, текстуры отображаются некорректно, а иногда и вовсе.

Я просмотрел форумы SO и OSG, и, хотя у людей были похожие проблемы, единственные ответы, которые я видел, предлагали перейти на Osg CompositeViewer. Для моих целей я хотел бы избежать использования этого, поскольку это нарушает мое желаемое требование к подвижным и штабелируемым виджетам, отображающим одну и ту же сцену.

Является ли это неразрешимой ситуацией, с которой Osg не может легко справиться? Я видел несколько сообщений, в которых говорится, что OSG «не должна работать», но они не предоставили фактов, подтверждающих это утверждение. Кто-нибудь делал что-то подобное или есть какие-либо идеи/понимание? Я могу предоставить фрагменты кода, если это необходимо, но, поскольку это может просто противоречить идеологии Osg, я подожду, чтобы получить некоторые ответы.


person kelano    schedule 04.03.2013    source источник
comment
Можете ли вы объяснить немного лучше, почему CompositeViewer не работает? Я не понимаю, почему вы не можете сделать с ним подвижные и прикрепляемые виджеты.   -  person Nathan Monteleone    schedule 04.03.2013
comment
Если я не ошибаюсь, CompositeViewer отображает разные представления в виде разделенных панелей, а не таким образом, чтобы их можно было разделить на отдельные окна. Разве это не обязательно так?   -  person kelano    schedule 04.03.2013
comment
Нет, это не так. Вы можете настроить представления в разных окнах.   -  person Nathan Monteleone    schedule 04.03.2013
comment
Интересно, не думал, что это возможно .. Я попробую и сообщу о своих выводах, спасибо!   -  person kelano    schedule 05.03.2013
comment
Итак, @kelano, что ты нашел? :)   -  person Adri C.S.    schedule 21.03.2013


Ответы (1)


Благодаря некоторой помощи комментариев и нескольких других сайтов, я смог успешно добиться от CompositeViewer нужного мне поведения.

По сути, все представления OSG проходят через мой «WidgetDriver», который содержит CompositeViewer.

class OsgWidgetDriver {
public:
    void init() {
        compositeViewer = new osgViewer::CompositeViewer;
        compositeViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
        compositeViewer->setReleaseContextAtEndOfFrameHint(false);
    }

    void start() {
        initialized = true;
    }

    void stop() {
        compositeViewer->stopThreading();
        compositeViewer->setDone(true);
    }

    void updateFrame() {
        if (initialized)
            compositeViewer->frame();
    }

    void addView(osgViewer::View *view) { compositeViewer->addView(view); }
    bool isInitialized() { return initialized; }
protected:
    bool initialized;
    osgViewer::CompositeViewer *compositeViewer;
};

Затем, всякий раз, когда я создаю новый виджет Qt OSG, я передаю osg::View драйверу. Я позволяю драйверу обновлять окно рендеринга, в то время как Qt все еще может соответствующим образом обновлять QWidget. Это даже позволяет мне размещать виджет в QDockWidget, чтобы я мог перемещать их и складывать по мере необходимости.

Несколько заключительных заметок о процессе, если кто-то еще хочет это сделать:

  • Скорее всего, вы столкнетесь со странными проблемами отображения текстур, когда несколько OSG Viewers просматривают одну сцену. В этом случае используйте osgUtil::Optimizer::TextureVisitor, чтобы установить для всех текстур значение «UnrefImageAfterApply = false». Это позволит корректно отображать текстуры в нескольких экземплярах osg::View.
  • Параметры CompositeViewer, которые я установил выше, для модели потоковой передачи — SingleThreaded, а для releaseContextAtEndOfFrame — false, необходимы, если вы хотите, чтобы один поток воздействовал на несколько представлений. Если вы используете драйвер виджета, как я, вам нужно будет это сделать.
person kelano    schedule 12.04.2013