NeHe 系列教程之一: 创建一个OpenGL 窗口
英文教程地址: lesson01
在Qt的实现中, 我们主要依赖QGLWidget类, 我们主要重载三个重要方法 :
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
下面给出实现代码,本课代码框架也是后续课程代码的基础,一些通用代码仅在此课中展示。
首先,声明创建OpenGL窗口类,它继承于QGLWidget, 代码如下:
#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H
#include <QGLWidget>
class QTimer;
class QKeyEvent;
class MyGLWidget : public QGLWidget
{
Q_OBJECT
public:
explicit MyGLWidget(QWidget *parent = 0);
protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
void keyPressEvent(QKeyEvent *);
void closeEvent(QCloseEvent *);
private:
QTimer *timer;
bool fullscreen; //窗口是否全屏显示
};
#endif // MYGLWIDGET_H
该类主要声明了三个重载方法,并重载了按键和关闭窗口事件响应方法。
窗口类的实现代码如下:
#include "myglwidget.h"
#include <QTimer>
#include <QKeyEvent>
#include <QMessageBox>
#include <QApplication>
#include <QDebug>
MyGLWidget::MyGLWidget(QWidget *parent) :
QGLWidget(parent), fullscreen(false)
{
setWindowTitle(tr("nehe----lesson01"));
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateGL())); //不停刷新窗口
timer->start(10);
}
void MyGLWidget::initializeGL()
{
glShadeModel(GL_SMOOTH); // Enables Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
}
void MyGLWidget::resizeGL(int width, int height)
{
if (height==0) { // Prevent A Divide By Zero By
height=1; // Making Height Equal One
}
glViewport(0, 0, width, height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
void MyGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
qDebug("NeHe--Lesson1");
}
void MyGLWidget::keyPressEvent(QKeyEvent *e)
{
switch (e->key()) {
case Qt::Key_F: //F 键进行全屏切换
fullscreen = !fullscreen;
if (fullscreen) {
showFullScreen();
} else {
resize(640, 480);
showNormal();
}
break;
case Qt::Key_Escape: //退出确认
QMessageBox::StandardButton reply;
reply = QMessageBox::question(NULL, "NeHe",
"Do you want to exit?",
QMessageBox::Yes | QMessageBox::No,
QMessageBox::Yes);
if (reply == QMessageBox::Yes) {
qApp->quit();
}
break;
default:
QGLWidget::keyPressEvent(e);
break;
}
}
//点击窗口关闭按键时确认退出
void MyGLWidget::closeEvent(QCloseEvent *e)
{
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "NeHe",
"Do you want to exit?",
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No);
if (reply == QMessageBox::Yes) {
e->accept();
} else {
e->ignore();
}
}
main函数中的代码如下所示:
#include <QApplication>
#include "myglwidget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyGLWidget win;
win.show();
return app.exec();
}
运行效果如下所示: