OpenGL: DOUBLE_BUFFER

本文深入探讨了OpenGL中的DOUBLE_BUFFER技术,通过分析代码展示了glutInitDisplayMode()如何启用双缓冲。内容包括glFlush()在双缓冲中的行为、全屏与窗口之间的数据流动,以及GL_BACK和GL_FRONT的角色。文章提出了四个关键推测,解释了缓冲区的工作原理。

PART ONE

078d4b7521ad4fbaac3cf63297e45a6e.png

14bf54b41243416a827234396e3f4d38.png

149ee05ba028428ba91051d0716fb02e.png

31db85ae19644eb9854bc54d88ea7c9a.png codes.cpp

 

#include <iostream>
#include <GL/freeglut.h>
using namespace std;

void grab(GLint w, GLint h)
{
	GLubyte* image;
	GLint dataLength = w * 4 * h; //四通道
	image = (GLubyte*)malloc(dataLength);// 分配CPU内存
	if (image == 0) {
		exit(0);
	}
	else {
		//将GPU缓存数据四通道解包存到CPU内存
		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
		glReadPixels(0, 0, w, h, GL_BGR_EXT, GL_UNSIGNED_BYTE, image);
	}
在使用 OpenSceneGraph 3.6.3 和 Qt 5.12 的环境下,正确实现 `setupOsgWidget` 函数以将 OSG 渲染窗口嵌入到 Qt 界面中,需要结合 Qt 的 QWidget 框架和 OSG 的图形渲染机制。以下是一个完整的实现方法: ### 实现步骤 #### 1. 创建自定义 OSG Widget 类 首先,创建一个继承自 `QWidget` 的类,并重写必要的事件处理函数,例如 `paintEvent`、`resizeEvent` 等。 ```cpp #include <osgQt/GraphicsWindowQt> #include <osgViewer/Viewer> #include <osgGA/TrackballManipulator> class OsgWidget : public QWidget { Q_OBJECT public: OsgWidget(QWidget* parent = nullptr); ~OsgWidget(); void setupOsgWidget(); osgViewer::Viewer* getViewer() { return _viewer.get(); } protected: void paintEvent(QPaintEvent*) override; void resizeEvent(QResizeEvent*) override; private: osg::Geode* createSampleGeometry(); osg::Group* _root; osg::Camera* _camera; osgViewer::ViewerRefPtr _viewer; osgQt::GLWidget* _glWidget; }; ``` #### 2. 实现 `setupOsgWidget` 函数 该函数负责初始化 OSG 的 Viewer 和 GLWidget,并将其嵌入到 Qt 的布局中。 ```cpp void OsgWidget::setupOsgWidget() { // 创建 OSG 根节点 _root = new osg::Group(); // 添加示例几何体 osg::Geode* geode = createSampleGeometry(); _root->addChild(geode); // 创建 OSG Viewer _viewer = new osgViewer::Viewer(); _viewer->setSceneData(_root); // 设置相机参数 _camera = _viewer->getCamera(); _camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); // 创建 OpenGL Widget 并设置为 Viewer 的图形窗口 _glWidget = new osgQt::GLWidget(this); _viewer->setUpViewerAsEmbeddedInWindow(0, 0, width(), height()); _viewer->getCamera()->setGraphicsContext(_glWidget->getGraphicsWindow()); // 设置主窗口操作器(如 Trackball) _viewer->setCameraManipulator(new osgGA::TrackballManipulator()); // 将 GLWidget 添加到当前 widget 的布局中 QVBoxLayout* layout = new QVBoxLayout(this); layout->addWidget(_glWidget); setLayout(layout); } ``` #### 3. 示例几何体创建函数 用于测试显示的简单几何体,如立方体。 ```cpp osg::Geode* OsgWidget::createSampleGeometry() { osg::Geode* geode = new osg::Geode(); geode->addDrawable(osg::createTexturedBoxGeometry(osg::Vec3(), osg::Vec3(1, 0, 0), osg::Vec3(0, 1, 0))); return geode; } ``` #### 4. 重写绘图与调整大小事件 确保每次窗口尺寸变化时更新 OSG 的视口。 ```cpp void OsgWidget::paintEvent(QPaintEvent*) { if (_viewer.valid()) { _viewer->frame(); } } void OsgWidget::resizeEvent(QResizeEvent* event) { if (_viewer.valid()) { _viewer->getCamera()->setViewport(0, 0, width(), height()); _viewer->getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(width()) / static_cast<double>(height()), 1.0f, 10000.0f); } QWidget::resizeEvent(event); } ``` ### 使用说明 - 在 Qt Designer 中创建 UI 文件后,将 `OsgWidget` 类作为提升部件(Promoted Widget)添加到界面中。 - 调用 `setupOsgWidget()` 方法完成初始化,即可在 Qt 界面中看到 OSG 渲染的三维场景。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值