将像素数据渲染到 OpenGL 纹理四边形中
Render Pixeldata into OpenGL Texture quad
经过几天的尝试,我无法将像素数据正确渲染到带纹理的四边形中。
我想要的很简单(我认为):我目前正在为我的公司编写一个 VNC 实现,以将其绑定到现有应用程序中。我已经成功实施了 RfbProtocol(至少在我需要的范围内)并且我能够获得正确的像素数据。因为 VNC 服务器只发送增量更改,所以我收到了带有更改区域和像素信息的小矩形。
我已经算出Pixeldata对应的OpenGL格式是GL_BGRA和GL_UNSIGNED_INT_8_8_8_8_REV。
因为我无法使用 Textured Quads(什么似乎是为此目的的最佳实现)我使用了不同的方法:
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 缩放到 Widget 的大小,这将与 OpenGLTexture 一起很好地工作,但正如我在开始时提到的,我根本无法正确地做到这一点。
不要使用 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 的定义。
然后只需绘制视口填充纹理四边形即可。带纹理的四边形免费为您提供漂亮的缩放比例。
经过几天的尝试,我无法将像素数据正确渲染到带纹理的四边形中。
我想要的很简单(我认为):我目前正在为我的公司编写一个 VNC 实现,以将其绑定到现有应用程序中。我已经成功实施了 RfbProtocol(至少在我需要的范围内)并且我能够获得正确的像素数据。因为 VNC 服务器只发送增量更改,所以我收到了带有更改区域和像素信息的小矩形。
我已经算出Pixeldata对应的OpenGL格式是GL_BGRA和GL_UNSIGNED_INT_8_8_8_8_REV。
因为我无法使用 Textured Quads(什么似乎是为此目的的最佳实现)我使用了不同的方法:
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 缩放到 Widget 的大小,这将与 OpenGLTexture 一起很好地工作,但正如我在开始时提到的,我根本无法正确地做到这一点。
不要使用 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 的定义。
然后只需绘制视口填充纹理四边形即可。带纹理的四边形免费为您提供漂亮的缩放比例。