文章目录

一、效果展示

OPenGL笔记--创建一个OPenGL窗口_OPenGL


二、详细代码

工程文件

QT       += core gui opengl

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler).
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
gl_test.cpp \
main.cpp \
mainwindow.cpp

HEADERS += \
gl_test.h \
mainwindow.h

FORMS += \
mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

LIBS += -lopengl32 -lglu32
LIBS += -LC:\glut

-------------------------------------------------------------------------------------------------------------------------------------------------------------------
注意:因为Qt没有自带glut库,所以添加glut库会显示找不到,解决办法:​​​Qt配置glut库(Windows)​-------------------------------------------------------------------------------------------------------------------------------------------------------------------

gl_test.h

#ifndef GL_TEST_H
#define GL_TEST_H

#include <qgl.h> //因为QGLWidget类被包含在qgl.h头文件中
#include <glut.h> //使用glut库中的API
#include <QKeyEvent>

//继承QGLWidget得到OPenGL窗口部件类
class GL_Test : public QGLWidget
{
public:
GL_Test(QWidget* parent = 0, bool fs = false);
~GL_Test();

protected:
/*************************************************************************************************
QGLWidget 类已经内置了对 OpenGL 的处理,就是通过对 initializeGL()、 paintGL()和 resizeGL()这三个函数实现
*************************************************************************************************/
void initializeGL() override; //用来初始化OPenGL窗口,可以在里面设定一些有关选项
void paintGL() override; //用来绘制OPenGL的窗口,只要有更新发生,这个函数就会被调用
void resizeGL(int w, int h) override; //用来处理窗口大小变换这一事件,resizeGL()在处理完后会自动刷新屏幕

void keyPressEvent(QKeyEvent* e) override; //Qt键盘事件处理函数

protected:
bool fullscreen; //用来保存窗口是否处于全屏状态的变量
};

#endif // GL_TEST_H

gl_test.cpp

#include "gl_test.h"

GL_Test::GL_Test(QWidget* parent, bool fs)
: QGLWidget(parent)
{
fullscreen = fs;

setGeometry(500,500,640,480); //设置窗口大小、位置

setWindowTitle("The first OpenGL Window"); //设置窗口标题

if(fullscreen) {
showFullScreen();
}
}

GL_Test::~GL_Test()
{

}

void GL_Test::initializeGL()
{
glShadeModel(GL_SMOOTH); //启用smooth shading(阴影平滑)

glClearColor(0.0, 0.0, 0.0, 0.0); //清除屏幕时所用的颜色,rgba【0.0(最黑)~1.0(最亮)】

glClearDepth(1.0); //设置深度缓存

glEnable(GL_DEPTH_TEST); //启动深度测试

glDepthFunc(GL_LEQUAL); //所作深度测试的类型

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //真正精细的透视修正,告诉OPenGL我们希望进行最好的透视修正,这会十分轻微的影响性能,但使得透视图看起来好一点
}

void GL_Test::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存

glLoadIdentity(); //重置当前的模型观察矩阵
}

void GL_Test::resizeGL(int w, int h)
{
if(h == 0) { //防止h为0
h = 1;
}

glViewport(0, 0, (GLint)w, (GLint)h); //重置当前的视口(Viewport)

glMatrixMode(GL_PROJECTION); //选择投影矩阵

glLoadIdentity(); //重置投影矩阵

gluPerspective( 45.0, (GLfloat)w/(GLfloat)h, 0.1, 100.0 ); //建立透视投影矩阵

glMatrixMode(GL_MODELVIEW); //选择模型观察矩阵

glLoadIdentity(); //重置模型观察矩阵
}

void GL_Test::keyPressEvent(QKeyEvent* e)
{
switch (e->key()) {
case Qt::Key_Q: {
fullscreen = !fullscreen;
if(fullscreen) {
showFullScreen();
}else {
showNormal();
setGeometry(500,500,640,480);
}
updateGL();
break;
}//case Qt::Key_Q

case Qt::Key_Escape: {
close();
}//Qt::Key_Escape

}//switch (e->key())
}