2015-01-29 14 views

risposta

2

Come sembra che tu voglia disegnare testo 2D, usa QPainter::drawText(). Vedere here per informazioni sull'utilizzo di QPainter su un QOpenGLWidget. Per utilizzare l'antialias per il rendering del testo su QOpenGLWidgets, vedere here.
Se si desidera disegnare testo 2.5D (testo 2D in movimento con la scena 3D) non è "troppo difficile" eseguire il rollover delle proprie classi. Usa QFont e QFontMetricsF per costruire una trama per i tuoi glifi dei caratteri, costruisci alcuni quad per ciascun glifo in un VBO e disegna i quad adatti per i glifi in una stringa ...

1

Puoi implementare questa funzionalità da solo in base alla vecchio codice sorgente Qt.

Nel tuo widget OpenGL classe ereditata da QOpenGLWidget (in questo esempio si tratta di GLBox) è necessario implementare i seguenti metodi:

renderText:

void GLBox::renderText(D3DVECTOR &textPosWorld, QString text) 
{ 
    int width = this->width(); 
    int height = this->height(); 

    GLdouble model[4][4], proj[4][4]; 
    GLint view[4]; 
    glGetDoublev(GL_MODELVIEW_MATRIX, &model[0][0]); 
    glGetDoublev(GL_PROJECTION_MATRIX, &proj[0][0]); 
    glGetIntegerv(GL_VIEWPORT, &view[0]); 
    GLdouble textPosX = 0, textPosY = 0, textPosZ = 0; 

    project(textPosWorld.x, textPosWorld.y, textPosWorld.z, 
       &model[0][0], &proj[0][0], &view[0], 
       &textPosX, &textPosY, &textPosZ); 

    textPosY = height - textPosY; // y is inverted 

    QPainter painter(this); 
    painter.setPen(Qt::yellow); 
    painter.setFont(QFont("Helvetica", 8)); 
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); 
    painter.drawText(textPosX, textPosY, text); // z = pointT4.z + distOverOp/4 
    painter.end(); 
} 

progetto:

inline GLint GLBox::project(GLdouble objx, GLdouble objy, GLdouble objz, 
    const GLdouble model[16], const GLdouble proj[16], 
    const GLint viewport[4], 
    GLdouble * winx, GLdouble * winy, GLdouble * winz) 
{ 
    GLdouble in[4], out[4]; 

    in[0] = objx; 
    in[1] = objy; 
    in[2] = objz; 
    in[3] = 1.0; 
    transformPoint(out, model, in); 
    transformPoint(in, proj, out); 

    if (in[3] == 0.0) 
     return GL_FALSE; 

    in[0] /= in[3]; 
    in[1] /= in[3]; 
    in[2] /= in[3]; 

    *winx = viewport[0] + (1 + in[0]) * viewport[2]/2; 
    *winy = viewport[1] + (1 + in[1]) * viewport[3]/2; 

    *winz = (1 + in[2])/2; 
    return GL_TRUE; 
} 

e finalmente transformPoint:

inline void GLBox::transformPoint(GLdouble out[4], const GLdouble m[16], const GLdouble in[4]) 
{ 
#define M(row,col) m[col*4+row] 
    out[0] = 
     M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3]; 
    out[1] = 
     M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3]; 
    out[2] = 
     M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3]; 
    out[3] = 
     M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3]; 
#undef M 
} 

Se avete bisogno di renderText() perché bisogna porta l'applicazione Qt4 per QT5 solo fare in modo di cambiare la firma della funzione fornita qui per

void GLBox::renderText(double x, double y, double z, const QString & str, const QFont & font = QFont(), int listBase = 2000) 

e non devono preoccuparsi di questo più .

3

Ho finito per fare una soluzione simile a ciò che @jaba ha scritto. Ho notato anche alcuni problemi di corruzione grafica a meno che non avessi chiamato painter.end() alla fine del metodo.

void MapCanvas::renderText(double x, double y, double z, const QString &str, const QFont & font = QFont()) { 
    // Identify x and y locations to render text within widget 
    int height = this->height(); 
    GLdouble textPosX = 0, textPosY = 0, textPosZ = 0; 
    project(x, y, 0f, &textPosX, &textPosY, &textPosZ); 
    textPosY = height - textPosY; // y is inverted 

    // Retrieve last OpenGL color to use as a font color 
    GLdouble glColor[4]; 
    glGetDoublev(GL_CURRENT_COLOR, glColor); 
    QColor fontColor = QColor(glColor[0], glColor[1], glColor[2], glColor[3]); 

    // Render text 
    QPainter painter(this); 
    painter.setPen(fontColor); 
    painter.setFont(font); 
    painter.drawText(textPosX, textPosY, text); 
    painter.end(); 
} 
+0

ho postato più su questo sul mio blog qui: http://nils.schimmelmann.us/post/134971073937/migrating-from -qglwidget-to-qopenglwidget –

Problemi correlati