我正在尝试在不使用自定义着色器的情况下绘制具有宽颜色轮廓的 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 上进行轮廓计算的目标?