C# 在GPU上计算多边形轮廓顶点

C# 在GPU上计算多边形轮廓顶点,c#,arrays,windows-phone-7,xna,gpu,C#,Arrays,Windows Phone 7,Xna,Gpu,我正在尝试在不使用自定义着色器的情况下绘制具有宽彩色轮廓的二维多边形。 (如果我要写一个,可能会比使用CPU慢,因为我不太熟悉着色器) 为此,我计划像法线一样绘制多边形,然后在绘制相同的展开几何体时,将生成的深度缓冲区用作模具 XNA“GraphicsDevice”可以在给定任何IVertexType实例数组的情况下绘制原语: DrawUserPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOf

我正在尝试在不使用自定义着色器的情况下绘制具有宽彩色轮廓的二维多边形。
(如果我要写一个,可能会比使用CPU慢,因为我不太熟悉着色器)
为此,我计划像法线一样绘制多边形,然后在绘制相同的展开几何体时,将生成的深度缓冲区用作模具

XNA“GraphicsDevice”可以在给定任何IVertexType实例数组的情况下绘制原语:

DrawUserPrimitives<T>(PrimitiveType primitiveType, T[] vertexData, int vertexOffset, int primitiveCount, VertexDeclaration vertexDeclaration) where T : struct;
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);
}
protected override void renderlocaly(图形设备)
{
//画图
mVertices.outlineDrawMode=true;//mVertices是VertexOutlineArray实例
device.RasterizerState=RasterizerState.CullNone;
device.PresentationParameters.DepthStencilFormat=DepthFormat.Depth16;
设备.清除(ClearOptions.DepthBuffer,Color.SkyBlue,0,0);
device.DrawUserPrimitives(PrimitiveType.TriangleList,(VertexPosition2DColor[])mVertices,0,mVertices.Length-2,VertexPosition2DColor.declaration);
//勾勒
mVertices.outlineDrawMode=true;
device.DepthStencilState=新的DepthStencilState{
DepthBufferWriteEnable=true,
DepthBufferFunction=CompareFunction.Greater//防止轮廓在形状上书写
};
device.DrawUserPrimitives(PrimitiveType.TriangleList,mVertices.ToArray(),0,mVertices.Count-2);
}

但这不起作用,因为我无法以t[]的成绩通过VertexArray课程。我怎样才能修改这一点,或者在没有自定义着色器的情况下在GPU上完成轮廓计算的目标呢?

我想知道为什么您不简单地编写一个类,使用成对的细三角形作为线来绘制轮廓?您可以创建一个通用多段线例程,该例程接收二维点的输入和线的宽度,并输出一个顶点缓冲区

我意识到这并没有回答你的问题,但我看不出你这样做有什么好处。是否有您想要实现的特定效果,或者您是否将非常频繁地操作数据或缩放多边形


您可能遇到的问题是,XNA4 for Windows Phone 7根本不支持自定义着色器。事实上,他们故意将其限制在一组预定义的着色器中,因为需要测试的排列数量太多。目前受支持的有:

字母效应 基本效果 环境地图效应 双重纹理效应 皮肤缺陷

您可以在此处阅读有关它们的信息:

我还没有测试过创建或使用带有Vector2位置和normal的IverTextType,因此我无法评论它是否受支持。如果我要这样做,我将只使用基本效果和顶点曝光法线进行主多边形形状渲染,并调整每个多边形的漫反射颜色。要渲染轮廓,请使用现有的VertexBuffer,并通过调用GraphicsDevice.Viewport.Unproject()来适当缩放轮廓,以确定生成n像素二维屏幕距离(轮廓宽度)所需的三维坐标距离

请记住,当您使用BasicFect或任何效果时,在进行Draw调用之前,必须循环CurrentTechnical的EffectPass数组,并为每个过程调用Apply()方法

        device.DepthStencilState = DepthStencilState.Default;
        device.BlendState = BlendState.AlphaBlend;
        device.RasterizerState = RasterizerState.CullCounterClockwise;

        //Set the appropriate vertex and indice buffers
        device.SetVertexBuffer(_polygonVertices);
        device.Indices = _polygonIndices;

        foreach (EffectPass pass in _worldEffect.CurrentTechnique.Passes)
        {
            pass.Apply();
            PApp.Graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _polygonVertices.VertexCount, 0, _polygonIndices.IndexCount / 3);
        }

你应该删除一篇文章,你已经创建了重复的文章questions@CuongLe nice catch被删除了我想你是误会了。GPU的速度惊人地快于CPU,你几乎不会出错。另外,它从CPU到GPU的发送速度很慢——你走的是最慢的路线。@DeadMG我能得到一个链接吗?知道XNA BasicFect是否必须发送如此缓慢的数据吗?会有很多缩放和突变,我想要一种可以应用于任何光栅化正交几何的效果,我不知道你指的是什么正交几何;这只是一个技术术语,用于描述平行于正交投影视口渲染的多边形吗?