不用Qt自带的QtOpenGL,而是在QtWidgets窗口中嵌入opengl (glew) 方式,有两个原因:
一、qt自带的opengl有bug 。
二、opengl 扩展功能可能不全,所以使用glew。
一、使用opengl方法:
首先创建opengl 设备上下文 程序,再创建一个OGLWidget继承 QWidget,在qt编辑器中对使用到的Widget 设置提升窗口部件,再设置提升的类名称、头文件。编译、运行即可。
二、代码:
GLContext.hpp
#pragma once
#include <windows.h>
#include <GL/glew.h>
class GLContext
{
protected:
int _format;
// 窗口句柄
HWND _hWnd;
// 绘制设备上下文
HDC _hDC;
// OpenGL上下文
HGLRC _hRC;
public:
GLContext();
~GLContext();
/**
* 初始化GL
*/
bool setup(HWND hWnd, HDC hDC);
/**
* 销毁OpenGL
*/
void shutdown();
/**
* 交换缓冲区
*/
void swapBuffer();
};
GLContext.cpp
#include "GLContext.hpp"
GLContext::GLContext() {
_format = 0;
_hWnd = 0;
_hDC = 0;
_hRC = 0;
}
GLContext::~GLContext() {
shutdown();
}
/**
* 初始化GL
*/
bool GLContext::setup(HWND hWnd, HDC hDC) {
_hWnd = hWnd;
_hDC = hDC;
unsigned PixelFormat;
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
24,
8,
0,
PFD_MAIN_PLANE,
0,
0,
0,
0
};
if (_format == 0) {
PixelFormat = ChoosePixelFormat(_hDC, &pfd);
}
else {
PixelFormat = _format;
}
if (!SetPixelFormat(_hDC, PixelFormat, &pfd)) {
return false;
}
_hRC = wglCreateContext(_hDC);
if (!wglMakeCurrent(_hDC, _hRC)) {
return false;
}
return true;
}
/**
* 销毁OpenGL
*/
void GLContext::shutdown() {
if (_hRC != NULL) {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(_hRC);
_hRC = NULL;
}
if (_hDC != NULL) {
ReleaseDC(_hWnd, _hDC);
_hDC = NULL;
}
}
/**
* 交换缓冲区
*/
void GLContext::swapBuffer() {
SwapBuffers(_hDC);
}
OGLWidget.h
#pragma once
#include <QtWidgets/QWidget>
#include <QTimer>
#include "GLContext.hpp"
class OGLWidget :public QWidget
{
Q_OBJECT
protected:
GLContext _context;
QTimer _renderTimer;
public:
OGLWidget(QWidget* parent = 0);
virtual ~OGLWidget();
protected:
void paintEvent(QPaintEvent* evt);
public Q_SLOTS:
/**
* 绘制函数
*/
virtual void render();
};
OGLWidget.cpp
#pragma once
#include "OGLWidget.h"
OGLWidget::OGLWidget(QWidget* parent)
:QWidget(parent,Qt::MSWindowsOwnDC)
{
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_NoSystemBackground);
setAutoFillBackground(true);
// init opengl
_context.setup((HWND)winId(),GetDC((HWND)winId()));
// setup glew
glewInit();
QObject::connect(&_renderTimer,SIGNAL(timeout()),this,SLOT(render()));
_renderTimer.setInterval(16);
_renderTimer.start();
}
OGLWidget::~OGLWidget()
{
_context.shutdown();
}
void OGLWidget::paintEvent(QPaintEvent* evt)
{}
/**
* 绘制函数
*/
void OGLWidget::render()
{
glClearColor(0,1,1,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_context.swapBuffer();
}
main.cpp
#include "mainwindow.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
三、运行结果:
来源:oschina
链接:https://my.oschina.net/u/4340589/blog/4264122