头文件
#ifndef OPENGLWIDGET_H
#define OPENGLWIDGET_H
#include "QtGui/QOpenGLBuffer"
#include "QtWidgets/QOpenGLWidget"
#include "QtGui/QOpenGLVertexArrayObject"
#include "QtGui/QOpenGLFunctions_4_5_Core"
class QOpenGLShaderProgram;
class OpenGLWidget
: public QOpenGLWidget
, protected QOpenGLFunctions_4_5_Core
{
public:
/* @接口 默认构造函数
* @类名 [OpenGLWidget]
* @时间 2021年10月8号
*/
OpenGLWidget();
/* @接口 默认析构
* @类名 [OpenGLWidget]
* @时间 2021年10月8号
*/
~OpenGLWidget();
/* @接口
* @返回
* @类名 [OpenGLWidget]
* @时间 2021年10月8号
*/
virtual void paintGL();
/* @接口
* @返回
* @类名 [OpenGLWidget]
* @时间 2021年10月8号
*/
virtual void initializeGL();
/* @接口
* @类名 [OpenGLWidget]
* @时间 2021年10月8号
*/
virtual void resizeGL(int, int);
private:
/* @接口
* @类名 [OpenGLWidget]
* @时间 2021年10月17号
*/
bool initShader();
/* @接口
* @类名 [OpenGLWidget]
* @时间 2021年10月17号
*/
void initQTimer();
/* @接口
* @类名 [OpenGLWidget]
* @时间 2021年10月17号
*/
void updateTimer();
private:
float m_scale = 1.0;
float m_xmove = 0.0;
float m_ymove = 0.0;
float m_rotate = 0;
QTimer *m_timer = NULL;
QOpenGLBuffer m_vbo, m_ebo;
QOpenGLVertexArrayObject m_vao;
QOpenGLShaderProgram *m_shaderProgram;
};
#endif /*OPENGLWIDGET_H*/
源文件
#include "QtCore/QTimer"
#include "openglwidget.h"
#include "QtGui/QWheelEvent"
#include "QtGui/QMouseEvent"
#include "QOpenGLShaderProgram"
const char *vertexShader =
"#version 450 core \n"
"in vec3 vPosition; \n"
"in vec3 vColor; \n"
"out vec4 outColor; \n"
"uniform mat4 gWorld; \n"
"void main() { \n"
" gl_Position = gWorld * vec4(vPosition * 0.5, 1.0); \n"
" outColor = vec4(vColor, 1.0); \n"
"} \n";
const char *fragmentShader =
"#version 450 core \n"
"in vec4 outColor; \n"
"out vec4 FragColor; \n"
"void main() { \n"
" FragColor = outColor; \n"
"} \n";
OpenGLWidget::OpenGLWidget()
: QOpenGLWidget(), m_vao()
, m_ebo(QOpenGLBuffer::IndexBuffer)
, m_vbo(QOpenGLBuffer::VertexBuffer)
{
}
OpenGLWidget::~OpenGLWidget()
{
}
void OpenGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
QMatrix4x4 gScale; gScale.scale(sin(m_scale));
QMatrix4x4 gMove;
gMove.translate(sin(m_xmove), cos(m_ymove));
QMatrix4x4 gRotate; gRotate.rotate(m_rotate, 1, 1);
QMatrix4x4 gWorld = gMove * gRotate * gScale;
m_shaderProgram->setUniformValue("gWorld", gWorld);
m_vao.bind();
glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, 0);
m_vao.release();
}
bool OpenGLWidget::initShader()
{
m_shaderProgram = new QOpenGLShaderProgram;
m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader);
m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader);
if (!m_shaderProgram->link()) return false;
return m_shaderProgram->bind();
}
void OpenGLWidget::initQTimer()
{
m_timer = new QTimer; m_timer->start(1);
connect(m_timer, &QTimer::timeout, this, &OpenGLWidget::updateTimer);
}
void OpenGLWidget::updateTimer()
{
m_scale += 0.01;
m_xmove += 0.01;
m_ymove += 0.01;
m_rotate += 1;
repaint();
}
void OpenGLWidget::initializeGL()
{
initializeOpenGLFunctions(); //初始化OPenGL功能函数
glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
if (!initShader()) return;
float vertices[] = {
-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f
};
GLuint indices[] = {
0, 3, 1,
1, 3, 2,
2, 3, 0,
0, 1, 2
};
m_vao.create();
m_vao.bind();
m_vbo.create();
m_vbo.bind();
m_vbo.allocate(vertices, 4 * 6 * sizeof(GLfloat));
m_ebo.create();
m_ebo.bind();
m_ebo.allocate(indices, 4 * 3 * sizeof(GLuint));
int attr = -1;
//顶点属性设置
attr = m_shaderProgram->attributeLocation("vPosition");
m_shaderProgram->setAttributeBuffer(attr, GL_FLOAT, 0, 3, sizeof(GLfloat) * 6);
m_shaderProgram->enableAttributeArray(attr);
//颜色属性设置
attr = m_shaderProgram->attributeLocation("vColor");
m_shaderProgram->setAttributeBuffer(attr, GL_FLOAT, sizeof(GLfloat) * 3, 3, sizeof(GLfloat) * 6);
m_shaderProgram->enableAttributeArray(attr);
m_vao.release();
m_vbo.release();
m_ebo.release();
initQTimer();
}
运行结果:
QOpenGLWidget 第二篇 EBO、VBO、VAO 绘制三棱锥
QOpenGLWidget 第四篇 透视投影