简体   繁体   中英

DrawUserPrimitives Invalid Operation Exception

I'm trying to draw a triangle using this code in XNA:

VertexPositionColor[] vertices = new VertexPositionColor[3];
vertices[0].Position = new Vector3(-0.5f, -0.5f, 0f);
vertices[0].Color = Color.Red;
vertices[1].Position = new Vector3(0, 0.5f, 0f);
vertices[1].Color = Color.Green;
vertices[2].Position = new Vector3(0.5f, -0.5f, 0f);
vertices[2].Color = Color.Yellow;
GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, vertices, 0, 1);

However, as soon as I run it, application closes, and InvalidOperationException is thrown. It's WP7 application. Am I missing something? Thanks for your help in advance.

The documentation says that DrawUserPrimitives throws InvalidOperationException when:

A valid vertex shader and pixel shader was not set before calling DrawUserPrimitives. Both a valid vertex shader and pixel shader (or valid effect) must be set on the device before any draw operations may be performed.

(It also says it will throw if your vertices are invalid - but they look ok to me.)

You need to set an Effect on the graphics device. Specifically you need to call EffectPass.Apply before you call DrawUserPrimitives . An easy way to start is with BasicEffect . Here is some code, suitable to put in the Draw method, to illustrate this:

// These three lines are required if you use SpriteBatch, to reset the states that it sets
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;

// Transform your model to place it somewhere in the world
basicEffect.World = Matrix.CreateRotationZ(MathHelper.PiOver4) * Matrix.CreateTranslation(0.5f, 0, 0); // for sake of example
//basicEffect.World = Matrix.Identity; // Use this to leave your model at the origin
// Transform the entire world around (effectively: place the camera)
basicEffect.View = Matrix.CreateLookAt(new Vector3(0, 0, -3), Vector3.Zero, Vector3.Up);
// Specify how 3D points are projected/transformed onto the 2D screen
basicEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45),
        (float)GraphicsDevice.Viewport.Width / (float)GraphicsDevice.Viewport.Height, 1.0f, 100.0f);

// Tell BasicEffect to make use of your vertex colors
basicEffect.VertexColorEnabled = true;
// I'm setting this so that *both* sides of your triangle are drawn
// (so it won't be back-face culled if you move it, or the camera around behind it)
GraphicsDevice.RasterizerState = RasterizerState.CullNone;

// Render with a BasicEffect that was created in LoadContent
// (BasicEffect only has one pass - but effects in general can have many rendering passes)
foreach(EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
    // This is the all-important line that sets the effect, and all of its settings, on the graphics device
    pass.Apply();

    // Here's your code:
    VertexPositionColor[] vertices = new VertexPositionColor[3];
    vertices[0].Position = new Vector3(-0.5f, -0.5f, 0f);
    vertices[0].Color = Color.Red;
    vertices[1].Position = new Vector3(0, 0.5f, 0f);
    vertices[1].Color = Color.Green;
    vertices[2].Position = new Vector3(0.5f, -0.5f, 0f);
    vertices[2].Color = Color.Yellow;
    GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, vertices, 0, 1);
}

That exception (InvalidOperationException) is typically thrown when a component finds it's in an unexpected state. So in your case, make sure GraphicsDevice does not need some other properties set before you invoke DrawUserPrimitives.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM