简体   繁体   English

将Pixeldata渲染为OpenGL Texture Quad

[英]Render Pixeldata into OpenGL Texture quad

After days of trying I was not able to render Pixeldata into a textured quad correctly. 经过数天的尝试,我无法正确将Pixeldata渲染到纹理四边形。

What I want is fairly simple (I think): I am currently writing a VNC implementation for my company to bind it into an existing application. 我想要的非常简单(我认为):我目前正在为公司编写VNC实现,以将其绑定到现有应用程序中。 I already successfully implemented the RfbProtocol (at least as far as I need it) and I am able to get the correct Pixeldata. 我已经成功实现了RfbProtocol(至少在我需要的时候),并且能够获得正确的Pixeldata。 Because the VNC server is sending incremental changes only I am receiving small rectangles with the changed region and the pixel information. 因为VNC服务器仅发送增量更改,所以我收到的小矩形具有更改的区域和像素信息。

I already worked out that the corresponding OpenGL Formats for the Pixeldata is GL_BGRA and GL_UNSIGNED_INT_8_8_8_8_REV . 我已经计算出Pixeldata的相应OpenGL格式为GL_BGRAGL_UNSIGNED_INT_8_8_8_8_REV

Because I was not able to use Textured Quads (whats seems to be the optimal implementation for this purpose) I used a different approach: 因为我无法使用带纹理的四边形(这似乎是实现此目的的最佳实现),所以我使用了另一种方法:

  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();
  }

This is all done inside an QOpenGLWidget. 这些都是在QOpenGLWidget中完成的。

Obviously this is not the best approach but it is working for testing. 显然,这不是最好的方法,但是它正在测试中。 The problem is that I need to scale the Pixeldata to the size of the Widget, which would work nicely together with a OpenGLTexture but as I mentioned at the beginning I simply wasn't able to do it correctly. 问题是我需要将Pixeldata缩放到Widget的大小,这可以与OpenGLTexture很好地配合使用,但是正如我在一开始提到的那样,我只是无法正确地做到这一点。

Don't use glDrawPixels . 不要使用glDrawPixels It's old and slow and has been removed from modern OpenGL. 它又旧又慢,已从现代OpenGL中删除。

Just use glTexSubImage2D to update the subrectangles of the texture holding the screen content. 只需使用glTexSubImage2D即可更新保存屏幕内容的纹理的子矩形。

EDIT : 编辑

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 );
}

I guess you can tink the definitions for RECT and RGBA yourself. 我想您可以自己修改RECT和RGBA的定义。

Then just draw a viewport filling textured quad and you're done. 然后只需绘制一个填充纹理四边形的视口即可。 Textured quads give you nice scaling for free. 带纹理的四边形可为您免费提供漂亮的缩放比例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM