~ubuntu-branches/ubuntu/saucy/koffice/saucy

« back to all changes in this revision

Viewing changes to krita/ui/opengl/kis_texture_tile.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-12-06 15:30:09 UTC
  • mfrom: (0.13.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20101206153009-yf0dqbp9l7fzwxi8
Tags: 1:2.2.91-0ubuntu1
New upstream RC release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (c) 2010 Dmitry Kazakov <dimula73@gmail.com>
 
3
 *
 
4
 *  This program is free software; you can redistribute it and/or modify
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
 
8
 *
 
9
 *  This program is distributed in the hope that it will be useful,
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 *  GNU General Public License for more details.
 
13
 *
 
14
 *  You should have received a copy of the GNU General Public License
 
15
 *  along with this program; if not, write to the Free Software
 
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
17
 */
 
18
 
 
19
 
 
20
#include "kis_texture_tile.h"
 
21
 
 
22
 
 
23
#ifdef HAVE_OPENGL
 
24
 
 
25
 
 
26
inline QRectF relativeRect(const QRect &br /* baseRect */,
 
27
                           const QRect &cr /* childRect */,
 
28
                           const KisGLTexturesInfo *texturesInfo)
 
29
{
 
30
    const qreal x = qreal(cr.x() - br.x()) / texturesInfo->width;
 
31
    const qreal y = qreal(cr.y() - br.y()) / texturesInfo->height;
 
32
    const qreal w = qreal(cr.width()) / texturesInfo->width;
 
33
    const qreal h = qreal(cr.height()) / texturesInfo->height;
 
34
 
 
35
    return QRectF(x, y, w, h);
 
36
}
 
37
 
 
38
 
 
39
KisTextureTile::KisTextureTile(QRect imageRect, const KisGLTexturesInfo *texturesInfo,
 
40
                               const GLvoid *fillData)
 
41
 
 
42
    : m_tileRectInImagePixels(imageRect), m_texturesInfo(texturesInfo)
 
43
{
 
44
    m_textureRectInImagePixels =
 
45
        stretchRect(m_tileRectInImagePixels, texturesInfo->border);
 
46
 
 
47
    m_tileRectInTexturePixels = relativeRect(m_textureRectInImagePixels,
 
48
                                             m_tileRectInImagePixels,
 
49
                                             m_texturesInfo);
 
50
 
 
51
    glGenTextures(1, &m_textureId);
 
52
    glBindTexture(GL_TEXTURE_2D, m_textureId);
 
53
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
54
    glTexImage2D(GL_TEXTURE_2D, 0,
 
55
                 m_texturesInfo->format,
 
56
                 m_texturesInfo->width,
 
57
                 m_texturesInfo->height, 0,
 
58
                 GL_BGRA, GL_UNSIGNED_BYTE, fillData);
 
59
}
 
60
 
 
61
KisTextureTile::~KisTextureTile() {
 
62
    glDeleteTextures(1, &m_textureId);
 
63
}
 
64
 
 
65
void KisTextureTile::update(const KisTextureTileUpdateInfo &updateInfo) {
 
66
    glBindTexture(GL_TEXTURE_2D, m_textureId);
 
67
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
68
 
 
69
    if (updateInfo.isEntireTileUpdated()) {
 
70
 
 
71
        glTexImage2D(GL_TEXTURE_2D, 0,
 
72
                     m_texturesInfo->format,
 
73
                     m_texturesInfo->width,
 
74
                     m_texturesInfo->height, 0,
 
75
                     GL_BGRA, m_texturesInfo->type,
 
76
                     updateInfo.data());
 
77
    } else {
 
78
        QPoint patchOffset = updateInfo.patchOffset();
 
79
        QSize patchSize = updateInfo.patchSize();
 
80
 
 
81
        glTexSubImage2D(GL_TEXTURE_2D, 0,
 
82
                        patchOffset.x(), patchOffset.y(),
 
83
                        patchSize.width(), patchSize.height(),
 
84
                        GL_BGRA, m_texturesInfo->type,
 
85
                        updateInfo.data());
 
86
    }
 
87
 
 
88
    /**
 
89
     * On the boundaries of KisImage, there is a border-effect as well.
 
90
     * So we just repeat the bounding pixels of the image to make
 
91
     * bilinear interpolator happy.
 
92
     */
 
93
    repeatStripes(updateInfo);
 
94
}
 
95
 
 
96
inline void KisTextureTile::repeatStripes(const KisTextureTileUpdateInfo &updateInfo) {
 
97
    /**
 
98
     * WARN: This function can repeat stripes of 1px width only!
 
99
     */
 
100
 
 
101
    const int pixelSize = updateInfo.pixelSize();
 
102
    const QRect imageRect = m_texturesInfo->imageRect;
 
103
    const QPoint patchOffset = updateInfo.patchOffset();
 
104
    const QSize patchSize = updateInfo.patchSize();
 
105
    const QRect patchRect = QRect(m_textureRectInImagePixels.topLeft() +
 
106
                                  patchOffset,
 
107
                                  patchSize);
 
108
 
 
109
    if(imageRect.top() == patchRect.top()) {
 
110
        glTexSubImage2D(GL_TEXTURE_2D, 0,
 
111
                        patchOffset.x(), patchOffset.y() - 1,
 
112
                        patchSize.width(), 1,
 
113
                        GL_BGRA, m_texturesInfo->type,
 
114
                        updateInfo.data());
 
115
 
 
116
    }
 
117
 
 
118
    if(imageRect.bottom() == patchRect.bottom()) {
 
119
        int shift = patchSize.width() * (patchSize.height() - 1) *
 
120
            pixelSize;
 
121
 
 
122
        glTexSubImage2D(GL_TEXTURE_2D, 0,
 
123
                        patchOffset.x(), patchOffset.y() + patchSize.height(),
 
124
                        patchSize.width(), 1,
 
125
                        GL_BGRA, m_texturesInfo->type,
 
126
                        updateInfo.data() + shift);
 
127
 
 
128
    }
 
129
 
 
130
    if(imageRect.left() == patchRect.left()) {
 
131
        QByteArray columnBuffer(patchSize.height() * pixelSize, 0);
 
132
 
 
133
        quint8 *srcPtr = updateInfo.data();
 
134
        quint8 *dstPtr = (quint8*) columnBuffer.data();
 
135
        for(int i = 0; i < patchSize.height(); i++) {
 
136
            memcpy(dstPtr, srcPtr, pixelSize);
 
137
 
 
138
            srcPtr += patchSize.width() * pixelSize;
 
139
            dstPtr += pixelSize;
 
140
        }
 
141
 
 
142
        glTexSubImage2D(GL_TEXTURE_2D, 0,
 
143
                        patchOffset.x() - 1, patchOffset.y(),
 
144
                        1, patchSize.height(),
 
145
                        GL_BGRA, m_texturesInfo->type,
 
146
                        columnBuffer.constData());
 
147
    }
 
148
 
 
149
    if(imageRect.right() == patchRect.right()) {
 
150
        QByteArray columnBuffer(patchSize.height() * pixelSize, 0);
 
151
 
 
152
        quint8 *srcPtr = updateInfo.data() + (patchSize.width() - 1) * pixelSize;
 
153
        quint8 *dstPtr = (quint8*) columnBuffer.data();
 
154
        for(int i = 0; i < patchSize.height(); i++) {
 
155
            memcpy(dstPtr, srcPtr, pixelSize);
 
156
 
 
157
            srcPtr += patchSize.width() * pixelSize;
 
158
            dstPtr += pixelSize;
 
159
        }
 
160
 
 
161
        glTexSubImage2D(GL_TEXTURE_2D, 0,
 
162
                        patchOffset.x() + patchSize.width(), patchOffset.y(),
 
163
                        1, patchSize.height(),
 
164
                        GL_BGRA, m_texturesInfo->type,
 
165
                        columnBuffer.constData());
 
166
    }
 
167
 
 
168
}
 
169
 
 
170
void KisTextureTile::drawPoints() {
 
171
    /**
 
172
     * We create a float rect here to workaround Qt's
 
173
     * "history reasons" in calculation of right()
 
174
     * and bottom() coordinates of integer rects.
 
175
     */
 
176
    QRectF imageRect(m_tileRectInImagePixels);
 
177
    QPointF ipt;
 
178
    QPointF tpt;
 
179
 
 
180
    glBegin(GL_QUADS);
 
181
 
 
182
    ipt = imageRect.topLeft();
 
183
    tpt = m_tileRectInTexturePixels.topLeft();
 
184
    glTexCoord2f(tpt.x(), tpt.y());
 
185
    glVertex2f(ipt.x(), ipt.y());
 
186
 
 
187
    ipt = imageRect.topRight();
 
188
    tpt = m_tileRectInTexturePixels.topRight();
 
189
    glTexCoord2f(tpt.x(), tpt.y());
 
190
    glVertex2f(ipt.x(), ipt.y());
 
191
 
 
192
    ipt = imageRect.bottomRight();
 
193
    tpt = m_tileRectInTexturePixels.bottomRight();
 
194
    glTexCoord2f(tpt.x(), tpt.y());
 
195
    glVertex2f(ipt.x(), ipt.y());
 
196
 
 
197
    ipt = imageRect.bottomLeft();
 
198
    tpt = m_tileRectInTexturePixels.bottomLeft();
 
199
    glTexCoord2f(tpt.x(), tpt.y());
 
200
    glVertex2f(ipt.x(), ipt.y());
 
201
 
 
202
    glEnd();
 
203
}
 
204
 
 
205
 
 
206
#endif /* HAVE_OPENGL */
 
207