Рендеринг Pixeldata в текстуру OpenGL Quad

После нескольких дней попыток я не смог правильно отобразить Pixeldata в текстурированный квад.

То, что я хочу, довольно просто (я думаю): я сейчас пишу реализацию VNC для моей компании, чтобы связать ее с существующим приложением. Я уже успешно внедрил RfbProtocol (по крайней мере, насколько мне это нужно), и я могу получить правильные пиксельные данные. Поскольку сервер VNC отправляет только инкрементные изменения, я получаю небольшие прямоугольники с измененной областью и информацией о пикселях.

Я уже понял, что соответствующие форматы OpenGL для пиксельных данных - это GL_BGRA и GL_UNSIGNED_INT_8_8_8_8_REV.

Поскольку я не мог использовать текстурированные квадраты (что представляется оптимальной реализацией для этой цели), я использовал другой подход:

  if(m_queue.size() > 0)
  {
    if (!m_fbo || m_fbo->size() != size())
    {
      delete m_fbo;
      QOpenGLFramebufferObjectFormat format;
      format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
      m_fbo = new QOpenGLFramebufferObject(size());
    }

    m_fbo->bind();

    Q_FOREACH (RfbProtocol::RfbRectangle rect, m_queue.dequeue().rectangles())
    {
      glViewport(0, 0, 1920, 1080);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(0, 1920, 0, 1080, -1, 1);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      glRasterPos2d(rect.xpos, rect.ypos);
      glDrawPixels(rect.width,rect.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, rect.pixelData.data());
    }
    m_fbo->release();
    this->update();
  }

Все это делается внутри QOpenGLWidget.

Очевидно, что это не лучший подход, но он работает для тестирования. Проблема в том, что мне нужно масштабировать данные Pixeldata до размера виджета, который бы прекрасно работал вместе с OpenGLTexture, но, как я уже упоминал в начале, я просто не смог сделать это правильно.

1 ответ

Не использовать glDrawPixels, Он старый и медленный и был удален из современного OpenGL.

Просто используйте glTexSubImage2D обновить под прямоугольники текстуры, содержащей содержимое экрана.

РЕДАКТИРОВАТЬ:

GLuint create_texture(unsigned width, unsigned height)
{
    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);

    /* initialize texture to nil */
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
        width, height, 0,
        GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);

    /* disable mipmapping */
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    return tex;
}

void update_texture(GLuint tex, RECT r, RGBA *pixels)
{
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexSubImage2D(GL_TEXTURE_2D, 0,
        r.left, r.bottom,
        r.right-r.left, r.top-r.bottom,
        GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,
        pixels );
}

Полагаю, вы можете сами определить определения RECT и RGBA.

Затем просто нарисуйте видовой экран, заполняющий текстурированный квад, и все готово. Текстурированные квадраты дают вам хорошее масштабирование бесплатно.

Другие вопросы по тегам