LINUX.ORG.RU

Планируется ли QVulkanPaintDevice?

 , , ,


0

2

По аналогии с QOpenGLPaintDevice.

Чтобы скормить ему в конструктор VkDevice, VkFramebuffer, VkCommandBuffer и рисовать QPainter-ом спокойно. А потом просто отправить этот командный буфер на счёт и изображение бы в VkImage отрендерилось. А внутри САБЖ бы сам менеджил необходимые ему буферы, текстуры, шейдеры, и т.д.

А может и вовсе система QPainter-ов устарела? Если так, то какой современный API agnostic способ рисовать в Qt двумерное что-то?

★★★★★

У тебя задача какая-то есть или так «Вулкан ради Вулкана»?

Избранные теги: vulkan

А, так ты из этих, как их там… Из секты «Святого Вулкана»? «Ударим Вулканом по производительности»?

API agnostic

Vulkan

vulkan_facepalm_layer.json

Если так, то какой современный API agnostic способ рисовать в Qt двумерное что-то?

<LINUX-ORG-RU>

u32 pixels[800*600];

</LINUX-ORG-RU>

anonymous
()

LMGTFY

Image The QImage class provides a hardware-independent image representation which is designed and optimized for I/O, and for direct pixel access and manipulation. QImage supports several image formats including monochrome, 8-bit, 32-bit and alpha-blended images. One advantage of using QImage as a paint device is that it is possible to guarantee the pixel exactness of any drawing operation in a platform-independent way. Another benefit is that the painting can be performed in another thread than the current GUI thread.

Если объектов много, есть ещё QGraphicsScene.

anonymous-angler ★☆
()
Последнее исправление: anonymous-angler (всего исправлений: 1)

QPainter

Тормоз. Хотел рендерить им текст в своём opengl софте. Даёт заметную просадку. Пришлось накостылять свой рендер текста c SDF (Signed Distance Field) шрифтом.

ox55ff ★★★★★
()
Ответ на: комментарий от anonymous-angler

Использовать QImage в качестве PaintDevice – сильно такоое. Он не аппаратно ускорен, т.е. рисовать в него можно только CPU-шкой.

QGraphicsScene

Т.е. только таща зависимость от Qt Widgets?

robus ★★★★★
() автор топика
Ответ на: комментарий от ox55ff

Тормоз. Хотел рендерить им текст в своём opengl софте. Даёт заметную просадку

Через QOpenGLPaintDevice?

robus ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Ещё не привык что ЛОР это перманентный тупняк?

anonymous
()
Ответ на: комментарий от anonymous

А, так ты из этих, как их там… Из секты «Святого Вулкана»? «Ударим Вулканом по производительности»?

«Зачем же сразу предполагать плохое, может, он просто умер».

Вулкан продвигают как технологию будущего, которая должна заменить openGL. У человека, поверившего в этот тезис, возникает естественное желание сразу писать на технологии будущего, а не на легаси. Вот он и спрашивает, поддерживает ли это кутя.

Так что про секту Святого Вулкана ты, может, и прав, но это не к топикстартеру, а к The Khronos Group Inc :) Если ты хочешь сказать, что Вулкан в обозримое время не победит — раскрой этот тезис.

hobbit ★★★★★
()
Ответ на: комментарий от robus

У меня был наследник QOpenglWindow. В методе paintGL делал QPainter p(this); и рисовал текст. В форму это окно (QOpenglWindow) вставлял через QWidget::createWindowContainer.

Окно, а не виджет использовал т.к. QOpenglWidget показывал худшую производительность. Читал, что если использовать QOpenGlWidget, то Qt начинает сначала рендерить в фреймбуфер, делать композицию, а только потом выводить на экран.

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

Не верю в тормоза QPainter при отрисовке текста на правильный paint device.

Пишу микробенчмарк – рендеринг строк вида «Line #00000» до «Line #09999».

#include <QGuiApplication>
#include <QOpenGLPaintDevice>
#include <QOpenGLWindow>
#include <QPainter>

