[calligra/krita-opengl2-rempt] krita: Also show the image properly.

Boudewijn Rempt boud at valdyas.org
Thu May 16 14:07:03 UTC 2013


Git commit 33fbffea6c44747336e6aeb09fed68612854f61e by Boudewijn Rempt.
Committed on 16/05/2013 at 15:59.
Pushed by rempt into branch 'krita-opengl2-rempt'.

Also show the image properly.

CCMAIL:kimageshop at kde.org

Please, everyone who has a different gpu from me, build this branch
and test painting, zooming, panning, everything. Checkout the
krita-opengl2-rempt branch

We can now also start testing on windows and osx...

TODO:

* reintegrate OCIO (which was fragment-only)
* move the texture updating to a separate thread
* move the canvas rendering to a separate thread
* integrate with krita sketch, somehow
* reimplement the opengl cursor outline
* reimplement the gradient shaders (perhaps? Not sure how useful they were.)
* reimplement the 3d cursors (low prio -- they were fun, but I guess no
pro artist used them)
* figure out a way to move the layerstack composition to the GPU?

M  +4    -1    krita/data/shaders/display.frag
M  +47   -148  krita/ui/opengl/kis_opengl_canvas2.cpp
M  +0    -19   krita/ui/opengl/kis_opengl_canvas2.h
M  +4    -0    krita/ui/opengl/kis_texture_tile.h

http://commits.kde.org/calligra/33fbffea6c44747336e6aeb09fed68612854f61e

diff --git a/krita/data/shaders/display.frag b/krita/data/shaders/display.frag
index 36c5aca..cd8462b 100644
--- a/krita/data/shaders/display.frag
+++ b/krita/data/shaders/display.frag
@@ -1,6 +1,9 @@
+/*
+ * shader for handling scaling
+ */
 uniform sampler2D texture0;
 
-varying vec4 v_textureCoordinate;
+varying mediump vec4 v_textureCoordinate;
 
 void main() {
     gl_FragColor = texture2D(texture0, v_textureCoordinate.st);
diff --git a/krita/ui/opengl/kis_opengl_canvas2.cpp b/krita/ui/opengl/kis_opengl_canvas2.cpp
index 8369a4b..e4eea83 100644
--- a/krita/ui/opengl/kis_opengl_canvas2.cpp
+++ b/krita/ui/opengl/kis_opengl_canvas2.cpp
@@ -78,24 +78,18 @@ public:
     Private()
         : displayShader(0)
         , checkerShader(0)
-        , vertexBuffer(0)
-        , indexBuffer(0)
     {
     }
 
     ~Private() {
         delete displayShader;
         delete checkerShader;
-        delete vertexBuffer;
-        delete indexBuffer;
     }
 
     KisOpenGLImageTexturesSP openGLImageTextures;
 
     QGLShaderProgram *displayShader;
     QGLShaderProgram *checkerShader;
-    QGLBuffer *vertexBuffer;
-    QGLBuffer *indexBuffer;
 };
 
 KisOpenGLCanvas2::KisOpenGLCanvas2(KisCanvas2 *canvas, KisCoordinatesConverter *coordinatesConverter, QWidget *parent, KisOpenGLImageTexturesSP imageTextures)
@@ -180,7 +174,7 @@ void KisOpenGLCanvas2::paintEvent(QPaintEvent *)
     glClear(GL_COLOR_BUFFER_BIT);
 
     drawCheckers();
-    //drawImage();
+    drawImage();
 
     QRect boundingRect = coordinatesConverter()->imageRectInWidgetPixels().toAlignedRect();
 
@@ -263,65 +257,71 @@ void KisOpenGLCanvas2::drawImage()
 
     KisCoordinatesConverter *converter = coordinatesConverter();
 
-    QRectF widgetRect(0,0, width(), height());
-    QRectF widgetRectInImagePixels = converter->documentToImage(converter->widgetToDocument(widgetRect));
-
-    qreal scaleX, scaleY;
-    converter->imageScale(&scaleX, &scaleY);
-
-    QRect wr = widgetRectInImagePixels.toAlignedRect() &
-            m_d->openGLImageTextures->storedImageBounds();
-
     m_d->displayShader->bind();
 
