立方 发表于 2013-2-4 01:26:43

如何在Windows Phone 7 3D开发中使用纹理贴图

Windows Phone 7对3D的支持还是不错的,据说是用OpenGL/ES做的,使用起来倒是也有点那种感觉。本文就不讲XNA 4.0的游戏框架了,直接上一段代码,该代码使用VertexPositionColor渲染了一个三角形,程序运行一切正常。

[*]+ expand sourceview plaincopy to clipboardprint?
[*]
运行结果如下:
http://images.51cto.com/files/uploadimg/20110316/1037080.gif
在确认了3D开发的这种代码结构以后,用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的第二个Vetex2代表的是UV坐标,对应的含义是(0,0)点对应了纹理图片的左上角,(1,1)点对应了纹理图片的右下角。
上述代码在运行的时候会在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          同时模拟器里的程序直接退出,看不到结果。原因是什么呢?疑惑并仔细检视代码中……
与前一个彩色三角形对比,顶点顺序没变,摄像机位置没变,投影矩阵没变,按说是不可能出现这种问题的,而且程序直接崩了,没有信息抛出,真是很郁闷。
经过不断的试错,在宣布放弃之前,忽然想起来关于纹理方面的一个注意事项。有过3D开发经验的朋友都知道,纹理是要求符合2的整数次方对齐的,而我所加载的来自于外部任意图片的纹理不符合这一要求,所以程序挂了。
又查了一些资料,找到了准确的原因。原来是Windows Phone 7 的XNA中默认的纹理寻址模式使用了Wrap,造成了与GPU的不兼容,如果改成Clamp就好了。
看来在这个地方微软得要有文档说明才好,否则还真是难找问题所在。修改后的代码如下:

[*]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 = SamplerState.PointClamp;   
[*]}   
[*]
最终的模拟器结果是:
http://images.51cto.com/files/uploadimg/20110316/1037081.gif
不管怎么说,Windows Phone 7的XNA游戏开发框架以及3D方面的开发接口还是很出色的,顶一下微软,并希望这个平台能尽快发展起来。
附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);   
[*]      }   
[*]    }   
[*]}   
[*]
本文转自http://blog.csdn.net/caowenbin
【编辑推荐】
   
[*]Windows Phone 7中用好Silverlight开发利器   
[*]Windows Phone 7的地图控件   
[*]Windows Phone 7的枢轴控件   
[*]Windows Phone 7的全景视图控件   
[*]使用独立存储开发Windows Phone 7应用程序
<DIV align=right>【责任编辑:立方 TEL:(010)68476606】
页: [1]
查看完整版本: 如何在Windows Phone 7 3D开发中使用纹理贴图