summaryrefslogtreecommitdiffstats
path: root/examples/opengl/paintedwindow/paintedwindow.cpp
blob: b9ecac129377afb05f32483a63f1330cfea0a954 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "paintedwindow.h"

#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QPainter>
#include <QTimer>

#include <qmath.h>

PaintedWindow::PaintedWindow()
    : m_fbo(0)
{
    QSurfaceFormat format;
    format.setStencilBufferSize(8);

    setSurfaceType(QWindow::OpenGLSurface);
    setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
    setFormat(format);

    create();

    m_context = new QOpenGLContext(this);
    m_context->setFormat(format);
    m_context->create();

    QTimer *timer = new QTimer(this);
    timer->setInterval(16);
    connect(timer, SIGNAL(timeout()), this, SLOT(paint()));
    timer->start();

    m_context->makeCurrent(this);

    QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char *vsrc =
        "attribute highp vec2 vertexCoordsInput;\n"
        "attribute mediump vec2 texCoordsInput;\n"
        "varying mediump vec2 texCoords;\n"
        "void main(void)\n"
        "{\n"
        "    texCoords = texCoordsInput;\n"
        "    gl_Position = vec4(vertexCoordsInput, 0, 1);\n"
        "}\n";
    vshader->compileSourceCode(vsrc);

    QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fsrc =
        "uniform sampler2D tex;\n"
        "varying mediump vec2 texCoords;\n"
        "void main(void)\n"
        "{\n"
        "    gl_FragColor = texture2D(tex, texCoords);\n"
        "}\n";
    fshader->compileSourceCode(fsrc);

    m_program = new QOpenGLShaderProgram;
    m_program->addShader(vshader);
    m_program->addShader(fshader);
    m_program->link();

    m_vertexAttribute = m_program->attributeLocation("vertexCoordsInput");
    m_texCoordsAttribute = m_program->attributeLocation("texCoordsInput");
}

void PaintedWindow::resizeEvent(QResizeEvent *)
{
    m_context->makeCurrent(this);

    delete m_fbo;
    m_fbo = new QOpenGLFramebufferObject(size());
}

void PaintedWindow::paint()
{
    if (!m_fbo)
        return;

    m_context->makeCurrent(this);

    QPainterPath path;
    path.addEllipse(0, 0, m_fbo->width(), m_fbo->height());

    QPainter painter;
    painter.begin(m_fbo);
    painter.fillRect(0, 0, m_fbo->width(), m_fbo->height(), Qt::white);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.fillPath(path, Qt::blue);
    painter.end();

    glViewport(0, 0, width(), height());

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);
    glDisable(GL_BLEND);

    glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    GLfloat texCoords[] = { 0, 0, 1, 0, 0, 1,
                           1, 0, 1, 1, 0, 1 };

    GLfloat vertexCoords[] = { -1, -1, 1, -1, -1, 1,
                              1, -1, 1, 1, -1, 1 };

    m_program->bind();

    m_context->functions()->glEnableVertexAttribArray(m_vertexAttribute);
    m_context->functions()->glEnableVertexAttribArray(m_texCoordsAttribute);

    m_context->functions()->glVertexAttribPointer(m_vertexAttribute, 2, GL_FLOAT, GL_FALSE, 0, vertexCoords);
    m_context->functions()->glVertexAttribPointer(m_texCoordsAttribute, 2, GL_FLOAT, GL_FALSE, 0, texCoords);

    glBindTexture(GL_TEXTURE_2D, m_fbo->texture());

    glDrawArrays(GL_TRIANGLES, 0, 6);

    glBindTexture(GL_TEXTURE_2D, 0);

    m_context->functions()->glDisableVertexAttribArray(m_vertexAttribute);
    m_context->functions()->glDisableVertexAttribArray(m_texCoordsAttribute);

    m_program->release();

    m_context->swapBuffers(this);
}