回答:
線のレンダリング-方法1(プリミティブ)
3D空間の単純な線の場合、LineList
またはLineStrip
プリミティブを使用してそれらを描くことができます。以下は、(0,0,0)から(0,0、-50)まで線を引くために空のXNAプロジェクトに追加する必要があるコードの最小量です。カメラがどこにあっても、ラインはほぼ同じ幅で表示されます。
// Inside your Game class
private BasicEffect basicEffect;
private Vector3 startPoint = new Vector3(0, 0, 0);
private Vector3 endPoint = new Vector3(0, 0, -50);
// Inside your Game.LoadContent method
basicEffect = new BasicEffect(GraphicsDevice);
basicEffect.View = Matrix.CreateLookAt(new Vector3(50, 50, 50), new Vector3(0, 0, 0), Vector3.Up);
basicEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45f), GraphicsDevice.Viewport.AspectRatio, 1f, 1000f);
// Inside your Game.Draw method
basicEffect.CurrentTechnique.Passes[0].Apply();
var vertices = new[] { new VertexPositionColor(startPoint, Color.White), new VertexPositionColor(endPoint, Color.White) };
GraphicsDevice.DrawUserPrimitives(PrimitiveType.LineList, vertices, 0, 1);
基本的BasicEffect
には、ビューと投影変換を保持するシンプルなものを作成し、2つの頂点(位置と色を格納する)GraphicsDevice.DrawUserPrimitives
をにレンダリングするメソッドに渡しましたLineList
。
もちろん、それを最適化する方法はたくさんありますが、そのほとんどは、VertexBuffer
すべての頂点を保存するためのの作成と、できるだけ多くの行を単一のDraw呼び出しにバッチ処理することですが、これは問題とは関係ありません。
レンダリングポイント-メソッド1(SpriteBatch)
ポイントの描画に関しては、これはポイントスプライトを使用すると簡単でしたが、XNA 4.0から削除されました。ただし、いくつかの選択肢があります。最も簡単な方法は、1x1の白いTexture2D
オブジェクトを作成し、それをSpriteBatch
正しい画面位置で使用してレンダリングすることです。これは、Viewport.Projectメソッドを使用して簡単に見つけることができます。
次のTexture2D
ように、必要なオブジェクトを作成できます。
Texture2D pixel = new Texture2D(GraphicsDevice, 1, 1);
pixel.SetData(new [] { Color.White });
そして、次のように(x、y、z)の場所にレンダリングします。
// Find screen equivalent of 3D location in world
Vector3 worldLocation = new Vector3(0, 0, 50);
Vector3 screenLocation = GraphicsDevice.Viewport.Project(worldLocation, projectionMatrix, viewMatrix, Matrix.Identity);
// Draw our pixel texture there
spriteBatch.Begin();
spriteBatch.Draw(pixel, new Vector2(screenLocation.X, screenLocation.Y), Color.White);
spriteBatch.End();
線のレンダリング-方法2(SpriteBatch)
または、ここで説明SpriteBatch
する手法を使用して、線を描くこともできます。この場合は、3Dラインの両端のスクリーンスペース座標を(もう一度を使用してViewport.Project
)見つけ、それらの間に通常のラインを描くだけです。
レンダリングポイント-方法2(プリミティブ付きの小さな線)
コメントで、eBusinessは次の質問を提起しました。
始点と終点が同じ線はどうですか、それで点が生成されませんか?それとも単に目に見えないでしょうか?
私は試してみましたがLineList
、同じ開始点と終了点を使用してレンダリングすると、何も描画されませんでした。私はそれを回避する方法を見つけたので、完全を期すためにここで説明します。
トリックは、同じ始点と終点を使用するのではなく、描画するときに1ピクセルとしてしか表示されないほど細い線を描画することです。だから、正しいエンドポイントを選択するために、私は最初、画面空間にワールド空間の点を投影右1つのピクセルを移動し、画面空間での、そして最終的に戻ってワールド空間にそれを投影しました。それが、ドットのように見えるようにするためのラインの終点です。このようなもの:
Vector3 GetEndPointForDot(Vector3 start)
{
// Convert start point to screen space
Vector3 screenPoint = GraphicsDevice.Viewport.Project(start, projection, view, Matrix.Identity);
// Screen space is defined in pixels so adding (1,0,0) moves it right one pixel
screenPoint += Vector3.Right;
// Finally unproject it back into world space
return GraphicsDevice.Viewport.Unproject(screenPoint, projection, view, Matrix.Identity);
}
その後、通常のラインプリミティブとしてレンダリングします。
デモンストレーション
これは、ラインリストプリミティブを使用して3Dスペースに白い線を描画し、1x1テクスチャとSpriteBatchを使用して線の両端に赤い点を描画したものです。使用したコードは、私が上で書いたものとほぼ同じです。また、ズームインして、幅がちょうど1ピクセルであることを確認します。
これはXNAとしてタグ付けされているので、それがあなたが尋ねていることだと思いますか?
もしそうなら、この記事は行に役立つはずです:
http://msdn.microsoft.com/en-us/library/bb196414(v=xnagamestudio.40).aspx
もちろん、それらの代わりに独自のビュー/投影行列を使用できます。基本的に、PrimitiveType.LineList
またはLineStrip
GPUレベルで線を描画する方法です。
ポイントについては、PrimitiveType.PointListを使用してXNA 4.0でポイントを描画することはできなくなりました。代わりに、非常に小さな三角形を作成する必要があります。このサンプルは良いベースラインを提供します:
http://create.msdn.com/education/catalog/sample/primitives_3d
以前のバージョンのXNAの場合、それらのいずれかを使用している場合は、先に投稿した記事のXNA 3.0バージョンのポイント部分を読むことができます。
http://msdn.microsoft.com/en-us/library/bb196414(v=xnagamestudio.30).aspx
リンクに注意してください:
graphics.GraphicsDevice.RenderState.PointSize = 10;
明らかにそれをに変更してください1
。