カスタム シェーダーを使用せずに、幅の広い色付きのアウトラインで 2D ポリゴンを描画しようとしています。
(シェーダーに精通していないので、CPU を使用するよりもおそらく遅くなるでしょう)
そうするために、通常のようにポリゴンを描画し、結果として得られる深度バッファーを使用する予定です。同じ展開されたジオメトリを描画するときのステンシル。
XNA の「GraphicsDevice」は、IVertexType インスタンスの任意の配列を指定してプリミティブを描画できます。
DrawUserPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int primitiveCount, VertexDeclaration vertexDeclaration) where T : struct;
2D 座標空間の IvertexType を定義しました。
public struct VertexPosition2DColor : IVertexType
{
public VertexPosition2DColor (Vector2 position, Color color) {
this.position = position;
this.color = color;
}
public Vector2 position;
public Color color;
public static VertexDeclaration declaration = new VertexDeclaration (
new VertexElement(0, VertexElementFormat.Vector2, VertexElementUsage.Position, 0),
new VertexElement(sizeof(float)*2, VertexElementFormat.Color, VertexElementUsage.Color, 0)
);
VertexDeclaration IVertexType.VertexDeclaration {
get {return declaration;}
}
}
ポリゴンの頂点、色、およびエッジの法線を格納するための配列クラスを定義しました。
このクラスを GraphicDevice の DrawPrimitives 関数の T[] パラメータとして渡したいと考えています。
目標は、アウトラインの頂点を GPU で計算することです。これは、明らかにそのようなことが得意であるためです。
internal class VertexOutlineArray : Array
{
internal VertexOutlineArray (Vector2[] positions, Vector2[] normals, Color[] colors, Color[] outlineColors, bool outlineDrawMode) {
this.positions = positions;
this.normals = normals;
this.colors = colors;
this.outlineColors = outlineColors;
this.outlineDrawMode = outlineDrawMode;
}
internal Vector2[] positions, normals;
internal Color[] colors, outlineColors;
internal float outlineWidth;
internal bool outlineDrawMode;
internal void SetVertex(int index, Vector2 position, Vector2 normal, Color color, Color outlineColor) {
positions[index] = position;
normals[index] = normal;
colors[index] = color;
outlineColors[index] = outlineColor;
}
internal VertexPosition2DColor this[int i] {
get {return (outlineDrawMode)? new VertexPosition2DColor(positions[i] + outlineWidth*normals[i], outlineColors[i])
: new VertexPosition2DColor(positions[i], colors[i]);
}
}
}
シェイプをレンダリングできるようにしたいのですが、アウトラインは次のようになります。 展開されたアウトライナー ジオメトリを描画するときに、深度バッファーがステンシルとして使用されます。
protected override void RenderLocally (GraphicsDevice device)
{
// Draw shape
mVertices.outlineDrawMode = true; //mVertices is a VertexOutlineArray instance
device.RasterizerState = RasterizerState.CullNone;
device.PresentationParameters.DepthStencilFormat = DepthFormat.Depth16;
device.Clear(ClearOptions.DepthBuffer, Color.SkyBlue, 0, 0);
device.DrawUserPrimitives<VertexPosition2DColor>(PrimitiveType.TriangleList, (VertexPosition2DColor[])mVertices, 0, mVertices.Length -2, VertexPosition2DColor.declaration);
// Draw outline
mVertices.outlineDrawMode = true;
device.DepthStencilState = new DepthStencilState {
DepthBufferWriteEnable = true,
DepthBufferFunction = CompareFunction.Greater //keeps the outline from writing over the shape
};
device.DrawUserPrimitives(PrimitiveType.TriangleList, mVertices.ToArray(), 0, mVertices.Count -2);
}
ただし、VertexArray クラスを T[] として渡すことができないため、これは機能しません。カスタム シェーダーを使用せずに GPU でアウトライン計算を行うという目標を達成するには、どうすればこれを修正できますか?