1

DirectX 9 を使用して 2D 画像を適切にパンする効率的な方法を見つけようとしています。

うまくいけば、私がやりたいことを説明する写真を下に添付しました。tu基本的に、テクスチャ全体のすべてのクワッドの頂点の座標をスクロールしtvて、2D テクスチャの「その場でスクロール」効果を生成したいと考えています。

下の最初の画像は、ロードしたテクスチャを表しています。2 番目のイメージは、標準レンダリング イメージを示す各コーナーの 4 つの頂点の座標をtu持つテクスチャです。tv3 番目の画像は、私が実現したいことを示しています。レンダリングされたボックスが画像の端にまたがり、雲の 2 つの半分が分離されたようにテクスチャがレンダリングされるように折り返して頂点を移動したいと考えています。4 番目の画像は、私の一時的な (無駄な) 解決策を示しています。単純にイメージを 2 倍にして、右端に到達するまでパンします。その時点で頂点の tu と tv をリセットして、レンダリングされるボックスが右端に戻るようにします。

すべてを2つの別々のクワッドに分割せずにこれを行う正当な方法はありますか?

雲のパンニング

現在の設計でソリューションへの道筋を明確にするのに役立つ場合は、セットアップとレンダリング コードの詳細を以下に追加しました。

次のように、2D レンダリング用に DirectX を設定する機能があります。推奨どおり、テクスチャ ステージ 0 にラップ プロパティを追加しました。

VOID SetupDirectXFor2DRender()
{
    pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
    pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
    pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT );

    // Set for wrapping textures to enable panning sprite render
    pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
    pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );

    pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
    pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0 );

    pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
    pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, false );

    pd3dDevice->SetRenderState( D3DRS_SRCBLEND , D3DBLEND_SRCALPHA );
    pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA) ;

    pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
    pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

    pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
    pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
    pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );

    pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
    pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

    return;
}

各フレームで、次のようにレンダリングします。

VOID RenderAllEntities()
{
    HRESULT hResult;
    // Void pointer for DirectX buffer locking
    VOID* pVoid;

    hResult = pd3dDevice->Clear( 0,
                                 NULL,
                                 D3DCLEAR_TARGET,
                                 0x0,
                                 1.0f,
                                 0 );

    hResult = pd3dDevice->BeginScene();

    // Do rendering on the back buffer here
    hResult = pd3dDevice->SetFVF( CUSTOMFVF );

    hResult = pd3dDevice->SetStreamSource( 0, pVertexBuffer, 0, sizeof(CUSTOM_VERTEX) );

    for ( std::vector<RenderContext>::iterator renderContextIndex = queuedContexts.begin(); renderContextIndex != queuedContexts.end(); ++renderContextIndex )
    {
        // Render each sprite
        for ( UINT uiIndex = 0; uiIndex < (*renderContextIndex).uiNumSprites; ++uiIndex )
        {
            // Lock the vertex buffer into memory
            hResult = pVertexBuffer->Lock( 0, 0, &pVoid, 0 );
            // Copy our vertex buffer to memory
            ::memcpy( pVoid, &renderContextIndex->vertexLists[uiIndex], sizeof(vertexList) );
            // Unlock buffer
            hResult = pVertexBuffer->Unlock();

            hResult = pd3dDevice->SetTexture( 0, (*renderContextIndex).textures[uiIndex]->GetTexture() );   
            hResult = pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 6 );
        }
    }

    // Complete and present the rendered scene
    hResult = pd3dDevice->EndScene();
    hResult = pd3dDevice->Present( NULL, NULL, NULL, NULL );

    return;
}

SetTransform をテストするために、 への呼び出しの前にレンダリング コード内に次の (ずさんですが一時的な) コード ブロックを追加してみましたDrawPrimitive

{
    static FLOAT di = 0.0f;
    static FLOAT dy = 0.0f;

    di += 0.03f;
    dy += 0.03f;
    // Build and set translation matrix
    D3DXMATRIX ret;

    D3DXMatrixIdentity(&ret);
    ret(3, 0) = di;
    ret(3, 1) = dy;
    //ret(3, 2) = dz;

    hResult = pd3dDevice->SetTransform( D3DTS_TEXTURE0, &ret );
}

これにより、レンダリングされたスプライトがパンしません。私は DirectX のチュートリアルに取り組み、MS のドキュメントを読んで最新情報に追いついていますが、私の知識には間違いなく穴があります。

どんな助けでも大歓迎です。

ありがとう!

4

1 に答える 1

1

これは、1 つのクワッドで静かに簡単に実行できるはずです。

固定関数パイプラインで DX9 を使用していると仮定すると、適切なテクスチャ( doc ) と 2D 変換マトリックスを使用してIDirect3DDevice9::SetTransform( doc ) でテクスチャを変換できます。サンプラーの状態と( doc ) が( doc ) に設定されていることを確認する必要があります。これにより、テクスチャが仮想的にタイル化されるため、負の UV 値または 1 より大きい値がテクスチャの無限の繰り返しにマップされます。D3DTRANSFORMSTATETYPED3DSAMP_ADDRESSUD3DSAMP_ADDRESSVD3DTADDRESS_WRAP

シェーダーまたは別のバージョンの directx を使用している場合は、シェーダーで自分でテクスチャ座標を変換したり、頂点の UV 値を操作したりできます。

于 2013-06-07T08:23:17.033 に答える