[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