如何在WP中绘制3D基元

时间:2013-04-11 15:13:15

标签: visual-studio-2012 3d xna windows-phone

我是XNA的绿色角,我一直试图解决这个问题好几天,但每次我试图完成它我得到一个例外或应用程序只是简单的退出,它一直非常恼人

我希望能够绘制3D基元而无需为其预制模型。我先得到这个代码:

VertexPositionColor[] primitiveList = { new VertexPositionColor(
                    new Vector3(1,1,0), Color.White), new VertexPositionColor(
                    new Vector3(0,1,-1), Color.White) };

short[] lineListIndices = { 0, 1 };

Controller.CurrentGame.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
    PrimitiveType.LineList,
    primitiveList,
    0,  // vertex buffer offset to add to each element of the index buffer
    2,  // number of vertices in pointList
    lineListIndices,  // the index buffer
    0,  // first index element to read
    1   // number of primitives to draw
);

我收到带有以下

的InvalidOperationException
  

消息“在执行任何绘制操作之前,必须在设备上设置顶点着色器和像素着色器。”

然后,我尝试按照http://msdn.microsoft.com/en-us/library/bb203926.aspx上的说明操作,最后得到以下代码:

BasicEffect basicEffect = new BasicEffect(Controller.Graphics.GraphicsDevice);

basicEffect.World = Matrix.Identity;
basicEffect.View = Controller.Cam.view;
basicEffect.Projection = Controller.Cam.projection;

// primitive color
basicEffect.AmbientLightColor = new Vector3(0.1f, 0.1f, 0.1f);
basicEffect.DiffuseColor = new Vector3(1.0f, 1.0f, 1.0f);
basicEffect.SpecularColor = new Vector3(0.25f, 0.25f, 0.25f);
basicEffect.SpecularPower = 5.0f;
basicEffect.Alpha = 1.0f;

basicEffect.LightingEnabled = true;
if (basicEffect.LightingEnabled)
{
    basicEffect.DirectionalLight0.Enabled = true; // enable each light individually
    if (basicEffect.DirectionalLight0.Enabled)
    {
        // x direction
        basicEffect.DirectionalLight0.DiffuseColor = new Vector3(1, 0, 0); // range is 0 to 1
        basicEffect.DirectionalLight0.Direction = Vector3.Normalize(new Vector3(-1, 0, 0));
        // points from the light to the origin of the scene
        basicEffect.DirectionalLight0.SpecularColor = Vector3.One;
    }

    basicEffect.DirectionalLight1.Enabled = true;
    if (basicEffect.DirectionalLight1.Enabled)
    {
        // y direction
        basicEffect.DirectionalLight1.DiffuseColor = new Vector3(0, 0.75f, 0);
        basicEffect.DirectionalLight1.Direction = Vector3.Normalize(new Vector3(0, -1, 0));
        basicEffect.DirectionalLight1.SpecularColor = Vector3.One;
    }

    basicEffect.DirectionalLight2.Enabled = true;
    if (basicEffect.DirectionalLight2.Enabled)
    {
        // z direction
        basicEffect.DirectionalLight2.DiffuseColor = new Vector3(0, 0, 0.5f);
        basicEffect.DirectionalLight2.Direction = Vector3.Normalize(new Vector3(0, 0, -1));
        basicEffect.DirectionalLight2.SpecularColor = Vector3.One;
    }
}

VertexDeclaration vertexDeclaration = new VertexDeclaration(new VertexElement[]
    {
        new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
        new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
        new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
    }
);

Vector3 topLeftFront = new Vector3(-1.0f, 1.0f, 1.0f);
Vector3 bottomLeftFront = new Vector3(-1.0f, -1.0f, 1.0f);
Vector3 topRightFront = new Vector3(1.0f, 1.0f, 1.0f);
Vector3 bottomRightFront = new Vector3(1.0f, -1.0f, 1.0f);
Vector3 topLeftBack = new Vector3(-1.0f, 1.0f, -1.0f);
Vector3 topRightBack = new Vector3(1.0f, 1.0f, -1.0f);
Vector3 bottomLeftBack = new Vector3(-1.0f, -1.0f, -1.0f);
Vector3 bottomRightBack = new Vector3(1.0f, -1.0f, -1.0f);

