您的位置:首页 > 编程语言 > Qt开发

QT中使用OpenGL(1)——画一个三角形

2016-04-10 20:33 661 查看
QOpenGLBuffer

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


window.cpp

#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();
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: