将 OpenGL 绘制到离屏位图

Posted

技术标签:

【中文标题】将 OpenGL 绘制到离屏位图【英文标题】:Draw OpenGL to an offscreen bitmap 【发布时间】:2016-07-08 12:14:07 【问题描述】:

我继承了一个使用 OpenGL 将 3D 场景直接渲染到窗口的项目。代码工作正常,但我们现在在 3D 视图上绘制一个图标以“退出 3D 视图模式”。这也可以正常工作,但会在视图快速旋转时导致大量闪烁。

我希望能够绘制到屏幕外位图(即没有 HWND),然后将我的图标绘制到位图,最后使用双缓冲将位图 StretchBlt 绘制到窗口。我们在其他情况下执行此操作(例如放大不需要 OpenGL 的图像)并且效果很好。我的问题是我是 OpenGL 新手,所有尝试从屏幕外位图的 DC 开始并从该 DC 创建 HWND 都失败了,通常是因为为 DC 选择了像素格式。

在 *** (eg. this question without an accepted answer) 上有几个问题在问类似的问题。这可能吗?如果是,是否有描述该过程的相对简单的教程?如果该过程非常复杂,需要详细的 OpenGL 知识,那么我可能只是不得不离开它并忍受闪烁,因为它是我们软件中很少使用的模式。

【问题讨论】:

【参考方案1】:

只需使用带纹理的四边形使用 OpenGL 绘制图标。

所有这些绘制到 DC StretchBlt 的位图副本涉及到图形内存的多次往返(浪费带宽),并且 StretchBlt 可能不会被 GPU 加速。总而言之,您想做的事情效率低下,甚至可能会降低质量。

我认为您将图标作为资源存储在可执行文件中。最简单的方法是创建一个带有 DIBSECTION (CreateDIBSection) 的内存 DC (CreateCompatibleDC),在上面绘制图标并将 DIBSECTION 数据加载到 OpenGL 纹理中。然后绘制图标使用glViewport在窗口坐标中选择目标矩形,使用恒等变换绘制覆盖整个视口的矩形(位置值(-1,1)→(1,1),纹理坐标值( 0,0)→(1,1) 给你正确的结果)。

重要的侧面修复:如果您的程序在窗口调整大小处理程序中设置视口和固定功能管道 GL_PROJECTION 矩阵等愚蠢的事情,您应该清理该反模式并将其移动到它所属的位置:在绘图代码中。

【讨论】:

以上是关于将 OpenGL 绘制到离屏位图的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 中的离屏帧缓冲区

使用 OpenGL ES 1.0 在 Android 上进行离屏渲染的选项?

c++:如何使用 sdl 将位图加载到 opengl 中的多维数据集中?

如何在 C++ 中将位图绘制为 OpenGL 纹理?

我的OpenGL学习进阶之旅解决使用Assimp和OpenGL进行在屏渲染和离屏渲染FBO时绘制3D模型出现各种诡异的模型渲染画面问题,都是血和泪的教训啊!!!

用OpenGL绘制位图字体,glRasterPos2i()是做啥的?