-    QVector3D imageSize(m_d->openGLImageTextures->storedImageBounds().width(),
-                        m_d->openGLImageTextures->storedImageBounds().height(),
-                        0.f);
-
-    QMatrix4x4 model;//(modelTransform);
-    m_d->displayShader->setUniformValue("modelMatrix", model);
-    model.scale(imageSize * scaleX);
+    QMatrix4x4 projectionMatrix;
+    projectionMatrix.setToIdentity();
+    projectionMatrix.ortho(0, width(), height(), 0, NEAR_VAL, FAR_VAL);
 
-    //Set view/projection matrices
-    QMatrix4x4 view;//(textureTransform);
-    m_d->displayShader->setUniformValue("viewMatrix", view);
+    // Set view/projection matrices
+    QMatrix4x4 modelMatrix(coordinatesConverter()->imageToWidgetTransform());
+    modelMatrix.optimize();
+    modelMatrix = projectionMatrix * modelMatrix;
+    m_d->displayShader->setUniformValue("modelViewProjection", modelMatrix);
 
-//    QMatrix4x4 textureMatrix;//(textureTransform);
-//    m_d->checkerShader->setUniformValue("textureMatrix", textureMatrix);
+    QMatrix4x4 textureMatrix;
+    textureMatrix.setToIdentity();
+    m_d->displayShader->setUniformValue("textureMatrix", textureMatrix);
 
-    //Setup the geometry for rendering
-    m_d->vertexBuffer->bind();
-    m_d->indexBuffer->bind();
+    QRectF widgetRect(0,0, width(), height());
+    QRectF widgetRectInImagePixels = converter->documentToImage(converter->widgetToDocument(widgetRect));
 
-    m_d->displayShader->setAttributeBuffer("a_vertexPosition", GL_FLOAT, 0, 3);
-    m_d->displayShader->enableAttributeArray("a_vertexPosition");
-    m_d->displayShader->setAttributeBuffer("a_texturePosition", GL_FLOAT, 12 * sizeof(float), 2);
-    m_d->displayShader->enableAttributeArray("a_vertexPosition");
-    m_d->displayShader->setUniformValue("texture0", 0);
+    qreal scaleX, scaleY;
+    converter->imageScale(&scaleX, &scaleY);
 
-    //    m_d->openGLImageTextures->activateHDRExposureProgram();
+    QRect wr = widgetRectInImagePixels.toAlignedRect() & m_d->openGLImageTextures->storedImageBounds();
 
     int firstColumn = m_d->openGLImageTextures->xToCol(wr.left());
     int lastColumn = m_d->openGLImageTextures->xToCol(wr.right());
     int firstRow = m_d->openGLImageTextures->yToRow(wr.top());
     int lastRow = m_d->openGLImageTextures->yToRow(wr.bottom());
 
