2015-07-16 1 views
0

J'ai un QOpenGLWidget dans lequel je dessine du texte avec un QPainter. Je voudrais implémenter une fonctionnalité snapshot en rendant le contenu du widget dans un QOpenGLFrameBuffer et en convertissant le tampon de trame en QImage.PointSize valide pour QFont

Malheureusement, si la taille du point de la police est trop élevée (> 46), le texte apparaît sous la forme d'une barre noire dans l'instantané, alors que dans le widget, il s'affiche correctement. Voir ci-dessous un aperçu exemple où le bloc sur la ligne est censé être un texte avec la taille de la police> 46. The block over the black line is supposed to be some text

Voici le code simplifié pour rendre l'image (il devrait fonctionner, car il est affiché correctement dans le QOpenGLWidget):

void renderSomething(const int x, const int y, const QString & str, const int fontSize) { 
    // 1. draw the line 
    // (calculate min_x, max_x, y and z values) 
    glLineWidth(3); 
    glColor3f(0., 0., 0.); 
    glBegin(GL_LINES); 
    glVertex3f(min_x, y, z); 
    glVertex3f(max_x, y, z); 
    glEnd(); 

    // 2. draw the text 
    GLint gl_viewport[4]; 
    glGetIntegerv(GL_VIEWPORT, gl_viewport); 
    backup_gl_state(); 
    QOpenGLPaintDevice paintDevice(gl_viewport[2], gl_viewport[3]); 
    QPainter painter(&paintDevice); 
    painter.setFont(QFont(painter.font().family(), fontSize); 
    painter.setPen(Qt::black); 
    painter.drawText(x, y, str); 
    painter.end(); 
    restore_gl_state(); 
} 

Voici le code pour stocker un instantané:

void Viewport::takeSnapshot(const QString & path, const int size) { 
    glPushAttrib(GL_VIEWPORT_BIT); 
    glViewport(0, 0, size, size); // since size varies I want the text to scale with it 
    QOpenGLFramebufferObject fbo(size, size, QOpenGLFramebufferObject::Depth); 
    fbo.bind(); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    renderer.renderSomething(100, 100, "Test", 50); // Here is the render call! 

    QImage fboImage(fbo.toImage()); 
    QImage image(fboImage.constBits(), fboImage.width(), fboImage.height(), QImage::Format_RGB32); 
    image.save(path); 
    glPopAttrib(); 
    fbo.bindDefault(); 
    fbo.release(); 
} 

EDIT

J'ai trouvé une solution de contournement en utilisant QPainter pour dessiner directement le texte sur QImage au lieu de dessiner dans le FBO. Pas de barre noire plus, mais cela complique mon code et je serais heureux de trouver une véritable solution ...

Répondre

0

La solution était simple: Relisez the documentation on QOpenGLFrameBufferObject dans lequel il est dit:

Créer le QOpenGLFrameBufferObject instance avec la pièce jointe CombinedDepthStencil si vous voulez que QPainter soit rendu correctement.

Je n'ai attaché qu'un tampon de profondeur. L'initialisation correcte serait:

QOpenGLFramebufferObject fbo(size, size, QOpenGLFramebufferObject::CombinedDepthStencil);