經過前幾節內容的學習,我們已經讓物體具有了平移、縮放、旋轉的三大運動能力,通過組合使用,可以形成復雜的物體運動模型。
接下來,我們要給物體增加些顏色了,改變灰濛濛的世界。
還記得我們之前定義的三角形數據嗎?當初定義的時候是這樣的:
~~~
??????????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;
運行一下,絢麗的三角形就出來了。

不過,僅用顏色顯然不能制作更逼真的物體,比如說木頭的三角形,用顏色就不能準確表達了。這時,我們需要的是使用紋理,即使用木紋的圖片貼到三角形上,最終看上去成為想要的效果。
在Windows Phone中,紋理是使用Texture2D類來表示的,最常用的就是代表資源中的一張圖片。具體的實現是在Content工程中添加一張圖片,比如在HelloContent中添加一張wood.jpg圖片,然后在LoadContent()方法中就可以使用如下語句將圖片表示為Texture2D對象了。
texture =Content.Load<Texture2D>(@"wood");
有了紋理,還要有正確的貼圖坐標,這里我們稱為UV坐標,一個紋理圖片的UV坐標規定為:

這樣我們就可以指定不同頂點的貼圖位置了。比如我們的三角形最上邊的點的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;
~~~
運行程序,可以得到帶木紋的三角形了。

附本節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開發之后記(附源碼)