On 04 Nov 2014, at 23:20, Nuno Santos <nunosan...@imaginando.pt> wrote:

> Gunnar,
> 
> I have implemented a really basic node for text rendering on scene graph 
> based on my previous approach but adapter to Qt API. The setup code is below. 
> I can already draw a string on OpenGL but the characters are not smooth at 
> small sizes with a pixel font. With a non pixel font, even at big sizes the 
> size is not appearing really good. I was wondering if the method i’m 
> performing and/or setup is the most appropriated. 

Is the contents of the QImage correct? If so, then your geometry data is 
probably using the wrong texture or vertex coordinates. If you want to dig 
through Qt's sources, the equivalent bits for drawing pixel-by-pixel (aka 
Text.NativeRendering) fonts in Qt are in the 
qtdeclarative/src/quick/scenegraph/qsgdefaultglyphnode* files.

cheers,
Gunnar

PS, always use QImage::Format_ARGB32_Premultiplied or 
QImage::Format_RGBA32_Premultiplied when working alpha images with QPainter. It 
is faster than ARGB32.



> 
> Below is the code that draws the glyphs in a texture and then transfers it to 
> a texture. I haven’t included the texture mapping into the vertices but I 
> don’t think that’s the origin of the problem. I would love to have your 
> feedback on this. 
> 
> Regards,
> 
> Nuno
> 
> // setup
> 
> QFont font("OpenSans");
> font.setPixelSize(32);
> QFontMetrics fm(font);
> QPainter painter;
> 
> _gs = qMax(fm.maxWidth(), fm.height());
> _ts = nextPowerOfTwo(_gs)*16;
> 
> for (int i=0; i<256; i++)
> {
>     _glyphs[i].character = (char) i;
>     _glyphs[i].pos.setX((i % 16) * _gs);
>     _glyphs[i].pos.setY((i / 16) * _gs);
>     _glyphs[i].rect = fm.boundingRect(QChar((char) i));
> }
> 
> QImage image(_ts, _ts, QImage::Format_ARGB32);
> 
> painter.begin(&image);
> //painter.setRenderHint(QPainter::TextAntialiasing, false);
> //painter.setRenderHint(QPainter::SmoothPixmapTransform, false);
> painter.setFont(font);
> painter.setBrush(QBrush(Qt::white));
> painter.setPen(QPen(Qt::black));
> 
> for (int i=0; i<256; i++)
> {
>     painter.drawText(_glyphs[i].pos,QString(_glyphs[i].character));
> }
> 
> painter.end();
> 
> _geometry.setDrawingMode(GL_TRIANGLES);
> setGeometry(&_geometry);
> 
> QSGTexture *t = window->createTextureFromImage(image);
> 
> //t->setMipmapFiltering(QSGTexture::Nearest);
> //t->setFiltering(QSGTexture::Linear);
> 
> _material.setTexture(t);
> setMaterial(&_material);
> 
> On 03 Nov 2014, at 21:11, Gunnar Sletta <gun...@sletta.org> wrote:
> 
>> 
>> On 03 Nov 2014, at 17:15, Nuno Santos <nunosan...@imaginando.pt> wrote:
>> 
>>> Hi,
>>> 
>>> I’m trying to render text on scene graph. My strategy consists in creating 
>>> a texture with all the glyphs and then draw a specific subset of the 
>>> texture for each glyph. I have already done this for iOS and Android native 
>>> API’s but now, i’m porting my app to Qt/Qml and need to do it on scene 
>>> graph.
>> 
>> If you already have working GL code, then maybe 
>> QQuickWindow::beforeRendering() is a more straightforward way to get this 
>> working? You only need to go through scene graph API if you want this to 
>> interact with a QML UI.
>> 
>>> 
>>> My new node is extending QSGSimpleTextureNode. The code below is just for 
>>> the most basic test purpose. 
>> 
>> QSGSimpleTextureNode only supports drawing a textured quad. If you want to 
>> draw a bunch of glyphs on one node (like a word or a sentence), you probably 
>> want to use a QSGGeomtryNode with TexturedPoint2D as attribute set combined 
>> with a QSGTextureMaterial.
>> 
>>> 
>>> unsigned char *data = (unsigned char*) malloc(ts*ts*4);
>>> uint8_t * p = data;
>>> 
>>> for(int i=0; i<ts*ts; ++i)
>>> {
>>>   *p = 0; ++p;
>>>   *p = 255; ++p;
>>>   *p = 255; ++p;
>>>   *p = 0; ++p;
>>> }
>>> 
>>> glGenTextures(1, &_texture);
>>> 
>>> glBindTexture(GL_TEXTURE_2D, _texture);
>>> 
>>> glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
>>> glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
>>> glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ts, ts, 0, GL_RGBA, 
>>> GL_UNSIGNED_BYTE, data);
>> 
>> You create QSGTexture instances from a GL texture id with 
>> QQuickWindow::createTextureFromId(). If your texture has special needs, you 
>> can also subclass QSGTexture and reimplement the pure virtuals.
>> 
>>> 
>>> // how do I set data to the texture?
>>> setTexture()
>>> 
>>> free(data);
>>> 
>>> The essential question right now is how do I set my custom texture data to 
>>> a texture? 
>>> 
>>> I have a Googled a lot about QSGSimpleTextureNode and QSGTexture but 
>>> couldn’t find any clear example on how to do this.
>>> 
>>> Any thoughts?
>> 
>> There are several examples that show how the scene graph APIs work in the 
>> qtdeclarative/examples/quick/scenegraph folder. That is the place to start.
>> 
>> cheers,
>> Gunnar
>> 
>>> 
>>> Thanks,
>>> 
>>> Nuno Santos
>>> _______________________________________________
>>> Interest mailing list
>>> Interest@qt-project.org
>>> http://lists.qt-project.org/mailman/listinfo/interest
> 

_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to