最近在QT平台上进行OpenGL的开发学习,再按照网上教程学习的过程中,常常出现网上代码中的函数无法使用的情况,因为使用的是QT自带的OpenGL库,而网上的教程大多是在VS平台上基于GLFW+GLEW或是GLFW+GLAD。当然,因为是初学,不确定是否有其他替换函数来实现的方法。 为了减少麻烦,索性尝试在QT平台配置GLFW+GLEW来学习OpenGL。以下是配置的流程,做一下记录,以防忘记。
我在工程目录中创建了名为 OpenGLEnvironment的文件夹 并在里面分别创建了glfw文件夹 glew文件夹 用来存放需要的配置文件
将刚刚下载的GLFW文件夹中的 include 文件夹 以及 lib-mingw-w64 文件夹放入OpenGLEnvironment文件夹的glfw文件夹内 如下图所示
四.QT配置
将刚刚include 文件夹内 以及 lib文件夹内的内容 加入进库中
glfw文件夹内 选择libglfw3dll.a 选择 动态链接 记得将 “为debug版本添加‘d’作为后缀”选项的勾去掉 包含路径选择 include文件夹所在路径
glew 也是外部库 选择glew32s.lib 不过这次选择静态库 包含路径选择 include文件夹所在路径 同样将 “为debug版本添加‘d’作为后缀”选项的勾去掉
最后对 工程的 pro 文件做修改 添加 LIBS += -lopengl32 -luser32 DEFINES += GLEW_STATIC
删除
最后应该如下图所示
五.添加工程文件
创建新的类 我这里取为QPaintingWidget h文件修改为
#ifndef QPAINTINGWIDGET_H
#define QPAINTINGWIDGET_H
#include <QWidget>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <QOpenGLWidget>
class QPaintingWidget : public QOpenGLWidget
{
Q_OBJECT
public:
explicit QPaintingWidget(QWidget *parent = nullptr);
~QPaintingWidget();
signals:
protected:
void initializeGL() override;
void paintGL() override;
void resizeGL(int w, int h) override;
private:
unsigned int shaderProgram ;
unsigned int VBO, VAO;
};
#endif
注意将#include <GL/glew.h> 放在#include <GLFW/glfw3.h> 前面
cpp 文件修改为
#include "qpaintingwidget.h"
#include <iostream>
using namespace std;
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
QPaintingWidget::QPaintingWidget(QWidget *parent) : QOpenGLWidget(parent)
{
}
QPaintingWidget::~QPaintingWidget()
{
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
}
void QPaintingWidget::initializeGL() {
glfwInit();
glewInit();
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void QPaintingWidget::paintGL() {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void QPaintingWidget::resizeGL(int w, int h) {
}
widget.h 修改为
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "qpaintingwidget.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
QPaintingWidget *m_painting;
};
#endif
widget.cpp修改为
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
resize(800,800);
m_painting=new QPaintingWidget(this);
m_painting->resize(800,800);
}
Widget::~Widget()
{
delete ui;
}
最后贴一张结果图
|