-    QMatrix4x4 proj;
-    proj.ortho(0, 0, width(), height(), NEAR_VAL, FAR_VAL);
-    m_d->displayShader->setUniformValue("projectionMatrix", proj);
-
     for (int col = firstColumn; col <= lastColumn; col++) {
         for (int row = firstRow; row <= lastRow; row++) {
 
             KisTextureTile *tile =
                     m_d->openGLImageTextures->getTextureTileCR(col, row);
 
-            //QRectF textureRect(tile->tileRectInTexturePixels());
+            /*
+             * We create a float rect here to workaround Qt's
+             * "history reasons" in calculation of right()
+             * and bottom() coordinates of integer rects.
+             */
+            QRectF textureRect(tile->tileRectInTexturePixels());
             QRectF modelRect(tile->tileRectInImagePixels());
 
-            model.translate(modelRect.x(), -modelRect.y());
-            model.scale(modelRect.width(), modelRect.height());
-            m_d->displayShader->setUniformValue("modelMatrix", model);
+            //Setup the geometry for rendering
+            QVector<QVector3D> vertices;
+            vertices << QVector3D(modelRect.left(),  modelRect.bottom(), 0.f)
+                     << QVector3D(modelRect.left(),  modelRect.top(),    0.f)
+                     << QVector3D(modelRect.right(), modelRect.bottom(), 0.f)
+                     << QVector3D(modelRect.left(),  modelRect.top(), 0.f)
+                     << QVector3D(modelRect.right(), modelRect.top(), 0.f)
+                     << QVector3D(modelRect.right(), modelRect.bottom(),    0.f);
+
+            m_d->displayShader->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE);
+            m_d->displayShader->setAttributeArray(PROGRAM_VERTEX_ATTRIBUTE, vertices.constData());
+
+            QVector<QVector2D> texCoords;
+            texCoords << QVector2D(textureRect.left(), textureRect.bottom())
+                      << QVector2D(textureRect.left(), textureRect.top())
+                      << QVector2D(textureRect.right(), textureRect.bottom())
+                      << QVector2D(textureRect.left(), textureRect.top())
+                      << QVector2D(textureRect.right(), textureRect.top())
+                      << QVector2D(textureRect.right(), textureRect.bottom());
+
+            m_d->displayShader->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE);
+            m_d->displayShader->setAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE, texCoords.constData());
 
             glBindTexture(GL_TEXTURE_2D, tile->textureId());
 
@@ -331,57 +331,16 @@ void KisOpenGLCanvas2::drawImage()
                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
             }
 
-            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+            glDrawArrays(GL_TRIANGLES, 0, 6);
 
         }
     }
 
     //    m_d->openGLImageTextures->deactivateHDRExposureProgram();
-
-    m_d->vertexBuffer->release();
-    m_d->indexBuffer->release();
+    glBindTexture(GL_TEXTURE_2D, 0);
     m_d->displayShader->release();
 }
 
-void KisOpenGLCanvas2::saveGLState()
-{
-    //    Q_ASSERT(!m_d->GLStateSaved);
-
-    //    if (!m_d->GLStateSaved) {
-    //        m_d->GLStateSaved = true;
-
-    //        glPushAttrib(GL_ALL_ATTRIB_BITS);
-    //        glMatrixMode(GL_PROJECTION);
-    //        glPushMatrix();
-    //        glMatrixMode(GL_TEXTURE);
-    //        glPushMatrix();
-    //        glMatrixMode(GL_MODELVIEW);
-    //        glPushMatrix();
-
-    //        glGetIntegerv(GL_CURRENT_PROGRAM, &m_d->savedCurrentProgram);
-    //        glUseProgram(NO_PROGRAM);
-    //    }
-}
-
-void KisOpenGLCanvas2::restoreGLState()
-{
-    //    Q_ASSERT(m_d->GLStateSaved);
-
-    //    if (m_d->GLStateSaved) {
-    //        m_d->GLStateSaved = false;
-
-    //        glMatrixMode(GL_PROJECTION);
-    //        glPopMatrix();
-    //        glMatrixMode(GL_TEXTURE);
-    //        glPopMatrix();
-    //        glMatrixMode(GL_MODELVIEW);
-    //        glPopMatrix();
-    //        glPopAttrib();
-
-    //        glUseProgram(m_d->savedCurrentProgram);
-    //    }
-}
-
 void KisOpenGLCanvas2::initializeShaders()
 {
 
@@ -406,68 +365,8 @@ void KisOpenGLCanvas2::initializeShaders()
         qDebug() << "OpenGL error" << glGetError();
         qFatal("Failed linking display shader");
     }
