OpenGL: QOpenGLWidget和QOpenGLFunctions_X_X_Core的使用 (五)

一、Windows上的OpenGL库
1、Windows平台,OpenGL库已经包含在Microsoft SDK里了。
2、OpenGL库64位版本的文件名仍然是OpenGL32.Lib,和32位版本一样。
3、Visual Studio项目属性的VC++目录已经配置好了SDK的包含目录、库目录和可执行文件目录,所以OpenGL库的目录就不需要我们配置了,我们只需在链接器的附加依赖项上添加OpenGL32.Lib即可。

4、Qt Creator的pro文件里,只要加入QT +=  openglwidgets opengl即可。


二、Qt中有QOpenGLWidget,不需要GLFW;有QOpenGLFunctions_X_X_Core,不需要GLAD。


三、QOpenGLWidget
1、QOpenGLWidget提供了三个便捷的虚函数,可以重写,用来重新实现典型的OpenGL任务。
      paintGL:渲染OpenGL场景。Widget需要更新时调用。
      resizeGL:设置OpenGL视口、投影等。Widget调整大小(或首次显示)时调用。
      initializeGL:设置OpenGL资源和状态。第一次调用resizeGL()/paintGL()之前调用一次。
2、如果需要从paintGL()以外的位置触发重新绘制(即重新调用paintGL(),典型示例是使用计时器设置场景动画),则应调用Widget的update()函数来安排更新。
3、调用paintGL()、resizeGL()或initializeGL()时,Widget的OpenGL呈现上下文将变为当前。
      如果需要从其它位置(例如,在Widget的构造函数或自己的绘制函数中)调用标准OpenGL API函数,则必须首先调用makeCurrent()。
 4、在paintGL()以外的地方调用绘制函数,没有意义,绘制图像最终将被paintGL()覆盖。


四、QOpenGLFunctions_X_X_Core
1、QOpenGLFunctions_X_X_Core提供OpenGLX.X版本核心模式的所有功能。

2、initializeOpenGLFunctions: 初始化和OpenGL API同名的所有函数指针,将这些函数指针指向显卡中真正的OpenGL函数。


五、视口
1、在渲染之前,我们必须告诉OpenGL渲染窗口的尺寸大小(像素),即视口(Viewport)。

2、这样OpenGL才能知道怎样根据视口大小显示数据和坐标,改变帧缓存大小和视口大小一一对应。

3、通过调用glViewport函数来设置视口的维度(Dimension)。

4、可以对窗口区域进行划分,在同一个窗口中显示分割屏幕的效果,以显示多个视图。

5、glViewport前两个参数定义视口矩形左下角的位置(单位像素),接着两个参数定义视口矩形的宽和高(单位像素)。

6、用户改变窗口的大小时,视口也应该被调整。


六、双缓冲(Double Buffer)
1、若应用程序使用单缓冲绘图时,可能会存在图像闪烁的问题。
      因为图像不是一下子被绘制出来的,而是按照从左到右、由上而下逐像素绘制而成,这会导致渲染的结果很不真实。
 2、应用双缓冲,前缓冲保存着最终输出的图像,它会在屏幕上显示。
      所有的渲染指令都会在后缓冲上绘制。
      当所有渲染指令执行完毕后,交换前缓冲和后缓冲,图像就立即呈显出来。


七、glClearColor()函数设置清空缓冲所用的颜色。


八、glClear()函数用于清空某个指定的缓冲。

       可能的缓冲位为GL_COLOR_BUFFER_BIT、GL_DEPTH_BUFFER_BIT、GL_STENCIL_BUFFER_BIT。

九、代码:

//MyOpenGLWidget.h

#pragma once

//需要的两个头文件
#include <QOpenGLWidget>
#include <QOpenGLFunctions_4_5_Core>


class MyOpenGLWidget: public QOpenGLWidget, QOpenGLFunctions_4_5_Core
{
	Q_OBJECT

public:
	explicit MyOpenGLWidget(QWidget * parent = nullptr);

protected:
	void initializeGL() override;
	void resizeGL(int w, int h) override;
	void paintGL() override;
};




//MyOpenGLWidget.cpp

#include "MyOpenGLWidget.h"


MyOpenGLWidget::MyOpenGLWidget(QWidget * parent) : QOpenGLWidget(parent)
{
}


void MyOpenGLWidget::initializeGL()
{
	//初始化所有指向真正OpenGL API的函数指针, 否则glXXX()会报错。
	initializeOpenGLFunctions();
}


void MyOpenGLWidget::resizeGL(int w, int h)
{
}


void MyOpenGLWidget::paintGL()
{
	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);
}




//HelloWindow.h

#pragma once

#include <QMainWindow>


namespace Ui { class HelloWindowClass; };


class HelloWindow : public QMainWindow
{
	Q_OBJECT

public:
	HelloWindow(QWidget * parent = nullptr);
	~HelloWindow();

private:
	Ui::HelloWindowClass * ui = nullptr;
};




//HelloWindow.cpp

#include "HelloWindow.h"
#include "ui_HelloWindow.h"


HelloWindow::HelloWindow(QWidget * parent) : QMainWindow(parent)
{
	ui = new Ui::HelloWindowClass();
	ui->setupUi(this);

	//用QOpenGLWidget替代掉中间一层Widget,不需要这个层级关系。
	setCentralWidget(ui->openGLWidget);
}


HelloWindow::~HelloWindow()
{
	delete ui;
}

HelloWindow.ui

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小马兰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值