2012-09-26 6 views
3

하나의 정점 배열 형식 만 사용하려면 생성하는 데이터를 렌더링하는 것이 꽤 어렵습니다.GL_Tessanelator가 GL_TRIANGLES 만 생성하도록 하시겠습니까?

GLU_TESS_EDGE_FLAG_DATA 콜백을 제공하려했지만 내 프로그램이 중단되었습니다. (또한 끝에 "_DATA"없이 동일한 효과) 시도.

GL_TRIANGLES 만 생성하려면 어떻게해야합니까?

+0

콜백은 무엇입니까? – Calvin1602

+0

@ Calvin1602, 어느 쪽입니까? 나는 5 gluTessCallback() '을 가지고있다 – Rookie

답변

5

gluTessCallback(), GLU_TESS_EDGE_FLAG : 비 NULL 에지 플래그 콜백이 제공되는 경우

는 ... 팬 삼각형 스트립 독립적으로 변환된다.

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

내가 Vec에 대한 Eigen::Vector2f을 사용하는 경향이 :

이 내가 사용했던 것입니다.

+0

내가 잘못된 매개 변수 형식을 가지고있는 것 같아 :'void'. 코드를 안전하게 보관하기위한 방법은 벡터입니까? 사용하는 clipper lib는 각 점에 대해 new []를 사용하여 포인터를 만든 다음 나중에 delete []를 사용하여 포인터를 해제합니다. 왜 그가 그렇게 복잡한 지 모르겠다. 나는 하나씩 그것을 할당하지 않기 때문에 당신의 버전을 정말 좋아합니다. 그 또한 더 빠릅니까? – Rookie

+0

또한'(void (CALLBACK *)()) & tess_begin' 등을 & nbsp 왜 가지고 있지 않습니까? – Rookie

+0

사용하는 것이 안전하지 않은 이유를 모르겠습니다. 벡터는'gluDeleteTess()'이후까지 할당 해제되지 않습니다. [운영자 정보 주소, 다시 : 함수 포인터] (http://stackoverflow.com/questions/6893285/why-do-all-these-crazy-function-pointer-definitions-all-work-what-is-really -goi). – genpfault