# 马宁的嵌入式开发研究

Windows Phone, XNA, Windows Embedded, Windows Mobile
posts - 84, comments - 752, trackbacks - 17, articles - 0

### 导航

http://files.cnblogs.com/aawolf/XNA_aawolf_3D.rar

http://msdn.microsoft.com/en-us/library/bb203926.aspx

http://www.cnblogs.com/aawolf/archive/2010/08/28/1811438.html

Matrix worldMatrix;

Matrix viewMatrix;

Matrix projectionMatrix;

VertexPositionNormalTexture[] cubeVertices;

VertexDeclaration vertexDeclaration;

VertexBuffer vertexBuffer;

BasicEffect basicEffect;

Martrix 的中文名叫“矩阵”，还有个翻译叫“黑客帝国”……扯远了，什么是矩阵？我们就不解释了，只要知道矩阵是一切3D线性变化的基础就可以了。我们不知道矩阵是什么，却身处其中。在Game1类中用了三个矩阵：worldMatrix用来描述世界坐标系；viewMatrix用来描述摄影机坐标系；projectionMatrix用来描述投影坐标系。这些都是3D图形学的概念，不解释了。

private void InitMatrices()

{

// Initialize the world, view, and projection matrices.

float tilt = MathHelper.ToRadians(0); // 0 degree angle

// Use the world matrix to tilt the cube along x and y axes.

worldMatrix = Matrix.CreateRotationX(tilt) * Matrix.CreateRotationY(tilt);

viewMatrix = Matrix.CreateLookAt(new Vector3(5, 5, 5), Vector3.Zero, Vector3.Up);

projectionMatrix = Matrix.CreatePerspectiveFieldOfView(

MathHelper.ToRadians(45), // 45 degree angle

(float)GraphicsDevice.Viewport.Width /

(float)GraphicsDevice.Viewport.Height,

1.0f, 100.0f);

}

private void InitEffect()

{

// Initialize BasicEffect with transformation and light values

basicEffect = new BasicEffect(graphics.GraphicsDevice);

basicEffect.World = worldMatrix;

basicEffect.View = viewMatrix;

basicEffect.Projection = projectionMatrix;

// 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;

}

}

}

private void InitVertexBuffer()

{

// Create a vertex declaration for the type VertexPositionNormalTexture

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)

}

);

// Create the per vertex data

cubeVertices = new VertexPositionNormalTexture[36];

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);

// 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);

// Back face.

cubeVertices[6] =

new VertexPositionNormalTexture(

topLeftBack, backNormal, textureTopRight);

cubeVertices[7] =

new VertexPositionNormalTexture(

topRightBack, backNormal, textureTopLeft);

cubeVertices[8] =

new VertexPositionNormalTexture(

bottomLeftBack, backNormal, textureBottomRight);

cubeVertices[9] =

new VertexPositionNormalTexture(

bottomLeftBack, backNormal, textureBottomRight);

cubeVertices[10] =

new VertexPositionNormalTexture(

topRightBack, backNormal, textureTopLeft);

cubeVertices[11] =

new VertexPositionNormalTexture(

bottomRightBack, backNormal, textureBottomLeft);

// Top face.

cubeVertices[12] =

new VertexPositionNormalTexture(

topLeftFront, topNormal, textureBottomLeft);

cubeVertices[13] =

new VertexPositionNormalTexture(

topRightBack, topNormal, textureTopRight);

cubeVertices[14] =

new VertexPositionNormalTexture(

topLeftBack, topNormal, textureTopLeft);

cubeVertices[15] =

new VertexPositionNormalTexture(

topLeftFront, topNormal, textureBottomLeft);

cubeVertices[16] =

new VertexPositionNormalTexture(

topRightFront, topNormal, textureBottomRight);

cubeVertices[17] =

new VertexPositionNormalTexture(

topRightBack, topNormal, textureTopRight);

// Bottom face.

cubeVertices[18] =

new VertexPositionNormalTexture(

bottomLeftFront, bottomNormal, textureTopLeft);

cubeVertices[19] =

new VertexPositionNormalTexture(

bottomLeftBack, bottomNormal, textureBottomLeft);

cubeVertices[20] =

