Change copyrights from Nokia to Digia
[profile/ivi/qtwayland.git] / examples / qwindow-compositor / textureblitter.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Compositor.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 **   * Redistributions of source code must retain the above copyright
15 **     notice, this list of conditions and the following disclaimer.
16 **   * Redistributions in binary form must reproduce the above copyright
17 **     notice, this list of conditions and the following disclaimer in
18 **     the documentation and/or other materials provided with the
19 **     distribution.
20 **   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 **     of its contributors may be used to endorse or promote products derived
22 **     from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 #include "textureblitter.h"
42
43 #include <QtGui/QOpenGLShaderProgram>
44 #include <QtGui/QOpenGLContext>
45 #include <QtGui/QOpenGLFunctions>
46
47 TextureBlitter::TextureBlitter()
48     : m_shaderProgram(new QOpenGLShaderProgram)
49 {
50     static const char *textureVertexProgram =
51             "uniform highp mat4 matrix;\n"
52             "attribute highp vec3 vertexCoordEntry;\n"
53             "attribute highp vec2 textureCoordEntry;\n"
54             "varying highp vec2 textureCoord;\n"
55             "void main() {\n"
56             "   textureCoord = textureCoordEntry;\n"
57             "   gl_Position = matrix * vec4(vertexCoordEntry, 1);\n"
58             "}\n";
59
60     static const char *textureFragmentProgram =
61             "uniform sampler2D texture;\n"
62             "varying highp vec2 textureCoord;\n"
63             "void main() {\n"
64             "   gl_FragColor = texture2D(texture, textureCoord);\n"
65             "}\n";
66
67     //Enable transparent windows
68     glEnable(GL_BLEND);
69     glBlendFunc (GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
70
71     m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
72     m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
73     m_shaderProgram->link();
74 }
75
76 TextureBlitter::~TextureBlitter()
77 {
78     delete m_shaderProgram;
79 }
80
81 void TextureBlitter::bind()
82 {
83
84     m_shaderProgram->bind();
85
86     m_vertexCoordEntry = m_shaderProgram->attributeLocation("vertexCoordEntry");
87     m_textureCoordEntry = m_shaderProgram->attributeLocation("textureCoordEntry");
88     m_matrixLocation = m_shaderProgram->uniformLocation("matrix");
89 }
90
91 void TextureBlitter::release()
92 {
93     m_shaderProgram->release();
94 }
95
96 void TextureBlitter::drawTexture(int textureId, const QRectF &targetRect, const QSize &targetSize, int depth, bool targethasInvertedY, bool sourceHasInvertedY)
97 {
98
99     glViewport(0,0,targetSize.width(),targetSize.height());
100     GLfloat zValue = depth / 1000.0f;
101     //Set Texture and Vertex coordinates
102     const GLfloat textureCoordinates[] = {
103         0, 0,
104         1, 0,
105         1, 1,
106         0, 1
107     };
108
109     int x1 = targetRect.left();
110     int x2 = targetRect.right();
111     int y1, y2;
112     if (targethasInvertedY) {
113         if (sourceHasInvertedY) {
114             y1 = targetRect.top();
115             y2 = targetRect.bottom();
116         } else {
117             y1 = targetRect.bottom();
118             y2 = targetRect.top();
119         }
120     } else {
121         if (sourceHasInvertedY) {
122             y1 = targetSize.height() - targetRect.top();
123             y2 = targetSize.height() - targetRect.bottom();
124         } else {
125             y1 = targetSize.height() - targetRect.bottom();
126             y2 = targetSize.height() - targetRect.top();
127         }
128     }
129
130     const GLfloat vertexCoordinates[] = {
131         x1, y1, zValue,
132         x2, y1, zValue,
133         x2, y2, zValue,
134         x1, y2, zValue
135     };
136
137     //Set matrix to transfrom geometry values into gl coordinate space.
138     m_transformMatrix.setToIdentity();
139     m_transformMatrix.scale( 2.0f / targetSize.width(), 2.0f / targetSize.height() );
140     m_transformMatrix.translate(-targetSize.width() / 2.0f, -targetSize.height() / 2.0f);
141
142     //attach the data!
143     QOpenGLContext *currentContext = QOpenGLContext::currentContext();
144     currentContext->functions()->glEnableVertexAttribArray(m_vertexCoordEntry);
145     currentContext->functions()->glEnableVertexAttribArray(m_textureCoordEntry);
146
147     currentContext->functions()->glVertexAttribPointer(m_vertexCoordEntry, 3, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
148     currentContext->functions()->glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
149     m_shaderProgram->setUniformValue(m_matrixLocation, m_transformMatrix);
150
151     glBindTexture(GL_TEXTURE_2D, textureId);
152
153     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
154     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
155
156     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
157
158     glBindTexture(GL_TEXTURE_2D, 0);
159
160     currentContext->functions()->glDisableVertexAttribArray(m_vertexCoordEntry);
161     currentContext->functions()->glDisableVertexAttribArray(m_textureCoordEntry);
162 }