qt+qml+render

来源:互联网 发布:淘宝店铺模板怎么用 编辑:程序博客网 时间:2024/05/17 21:48
#ifndef OPENGLRENDERER_H
#define OPENGLRENDERER_H
#include <QObject>
#include <qquickframebufferobject>
#include <qopenglframebufferobject>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QMatrix4x4>
class RGBRenderer : public QQuickFramebufferObject::Renderer, public QOpenGLFunctions
{
public:
    explicit RGBRenderer();
    ~RGBRenderer();
    QOpenGLFramebufferObject *createFramebufferObject(const QSize &size)
    {
        QOpenGLFramebufferObjectFormat format;
        format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
        return new QOpenGLFramebufferObject(size, format);
    }
    void render();
    void synchronize(QQuickFramebufferObject *);
protected:
    void initShader();
    void initTexture();
private:
    GLuint m_textureID;
    GLuint m_program;
    int m_width;
    int m_height;
    unsigned char *m_rgbData;
    int m_line;
    QMatrix4x4 projection;
};
class OpenglRenderer : public QQuickFramebufferObject
{
    Q_OBJECT
public:
    explicit OpenglRenderer(QQuickItem *parent = Q_NULLPTR): QQuickFramebufferObject(parent){}
    Renderer *createRenderer() const{
        return new RGBRenderer;
    }
signals:
public slots:
};
#endif // OPENGLRENDERER_H
#include "openglrenderer.h"
#include <QQuickWindow>
RGBRenderer::RGBRenderer()
    : m_program(NULL)
    , m_width(800)
    , m_height(400)
    , m_line(0)
{
    initializeOpenGLFunctions();
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    m_rgbData = new unsigned char[m_width*m_height*3];
    memset(m_rgbData, 0, m_width*m_height*3);
    initShader();
    initTexture();
    qreal aspect = 2;
    // Set near plane to 3.0, far plane to 7.0, field of view 45 degrees
    const qreal zNear = 1.0, zFar = 100.0, fov = 45.0;
    // Reset projection
    //projection.setToIdentity();
    // Set perspective projection
    //projection.perspective(fov, aspect, zNear, zFar);
    projection.ortho(QRect(-400,-200,800,400));
}
RGBRenderer::~RGBRenderer()
{
    glDeleteTextures(1, &m_textureID);
    glDeleteProgram(m_program);
}
void RGBRenderer::synchronize(QQuickFramebufferObject *fbo)
{
    //fbo->window()->setClearBeforeRendering(false);
    for(int m = 0; m < m_width*m_height*3; m+=3) {
        if(m>= m_line*m_width*3 && m<=(m_line+10)*m_width*3) {
            m_rgbData[m] = 0xFF;
        } else {
            m_rgbData[m] = 0x7F;
        }
        m_rgbData[m+1]=0x00;
        m_rgbData[m+2]=0x00;
    }
    m_line += 2;
    if(m_line >= m_height) {
        m_line = 0;
    }
}
void RGBRenderer::initShader()
{
    const GLchar* vfSource[] = {
        "attribute vec4 vertices;"
        "attribute vec2 a_texcoord;"
        "uniform mat4 mvp_matrix;"
        "varying vec2 v_texcoord;"
        "void main() {"
        "    gl_Position = mvp_matrix*vertices;"
        "    v_texcoord = a_texcoord;"
        "}\n"
    };
    const GLchar* fsSource[] = {
            "uniform sampler2D texture;"
            "varying vec2 v_texcoord;"
            "void main() {"
            "    gl_FragColor = texture2D(texture, v_texcoord);"
            "}\n"
    };
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, vfSource, NULL);
    glCompileShader(vertexShader);
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, fsSource, NULL);
    glCompileShader(fragmentShader);
    m_program = glCreateProgram();
    glAttachShader(m_program, vertexShader);
    glAttachShader(m_program, fragmentShader);
    glBindAttribLocation(m_program, 0, "vertices");
    glBindAttribLocation(m_program, 1, "a_texcoord");
    glLinkProgram(m_program);
}
void RGBRenderer::initTexture()
{
    glGenTextures(1, &m_textureID);
    glBindTexture(GL_TEXTURE_2D, m_textureID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_BGR, GL_UNSIGNED_BYTE, m_rgbData);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
}
void RGBRenderer::render()
{
    glUseProgram(m_program);
    glBindTexture(GL_TEXTURE_2D, m_textureID);
    glTexSubImage2D(GL_TEXTURE_2D, 0,0,0,m_width,m_height, GL_RGB,GL_UNSIGNED_BYTE, m_rgbData);
    glActiveTexture(GL_TEXTURE0);
    static float a = 0;
    QMatrix4x4 matrix;
    //+移近 -移远
    //matrix.translate(0.0, 0.0, 0.0f);
    matrix.rotate(a, 0.0f,0.0f,1.0f);
    a+=2;
    // Set modelview-projection matrix
    glUniformMatrix4fv(glGetUniformLocation(m_program, "mvp_matrix"), 1, GL_FALSE, (projection * matrix).data());
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    float values[] = {
        -200, -100,
         100, -100,
        -200,  100,
         100,  100
    };
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, values);
    float texs[] = {
        0, 1,
        1, 1,
        0, 0,
        1, 0
    };
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texs);
    glDisable(GL_DEPTH_TEST);
    glClearColor(0, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
}
doc: http://www.cnblogs.com/bitzhuwei/p/matrix-vs-projection.html
                                             
0 0