在使用纯C++进行OpenGL开发的时候,需要使用额外的库(例如:GLFW、GLAD等),但是使用Qt进行OpenGL开发时将不再需要安装额外的库,自Qt5.4以后Qt便有了QOpenGLWidget类使我们方便的进行开发。
初学OpenGL在求助前辈后得到一个国外大神编写的OpenGL教程,由国内大神进行了翻译(网址在文末给出)。但是大神是用的纯C++进行的开发,所以并不是很适合Qt+OpenGL的模式。那么如何根据大神的代码进行修改变成适合Qt的代码呢?
1、创建自定义OpenGLWidget并继承自QOpenGLWidget以及QOpenGLFunctions_4_5_Core(此处根据需要采用的OpenGL版本进行调整);
2、实现QOpenGLWidget的三个纯虚函数initializeGL()、paintGL()、resizeGL(int w,int h)以及初始化functions。代码如下:
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions_4_5_Core>
#include <QOpenGLShaderProgram> //着色器
class GLWidget : public QOpenGLWidget,public QOpenGLFunctions_4_5_Core
{
Q_OBJECT
public:
explicit GLWidget(QWidget *parent=nullptr);
~GLWidget();
protected:
void iniDatas();
void initializeGL(); //初始化相关的操作全在这个函数中完成
void resizeGL(int w,int h);
void paintGL();
private:
QOpenGLShaderProgram *m_pShaderProgram = nullptr;
};
#endif // GLWIDGET_H
#include "glwidget.h"
#include <QDebug>
#define BUFFER_OFFSET(offset) ((void*)(offset))
const char *g_vertexShaderSource =
"#version 450 core\n"
"layout (location = 0) in vec3 aPos;\n"
"layout (location = 2) in vec3 inColor;\n"
// "uniform mat4 model;\n"
// "uniform mat4 view;\n"
// "uniform mat4 projection;\n"
"out vec4 posColor;\n"
"void main(){\n"
" posColor = vec4(inColor,1.0);\n"
" gl_Position = vec4(aPos,1.0);"
// " gl_Position = projection * view * model * vec4(aPos, 1.0);\n"
"}\n\0";
const char *g_fragmentShaderSource =
"#version 450 core\n"
"in vec4 posColor;\n"
"out vec4 FragColor;\n"
"void main(){\n"
" FragColor = posColor;\n"
"}\n\0";
GLuint g_VAO[1];
GLuint g_VBO[1];
GLWidget::GLWidget(QWidget *parent):
QOpenGLWidget(parent)
{
}
GLWidget::~GLWidget()
{
}
void GLWidget::iniDatas()
{
static const GLfloat vertices[]={
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右上
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 右下
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, // 左下
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f // 左上
};
glCreateVertexArrays(1,g_VAO);
glCreateBuffers(1,g_VBO);
glNamedBufferStorage(g_VBO[0],sizeof(vertices),vertices,0);
GLuint programID = m_pShaderProgram->programId();
glUseProgram(programID);
glBindVertexArray(g_VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER,g_VBO[0]);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,6*sizeof(float),BUFFER_OFFSET(0));//第一个参数与location对应
glEnableVertexAttribArray(0); //参数值与location对应
glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,6*sizeof(float),BUFFER_OFFSET(3*sizeof(float)));
glEnableVertexAttribArray(2);
}
void GLWidget::initializeGL()
{
initializeOpenGLFunctions();
m_pShaderProgram = new QOpenGLShaderProgram(this);
m_pShaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex,g_vertexShaderSource);
m_pShaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment,g_fragmentShaderSource);
m_pShaderProgram->link();
m_pShaderProgram->bind();
iniDatas();
}
void GLWidget::resizeGL(int w, int h)
{
glViewport(0,0,w,h);
}
void GLWidget::paintGL()
{
static const GLfloat color[] = {0.0f,0.0f,0.0f,1.0f};
glClearBufferfv(GL_COLOR,0,color);
glBindVertexArray(g_VAO[0]);
glDrawArrays(GL_TRIANGLES,0,3);
update();
}
代码运行结果如下:
笔者Qt版本:5.12.6
参考网址:https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/