Qt5 OpenGL框架
#ifndef MYRENDERER_H #define MYRENDERER_H #include <QOpenGLContext> #include <QOpenGLFunctions> #include <QSurface> #include <QSurfaceFormat> #include <QScreen> #include <QOpenGLShader> #include <QOpenGLShaderProgram> #include <QColor> #include <QSize> class MyRenderer : public QObject { Q_OBJECT public: MyRenderer(QSurfaceFormat & format, MyRenderer * share = 0, QScreen * screen = 0); QSurfaceFormat format() const {return m_format;} public slots: void Render(QSurface * surface, const QColor & color, const QSize & size); private: void Initialize(); void Init_QUAD_VBO(); void Init_QUAD_Shader(); void Draw_QUAD(); private: bool m_bInitialized; QSurfaceFormat m_format; QOpenGLContext * m_context; QOpenGLFunctions * m_fun; QOpenGLShader * m_QUAD_vShader; QOpenGLShader * m_QUAD_fShader; QOpenGLShaderProgram * m_QUAD_program; QVector<QVector3D > m_quad_vertices; GLuint m_quad_vbo; GLuint m_MODEL_MATRIX_LOC; GLuint m_VIEW_MATRIX_LOC; GLuint m_PROJECTION_MATRIX_LOC; QMatrix4x4 m_model_matrix; QMatrix4x4 m_view_matrix; QMatrix4x4 m_projection_matrix; QSize m_viewSize; }; #endif // MYRENDERER_H
#include "myrenderer.h" MyRenderer::MyRenderer(QSurfaceFormat &format, MyRenderer *share, QScreen *screen) :m_bInitialized(false) ,m_format(format) ,m_context(0) ,m_fun(0) ,m_QUAD_vShader(0) ,m_QUAD_fShader(0) ,m_QUAD_program(0) { m_context = new QOpenGLContext(this); if (screen) { m_context->setScreen(screen); } m_context->setFormat(format); if (share) { m_context->setShareContext(share->m_context); } m_context->create(); } void MyRenderer::Render(QSurface * surface, const QColor & color, const QSize & viewSize) { m_viewSize = surface->size(); if (m_context == NULL) { return; } if (m_context->makeCurrent(surface) != true) { return; } if (m_bInitialized == false) { m_bInitialized = true; Initialize(); } m_fun->glViewport(0, 0, surface->size().width(), surface->size().height()); m_fun->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); m_fun->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Draw_QUAD(); m_context->swapBuffers(surface); } void MyRenderer::Initialize() { m_fun = m_context->functions(); m_fun->glClearColor(0.0f, 0.0f, 0.0f, 1.0f); Init_QUAD_VBO(); Init_QUAD_Shader(); } void MyRenderer::Init_QUAD_VBO() { m_quad_vertices << QVector3D(-1.0f, -1.0f, 0.0f); m_quad_vertices << QVector3D(1.0f, -1.0f, 0.0f); m_quad_vertices << QVector3D(1.0f, 1.0f, 0.0f); m_quad_vertices << QVector3D(-1.0f, 1.0f, 0.0f); m_fun->glGenBuffers(1, &m_quad_vbo); m_fun->glBindBuffer(GL_ARRAY_BUFFER, m_quad_vbo); m_fun->glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * m_quad_vertices.size(), &m_quad_vertices.at(0), GL_STATIC_COPY); m_fun->glBindBuffer(GL_ARRAY_BUFFER, 0); } void MyRenderer::Init_QUAD_Shader() { m_QUAD_vShader = new QOpenGLShader(QOpenGLShader::Vertex, this); m_QUAD_fShader = new QOpenGLShader(QOpenGLShader::Fragment, this); m_QUAD_program = new QOpenGLShaderProgram(this); m_QUAD_vShader->compileSourceFile(":/quad.vert"); m_QUAD_fShader->compileSourceFile(":/quad.frag"); m_QUAD_program->addShader(m_QUAD_vShader); m_QUAD_program->addShader(m_QUAD_fShader); m_QUAD_program->link(); m_MODEL_MATRIX_LOC = m_QUAD_program->uniformLocation("MODEL_MATRIX"); m_VIEW_MATRIX_LOC = m_QUAD_program->uniformLocation("VIEW_MATRIX"); m_PROJECTION_MATRIX_LOC = m_QUAD_program->uniformLocation("PROJECTION_MATRIX"); } void MyRenderer::Draw_QUAD() { m_model_matrix.setToIdentity(); m_view_matrix.setToIdentity(); m_projection_matrix.setToIdentity(); m_view_matrix.lookAt(QVector3D(0.0f, 0.0f, 10.0f), QVector3D(0.0f, 0.0f, 0.0f), QVector3D(0.0, 1.0f, 0.0f)); m_projection_matrix.perspective(45.0f, m_viewSize.width()/ m_viewSize.height(), 1.0f, 100.0f); m_QUAD_program->bind(); m_QUAD_program->setUniformValue(m_MODEL_MATRIX_LOC, m_model_matrix); m_QUAD_program->setUniformValue(m_VIEW_MATRIX_LOC, m_view_matrix); m_QUAD_program->setUniformValue(m_PROJECTION_MATRIX_LOC, m_projection_matrix); m_fun->glBindBuffer(GL_ARRAY_BUFFER, m_quad_vbo); m_fun->glEnableVertexAttribArray(0); m_fun->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); m_fun->glDrawArrays(GL_QUADS, 0, 4); m_fun->glDisableVertexAttribArray(0); m_fun->glBindBuffer(GL_ARRAY_BUFFER, 0); m_QUAD_program->release(); }
#ifndef MYFRAME_H #define MYFRAME_H #include "myrenderer.h" #include <QWindow> class MyFrame : public QWindow { Q_OBJECT public: MyFrame(const QSharedPointer<MyRenderer> & renderer); signals: void NeedRender(QSurface * surface , const QColor & color, const QSize & viewSize); private: void Render(); protected: void exposeEvent(QExposeEvent *); void timerEvent(QTimerEvent *); private: QSharedPointer<MyRenderer> m_myRenderer; }; #endif // MYFRAME_H
#include "myframe.h" MyFrame::MyFrame(const QSharedPointer<MyRenderer> &renderer) :m_myRenderer(renderer) { setSurfaceType(QWindow::OpenGLSurface); setFormat(renderer->format()); setGeometry(35, 35, 1024, 800); connect(this, SIGNAL(NeedRender(QSurface*,QColor,QSize)), renderer.data(), SLOT(Render(QSurface*,QColor,QSize))); startTimer(1000); } void MyFrame::Render() { if (isExposed()) emit NeedRender(this, QColor(0.0f, 0.0f, 0.0f, 1.0f), size()); } void MyFrame::exposeEvent(QExposeEvent *) { Render(); } void MyFrame::timerEvent(QTimerEvent *) { Render(); }
#version 430 layout(location = 0) in vec4 VERTEX; uniform mat4 MODEL_MATRIX; uniform mat4 VIEW_MATRIX; uniform mat4 PROJECTION_MATRIX; out vec4 VERTEX_COLOR; void main() { VERTEX_COLOR = VERTEX; gl_Position = PROJECTION_MATRIX * VIEW_MATRIX * MODEL_MATRIX * VERTEX; }
#version 430 out vec4 FragColor; in vec4 VERTEX_COLOR; void main() { FragColor = VERTEX_COLOR; }
#include "myframe.h" #include <QGuiApplication> int main(int argc, char *argv[]) { QGuiApplication a(argc, argv); QScreen * screen = QGuiApplication::primaryScreen(); QSurfaceFormat format; format.setDepthBufferSize(16); format.setSamples(4); QSharedPointer<MyRenderer>renderer(new MyRenderer(format, 0, screen)); MyFrame w(renderer); w.setVisible(true); w.show(); return a.exec(); }