如何在Windows Phone 7 3D開(kāi)發(fā)中使用紋理貼圖
Windows Phone 7對(duì)3D的支持還是不錯(cuò)的,據(jù)說(shuō)是用OpenGL/ES做的,使用起來(lái)倒是也有點(diǎn)那種感覺(jué)。本文就不講XNA 4.0的游戲框架了,直接上一段代碼,該代碼使用VertexPositionColor渲染了一個(gè)三角形,程序運(yùn)行一切正常。
- + expand sourceview plaincopy to clipboardprint?
運(yùn)行結(jié)果如下:
在確認(rèn)了3D開(kāi)發(fā)的這種代碼結(jié)構(gòu)以后,用VertexPositionTexture渲染同樣的三角形,只是這次采用紋理貼圖,代碼如下:
- view plaincopy to clipboardprint?
- VertexPositionTexture[] trangleTexture;
- protected override void LoadContent()
- {
- spriteBatch = new SpriteBatch(GraphicsDevice);
- image = Content.Load<Texture2D>(@"Images/Tulips");
- trangleTexture = new VertexPositionTexture[]{
- new VertexPositionTexture(new Vector3(0, 1, 0),new Vector2(0.5f,0) ),
- new VertexPositionTexture(new Vector3(1, -1, 0),new Vector2(1,1f) ),
- new VertexPositionTexture(new Vector3(-1,-1, 0),new Vector2(0,1f) )
- };
- vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionTexture), trangleTexture.Length, BufferUsage.None);
- vertexBuffer.SetData<VertexPositionTexture>(trangleTexture);
- basicEffect = new BasicEffect(GraphicsDevice);
- GraphicsDevice.SetVertexBuffer(vertexBuffer);
- }
- protected override void Draw(GameTime gameTime)
- {
- GraphicsDevice.Clear(Color.CornflowerBlue);
- basicEffect.World = world;
- basicEffect.View = camera.view;
- basicEffect.Projection = camera.projection;
- basicEffect.Texture = image;
- basicEffect.TextureEnabled = true;
- foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
- {
- pass.Apply();
- GraphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, trangleTexture, 0, 1);
- }
- base.Draw(gameTime);
- }
啰嗦一句,在此代碼中VertexPositionTexture的第二個(gè)Vetex2代表的是UV坐標(biāo),對(duì)應(yīng)的含義是(0,0)點(diǎn)對(duì)應(yīng)了紋理圖片的左上角,(1,1)點(diǎn)對(duì)應(yīng)了紋理圖片的右下角。
上述代碼在運(yùn)行的時(shí)候會(huì)在VS2010的輸出窗口中顯示:
A first chance exception of type 'System.NotSupportedException' occurred in Microsoft.Xna.Framework.Graphics.dll A first chance exception of type 'System.Threading.ThreadAbortException' occurred in Microsoft.Xna.Framework.dll |
與前一個(gè)彩色三角形對(duì)比,頂點(diǎn)順序沒(méi)變,攝像機(jī)位置沒(méi)變,投影矩陣沒(méi)變,按說(shuō)是不可能出現(xiàn)這種問(wèn)題的,而且程序直接崩了,沒(méi)有信息拋出,真是很郁悶。
經(jīng)過(guò)不斷的試錯(cuò),在宣布放棄之前,忽然想起來(lái)關(guān)于紋理方面的一個(gè)注意事項(xiàng)。有過(guò)3D開(kāi)發(fā)經(jīng)驗(yàn)的朋友都知道,紋理是要求符合2的整數(shù)次方對(duì)齊的,而我所加載的來(lái)自于外部任意圖片的紋理不符合這一要求,所以程序掛了。
又查了一些資料,找到了準(zhǔn)確的原因。原來(lái)是Windows Phone 7 的XNA中默認(rèn)的紋理尋址模式使用了Wrap,造成了與GPU的不兼容,如果改成Clamp就好了。
看來(lái)在這個(gè)地方微軟得要有文檔說(shuō)明才好,否則還真是難找問(wèn)題所在。修改后的代碼如下:
- view plaincopy to clipboardprint?
- protected override void LoadContent()
- {
- // Create a new SpriteBatch, which can be used to draw textures.
- spriteBatch = new SpriteBatch(GraphicsDevice);
- image = Content.Load<Texture2D>(@"Images/Tulips");
- trangleTexture = new VertexPositionTexture[]{
- new VertexPositionTexture(new Vector3(0, 1, 0),new Vector2(0.5f,0) ),
- new VertexPositionTexture(new Vector3(1, -1, 0),new Vector2(1,1f) ),
- new VertexPositionTexture(new Vector3(-1,-1, 0),new Vector2(0,1f) )
- };
- vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionTexture), trangleTexture.Length, BufferUsage.None);
- vertexBuffer.SetData<VertexPositionTexture>(trangleTexture);
- basicEffect = new BasicEffect(GraphicsDevice);
- GraphicsDevice.SetVertexBuffer(vertexBuffer);
- GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
- }
最終的模擬器結(jié)果是:
不管怎么說(shuō),Windows Phone 7的XNA游戲開(kāi)發(fā)框架以及3D方面的開(kāi)發(fā)接口還是很出色的,頂一下微軟,并希望這個(gè)平臺(tái)能盡快發(fā)展起來(lái)。
附Camera的代碼:
- view plaincopy to clipboardprint?
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Audio;
- using Microsoft.Xna.Framework.Content;
- using Microsoft.Xna.Framework.GamerServices;
- using Microsoft.Xna.Framework.Graphics;
- using Microsoft.Xna.Framework.Input;
- using Microsoft.Xna.Framework.Media;
- namespace WindowsPhoneGame1
- {
- public class Camera : Microsoft.Xna.Framework.GameComponent
- {
- public Matrix view{get;protected set;}
- public Matrix projection { get; protected set; }
- public Camera(Game game,Vector3 pos,Vector3 target,Vector3 up)
- : base(game)
- {
- view = Matrix.CreateLookAt(pos, target, up);
- projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)game.Window.ClientBounds.Width / (float)game.Window.ClientBounds.Height, 1, 100);
- }
- public override void Initialize()
- {
- base.Initialize();
- }
- public override void Update(GameTime gameTime)
- {
- base.Update(gameTime);
- }
- }
- }
本文轉(zhuǎn)自http://blog.csdn.net/caowenbin
【編輯推薦】