【问题标题】:Force GLUtesselator to generate only GL_TRIANGLES?强制 GLUtesselator 只生成 GL_TRIANGLES?
【发布时间】:2012-09-17 23:54:25
【问题描述】:

如果我只想使用一种顶点数组格式,渲染生成的数据非常困难。

我尝试提供 GLU_TESS_EDGE_FLAG_DATA 回调,但它使我的程序崩溃。 (也试过不带“_DATA”,效果一样)。

我怎样才能让它只生成 GL_TRIANGLES?

【问题讨论】:

  • @Calvin1602,哪一个?我有 5 个 gluTessCallback() 的

标签: c++ opengl glu tesselation


【解决方案1】:

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

我倾向于将Eigen::Vector2f 用于Vec

【讨论】:

  • 看起来我的参数类型错误:void。用于存储坐标的矢量方法是否可以安全使用?我使用的裁剪器库正在为每个点创建带有 new[] 的指针,然后使用 delete[] 释放它。我不知道他为什么做的这么复杂。我真的很喜欢你的版本,因为它没有一一分配。这也更快吗?
  • 还有,为什么(void (CALLBACK *)())&amp;tess_begin 等没有&?
  • 我不明白为什么使用它不安全。直到gluDeleteTess() 之后,向量才会被释放。 Address-of operator information, re: function pointers.
  • 加上&标记不是更聪明,而不是使用隐式转换吗?至少许多指南说您不应该让隐式转换发生; “始终明确表示有转化”。
  • 嗯,可能。随意添加它们:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 2019-05-07
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多