游戏编辑器开发三: QT中使用glew进行opengl开发

女生的网名这么多〃 提交于 2020-05-04 12:17:01

  不用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();
}

三、运行结果:

在这里插入图片描述

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!