0

私は 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 の正しい方向性を示すあらゆる種類の読み物にも大いに感謝しています。読んでくれてありがとう。

4

1 に答える 1

2

最初の例では、頂点のリストを適切に描画していますが、エラーが言ったように、シェーダーがありませんでした。シェーダーについての簡単なメモ: WP7 にはカスタム シェーダーがないため、これは何も適用していないことを意味しますEffectEffectWP7 は、ここにあるサブクラスに限定されています。基本的に組み込みのシェーダーが含まれています。

2 番目の例では、シェーダーがセットアップされていますが、リストやバッファーから描画していません。DrawUserIndexedPrimitvesインデックスと頂点の配列を取ります。それらを使って描画します。DrawPrimitivesしません。グラフィックス デバイスにバインドされている頂点バッファーに依存します。

2 番目の例を に変更しDrawUserIndexedPrimitivesて配列を渡すか (cubeVerticesそして...待って、インデックス配列がない場合は作成します) VertexBuffer、同じ情報で を設定して次のようにバインドします。

Controller.Graphics.GraphicsDevice.SetVertexBuffer(vb);

于 2013-04-11T15:27:12.147 に答える