2016-08-02 9 views
0

シンプルなポイントクラウドビューアを作成したいと思います。私はC#とXNAを使っています。私は回転し、それにズームけどもパフォーマンスが弱いことができポイントクラウドビューアのパフォーマンスを向上させる方法

Link

: この瞬間に私はこれを作成しました。 1,500,000ポイントのクラウドでは、回転またはズームを完了するのに約6秒かかります。それをより良くする方法は?すべてを再描画せずに回転またはズームする可能性はありますか?

図面についてのマイコードスニペット。イム使用してSpriteBatches:

ba.Begin(); 
for (int i = 0; i < DBmanager.data.Length; i++) 
{ 
    Vector3 screenLocation = Device.Viewport.Project(DBmanager.data[i], basicEffect.Projection, basicEffect.View, basicEffect.World); 
    ba.Draw(pixel, new Vector2(screenLocation.X, screenLocation.Y), Color.Orange); 
} 
ba.End(); 

移動機能:

private void move(float x,float y) 
{ 
    //currentx += x; 
    Debug.WriteLine(x); 
    Debug.WriteLine(y); 
    if (x == 0) 
    { 
     Vector3 target = new Vector3(Center.X, Center.Y, Center.Z); 
     cameraPosition = Vector3.Transform(cameraPosition - target, Matrix.CreateRotationY(y)) + target; 
     basicEffect.View = Matrix.CreateLookAt(cameraPosition, target, Vector3.Up); 
    } 
    if (y == 0) 
    { 
     Vector3 target = new Vector3(Center.X, Center.Y, Center.Z); 
     cameraPosition = Vector3.Transform(cameraPosition - target, Matrix.CreateRotationX(x)) + target; 
     basicEffect.View = Matrix.CreateLookAt(cameraPosition, target, Vector3.Up); 
    } 
} 

マイDraw関数:

 protected override void Draw() 
    { 
     if (called) 
     { 
      Application.Idle -= IdleHandler; 
      timer.Stop(); 
      SetUpVertices(); 
      called = false; 
      //Invalidate(); 
     } 
     // if (drawn) 
     // { 
      //Application.Idle -= IdleHandler; 
      //timer.Stop(); 
      // UpdateCam(); 
      // Debug.WriteLine("Obrót zakonczony"); 
      //SetUpVertices(); 
     // } 
     if (leftDrag) 
     { 
      Application.Idle -= IdleHandler; 
      timer.Stop(); 
      UpdateCam(); 
      //SetUpVertices(); 
      leftDrag = false; 
     } 
     if (Zoomed) 
     { 
      Application.Idle -= IdleHandler; 
      timer.Stop(); 
      Zoom(Zoomlevel); 
      //UpdateCam(); 
      //SetUpVertices(); 
      Zoomed = false; 
     } 

    } 

SetupVertices:

private void SetUpVertices() 
    { 
     Device.Clear(Color.Black); 
     VertexPositionColor [] Verts = new VertexPositionColor [65535]; 
     RasterizerState rasterizerState = new RasterizerState(); 
     rasterizerState.CullMode = CullMode.None; 
     Device.RasterizerState = rasterizerState; 
     int j = 0; 
     for (int i = 0; i < DBmanager.data.Length; i++) 
     { 
      if (j==65535) 
      { 
       buf = new VertexBuffer(Device, typeof(VertexPositionColor), Verts.Length, BufferUsage.WriteOnly); 
       buf.SetData<VertexPositionColor>(Verts); 
       Device.SetVertexBuffer(buf); 
       foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) 
       { 
        pass.Apply(); 
        Device.DrawPrimitives(PrimitiveType.TriangleList, 0, Verts.Length); 
       } 
       Verts = new VertexPositionColor[65535]; 
       j = 0; 
      } 
      else 
      { 
       Verts[j] = new VertexPositionColor(new Vector3(DBmanager.data[i].X, DBmanager.data[i].Y, DBmanager.data[i].Z),Color.Orange); 
       j++; 
      } 
     } 
     if (!IsCenterCalculated) 
     { 
      Box = BoundingBox.CreateFromPoints(DBmanager.data); 
      corners = Box.GetCorners(); 
      setCenter(CalculateCenter(corners)); 
      IsCenterCalculated = true; 
      basicEffect.View = Matrix.CreateLookAt(cameraPosition, new Vector3(Center.X, Center.Y, Center.Z), Vector3.Up); 
     } 
    } 
+1

相互作用( 'Game.Update()')、データ管理、および実際の描画( 'Game.Draw()')を分離する必要があります。 'SetupVertices()'を使ってポイントクラウドを描くように見えます。これにより、常にGPUにデータ全体が送信されるため、以前と同じ問題が発生します。頂点を一度しか設定しないと、フレームごとに 'DrawPrimitives()'を行うことができます。 Btw、 'TriangleList'ではなく' PointList'ですか? –

+0

セットアップ中に 'basicEffect.View'を呼び出すべきではありません。 – MickyD

+0

スプライトバッチは遅く、基本的にすべての描画操作が各フレームにGPUに再送される_immediateモードです。あなたはGPUに保存されている多くのテクニックを欲しい – MickyD

答えて

0

これを行うための正しい方法を使用することです点を格納する頂点バッファデータ。それらを一度グラフィックスカードにアップロードしてから、ビューマトリックスを変更するだけです。

これにより、すべてのフレームにデータがアップロードされることがなくなり、グラフィックスカードが投影を並行して実行します。ポイントあたり約24バイトのデータサイズを最小限に見積もると、約36 MBのデータが得られます。これを60fpsですべてのフレームにアップロードすると、プレーンポイントデータに約16Gb/sの転送速度が必要になります。そして、スプライトバッチでは、点の代わりに長方形をアップロードする必要があるため、さらに多くなります。

頂点バッファに慣れてください。データを一度入れてGPUにアップロードします。一回のドローコールですべてのポイントを一度に描画できます。

+0

あなたのソリューションを試しましたが、まだ同じです。すべてのものを再描画せずに回転またはズームすると、Dockedフォームは空白になります。たぶん私は何かを誤解しました。私は私の全解決策を掲示することができ、あなたは私が間違っていることを教えてくれるでしょう。 – Habababa

+0

回転時にすべてを描画することは問題ありません。あなたの描画コードを表示するだけです(初期化の必要はありません)。これは、あなたがしていることを判断するのに十分なはずです。 –

+0

Iveが私の質問を更新しました – Habababa

関連する問題