Qt中自带OpenGL模块可以用来进行三维开发,下面介绍一下在Qt中进行OpenGL开发的一些简单Demo。OpenGL的最小图元是三角形。矩形则由两个三角形组成。通过四个顶点坐标和顶点的索引确定两个三角形,从而组成一个矩形。代码采用的是Qt的Opengl模块,管道编程采用的是GLSL语言。
在头文件中需要包含Qt对应的模块头文件,对应的头文件代码如下。
opengl.h
#ifndef OPENGL_H
#define OPENGL_H
#include <QtWidgets/QWidget>
#include <QtOpenGL/QGLWidget>
#include <QtOpenGL/QGLFunctions>
#include <QtOpenGL\QGLShader>
#include <QtOpenGL\QGLBuffer>
#include <QtOpenGL\QGLShaderProgram>
class openGL : public QGLWidget, protected QGLFunctions
{
Q_OBJECT
public:
openGL(QWidget *parent = 0);
~openGL();
protected:
void initializeGL(); //初始化OpenGL
void resizeGL(int w, int h); //调整oeenGL的显示窗口
void paintGL(); //绘制opengl图像
private:
void InitShader();
void InitBuffer();
private:
QGLShaderProgram shader;
QGLBuffer* vertexBuffer;
QGLBuffer* indexBuffer;
float viewPortWidth;
float viewPortHeight;
};
#endif // OPENGL_H
opengl.cpp
#include "opengl.h"
QString vertexShaderSource =
"#version 330 core\n\
layout (location = 0) in vec3 aPos;\n\
void main()\n\
{\n\
gl_Position = vec4(aPos, 1.0);\n\
}";
QString fragmentShaderSource =
"#version 330 core\n\
out vec4 FragColor;\n\
void main()\n\
{\n\
FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n\
}";
float vertices[] = {
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f
};
unsigned int indices[] =
{
0, 1, 3,
1, 2, 3
};
openGL::openGL(QWidget *parent)
: QGLWidget(parent)
,viewPortWidth(300.0)
,viewPortHeight(300.0)
{
}
openGL::~openGL()
{
delete vertexBuffer;
delete indexBuffer;
}
void openGL::initializeGL()
{
glViewport(0, 0, viewPortWidth, viewPortHeight);
glEnable(GL_DEPTH_TEST);
initializeGLFunctions();
InitShader();
InitBuffer();
}
void openGL::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
void openGL::paintGL()
{
resize(viewPortWidth, viewPortHeight);
glViewport(0, 0, viewPortWidth, viewPortHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
indexBuffer->bind();
shader.bind();
shader.enableAttributeArray("aPos");
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
shader.disableAttributeArray("aPos");
shader.release();
indexBuffer->release();
}
void openGL::InitShader()
{
shader.addShaderFromSourceCode(QGLShader::Vertex, vertexShaderSource);
shader.addShaderFromSourceCode(QGLShader::Fragment, fragmentShaderSource);
shader.link();
}
void openGL::InitBuffer()
{
vertexBuffer = new QGLBuffer(QGLBuffer::VertexBuffer);
indexBuffer = new QGLBuffer(QGLBuffer::IndexBuffer);
shader.bind();
vertexBuffer->create();
vertexBuffer->bind();
vertexBuffer->allocate(vertices, sizeof(vertices));
vertexBuffer->setUsagePattern(QGLBuffer::StaticDraw);
shader.setAttributeBuffer("aPos", GL_FLOAT, 0, 3, 12);
vertexBuffer->release();
shader.release();
indexBuffer->create();
indexBuffer->bind();
indexBuffer->allocate(indices, sizeof(indices));
indexBuffer->setUsagePattern(QGLBuffer::StaticDraw);
indexBuffer->release();
}
需要注意的是qt中opengl对应的显示方法都在QGLWidget中其它的操作方法都在QGLFunctions模块中,所以自定义的模块一定要继承这两个类。
对应的显示效果如下图所示: