Hi, Boud!<br><br>It still crashes on Virtual Box. I'm going to check it on old intel GMA without Virtual Box, but a bit later.<br><br><div class="gmail_quote">On Thu, May 16, 2013 at 6:07 PM, Boudewijn Rempt <span dir="ltr"><<a href="mailto:boud@valdyas.org" target="_blank">boud@valdyas.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Git commit 33fbffea6c44747336e6aeb09fed68612854f61e by Boudewijn Rempt.<br>
Committed on 16/05/2013 at 15:59.<br>
Pushed by rempt into branch 'krita-opengl2-rempt'.<br>
<br>
Also show the image properly.<br>
<br>
<a href="mailto:CCMAIL%3Akimageshop@kde.org">CCMAIL:kimageshop@kde.org</a><br>
<br>
Please, everyone who has a different gpu from me, build this branch<br>
and test painting, zooming, panning, everything. Checkout the<br>
krita-opengl2-rempt branch<br>
<br>
We can now also start testing on windows and osx...<br>
<br>
TODO:<br>
<br>
* reintegrate OCIO (which was fragment-only)<br>
* move the texture updating to a separate thread<br>
* move the canvas rendering to a separate thread<br>
* integrate with krita sketch, somehow<br>
* reimplement the opengl cursor outline<br>
* reimplement the gradient shaders (perhaps? Not sure how useful they were.)<br>
* reimplement the 3d cursors (low prio -- they were fun, but I guess no<br>
pro artist used them)<br>
* figure out a way to move the layerstack composition to the GPU?<br>
<br>
M +4 -1 krita/data/shaders/display.frag<br>
M +47 -148 krita/ui/opengl/kis_opengl_canvas2.cpp<br>
M +0 -19 krita/ui/opengl/kis_opengl_canvas2.h<br>
M +4 -0 krita/ui/opengl/kis_texture_tile.h<br>
<br>
<a href="http://commits.kde.org/calligra/33fbffea6c44747336e6aeb09fed68612854f61e" target="_blank">http://commits.kde.org/calligra/33fbffea6c44747336e6aeb09fed68612854f61e</a><br>
<br>
diff --git a/krita/data/shaders/display.frag b/krita/data/shaders/display.frag<br>
index 36c5aca..cd8462b 100644<br>
--- a/krita/data/shaders/display.frag<br>
+++ b/krita/data/shaders/display.frag<br>
@@ -1,6 +1,9 @@<br>
+/*<br>
+ * shader for handling scaling<br>
+ */<br>
uniform sampler2D texture0;<br>
<br>
-varying vec4 v_textureCoordinate;<br>
+varying mediump vec4 v_textureCoordinate;<br>
<br>
void main() {<br>
gl_FragColor = texture2D(texture0, v_textureCoordinate.st);<br>
diff --git a/krita/ui/opengl/kis_opengl_canvas2.cpp b/krita/ui/opengl/kis_opengl_canvas2.cpp<br>
index 8369a4b..e4eea83 100644<br>
--- a/krita/ui/opengl/kis_opengl_canvas2.cpp<br>
+++ b/krita/ui/opengl/kis_opengl_canvas2.cpp<br>
@@ -78,24 +78,18 @@ public:<br>
Private()<br>
: displayShader(0)<br>
, checkerShader(0)<br>
- , vertexBuffer(0)<br>
- , indexBuffer(0)<br>
{<br>
}<br>
<br>
~Private() {<br>
delete displayShader;<br>
delete checkerShader;<br>
- delete vertexBuffer;<br>
- delete indexBuffer;<br>
}<br>
<br>
KisOpenGLImageTexturesSP openGLImageTextures;<br>
<br>
QGLShaderProgram *displayShader;<br>
QGLShaderProgram *checkerShader;<br>
- QGLBuffer *vertexBuffer;<br>
- QGLBuffer *indexBuffer;<br>
};<br>
<br>
KisOpenGLCanvas2::KisOpenGLCanvas2(KisCanvas2 *canvas, KisCoordinatesConverter *coordinatesConverter, QWidget *parent, KisOpenGLImageTexturesSP imageTextures)<br>
@@ -180,7 +174,7 @@ void KisOpenGLCanvas2::paintEvent(QPaintEvent *)<br>
glClear(GL_COLOR_BUFFER_BIT);<br>
<br>
drawCheckers();<br>
- //drawImage();<br>
+ drawImage();<br>
<br>
QRect boundingRect = coordinatesConverter()->imageRectInWidgetPixels().toAlignedRect();<br>
<br>
@@ -263,65 +257,71 @@ void KisOpenGLCanvas2::drawImage()<br>
<br>
KisCoordinatesConverter *converter = coordinatesConverter();<br>
<br>
- QRectF widgetRect(0,0, width(), height());<br>
- QRectF widgetRectInImagePixels = converter->documentToImage(converter->widgetToDocument(widgetRect));<br>
-<br>
- qreal scaleX, scaleY;<br>
- converter->imageScale(&scaleX, &scaleY);<br>
-<br>
- QRect wr = widgetRectInImagePixels.toAlignedRect() &<br>
- m_d->openGLImageTextures->storedImageBounds();<br>
-<br>
m_d->displayShader->bind();<br>
<br>
- QVector3D imageSize(m_d->openGLImageTextures->storedImageBounds().width(),<br>
- m_d->openGLImageTextures->storedImageBounds().height(),<br>
- 0.f);<br>
-<br>
- QMatrix4x4 model;//(modelTransform);<br>
- m_d->displayShader->setUniformValue("modelMatrix", model);<br>
- model.scale(imageSize * scaleX);<br>
+ QMatrix4x4 projectionMatrix;<br>
+ projectionMatrix.setToIdentity();<br>
+ projectionMatrix.ortho(0, width(), height(), 0, NEAR_VAL, FAR_VAL);<br>
<br>
- //Set view/projection matrices<br>
- QMatrix4x4 view;//(textureTransform);<br>
- m_d->displayShader->setUniformValue("viewMatrix", view);<br>
+ // Set view/projection matrices<br>
+ QMatrix4x4 modelMatrix(coordinatesConverter()->imageToWidgetTransform());<br>
+ modelMatrix.optimize();<br>
+ modelMatrix = projectionMatrix * modelMatrix;<br>
+ m_d->displayShader->setUniformValue("modelViewProjection", modelMatrix);<br>
<br>
-// QMatrix4x4 textureMatrix;//(textureTransform);<br>
-// m_d->checkerShader->setUniformValue("textureMatrix", textureMatrix);<br>
+ QMatrix4x4 textureMatrix;<br>
+ textureMatrix.setToIdentity();<br>
+ m_d->displayShader->setUniformValue("textureMatrix", textureMatrix);<br>
<br>
- //Setup the geometry for rendering<br>
- m_d->vertexBuffer->bind();<br>
- m_d->indexBuffer->bind();<br>
+ QRectF widgetRect(0,0, width(), height());<br>
+ QRectF widgetRectInImagePixels = converter->documentToImage(converter->widgetToDocument(widgetRect));<br>
<br>
- m_d->displayShader->setAttributeBuffer("a_vertexPosition", GL_FLOAT, 0, 3);<br>
- m_d->displayShader->enableAttributeArray("a_vertexPosition");<br>
- m_d->displayShader->setAttributeBuffer("a_texturePosition", GL_FLOAT, 12 * sizeof(float), 2);<br>
- m_d->displayShader->enableAttributeArray("a_vertexPosition");<br>
- m_d->displayShader->setUniformValue("texture0", 0);<br>
+ qreal scaleX, scaleY;<br>
+ converter->imageScale(&scaleX, &scaleY);<br>
<br>
- // m_d->openGLImageTextures->activateHDRExposureProgram();<br>
+ QRect wr = widgetRectInImagePixels.toAlignedRect() & m_d->openGLImageTextures->storedImageBounds();<br>
<br>
int firstColumn = m_d->openGLImageTextures->xToCol(wr.left());<br>
int lastColumn = m_d->openGLImageTextures->xToCol(wr.right());<br>
int firstRow = m_d->openGLImageTextures->yToRow(wr.top());<br>
int lastRow = m_d->openGLImageTextures->yToRow(wr.bottom());<br>
<br>
- QMatrix4x4 proj;<br>
- proj.ortho(0, 0, width(), height(), NEAR_VAL, FAR_VAL);<br>
- m_d->displayShader->setUniformValue("projectionMatrix", proj);<br>
-<br>
for (int col = firstColumn; col <= lastColumn; col++) {<br>
for (int row = firstRow; row <= lastRow; row++) {<br>
<br>
KisTextureTile *tile =<br>
m_d->openGLImageTextures->getTextureTileCR(col, row);<br>
<br>
- //QRectF textureRect(tile->tileRectInTexturePixels());<br>
+ /*<br>
+ * We create a float rect here to workaround Qt's<br>
+ * "history reasons" in calculation of right()<br>
+ * and bottom() coordinates of integer rects.<br>
+ */<br>
+ QRectF textureRect(tile->tileRectInTexturePixels());<br>
QRectF modelRect(tile->tileRectInImagePixels());<br>
<br>
- model.translate(modelRect.x(), -modelRect.y());<br>
- model.scale(modelRect.width(), modelRect.height());<br>
- m_d->displayShader->setUniformValue("modelMatrix", model);<br>
+ //Setup the geometry for rendering<br>
+ QVector<QVector3D> vertices;<br>
+ vertices << QVector3D(modelRect.left(), modelRect.bottom(), 0.f)<br>
+ << QVector3D(modelRect.left(), modelRect.top(), 0.f)<br>
+ << QVector3D(modelRect.right(), modelRect.bottom(), 0.f)<br>
+ << QVector3D(modelRect.left(), modelRect.top(), 0.f)<br>
+ << QVector3D(modelRect.right(), modelRect.top(), 0.f)<br>
+ << QVector3D(modelRect.right(), modelRect.bottom(), 0.f);<br>
+<br>
+ m_d->displayShader->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE);<br>
+ m_d->displayShader->setAttributeArray(PROGRAM_VERTEX_ATTRIBUTE, vertices.constData());<br>
+<br>
+ QVector<QVector2D> texCoords;<br>
+ texCoords << QVector2D(textureRect.left(), textureRect.bottom())<br>
+ << QVector2D(textureRect.left(), textureRect.top())<br>
+ << QVector2D(textureRect.right(), textureRect.bottom())<br>
+ << QVector2D(textureRect.left(), textureRect.top())<br>
+ << QVector2D(textureRect.right(), textureRect.top())<br>
+ << QVector2D(textureRect.right(), textureRect.bottom());<br>
+<br>
+ m_d->displayShader->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE);<br>
+ m_d->displayShader->setAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE, texCoords.constData());<br>
<br>
glBindTexture(GL_TEXTURE_2D, tile->textureId());<br>
<br>
@@ -331,57 +331,16 @@ void KisOpenGLCanvas2::drawImage()<br>
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);<br>
}<br>
<br>
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);<br>
+ glDrawArrays(GL_TRIANGLES, 0, 6);<br>
<br>
}<br>
}<br>
<br>
// m_d->openGLImageTextures->deactivateHDRExposureProgram();<br>
-<br>
- m_d->vertexBuffer->release();<br>
- m_d->indexBuffer->release();<br>
+ glBindTexture(GL_TEXTURE_2D, 0);<br>
m_d->displayShader->release();<br>
}<br>
<br>
-void KisOpenGLCanvas2::saveGLState()<br>
-{<br>
- // Q_ASSERT(!m_d->GLStateSaved);<br>
-<br>
- // if (!m_d->GLStateSaved) {<br>
- // m_d->GLStateSaved = true;<br>
-<br>
- // glPushAttrib(GL_ALL_ATTRIB_BITS);<br>
- // glMatrixMode(GL_PROJECTION);<br>
- // glPushMatrix();<br>
- // glMatrixMode(GL_TEXTURE);<br>
- // glPushMatrix();<br>
- // glMatrixMode(GL_MODELVIEW);<br>
- // glPushMatrix();<br>
-<br>
- // glGetIntegerv(GL_CURRENT_PROGRAM, &m_d->savedCurrentProgram);<br>
- // glUseProgram(NO_PROGRAM);<br>
- // }<br>
-}<br>
-<br>
-void KisOpenGLCanvas2::restoreGLState()<br>
-{<br>
- // Q_ASSERT(m_d->GLStateSaved);<br>
-<br>
- // if (m_d->GLStateSaved) {<br>
- // m_d->GLStateSaved = false;<br>
-<br>
- // glMatrixMode(GL_PROJECTION);<br>
- // glPopMatrix();<br>
- // glMatrixMode(GL_TEXTURE);<br>
- // glPopMatrix();<br>
- // glMatrixMode(GL_MODELVIEW);<br>
- // glPopMatrix();<br>
- // glPopAttrib();<br>
-<br>
- // glUseProgram(m_d->savedCurrentProgram);<br>
- // }<br>
-}<br>
-<br>
void KisOpenGLCanvas2::initializeShaders()<br>
{<br>
<br>
@@ -406,68 +365,8 @@ void KisOpenGLCanvas2::initializeShaders()<br>
qDebug() << "OpenGL error" << glGetError();<br>
qFatal("Failed linking display shader");<br>
}<br>
-<br>
- m_d->vertexBuffer = new QGLBuffer(QGLBuffer::VertexBuffer);<br>
- m_d->vertexBuffer->create();<br>
- m_d->vertexBuffer->bind();<br>
-<br>
- QVector<float> vertices;<br>
- /*<br>
- * 0.0, 1.0 ---- 1.0, 1.0<br>
- * | |<br>
- * | |<br>
- * 0.0, 0.0 ---- 1.0, 0.0<br>
- */<br>
- vertices << 0.0f << 0.0f << 0.0f;<br>
- vertices << 0.0f << 1.0f << 0.0f;<br>
- vertices << 1.0f << 0.0f << 0.0f;<br>
- vertices << 1.0f << 1.0f << 0.0f;<br>
- int vertSize = sizeof(float) * vertices.count();<br>
-<br>
- // coordinates to convert vertex points to a position in the texture. Follows order of corner<br>
- // points in vertices<br>
- QVector<float> uvs;<br>
- uvs << 0.f << 0.f;<br>
- uvs << 0.f << 1.f;<br>
- uvs << 1.f << 0.f;<br>
- uvs << 1.f << 1.f;<br>
- int uvSize = sizeof(float) * uvs.count();<br>
-<br>
- m_d->vertexBuffer->allocate(vertSize + uvSize);<br>
- m_d->vertexBuffer->write(0, reinterpret_cast<void*>(vertices.data()), vertSize);<br>
- m_d->vertexBuffer->write(vertSize, reinterpret_cast<void*>(uvs.data()), uvSize);<br>
- m_d->vertexBuffer->release();<br>
-<br>
- m_d->indexBuffer = new QGLBuffer(QGLBuffer::IndexBuffer);<br>
- m_d->indexBuffer->create();<br>
- m_d->indexBuffer->bind();<br>
-<br>
- QVector<uint> indices;<br>
- // determines where opengl looks for vertex data. create two clockwise triangles from<br>
- // the points.<br>
- /*<br>
- * 1->-3<br>
- * |\ |<br>
- * ^ \ v<br>
- * | \|<br>
- * 0...2<br>
- */<br>
- indices << 0 << 1 << 2 << 1 << 3 << 2;<br>
- m_d->indexBuffer->allocate(reinterpret_cast<void*>(indices.data()), indices.size() * sizeof(uint));<br>
- m_d->indexBuffer->release();<br>
-}<br>
-<br>
-void KisOpenGLCanvas2::beginOpenGL(void)<br>
-{<br>
- // saveGLState();<br>
}<br>
<br>
-void KisOpenGLCanvas2::endOpenGL(void)<br>
-{<br>
- // restoreGLState();<br>
-}<br>
-<br>
-<br>
void KisOpenGLCanvas2::slotConfigChanged()<br>
{<br>
notifyConfigChanged();<br>
diff --git a/krita/ui/opengl/kis_opengl_canvas2.h b/krita/ui/opengl/kis_opengl_canvas2.h<br>
index 4f76dde..40f5438 100644<br>
--- a/krita/ui/opengl/kis_opengl_canvas2.h<br>
+++ b/krita/ui/opengl/kis_opengl_canvas2.h<br>
@@ -56,22 +56,6 @@ public:<br>
<br>
virtual ~KisOpenGLCanvas2();<br>
<br>
- /**<br>
- * Prepare the canvas for rendering using native OpenGL<br>
- * commands. This sets the projection and model view matrices so<br>
- * that primitives can be rendered using coordinates returned<br>
- * from pixelToView().<br>
- */<br>
- void beginOpenGL();<br>
-<br>
- /**<br>
- * Notify the canvas that rendering using native OpenGL commands<br>
- * has finished. This restores the state so that the canvas can<br>
- * be painted on using a QPainter.<br>
- */<br>
- void endOpenGL();<br>
-<br>
-<br>
public: // QWidget<br>
<br>
/// reimplemented method from superclass<br>
@@ -108,9 +92,6 @@ private:<br>
void drawCheckers();<br>
<br>
void initializeShaders();<br>
-<br>
- void saveGLState();<br>
- void restoreGLState();<br>
};<br>
<br>
#endif // HAVE_OPENGL<br>
diff --git a/krita/ui/opengl/kis_texture_tile.h b/krita/ui/opengl/kis_texture_tile.h<br>
index 9a3517e..60fd6f6 100644<br>
--- a/krita/ui/opengl/kis_texture_tile.h<br>
+++ b/krita/ui/opengl/kis_texture_tile.h<br>
@@ -74,6 +74,10 @@ public:<br>
return m_textureRectInImagePixels;<br>
}<br>
<br>
+ inline QRectF tileRectInTexturePixels() {<br>
+ return m_tileRectInTexturePixels;<br>
+ }<br>
+<br>
private:<br>
void repeatStripes(const KisTextureTileUpdateInfo &updateInfo);<br>
<br>
_______________________________________________<br>
Krita mailing list<br>
<a href="mailto:kimageshop@kde.org">kimageshop@kde.org</a><br>
<a href="https://mail.kde.org/mailman/listinfo/kimageshop" target="_blank">https://mail.kde.org/mailman/listinfo/kimageshop</a><br>
</blockquote></div><br><br clear="all"><br>-- <br>Dmitry Kazakov