2012-09-26 65 views
3

如果我只想使用一個頂點數組格式,那麼渲染我生成的數據相當困難。強制GLUtesselator只生成GL_TRIANGLES?

我試圖提供GLU_TESS_EDGE_FLAG_DATA回調,但它使我的程序崩潰。 (在最後也嘗試沒有「_DATA」,效果相同)。

我怎樣才能得到它只生成GL_TRIANGLES?

+0

你的回撥是什麼? – Calvin1602

+0

@ Calvin1602,哪一個?我有5 gluTessCallback()的 – Rookie

回答

5

gluTessCallback()GLU_TESS_EDGE_FLAG

...如果提供一個非空邊緣標誌回調...風扇和帶被轉換爲獨立的三角形。

這是我一直使用的是什麼:

struct TessContext 
{ 
    ~TessContext() 
    { 
     for(size_t i = 0; i < combined.size(); ++i) 
     { 
      delete[] combined[i]; 
     } 
    } 

    typedef std::pair< double, double > Point; 
    std::vector<Point> pts; 
    std::vector< GLdouble* > combined; 
}; 

#ifndef CALLBACK 
#define CALLBACK __stdcall 
#endif 

void CALLBACK tess_begin(GLenum) {} 
void CALLBACK tess_edgeFlag(GLboolean) {} 
void CALLBACK tess_end() {} 

void CALLBACK tess_vertex 
    ( 
    void*   data, 
    TessContext* ctx 
    ) 
{ 
    GLdouble* coord = (GLdouble*)data; 
    ctx->pts.push_back(TessContext::Point(coord[0], coord[1])); 
} 

void CALLBACK tess_combine 
    ( 
    GLdouble  coords[3], 
    void*   vertex_data[4], 
    GLfloat   weight[4], 
    void**   outData, 
    TessContext* ctx 
    ) 
{ 
    GLdouble* newVert = new GLdouble[3]; 
    ctx->combined.push_back(newVert); 

    newVert[0] = coords[0]; 
    newVert[1] = coords[1]; 
    newVert[2] = coords[2]; 
    *outData = newVert; 
} 

template< typename Vec > 
std::vector<Vec> Triangulate 
    ( 
    const vector<Vec>& aSimplePolygon 
    ) 
{ 
    std::vector<GLdouble> coords; 
    for(size_t i = 0; i < aSimplePolygon.size(); ++i) 
    { 
     coords.push_back(aSimplePolygon[i].x()); 
     coords.push_back(aSimplePolygon[i].y()); 
     coords.push_back(0); 
    } 

    GLUtesselator* tess = gluNewTess(); 
    gluTessCallback(tess, GLU_TESS_BEGIN,   (void (CALLBACK *)()) tess_begin  ); 
    gluTessCallback(tess, GLU_TESS_EDGE_FLAG,  (void (CALLBACK *)()) tess_edgeFlag ); 
    gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (void (CALLBACK *)()) tess_vertex ); 
    gluTessCallback(tess, GLU_TESS_END,   (void (CALLBACK *)()) tess_end  ); 
    gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (void (CALLBACK *)()) tess_combine ); 
    gluTessNormal(tess, 0.0, 0.0, 1.0); 

    TessContext ctx; 

    gluTessBeginPolygon(tess, &ctx); 
    gluTessBeginContour(tess); 

    for(size_t i = 0; i < aSimplePolygon.size(); ++i) 
    { 
     gluTessVertex(tess, &coords[i*3], &coords[i*3]); 
    } 

    gluTessEndContour(tess); 
    gluTessEndPolygon(tess); 

    gluDeleteTess(tess); 

    std::vector<Vec> ret(ctx.pts.size()); 
    for(size_t i = 0; i < ret.size(); ++i) 
    { 
     ret[i].x() = static_cast<Vec::Scalar>(ctx.pts[i].first); 
     ret[i].y() = static_cast<Vec::Scalar>(ctx.pts[i].second); 
    } 

    return ret; 
} 

我傾向於使用Eigen::Vector2fVec

+0

看起來我有錯誤的參數類型:'void'。該矢量方法是否可以安全使用嗎?即時消息使用的裁剪器庫正在爲每個點創建帶有新[]的指針,然後使用delete []將其釋放。我不知道他爲什麼這麼複雜。我真的很喜歡你的版本,因爲它不會一個一個地分配它們。這也更快嗎? – Rookie

+0

也,爲什麼你沒有&爲'(void(CALLBACK *)())&tess_begin'等? – Rookie

+0

我不明白爲什麼它不會安全使用。在gluDeleteTess()之後,矢量不會被釋放。 [地址 - 運營商信息,重新:函數指針](http://stackoverflow.com/questions/6893285/why-do-all-these-crazy-function-pointer-definitions-all-work-what-is-really -goi)。 – genpfault