QT中使用OpenGL(1)——画一个三角形
QOpenGLBuffer
QT提供给我们使用OpenGL缓冲区的辅助类,使用此类由QT负责后端实现
我们可以自由的使用而不用担心效率问题,如果调用了destroy(),缓冲区就变为了无效,
此时就不要在使用缓冲区。
QOpenGLVertexArrayObject
顶点数组对象
典型用法是:对于每个可视化对象
绑定顶点数组
设置顶点状态、属性等
解绑定顶点数组
main.cpp

![]()
QT提供给我们使用OpenGL缓冲区的辅助类,使用此类由QT负责后端实现
我们可以自由的使用而不用担心效率问题,如果调用了destroy(),缓冲区就变为了无效,
此时就不要在使用缓冲区。
QOpenGLVertexArrayObject
顶点数组对象
典型用法是:对于每个可视化对象
绑定顶点数组
设置顶点状态、属性等
解绑定顶点数组
着色器QOpenGLShaderProgram

vertex.h
#ifndef VERTEX_H
#define VERTEX_H
#include <QVector3D>
class Vertex
{
public:
// 构造函数
Q_DECL_CONSTEXPR Vertex();
Q_DECL_CONSTEXPR explicit Vertex(const QVector3D &position);
Q_DECL_CONSTEXPR Vertex(const QVector3D &position, const QVector3D &color);
// 访问器
Q_DECL_CONSTEXPR const QVector3D& position() const;
Q_DECL_CONSTEXPR const QVector3D& color() const;
void setPosition(const QVector3D &position);
void setColor(const QVector3D &color);
// OpenGL辅助信息
static const int PositionTupleSize = 3;
static const int ColorTupleSize = 3;
static Q_DECL_CONSTEXPR int positionOffset();
static Q_DECL_CONSTEXPR int colorOffset();
static Q_DECL_CONSTEXPR int stride();
private:
QVector3D m_position;
QVector3D m_color;
};
// Q_MOVABLE_TYPE意味着对象可以移动拷贝
Q_DECLARE_TYPEINFO(Vertex, Q_MOVABLE_TYPE);
// 构造函数
Q_DECL_CONSTEXPR inline Vertex::Vertex() {}
Q_DECL_CONSTEXPR inline Vertex::Vertex(const QVector3D &position) : m_position(position) {}
Q_DECL_CONSTEXPR inline Vertex::Vertex(const QVector3D &position, const QVector3D &color) : m_position(position), m_color(color) {}
// 访问器
Q_DECL_CONSTEXPR inline const QVector3D& Vertex::position() const { return m_position; }
Q_DECL_CONSTEXPR inline const QVector3D& Vertex::color() const { return m_color; }
void inline Vertex::setPosition(const QVector3D &position) { m_position = position; }
void inline Vertex::setColor(const QVector3D &color) { m_color = color; }
// OpenGL辅助信息
Q_DECL_CONSTEXPR inline int Vertex::positionOffset() { return offsetof(Vertex, m_position); }
Q_DECL_CONSTEXPR inline int Vertex::colorOffset() { return offsetof(Vertex, m_color); }
Q_DECL_CONSTEXPR inline int Vertex::stride() { return sizeof(Vertex); }
#endif // VERTEX_H
window.h
#ifndef WINDOW_H
#define WINDOW_H
#include <QOpenGLWindow>
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
class QOpenGLShaderProgram;
class Window: public QOpenGLWindow,
protected QOpenGLFunctions
{
Q_OBJECT
public:
~Window();
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
void teardownGL();
private:
// OpenGL状态信息
QOpenGLBuffer m_vertex;
QOpenGLVertexArrayObject m_object;
QOpenGLShaderProgram *m_program;
private:
// 私有辅助函数
void printContextInformation();
};
#endif
#include "window.h"
#include <QDebug>
#include <QString>
#include <QOpenGLShaderProgram>
#include "vertex.h"
// 创建一个彩色三角形
static const Vertex sg_vertexes[] = {
Vertex(QVector3D( 0.00f, 0.75f, 1.0f), QVector3D(1.0f, 0.0f, 0.0f)),
Vertex(QVector3D( 0.75f, -0.75f, 1.0f), QVector3D(0.0f, 1.0f, 0.0f)),
Vertex(QVector3D(-0.75f, -0.75f, 1.0f), QVector3D(0.0f, 0.0f, 1.0f))
};
Window::~Window()
{
makeCurrent();
teardownGL();
}
void Window::initializeGL()
{
// 初始化 OpenGL 后端
initializeOpenGLFunctions();
printContextInformation();
// 设置全局信息
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
// 应用程序相关初始化
{
// 创建Shader(VAO创建之前不要释放)
m_program = new QOpenGLShaderProgram();
m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/simple.vert");
m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/simple.frag");
m_program->link();
m_program->bind();
// 创建Buffer(VAO创建之前不要释放)
m_vertex.create();
m_vertex.bind();
m_vertex.setUsagePattern(QOpenGLBuffer::StaticDraw);
m_vertex.allocate(sg_vertexes, sizeof(sg_vertexes));
// 创建VAO(Vertex Array Object)
m_object.create();
m_object.bind();
m_program->enableAttributeArray(0);
m_program->enableAttributeArray(1);
m_program->setAttributeBuffer(0, GL_FLOAT, Vertex::positionOffset(), Vertex::PositionTupleSize, Vertex::stride());
m_program->setAttributeBuffer(1, GL_FLOAT, Vertex::colorOffset(), Vertex::ColorTupleSize, Vertex::stride());
// 释放(解绑定)所有对象
m_object.release();
m_vertex.release();
m_program->release();
}
}
void Window::resizeGL(int width, int height)
{
// 未做处理
}
void Window::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
// 渲染Shader
m_program->bind();
{
m_object.bind();
glDrawArrays(GL_TRIANGLES, 0, sizeof(sg_vertexes) / sizeof(sg_vertexes[0]));
m_object.release();
}
m_program->release();
}
// 回收资源
void Window::teardownGL()
{
m_object.destroy();
m_vertex.destroy();
delete m_program;
}
// 打印相关信息,调试用
void Window::printContextInformation()
{
QString glType;
QString glVersion;
QString glProfile;
// 获取版本信息
glType = (context()->isOpenGLES()) ? "OpenGL ES" : "OpenGL";
glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION));
// 获取 Profile 信息
#define CASE(c) case QSurfaceFormat::c: glProfile = #c; break
switch (format().profile())
{
CASE(NoProfile);
CASE(CoreProfile);
CASE(CompatibilityProfile);
}
#undef CASE
qDebug() << qPrintable(glType) << qPrintable(glVersion) << "(" << qPrintable(glProfile) << ")";
}
/*
void MyGlWidget::keyPressEvent(QKeyEvent *e)
{
switch(e->key())
{
case Qt::Key_F2:
fullscreen = !fullscreen;
if (fullscreen)
{
showFullScreen();
}
else
{
showNormal();
setGeometry(100, 100, 640, 480);
}
updateGL();
break;
case Qt::Key_Escape:
close();
}
}
*/
main.cpp
#include <QApplication>
#include "window.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
// 设置 OpenGL 信息
// 注意:必须在show()之前设置信息
QSurfaceFormat format;
format.setRenderableType(QSurfaceFormat::OpenGL);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setVersion(3,3);
Window window;
window.setFormat(format);
window.resize(QSize(800, 600));
window.show();
return app.exec();
}声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
- 上一篇:没有了
- 下一篇:没有了