Vector2 textureTopLeft = new Vector2(0.0f, 0.0f);
Vector2 textureTopRight = new Vector2(1.0f, 0.0f);
Vector2 textureBottomLeft = new Vector2(0.0f, 1.0f);
Vector2 textureBottomRight = new Vector2(1.0f, 1.0f);

Vector3 frontNormal = new Vector3(0.0f, 0.0f, 1.0f);
Vector3 backNormal = new Vector3(0.0f, 0.0f, -1.0f);
Vector3 topNormal = new Vector3(0.0f, 1.0f, 0.0f);
Vector3 bottomNormal = new Vector3(0.0f, -1.0f, 0.0f);
Vector3 leftNormal = new Vector3(-1.0f, 0.0f, 0.0f);
Vector3 rightNormal = new Vector3(1.0f, 0.0f, 0.0f);

VertexPositionNormalTexture[] cubeVertices = new VertexPositionNormalTexture[6];

// Front face.
cubeVertices[0] =
    new VertexPositionNormalTexture(
    topLeftFront, frontNormal, textureTopLeft);
cubeVertices[1] =
    new VertexPositionNormalTexture(
    bottomLeftFront, frontNormal, textureBottomLeft);
cubeVertices[2] =
    new VertexPositionNormalTexture(
    topRightFront, frontNormal, textureTopRight);
cubeVertices[3] =
    new VertexPositionNormalTexture(
    bottomLeftFront, frontNormal, textureBottomLeft);
cubeVertices[4] =
    new VertexPositionNormalTexture(
    bottomRightFront, frontNormal, textureBottomRight);
cubeVertices[5] =
    new VertexPositionNormalTexture(
    topRightFront, frontNormal, textureTopRight);

RasterizerState rasterizerState1 = new RasterizerState();
rasterizerState1.CullMode = CullMode.None;
Controller.Graphics.GraphicsDevice.RasterizerState = rasterizerState1;
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
    pass.Apply();

    Controller.Graphics.GraphicsDevice.DrawPrimitives(
        PrimitiveType.TriangleList,
        0,
        12
    );
}

我得到以下例外

  

消息“在执行任何绘制操作之前,必须在设备上设置有效的顶点缓冲区(如果使用索引基元,则为有效的索引缓冲区)。”

我知道我不应该在同一个地方拥有所有这些代码,但我只是希望能够得到一些东西来绘制所以我可以看到它是如何工作但是没有任何作用,我似乎无法加载任何VS的例子。

正如我所说的那样,我是一个新的超越问题的人,我也非常欣赏任何能够指向3D XNA正确方向的阅读材料。谢谢你的阅读。

1 个答案:

答案 0 :(得分:2)

在你的第一个例子中,你正确地绘制了一个顶点列表,但是因为错误说它没有着色器。关于着色器的快速说明:由于WP7上没有自定义着色器,这意味着您没有应用任何Effect; WP7仅限于可以找到的Effect子类here。它们基本上包含内置着色器。

在第二个示例中,您设置了着色器,但现在您没有从任何列表或缓冲区中进行绘制。 DrawUserIndexedPrimitves采用一系列索引&amp;顶点。它使用那些绘制。 DrawPrimitives没有;它依赖于绑定到图形设备的顶点缓冲区。

将第二个示例更改为DrawUserIndexedPrimitives并传入数组(cubeVertices并...等待,您没有索引数组,制作一个),或者设置一个VertexBuffer具有相同的信息并按如下方式绑定:

Controller.Graphics.GraphicsDevice.SetVertexBuffer(vb);