一、使用penGLWidget:

创建一个带widget类的项目:

widget.h为:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include <QOpenGLWidget>
#include <QOpenGLFunctions>
class Widget : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT

public:
Widget(QWidget *parent = 0);
~Widget();
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
};

#endif // WIDGET_H

widget.cpp:

#include "widget.h"

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

Widget::~Widget()
{

}
void Widget::initializeGL()
{
initializeOpenGLFunctions();

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

glViewport(0, 0, w, h);



}
void Widget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

}


main.cpp:

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();

return a.exec();
}

二、使用QGLWidget创建

需要在pro文件里+=opengl

并包含GL/glut.h 没用的话需要自己把glut.h放到Qt的include的GL文件夹下:

widget.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtOpenGL/QGLWidget>
#include <GL/glut.h>
class Widget : public QGLWidget
{
Q_OBJECT

public:
Widget(QWidget *parent = 0);
~Widget();

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

#endif // WIDGET_H

widget.cpp:

#include "widget.h"

Widget::Widget(QWidget *parent)
: QGLWidget(parent)
{
}

Widget::~Widget()
{

}

void Widget::initializeGL()
{
glClearColor(0.0,0.0,0.0,1.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);


}

void Widget::resizeGL(int w,int h){
glViewport(0,0,(GLsizei)w,(GLsizei)h);


}
void Widget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

}

main.cpp:

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();

return a.exec();
}


三、在有就是自己创建一个

OpenGLWindow类继承自 QWindow然后创建子类并覆盖初始化函数和渲染函数:


openglwindow.h:

#include <QtGui/QWindow>
#include <QtGui/QOpenGLFunctions>

QT_BEGIN_NAMESPACE
class QPainter;
class QOpenGLContext;
class QOpenGLPaintDevice;
QT_END_NAMESPACE
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit OpenGLWindow(QWindow *parent = 0);
~OpenGLWindow();

virtual void render(QPainter *painter);
virtual void render();

virtual void initialize();

void setAnimating(bool animating);

public slots:
void renderLater();
void renderNow();

protected:
bool event(QEvent *event) override;

void exposeEvent(QExposeEvent *event) override;

private:
bool m_animating;

QOpenGLContext *m_context;
QOpenGLPaintDevice *m_device;
};


openglwindow.cpp:

#include "openglwindow.h"

#include <QtCore/QCoreApplication>

#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLPaintDevice>
#include <QtGui/QPainter>


#include <QDebug>

OpenGLWindow::OpenGLWindow(QWindow *parent)
: QWindow(parent)
, m_animating(false)
, m_context(0)
, m_device(0)
{
setSurfaceType(QWindow::OpenGLSurface);
}


OpenGLWindow::~OpenGLWindow()
{
delete m_device;
}

void OpenGLWindow::render(QPainter *painter)//这个函数会在三角形类中重载
{
Q_UNUSED(painter);//Q_UNUSED避免警告
}

void OpenGLWindow::initialize()//这个函数会在三角形类中重载
{
}

void OpenGLWindow::render()
{
}

void OpenGLWindow::renderLater()
{
qDebug()<<"renderLater";
requestUpdate();
}

bool OpenGLWindow::event(QEvent *event)
{
qDebug()<<"event";
switch (event->type()) {

case QEvent::UpdateRequest:
renderNow();
return true;
default:
return QWindow::event(event);
}
}

void OpenGLWindow::exposeEvent(QExposeEvent *event)
{
qDebug()<<"exposeEvent";
Q_UNUSED(event);
qDebug()<<"stop1";
if (isExposed())//是否显示,也就是最小化时
renderNow();
else {
qDebug()<<"stop2";
}
}

void OpenGLWindow::renderNow()
{
qDebug()<<"renderNow";
if (!isExposed()){
return;
qDebug()<<"no exposed";
}

bool needsInitialize = false;

if (!m_context) {
m_context = new QOpenGLContext(this);
m_context->setFormat(requestedFormat());
m_context->create();

needsInitialize = true;
}

m_context->makeCurrent(this);

if (needsInitialize) {
initializeOpenGLFunctions();
initialize();
}

render();

m_context->swapBuffers(this);

if (m_animating)
renderLater();
}

void OpenGLWindow::setAnimating(bool animating)
{
qDebug()<<"setAnimating";
m_animating = animating;

if (animating)
renderLater();
}


main.cpp:

#include "openglwindow.h"

#include <QtGui/QGuiApplication>
#include <QtGui/QMatrix4x4>
#include <QtGui/QOpenGLShaderProgram>
#include <QtGui/QScreen>

#include <QtCore/qmath.h>

class TriangleWindow : public OpenGLWindow
{
public:
TriangleWindow();

void initialize() override;
void render() override;//重载这两个函数

private:
GLuint m_posAttr;
GLuint m_colAttr;
GLuint m_matrixUniform;

QOpenGLShaderProgram *m_program;
int m_frame;
};

TriangleWindow::TriangleWindow()
: m_program(0)
, m_frame(0)
{
}

int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);


TriangleWindow window;
window.resize(640, 480);
window.show();

window.setAnimating(true);

return app.exec();
}

void TriangleWindow::initialize()
{
qDebug()<<"initialize";

}

void TriangleWindow::render()
{
qDebug()<<"render";


}

四、继承自QOpenGLWindow的窗口,跑不出来。