经过前几节内容的学习,我们已经让物体具有了平移、缩放、旋转的三大运动能力,通过组合使用,可以形成复杂的物体运动模型。
接下来,我们要给物体增加些颜色了,改变灰濛濛的世界。
还记得我们之前定义的三角形数据吗?当初定义的时候是这样的:
~~~
triangle = new VertexPositionColor[]{
new VertexPositionColor(new Vector3(0, 1, 0), Color.Red),
new VertexPositionColor(new Vector3(1, -1, 0), Color.Green),
new VertexPositionColor(new Vector3(-1,-1, 0), Color.Blue)
};
~~~
我们使用了VertexPositionColor对象数组,该类型使用坐标和颜色值来表示一个顶点,但在此之前,该颜色值一直没起到作用,我们看到的都是白色的三角形,其实想让颜色生效非常简单,只要在Draw()方法添加下句即可:
basicEffect.VertexColorEnabled= true;
运行一下,绚丽的三角形就出来了。
![](https://box.kancloud.cn/2016-04-08_570727fad2952.gif)
不过,仅用颜色显然不能制作更逼真的物体,比如说木头的三角形,用颜色就不能准确表达了。这时,我们需要的是使用纹理,即使用木纹的图片贴到三角形上,最终看上去成为想要的效果。
在Windows Phone中,纹理是使用Texture2D类来表示的,最常用的就是代表资源中的一张图片。具体的实现是在Content工程中添加一张图片,比如在HelloContent中添加一张wood.jpg图片,然后在LoadContent()方法中就可以使用如下语句将图片表示为Texture2D对象了。
texture =Content.Load<Texture2D>(@"wood");
有了纹理,还要有正确的贴图坐标,这里我们称为UV坐标,一个纹理图片的UV坐标规定为:
![](https://box.kancloud.cn/2016-04-08_570727faedc83.gif)
这样我们就可以指定不同顶点的贴图位置了。比如我们的三角形最上边的点的UV坐标就是(0.5,0),左下角点是(0,1),右下角点是(1,1)。对于需要使用纹理坐标的三角形,前文用到的VertexPositionColor类型已经不够了,我们需要使用VertexPositionTexture类型,即每个顶点使用坐标和纹理坐标来描述,而不再是坐标和颜色来描述了。对应的三角形数据如下:
~~~
triangle = newVertexPositionTexture[]{
new VertexPositionTexture(newVector3(0, 1, 0), new Vector2(0.5f,0)),
new VertexPositionTexture(newVector3(1, -1, 0), new Vector2(1,1)),
new VertexPositionTexture(newVector3(-1,-1, 0), new Vector2(0,1))
};
~~~
最后,要想得到渲染结果,修改Draw()方法,调整basicEffect的纹理属性为:
~~~
basicEffect.TextureEnabled = true;
basicEffect.Texture = texture;
~~~
运行程序,可以得到带木纹的三角形了。
![](https://box.kancloud.cn/2016-04-08_570727fb0a667.gif)
附本节Game1类的完整源码:
~~~
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
Camera camera;
Matrix world = Matrix.Identity;
BasicEffect basicEffect;
VertexPositionTexture[] triangle;
Matrix translateMatrix=Matrix.Identity;
Matrix scaleMatrix = Matrix.CreateScale(0.5f);
Matrix rotateMatrix = Matrix.Identity;
Texture2D texture;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
// Frame rate is 30 fps by default for Windows Phone.
TargetElapsedTime = TimeSpan.FromTicks(333333);
// Extend battery life under lock.
InactiveSleepTime = TimeSpan.FromSeconds(1);
graphics.IsFullScreen = true;
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
camera = new Camera(this, new Vector3(0, 0, 5), Vector3.Zero, Vector3.Up, MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 1.0f, 50.0f);
Components.Add(camera);
basicEffect = new BasicEffect(GraphicsDevice);
triangle = new VertexPositionTexture[]{
new VertexPositionTexture(new Vector3(0, 1, 0), new Vector2(0.5f,0)),
new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1,1)),
new VertexPositionTexture(new Vector3(-1,-1, 0), new Vector2(0,1))
};
texture = Content.Load<Texture2D>(@"wood");
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
TouchPanel.EnabledGestures = GestureType.Tap;
if (TouchPanel.IsGestureAvailable)
{
GestureSample gestureSample = TouchPanel.ReadGesture();
if (gestureSample.GestureType == GestureType.Tap)
{
translateMatrix *= Matrix.CreateTranslation(0.3f, 0, 0);
//scaleMatrix = Matrix.CreateScale(0.9f);
rotateMatrix *= Matrix.CreateRotationY(MathHelper.ToRadians(10));
}
}
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
RasterizerState rasterizerState = new RasterizerState();
rasterizerState.CullMode = CullMode.None;
GraphicsDevice.RasterizerState = rasterizerState;
basicEffect.World = scaleMatrix * translateMatrix * rotateMatrix;
basicEffect.View = camera.view;
basicEffect.Projection = camera.projection;
basicEffect.TextureEnabled = true;
basicEffect.Texture = texture;
GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, triangle, 0, 1);
}
base.Draw(gameTime);
}
}
~~~
——欢迎转载,请注明出处 [http://blog.csdn.net/caowenbin](http://blog.csdn.net/caowenbin) ——
- 前言
- Windows Phone 7开发环境初体验
- Windows Phone 7 3D开发中使用纹理贴图
- 在Windows Phone中进行3D开发之一坐标系
- 在Windows Phone中进行3D开发之二摄像机
- 在Windows Phone中进行3D开发之三空间
- 在Windows Phone中进行3D开发之四三角形
- 在Windows Phone中进行3D开发之五平移缩放
- 在Windows Phone中进行3D开发之六旋转
- 在Windows Phone中进行3D开发之七纹理
- 在Windows Phone中进行3D开发之八光照
- 在Windows Phone中进行3D开发之九模型
- 在Windows Phone中进行3D开发之十组件
- 在Windows Phone中进行3D开发之十一天空
- 在Windows Phone中进行3D开发之十二飞行
- 在Windows Phone中进行3D开发之十三阳光
- 在Windows Phone中进行3D开发之后记(附源码)