class BenchWindow: public QOpenGLWindow
{
  std::unique_ptr<QOpenGLPaintDevice> dev;
  const QFont fnt;
  int charWidth;
  int charHeight;
  const bool useQOpenGLPaintDevice;

  QPaintDevice* getPD()
  {
    if(useQOpenGLPaintDevice)
      return dev.get();
    else
      return this;
  }

public:
  BenchWindow(bool useQOpenGLPaintDevice):
    fnt {([] {
      QFont result;
      result.setFamily("Monospace");
      result.setPixelSize(16);
      result.setItalic(true);
      return result;
    })()},

    charWidth(-1),
    charHeight(-1),

    useQOpenGLPaintDevice(useQOpenGLPaintDevice)
  {
    QSurfaceFormat fmt(format());
    fmt.setDepthBufferSize(0);
    fmt.setMajorVersion(4);
    fmt.setMinorVersion(6);
    fmt.setProfile(QSurfaceFormat::CoreProfile);
    fmt.setSwapInterval(0);
    setSurfaceType(QWindow::OpenGLSurface);
    setFormat(fmt);
  }

  // QOpenGLWindow interface
protected:
  void initializeGL() override
  {
    glClearColor(0,0,0,0);
    glDisable(GL_DEPTH_TEST);
    if(useQOpenGLPaintDevice)
      dev = std::make_unique<QOpenGLPaintDevice>(size());
  }

  void resizeGL(int w, int h) override
  {
    if(dev)
      dev->setSize(QSize(w,h));
  }

  void paintGL() override
  {
    const static std::array<QString, 10000> lines = ([] {
        std::array<QString, 10000> result;
        for(size_t i = 0; i < result.size(); ++i)
          result[i] = QStringLiteral("Line #%1").arg(i, 5, 10, QChar('0'));
        return result;
      })();

    if(charWidth == -1)
      {
        QFontMetrics fontMetrics(fnt, getPD());
        charWidth = fontMetrics.horizontalAdvance(QChar('0')) * QStringLiteral("Line #10000  ").size();
        charHeight = fontMetrics.height();
      }

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    QPainter p(getPD());
    p.setPen(Qt::yellow);
    p.setFont(fnt);

    const int linesN = height() / charHeight;
    const float _linesN = 1.0 / linesN;
    for(size_t i = 0; i < lines.size(); ++i)
      {
        float col = charWidth * std::floor(_linesN * i);
        float row = charHeight * (i%linesN);

        p.drawText(col, row, lines[i]);
      }
    p.end();
    requestUpdate();
  }
};


int main(int argc, char *argv[])
{
  QGuiApplication app(argc, argv);

  BenchWindow wnd(true);
  wnd.showMaximized();

  return app.exec();
}

Гоняю – получаю лютый CPU-bound и меньше 20 fps.

А если вызов QPainter::drawText будет 1?

void paintGL() override
  {
    static const QString str(640000, '0');

    if(charHeight == -1)
      {
        QFontMetrics fontMetrics(fnt, getPD());
        charHeight = fontMetrics.height();
      }

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    QPainter p(getPD());
    p.setPen(Qt::yellow);
    p.setFont(fnt);
    p.drawText(0, charHeight, str);
    p.end();
    requestUpdate();
  }

Поигравшись с размером str, видим, что сложность drawText для хоста линейна относительно размера строки-аргумента. ПЦ ящитаю. И правда тормоз :(

Значит придётся для своего движка поддержку 2д (а она там быть обязана – менюшки и внутриигровые гуи никто не отменял) пилить самостоятельно.

robus ★★★★★
() автор топика
Ответ на: комментарий от robus

У меня текст редко менялся. Я уже потом подумал, что можно было запечь в текстуру и рендерить. А когда нужно изменить, то дёргать QPainter. Всё-таки он фичастый и сильно облегчает работу. Не знаю насколько удачен такой подход в реальности.

ox55ff ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.