new VertexPositionNormalTexture(

bottomRightBack, bottomNormal, textureBottomRight);

cubeVertices[21] =

new VertexPositionNormalTexture(

bottomLeftFront, bottomNormal, textureTopLeft);

cubeVertices[22] =

new VertexPositionNormalTexture(

bottomRightBack, bottomNormal, textureBottomRight);

cubeVertices[23] =

new VertexPositionNormalTexture(

bottomRightFront, bottomNormal, textureTopRight);

// Left face.

cubeVertices[24] =

new VertexPositionNormalTexture(

topLeftFront, leftNormal, textureTopRight);

cubeVertices[25] =

new VertexPositionNormalTexture(

bottomLeftBack, leftNormal, textureBottomLeft);

cubeVertices[26] =

new VertexPositionNormalTexture(

bottomLeftFront, leftNormal, textureBottomRight);

cubeVertices[27] =

new VertexPositionNormalTexture(

topLeftBack, leftNormal, textureTopLeft);

cubeVertices[28] =

new VertexPositionNormalTexture(

bottomLeftBack, leftNormal, textureBottomLeft);

cubeVertices[29] =

new VertexPositionNormalTexture(

topLeftFront, leftNormal, textureTopRight);

// Right face.

cubeVertices[30] =

new VertexPositionNormalTexture(

topRightFront, rightNormal, textureTopLeft);

cubeVertices[31] =

new VertexPositionNormalTexture(

bottomRightFront, rightNormal, textureBottomLeft);

cubeVertices[32] =

new VertexPositionNormalTexture(

bottomRightBack, rightNormal, textureBottomRight);

cubeVertices[33] =

new VertexPositionNormalTexture(

topRightBack, rightNormal, textureTopRight);

cubeVertices[34] =

new VertexPositionNormalTexture(

topRightFront, rightNormal, textureTopLeft);

cubeVertices[35] =

new VertexPositionNormalTexture(

bottomRightBack, rightNormal, textureBottomRight);

vertexBuffer = new VertexBuffer(

graphics.GraphicsDevice,

typeof(VertexPositionNormalTexture),

cubeVertices.Length,

BufferUsage.None

);

vertexBuffer.SetData<VertexPositionNormalTexture>(cubeVertices);

}

vertexBuffer = new VertexBuffer(

graphics.GraphicsDevice,

VertexPositionNormalTexture.SizeInBytes * cubeVertices.Length,

BufferUsage.None

);

vertexBuffer = new VertexBuffer(

graphics.GraphicsDevice,

typeof(VertexPositionNormalTexture),

cubeVertices.Length,

BufferUsage.None

);

VertexBuffer增加了一个Type类型的参数（第二个），我们必须传入一个IVertexType接口的派生类型，构造函数会用类型和顶点列表的长度计算VertexBuffer的size，这显然比上边的实现好了许多。

protected override void Initialize()

{

InitMatrices();

InitEffect();

InitVertexBuffer();

base.Initialize();

}

protected override void Draw(GameTime gameTime)

{

GraphicsDevice.Clear(Color.CornflowerBlue);

// TODO: Add your drawing code here

RasterizerState rasterizerState1 = new RasterizerState();

rasterizerState1.CullMode = CullMode.None;

graphics.GraphicsDevice.RasterizerState = rasterizerState1;

GraphicsDevice.SetVertexBuffer(vertexBuffer);

foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)

{

pass.Apply();

graphics.GraphicsDevice.DrawPrimitives(

PrimitiveType.TriangleList,

0,

36

);

}

base.Draw(gameTime);

}

GraphicsDevice.SetVertexBuffer(vertexBuffer);

An unhandled exception of type 'System.InvalidOperationException' occurred in Microsoft.Xna.Framework.Graphics.dll

Additional information: A valid vertex buffer (and a valid index buffer if you are using indexed primitives) must be set on the device before any draw operations may be performed.

protected override void Update(GameTime gameTime)

{

// Allows the game to exit

if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)

this.Exit();

// TODO: Add your update logic here

Matrix matrix = Matrix.CreateRotationX(0.1f);

basicEffect.World = basicEffect.World * matrix;

base.Update(gameTime);

}