2015-01-29 21 views
10

Qt'nin eski sürümünde, renderText adı verilen güzel bir işlevle QGLWidget vardı. Şimdi QOpenGLWidget sınıfını kullanıyorum ve metin oluşturma işlevi eksik.QOpenGLWidget ile metin oluşturma

QOpenGLWidget kullanarak metin oluşturmanın kolay bir yolu var mı? OpenGL ile tüm metin oluşturma işlemini sıfırdan oluşturmak istemiyorum ...

+0

https://code.google.com/p/freetype-gl/ –

cevap

2

2B metin çizmek istediğiniz gibi, QPainter::drawText() kullanın. QOpenGLWidget'ta QPainter kullanma hakkında bilgi için bkz. here. QOpenGLWidgets üzerinde metin oluşturma için antialiasing kullanmak için bkz. here.
Eğer 2.5D metin çizmek istiyorsanız (3B sahneyi 2D metin ile hareket ettirerek) kendi sınıflarınızı oluşturmak için "çok zor" değilsiniz. Yazı tipi glifleriniz için bir doku oluşturmak için QFont ve QFontMetricsF'i kullanın, her bir glif için bir VB'yi bir VBO'ya yerleştirin ve bir dizedeki glifler için uygun dörtlü çizin ...

1

Bu işlevi kendiniz uygulayarak kendiniz uygulayabilirsiniz. eski Qt kaynak kodu.

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(); 
} 

projesi: QOpenGLWidget miras OpenGL Widget sınıfta

aşağıdaki yöntemleri uygulamak zorunda (bu örnekte bu GLBox var)

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; 
} 

ve son olarak transforme noktası:

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 
} 

Eğer renderText() gerekirse bağlantı noktasına sahip olduğundan Qt5 için QT4 uygulama sadece

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

burada sağlanan fonksiyonun imzasını değiştirmek emin olun ve artık bu konuda endişelenmenize gerek yok .

3

Jaba'nın yazdıklarına benzer bir çözüm yapmayı bitirdim. Ayrıca, yöntemin sonunda painter.end() yöntemini çağırmadığım sürece bazı grafik bozulmalarını da fark ettim.

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

Burada blogumda bu konuda daha fazla yayınlanmıştır: http://nils.schimmelmann.us/post/134971073937/migrating-from -qglwidget-için-qopenglwidget –