-
-    m_d->vertexBuffer = new QGLBuffer(QGLBuffer::VertexBuffer);
-    m_d->vertexBuffer->create();
-    m_d->vertexBuffer->bind();
-
-    QVector<float> vertices;
-    /*
-     *  0.0, 1.0  ---- 1.0, 1.0
-     *     |              |
-     *     |              |
-     *  0.0, 0.0  ---- 1.0, 0.0
-     */
-    vertices << 0.0f << 0.0f << 0.0f;
-    vertices << 0.0f << 1.0f << 0.0f;
-    vertices << 1.0f << 0.0f << 0.0f;
-    vertices << 1.0f << 1.0f << 0.0f;
-    int vertSize = sizeof(float) * vertices.count();
-
-    // coordinates to convert vertex points to a position in the texture. Follows order of corner
-    // points in vertices
-    QVector<float> uvs;
-    uvs << 0.f << 0.f;
-    uvs << 0.f << 1.f;
-    uvs << 1.f << 0.f;
-    uvs << 1.f << 1.f;
-    int uvSize = sizeof(float) * uvs.count();
-
-    m_d->vertexBuffer->allocate(vertSize + uvSize);
-    m_d->vertexBuffer->write(0, reinterpret_cast<void*>(vertices.data()), vertSize);
-    m_d->vertexBuffer->write(vertSize, reinterpret_cast<void*>(uvs.data()), uvSize);
-    m_d->vertexBuffer->release();
-
-    m_d->indexBuffer = new QGLBuffer(QGLBuffer::IndexBuffer);
-    m_d->indexBuffer->create();
-    m_d->indexBuffer->bind();
-
-    QVector<uint> indices;
-    // determines where opengl looks for vertex data. create two clockwise triangles from
-    // the points.
-    /*
-     *  1->-3
-     *  |\  |
-     *  ^ \ v
-     *  |  \|
-     *  0...2
-     */
-    indices << 0 << 1 << 2 << 1 << 3 << 2;
-    m_d->indexBuffer->allocate(reinterpret_cast<void*>(indices.data()), indices.size() * sizeof(uint));
-    m_d->indexBuffer->release();
-}
-
-void KisOpenGLCanvas2::beginOpenGL(void)
-{
-    //    saveGLState();
 }
 
-void KisOpenGLCanvas2::endOpenGL(void)
-{
-    //    restoreGLState();
-}
-
-
 void KisOpenGLCanvas2::slotConfigChanged()
 {
     notifyConfigChanged();
diff --git a/krita/ui/opengl/kis_opengl_canvas2.h b/krita/ui/opengl/kis_opengl_canvas2.h
index 4f76dde..40f5438 100644
--- a/krita/ui/opengl/kis_opengl_canvas2.h
+++ b/krita/ui/opengl/kis_opengl_canvas2.h
@@ -56,22 +56,6 @@ public:
 
     virtual ~KisOpenGLCanvas2();
 
-    /**
-     * Prepare the canvas for rendering using native OpenGL
-     * commands. This sets the projection and model view matrices so
-     * that primitives can be rendered using coordinates returned
-     * from pixelToView().
-     */
-    void beginOpenGL();
-
-    /**
-     * Notify the canvas that rendering using native OpenGL commands
-     * has finished. This restores the state so that the canvas can
-     * be painted on using a QPainter.
-     */
-    void endOpenGL();
-
-
 public: // QWidget
 
     /// reimplemented method from superclass
@@ -108,9 +92,6 @@ private:
     void drawCheckers();
 
     void initializeShaders();
-
-    void saveGLState();
-    void restoreGLState();
 };
 
 #endif // HAVE_OPENGL
diff --git a/krita/ui/opengl/kis_texture_tile.h b/krita/ui/opengl/kis_texture_tile.h
index 9a3517e..60fd6f6 100644
--- a/krita/ui/opengl/kis_texture_tile.h
+++ b/krita/ui/opengl/kis_texture_tile.h
@@ -74,6 +74,10 @@ public:
         return m_textureRectInImagePixels;
     }
 
+    inline QRectF tileRectInTexturePixels() {
+        return m_tileRectInTexturePixels;
+    }
+
 private:
     void repeatStripes(const KisTextureTileUpdateInfo &updateInfo);
 


More information about the kimageshop mailing list