## Qt+OpenGL——第一个三角形

1、创建自定义OpenGLWidget并继承自QOpenGLWidget以及QOpenGLFunctions_3_0（此处根据需要采用的OpenGL版本进行调整，为了跟教程一致故笔者采用3.0版本）；

2、实现QOpenGLWidget的三个纯虚函数initializeGL()、paintGL()、resizeGL(int w,int h)以及初始化functions。代码如下：

``````//openglwidget_glfw.h文件
#ifndef OPENGL_GLFW_H
#define OPENGL_GLFW_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_0>
#include <QObject>
#include <QWidget>

class OpenGL_GLFW:public QOpenGLWidget,protected QOpenGLFunctions_3_0
{
Q_OBJECT
public:
explicit OpenGL_GLFW(QWidget *parent = nullptr);
~OpenGL_GLFW();

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

private:
};

#endif // OPENGL_GLFW_H
``````
``````//openglwidget_glfw.cpp
#include "opengl_glfw.h"
#include <QDebug>

float vertices[] = {
-0.5f,-0.5f,0.0f,
0.5f,0.5f,0.0f,
0.0f,0.5f,0.0f
};

//顶点着色器源码
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";

OpenGL_GLFW::OpenGL_GLFW(QWidget *parent):
QOpenGLWidget(parent)
{

}

OpenGL_GLFW::~OpenGL_GLFW()
{

}

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

void OpenGL_GLFW::paintGL()
{

}

void OpenGL_GLFW::resizeGL(int w, int h)
{
glViewport(0,0,w,h);
}``````

3、教程中的定义着色器部分以及编译链接着色器只需要执行一次，故我们放在initializeGL中，代码如下：

``````void OpenGL_GLFW::initializeGL()
{
initializeOpenGLFunctions();

int  success;
char infoLog[512];
if(!success)
{
}

success = -1;
if(!success)
{
}

if(!success) {
}

}
}``````

4、绘制代码放入paintGL中，代码如下：

``````void OpenGL_GLFW::paintGL()
{

glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

float vertices[] = {
-0.5f, -0.5f, 0.0f, // left
0.5f, -0.5f, 0.0f, // right
0.0f,  0.5f, 0.0f  // top
};

unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
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);

// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
glBindBuffer(GL_ARRAY_BUFFER, 0);

// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
glBindVertexArray(0);

glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
glDrawArrays(GL_TRIANGLES, 0, 3);

}``````