2013年2月28日 星期四

3D text on Qt with OpenGL


利用QPainterPath算出polygon之後,就可以畫出邊框
QPainterPath path;
path.addText(QPointF(0, 0), QFont("Arial", 100), QString::fromUtf8("你要不要喝紅茶ˊ_>ˋ?"));
GLuint id = glGenLists(1);
glNewList(id, GL_COMPILE);
foreach(QPolygonF polygon, path.toSubpathPolygons()){
    glBegin(GL_LINE_LOOP);
    foreach(QPointF point, polygon){
        glVertex3f(point.rx(), -point.ry(), 0);
    }
    glEnd();
}
glEndList();


最後再利用glu提供的tessellation功能,繪出文字

#include <OpenGL/glu.h>
#ifndef CALLBACK
#define CALLBACK
#endif
typedef void (*TessFuncPtr)();

void CALLBACK tessBeginCB(GLenum which)
{
    glBegin(which);
}

void CALLBACK tessEndCB()
{
    glEnd();
}

void CALLBACK tessVertexCB(const GLvoid *data)
{
    const GLdouble *ptr = (const GLdouble*)data;
    glVertex3dv(ptr);
}
QPainterPath path;
path.addText(QPointF(0, 0), QFont("Arial", 100), QString::fromUtf8("你要不要喝紅茶ˊ_>ˋ?"));
GLuint id = glGenLists(1);
GLUtesselator *tess = gluNewTess();
gluTessCallback(tess, GLU_TESS_BEGIN, (TessFuncPtr)tessBeginCB);
gluTessCallback(tess, GLU_TESS_END, (TessFuncPtr)tessEndCB);
gluTessCallback(tess, GLU_TESS_VERTEX, (TessFuncPtr)tessVertexCB);
glNewList(id, GL_COMPILE);
gluTessBeginPolygon(tess, NULL);
    foreach(QPolygonF polygon, path.toSubpathPolygons()){
        GLdouble (*quad)[3] = new GLdouble[polygon.count()][3];
        for(int i=0; i<polygon.count(); i++){
            QPointF point = polygon.at(i);
            quad[i][0] = point.rx();
            quad[i][1] = -point.ry();
            quad[i][2] =  0;
        }
        gluTessBeginContour(tess);
        for(int i=0; i<polygon.count(); i++){
            gluTessVertex(tess, quad[i], quad[i]);
        }
        gluTessEndContour(tess);
    }
gluTessEndPolygon(tess);
glEndList();
gluDeleteTess(tess);

參考資料
http://stackoverflow.com/questions/3514935/3d-text-on-qglwidget-in-qt-4-6-3
http://gamedev.stackexchange.com/questions/35662/creating-a-3d-text-mesh-from-a-2d-glyph
http://stackoverflow.com/questions/406301/polygon-triangulation-with-holes

Source Code
https://bitbucket.org/yycking/3d-text

2 則留言:

匿名 提到...

阿勇大大你好, 請問一下這個範例是可以輸入文字後將他轉成3D模型檔案嗎
我嘗試了一下, 出來的網格連接雖然有個樣子 但很多錯誤, 能否討論一下呢@@?

阿勇 提到...

抱歉很久回這裡了,今天才看到你的留言
你說的很多錯誤,是指?