Box 2 D C++チュートリアル-debug Drawの使用

104243 ワード

転載文章:原貼住所:http://ohcoder.com/blog/2012/11/30/using-debug-draw/
Debug draw の使用
testbedは、「debug draw」という特性を使用して、あなたが見た形状を描きます.しかし、ゲームをより目立たせるには、退屈なポリゴンを置き換える必要があるのは明らかですが、物理的なシーンで問題が発生すると、debug drawは非常に役に立ちます.ゲームシーンの一部で問題が発生することがあります.例えば、精霊が間違った位置に表示されたり、誤った回転方式が発生したりして、不正確な物理現象が発生します.Box 2 dの世界で何が起こっているのかを正確に検出したい場合は、debug drawの機能を維持することをお勧めします.
その働き方はとても簡単です.Box 2 dのすべての形状やこれらの形状の位置などを教えてくれます.「x,yの位置で、半径rの円弧」、または「aからbまでのエッジ」など、他の必要な形状.変換したり、物体の位置やカスタムがどの物体に属しているかを心配したりする必要はありません.これらのジオメトリを簡単に描くことができます.つまり、線分をいくつか描くだけで、事を台無しにすることはありません:-).
testbedのデフォルトのdebug drawは、仮想メソッドの山を含むサブクラスb 2 DebugDrawクラスによって完了します.ここでは、主な方法を示します.
1
2
3
4
5
6
virtual void DrawPolygon(b2Vec2* vertices, int32 vertexCount, b2Color& color) = 0;
virtual void DrawSolidPolygon(b2Vec2* vertices, int32 vertexCount, b2Color& color) = 0;
virtual void DrawCircle(b2Vec2& center, float32 radius, b2Color& color) = 0;
virtual void DrawSolidCircle(b2Vec2& center, float32 radius, b2Vec2& axis, b2Color& color) = 0;
virtual void DrawSegment(b2Vec2& p1, b2Vec2& p2, b2Color& color) = 0;
virtual void DrawTransform(const b2Transform& xf) = 0;

専用のレンダリングコードを独立した場所に配置し、DirectXやOpenGL ESのように、異なるAPIを簡単に呼び出してレンダリングデバッグを実現したり、異なるレンダリング方法の間で簡単に切り替えることができます.
testbedのdebug drawはよく機能しており、本当にカスタマイズする必要はありませんが、この話題について議論している以上、カスタマイズしたサブクラスを使用して変更しましょう.以前に議論したトピックのシーンはすべて試してみることができます.ここでは、均一な動き(moving at constant speed)トピックで議論したシーンを使用します.
カスタムdebug drawクラスを実装するには、すべての純粋な虚関数を実装する必要があります.まず、これらの方法をクリアしましょう.
1
2
3
4
5
6
7
8
9
10
class FooDraw : public b2DebugDraw
{
    public:
        void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {}
        void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) {}
        void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) {}
        void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) {}
        void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) {}
        void DrawTransform(const b2Transform& xf) {}
};

SetDebugDrawメソッドを使用して、Box 2 D世界にデフォルトの代わりにこのようなものを使用することを伝えることができます.この方法のパラメータは、b 2 DebugDrawオブジェクトを指すポインタを使用するので、このようなオブジェクトを指すポインタが必要です.新しいグローバル変数を宣言できます.
1
2
3
4
5
6
//at global scope
FooDraw fooDrawInstance;
//in constructor, usually
m_world->SetDebugDraw( &fooDrawInstance );
//somewhere appropriate
fooDrawInstance.SetFlags( b2DebugDraw::e_shapeBit );

これにより、物理世界でレンダリングするタスクは、新しく指定されたクラスオブジェクトが完了することを示すことができます.最後の行のコードに設定されているフラグは、レンダリングのタイプです.物理世界を表示するときに、シェイプ(カスタマイザ)をより面白くするには、次のフラグを設定する必要があります.
-e_shapeBit(画形状(draw shapes))  -e_义齿  -e_aabBit  -e_pairBit(broad-phaseペアを描く)  -e_centerOfMassBit(物体にセントロイド(draw a marker at body CoM))
実際には、これらの設定を「適切な場所」に置きたいという意味です.実行中に設定したい設定があるかもしれません.上記のように、レンダリングされたゲームエンティティとBox 2 Dが同じものかどうかをたまに判断したい場合があります.testbedでは、右の選択パネルに設定されているのが見えます.
自分のプロジェクトでdebug drawクラスを使用している場合は、物理世界でDrawDebugData()メソッドを呼び出す必要があります.このメソッドでは、Box 2 Dがレンダリングするシェイプを呼び出す必要があるdebug drawクラスメソッドごとにコールバックします.
これでtestbedが実行され、シーンでは何も見えないはずです.これは、まだ対応するdebug drawメソッドが実装されていないためです.この点から、あなたが実装するレンダリング方法は、どのプラットフォームとあなたが使用しているレンダリングのAPIに依存します.一例として、組み込みプラットフォームiPhone上でOpenGL ESを使用してDrawSolidPolygonメソッドを実装します.フレキシブルな例ですが、OpenGL ESはOpenGLのサブセットであるため、PCプラットフォームのtestbed上で一般的なプログラムのように実行することができ、プラットフォーム間の問題もよく発生する問題です.
OpenGL ESではglBegin/glEnd/glVertexメソッドはありませんので、レンダリングの代わりに頂点配列を使用します.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
{
    //set up vertex array
    GLfloat glverts[16]; //allow for polygons up to 8 vertices
    glVertexPointer(2, GL_FLOAT, 0, glverts); //tell OpenGL where to find vertices
    glEnableClientState(GL_VERTEX_ARRAY); //use vertices in subsequent calls to glDrawArrays

    //fill in vertex positions as directed by Box2D
    for (int i = 0; i < vertexCount; i++) {
        glverts[i*2]   = vertices[i].x;
        glverts[i*2+1] = vertices[i].y;
    }

    //draw solid area
    glColor4f( color.r, color.g, color.b, 1);
    glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount);

    //draw lines
    glLineWidth(3); //fat lines
    glColor4f( 1, 0, 1, 1 ); //purple
    glDrawArrays(GL_LINE_LOOP, 0, vertexCount);
}

他のレンダリング方法も類比できます.使用するAPIによっては、円弧は複数の短いセグメントを使用してレンダリングできます.
更新:iPhoneのBox 2 Dソースコードに、OpenGL ESを使ってdebug drawを実現する方法があることに気づきました.これはObj-Cのために書かれていますが、普通のC++を使っているだけなので、何の修正もしなくてもいいです.GLES-Render.mm