Nano Hash - криптовалюты, майнинг, программирование

Рендеринг QImage на QGLWidget плагина QML

Я пытаюсь написать плагин QML, который считывает кадры из видео (используя для этой задачи специальный виджет, а НЕ QtMultimedia/Phonon), и каждый кадр преобразуется в QImage RGB888, а затем отображается на QGLWidget (по соображениям производительности). Прямо сейчас ничего не рисуется на экране, и экран все время остается белым.

Важно отметить, что все это уже работает без QGLWidget, поэтому я знаю, что проблема заключается в настройке и отрисовке QGLWidget.

Плагин регистрируется с помощью:

qmlRegisterType<Video>(uri,1,0,"Video");

поэтому Video является основным классом плагина. В его конструкторе у нас есть:

Video::Video(QDeclarativeItem* parent)
: QDeclarativeItem(parent), d_ptr(new VideoPrivate(this))
{    
    setFlag(QGraphicsItem::ItemHasNoContents, false);            

    Q_D(Video);
    QDeclarativeView* view = new QDeclarativeView;
    view->setViewport(&d->canvas()); // canvas() returns a reference to my custom OpenGL Widget
}

Прежде чем я перейду к объекту canvas, позвольте мне сказать, что я перегрузил Video::paint(), поэтому он вызывает canvas.paint() при передаче QImage в качестве параметра, я не знаю, правильный ли это способ сделать это, поэтому мне нужен совет по этому поводу:

void Video::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    Q_UNUSED(painter);
    Q_UNUSED(widget);
    Q_UNUSED(option);

    Q_D(Video);
    // I know for sure at this point "d->image()" is valid, but I'm hiding the code for clarity
    d->canvas().paint(painter, option, d->image());
}

Объект canvas объявляется как GLWidget canvas;, а заголовок этого класса определяется как:

class GLWidget : public QGLWidget
{
    Q_OBJECT
public:        
    explicit GLWidget(QWidget* parent = NULL);
    ~GLWidget();

    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QImage* image);
};

Кажется довольно простым. Теперь реализация QGLWidget выглядит следующим образом:

GLWidget::GLWidget(QWidget* parent)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
   // Should I do something here?
   // Maybe setAutoFillBackground(false); ???
}

GLWidget::~GLWidget()
{
}

И наконец:

void GLWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QImage* image)
{
   // I ignore painter because it comes from Video, so I create a new one:
   QPainter gl_painter(this);


   // Perform drawing as Qt::KeepAspectRatio

   gl_painter.fillRect(QRectF(QPoint(0, 0), QSize(this->width(), this->height())), Qt::black);

   QImage scaled_img = image->scaled(QSize(this->width(), this->height()), _ar, Qt::FastTransformation);

   gl_painter.drawImage(qRound(this->width()/2)  - qRound(scaled_img.size().width()/2),
                        qRound(this->height()/2) - qRound(scaled_img.size().height()/2),
                        scaled_img); 
}

Что мне не хватает?

Сначала я задал этот вопрос на форуме Qt, но не получил ответа.

09.12.2011

Ответы:


1

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

Этот код оказался очень полезным< /strong> чтобы понять, как это сделать.

Кстати, я обнаружил, что материал рисуется внутри view. Просто мне нужно было выполнить view->show(), но это создало другое окно, которое я не искал. Ссылка, которой я поделился выше, содержит ответ.

13.12.2011
  • У вас еще есть исходник? В настоящее время я сталкиваюсь с аналогичной проблемой, и ссылка ведет на 404. 29.12.2011
  • Я постараюсь вставить это здесь, когда я могу. 29.12.2011
  • Вот это 29.12.2011
  • Мертвая ссылка. Тоже новый то есть. 16.11.2020
  • Этой теме почти 9 лет. Репозиторий, в котором исходный код был первоначально опубликован, УМЕР и давно исчез. Это последний раз, когда я отслеживаю аналогичный исходный код в Интернете для справки. Вот оно. Удачи с этого момента. 16.11.2020

  • 2

    Я думаю, что вы должны рисовать на своем glwidget, используя функции opengl.

    Один из возможных способов — переопределить метод paintGL() в GLWidget, а затем нарисовать изображение с помощью glDrawPixels().

    glClear(GL_COLOR_BUFFER_BIT);
    glDrawPixels(buffer.width(), buffer.height(), GL_RGBA, GL_UNSIGNED_BYTE, buffer.bits());
    

    Где буфер — это объект QImage, который необходимо преобразовать с помощью статического метода QGLWidget::converrtToGLFormat().

    Посмотрите этот источник для справки: https://github.com/nayyden/ZVector/blob/master/src/GLDebugBufferWidget.cpp

    09.12.2011
  • По какой-то причине GLWidget::paintGL() не вызывается, даже если я перейду на Video::paint(), чтобы он выполнил d->canvas().update(); d->canvas().repaint(); 09.12.2011
  • Одно глупое предложение, которое я мог бы дать, — это добавить новый публичный метод в ваш GLWidget и в этом методе вызвать paintGL() и updateGL(), но тогда вам нужно будет ввести тип canvas, когда вы захотите его вызвать. 09.12.2011
  • Я действительно не хочу использовать вызовы OpenGL напрямую, поэтому я не перегружаю методы GL, такие как paintGL(). 09.12.2011
  • Если вы все еще заинтересованы, эта проблема была решена. Вы можете проверить мой ответ, если хотите. 13.12.2011
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..


    © 2024 nano-hash.ru, Nano Hash - криптовалюты, майнинг, программирование