Cork

ごすらぼ!

バイクと車とゲーム開発の記録

【Box2D】【DXライブラリ】デバッグ描画方法まとめ

この記事をシェアする

f:id:gothlab:20210720210558g:plain

まとめ

  • Box2D のデバッグ描画に DXライブラリを使う方法をまとめた

参考

DXライブラリでのデバッグ描画は主にこちらを参考にした.
というかほぼこちらの実装そのまま.
ncj-blog.blogspot.com

上記エントリでは,一部メソッドが実装されていなかったため,
残りは自力で実装した.

デバッグ描画クラス

Box2D にはデバッグ描画クラスがある.

  • b2Draw

このクラスを継承したデバッグ描画クラスを作成し,
環境に合わせた描画メソッドを実装すれば良い.

という,ミドルウェアでよくあるデバッグ描画形式.

利用方法は,
Box2D のワールドに
作成したデバッグ描画クラスのインスタンスを渡し,
描画するフラグを設定し,

Box2dDebugDraw debugdraw;
debugdraw.SetFlags( debugdraw.e_shapeBit | debugdraw.e_aabbBit | debugdraw.e_pairBit | debugdraw.e_centerOfMassBit | debugdraw.e_jointBit );
b2World world(gravity);
world.SetDebugDraw( &debugdraw );

Update 時に

world.DebugDraw();

を呼び出せば良い.

DXライブラリを使ったデバッグ描画クラス

完成コード
Box2dDebugDraw.h

#pragma once
#include "DxLib.h"
#include <box2d.h>

class Box2dDebugDraw: public b2Draw
{
    /// Draw a closed polygon provided in CCW order.
    void DrawPolygon( const b2Vec2* vertices, int32 vertexCount, const b2Color& color )
    {
        int mode;
        int parm;
        DxLib::GetDrawBlendMode( &mode, &parm );

        DxLib::SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 128 );

        int i = 1;

        for( ; i < vertexCount; i++ )
        {
            DrawLine( vertices[ i - 1 ].x, vertices[ i - 1 ].y,
                vertices[ i ].x, vertices[ i ].y,
                GetColor( 255 * color.r, 255 * color.g, 255 * color.b ) );
        }

        DrawLine( vertices[ 0 ].x, vertices[ 0 ].y,
            vertices[ i - 1 ].x, vertices[ i - 1 ].y,
            GetColor( 255 * color.r, 255 * color.g, 255 * color.b ) );

        DxLib::SetDrawBlendMode( mode, parm );
    }

    /// Draw a solid closed polygon provided in CCW order.
    void DrawSolidPolygon( const b2Vec2* vertices, int32 vertexCount, const b2Color& color )
    {
        int mode;
        int parm;

        DxLib::GetDrawBlendMode( &mode, &parm );

        DxLib::SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 128 );

        DxLib::SetDrawBlendMode( DX_BLENDMODE_ALPHA, 128 );

        for( int i = 2; i < vertexCount; i++ )
        {
            DrawTriangle( vertices[ 0 ].x, vertices[ 0 ].y,
                vertices[ i - 1 ].x, vertices[ i - 1 ].y,
                vertices[ i ].x, vertices[ i ].y,
                GetColor( 255 * color.r, 255 * color.g, 255 * color.b ),
                true );
        }

        DxLib::SetDrawBlendMode( mode, parm );

        return;
    }

    /// Draw a circle.
    void DrawCircle( const b2Vec2& center, float radius, const b2Color& color )
    {
        int mode;
        int parm;
        DxLib::GetDrawBlendMode( &mode, &parm );

        DxLib::SetDrawBlendMode( DX_BLENDMODE_ALPHA, 128 );
        DxLib::DrawCircle( center.x, center.y, radius, GetColor( 255 * color.r, 255 * color.g, 255 * color.b ), false );

        DxLib::SetDrawBlendMode( mode, parm );

    }

    /// Draw a solid circle.
    void DrawSolidCircle( const b2Vec2& center, float radius, const b2Vec2& axis, const b2Color& color )
    {
        int mode;
        int parm;
        DxLib::GetDrawBlendMode( &mode, &parm );

        DxLib::SetDrawBlendMode( DX_BLENDMODE_ALPHA, 128 );
        DxLib::DrawCircle( center.x, center.y, radius, GetColor( 255 * color.r, 255 * color.g, 255 * color.b ), true );

        DxLib::SetDrawBlendMode( mode, parm );

    }

    /// Draw a line segment.
    void DrawSegment( const b2Vec2& p1, const b2Vec2& p2, const b2Color& color )
    {
        int mode;
        int parm;

        DxLib::GetDrawBlendMode( &mode, &parm );

        DxLib::SetDrawBlendMode( DX_BLENDMODE_ALPHA, 128 );
        
        DrawLine( p1.x, p1.y, p2.x, p2.y, GetColor( 255 * color.r, 255 * color.g, 255 * color.b ) );

        DxLib::SetDrawBlendMode( mode, parm );
    }

    /// Draw a transform. Choose your own length scale.
    /// @param xf a transform.
    void DrawTransform( const b2Transform& xf )
    {
        b2Vec2 p1 = xf.p, p2;
        const float k_axisScale = 0.4f;
    
        p2 = p1 + k_axisScale * xf.q.GetXAxis();
        DrawLine( p1.x, p1.y, p2.x,p2.y, GetColor( 255, 0, 0 ) );

        p2 = p1 + k_axisScale * xf.q.GetYAxis();
        DrawLine( p1.x, p1.y, p2.x,p2.y, GetColor( 0, 255, 0 ) );
    }

    /// Draw a point.
    void DrawPoint( const b2Vec2& p, float size, const b2Color& color )
    {
        int mode;
        int parm;

        DxLib::GetDrawBlendMode( &mode, &parm );

        DxLib::SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 128 );

        DxLib::DrawBox( p.x - ( size ), p.y - ( size ),
            p.x + ( size ), p.y + ( size ),
            GetColor( 255 * color.r, 255 * color.g, 255 * color.b ), true );

        DxLib::SetDrawBlendMode( mode, parm );
    }
};

おわりに

DXライブラリ環境で,
Box2D のデバッグ描画まで行った.

さて次は何をしよう.