gluTess *関数を使用して、非凸多角形を描画しています。すべてのステップでテッセレーションをやり直すのを避けるために、結果を配列に格納し、OpenGLの頂点配列機能を使用して描画します。最初の呼び出しでgluTessが機能しないのはなぜですか?
私の問題は、何らかの理由で初めてgluTess *を使うときに、三角形の一部だけが描画されることです。私がgluTess *を再現するように強制すると、すべてうまくいきます。
gluTess *を再作成するには、頂点配列を含むオブジェクトを完全に破棄して再作成します(これにより、頂点配列オブジェクトの再計算が強制されます)。
なぜそうなのでしょうか?
いくつかのランダムなアイデア:
- 最初のOpenGLのためのウィンドウを呼び出すので、それができるが、そのフルサイズではまだないのですか?
- 私はいくつかのOpenGL状態を設定する必要があります。これは後で実行されますが、最初の呼び出しでは実行されませんか?
ありがとうございます。
:テストとして、私はちょうど、頂点配列を作成、破棄、再作成しました。それは問題を解決する。つまり、OpenGL状態を変更しなければ、gluTess *への最初の呼び出しではポリゴンを正しくテッセレーションできません。しかし、第二のものは成功する。誰かがそれに気づいたか?
編集(2):2番目の呼び出しが成功したように、私は(私が言ったように、2番目の呼び出しがで作られbeginVA、endVAとvertexVAが正常に動作することを疑う
VA va;
GLUtesselator *t = gluNewTess();
gluTessCallback(t, GLU_TESS_BEGIN_DATA, (GLvoid (*)())beginVA);
gluTessCallback(t, GLU_TESS_END_DATA, (GLvoid (*)())endVA);
gluTessCallback(t, GLU_TESS_VERTEX_DATA, (GLvoid (*)())vertexVA);
gluTessCallback(t, GLU_TESS_ERROR, (GLvoid (*)())&tessError);
gluTessCallback(t, GLU_TESS_COMBINE, (GLvoid (*)())&tessCombine);
gluTessProperty(t, GLU_TESS_BOUNDARY_ONLY, GL_FALSE);
gluTessProperty(t, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
gluTessBeginPolygon(t, &va);
gluTessBeginContour(t);
foreach(Point3d& p, points)
gluTessVertex(t, const_cast<GLdouble*>(p.c_data()), (void*)&p);
gluTessEndContour(t);
gluTessEndPolygon(t);
gluDeleteTess(t);
:ここでは、コードです主に頂点配列を保持するデータ構造VAを破壊する)。
編集(3):ここでは欠落しているコードです:
struct VA
{
std::vector<Point3d> positions; // Vertex array
GLenum current_mode; // Drawing mode (GL_TRIANGLE, *_FAN or *_STRIP)
Point3d v1, v2; // Two last vertices for _FAN or _STRIP
bool has_v1, has_v2; // did we get the two last vertices?
int n; // Index of the vertex, for *_STRIP
};
void beginVA(GLenum mode, VA *va)
{
va->current_mode = mode; // Store the mode
va->has_v1 = va->has_v2 = false; // We haven't had any vertex yet
va->n = 0;
}
void endVA(VA *va)
{
va->current_mode = 0; // Not really necessary, but cleaner
}
void vertexVA(Point3d *p, VA *va)
{
++va->n;
if(va->current_mode == GL_TRIANGLES) // The simple case
va->positions.push_back(*p);
else if(!va->has_v1) {
va->v1 = *p;
va->has_v1 = true;
} else if(!va->has_v2) {
va->v2 = *p;
va->has_v2 = true;
} else if(va->current_mode == GL_TRIANGLE_STRIP) {
if(va->n%2 == 1) {
va->positions.push_back(va->v1);
va->positions.push_back(va->v2);
va->positions.push_back(*p);
} else {
va->positions.push_back(va->v2);
va->positions.push_back(va->v1);
va->positions.push_back(*p);
}
va->v1 = va->v2;
va->v2 = *p;
} else { // GL_TRIANGLE_FAN
va->positions.push_back(va->v1);
va->positions.push_back(va->v2);
va->positions.push_back(*p);
va->v2 = *p;
}
}
編集(4):最後に、エラーがどこか別の場所でした。私は疲れていなければならないでしょう、私はstd :: vectorを使って結合関数の結果を格納しました。なぜそれが後で働いたのかわかりませんが、初めて正常に動作しなかったのは確かです!申し訳ありません、私は今この問題を閉じるでしょう。
テッセレーションコードを投稿として編集しました。しかし、「データを再作成せずに再描画」することはどういう意味ですか?私のオブジェクトは常に動き回ります。図面は完全に一貫しており、フリッカーはなく、三角形は実際には存在しません。 – PierreBdR
@PierreBdR:一部の人は、描画関数の反復ごとにメッシュを再テッセレーションします。あなたがあなたの頂点を私によるばかげた質問に保存したと言ったからです。 – datenwolf
mmmh ..描画するポリゴンがたくさんあるため、_STRIPまたは_FANを使用すると、ストリップまたはファンごとにglDrawElementsを呼び出す必要があります。 – PierreBdR