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

 

posted @ 2014-06-22 14:47  20118281131  阅读(1898)  评论(1编辑  收藏  举报