[翻译]XNA外文博客文章精选之two
PS:自己翻译的,转载请著明出处
写一个纹理到XNA中
在这个教程中你将会写到纹理内存中创建一个纹理。
声明创建一个XNA游戏的标准组件:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using Microsoft.Xna.Framework;
5 using Microsoft.Xna.Framework.Audio;
6 using Microsoft.Xna.Framework.Content;
7 using Microsoft.Xna.Framework.GamerServices;
8 using Microsoft.Xna.Framework.Graphics;
9 using Microsoft.Xna.Framework.Input;
10 using Microsoft.Xna.Framework.Media;
11 using Microsoft.Xna.Framework.Net;
12 using Microsoft.Xna.Framework.Storage;
定义命名空间并创建Game1类
2 using System.Collections.Generic;
3 using System.Linq;
4 using Microsoft.Xna.Framework;
5 using Microsoft.Xna.Framework.Audio;
6 using Microsoft.Xna.Framework.Content;
7 using Microsoft.Xna.Framework.GamerServices;
8 using Microsoft.Xna.Framework.Graphics;
9 using Microsoft.Xna.Framework.Input;
10 using Microsoft.Xna.Framework.Media;
11 using Microsoft.Xna.Framework.Net;
12 using Microsoft.Xna.Framework.Storage;
1 namespace WriteToTexture
2 {
3 partial class Game1 : Microsoft.Xna.Framework.Game
4 {
这个GraphicsDeviceManager对象让你改变视频的模式并且改变窗口的大小。使用这个GraphicsDeviceManager的PreferredBackBufferWidth和PreferredBackBufferHeight值在Game1的结构中,如果你想改变窗口的大小的话。
2 {
3 partial class Game1 : Microsoft.Xna.Framework.Game
4 {
1 GraphicsDeviceManager graphics;
为了绘制这个纹理,你需要一个SpriteBatch对象来写它。
1 SpriteBatch spriteBatch;
2 Texture2D texture;
创建一个sprite batch在LoadContent方法里
2 Texture2D texture;
1 public Game1()
2 {
3 graphics = new GraphicsDeviceManager(this);
4 Content.RootDirectory = "Content";
5 }
6 protected override void Initialize()
7 {
8 base.Initialize();
9 }
创建一个sprite batch在LoadContent方法中
2 {
3 graphics = new GraphicsDeviceManager(this);
4 Content.RootDirectory = "Content";
5 }
6 protected override void Initialize()
7 {
8 base.Initialize();
9 }
1 protected override void LoadContent()
2 {
3 // Create a new SpriteBatch,
4 //which can be used to draw textures.
5 spriteBatch = new SpriteBatch(GraphicsDevice);
现在你需要创建一个纹理,你可以修改它。2 {
3 // Create a new SpriteBatch,
4 //which can be used to draw textures.
5 spriteBatch = new SpriteBatch(GraphicsDevice);
设置宽度和高度到后备缓冲的宽和高。
第四个参数是mip的级数。0表示很多的设备可以处理。在这个例子中,你没有使用mip maps所以设置为1。这在内存中只创建一个表面。
第五个参数设置纹理的用法。现在你不需要使用它,所以设置它为TextureUsage.None。
最后一个参数是纹理表面的格式。XNA使用SurfaceFormat.Color作为一般的格式。
1 //lets create an empty texture
2 texture = new Texture2D(GraphicsDevice,graphics.PreferredBackBufferWidth,graphics.PreferredBackBufferHeight,1, TextureUsage.None, SurfaceFormat.Color);
现在定义一个数组去保存这些纹理的象素和从它的表面上填充纹理
2 texture = new Texture2D(GraphicsDevice,graphics.PreferredBackBufferWidth,graphics.PreferredBackBufferHeight,1, TextureUsage.None, SurfaceFormat.Color);
1 Color[] rgba = new Color[texture.Width * texture.Height];
2 texture.GetData<Color>(rgba);
现在你需要把一些颜色放入到这个纹理中2 texture.GetData<Color>(rgba);
创建一个点在这个纹理的中心,并且计算它到每个象素的距离
这样就产生了各种各样的光亮图
1 //set a point that is above and in the middle of the texture
2 Vector3 vLightPos = new Vector3(graphics.PreferredBackBufferWidth / 2,graphics.PreferredBackBufferHeight / 2,0);
3 for (int x = 0; x < texture.Width; x++)
4 {
5 for (int y = 0; y < texture.Height; y++)
6 {
7 Vector3 v = new Vector3(x, y, 0);
8 float f = Vector3.Distance(v, vLightPos);
你需要clamp(夹住)距离值在0到255之间
2 Vector3 vLightPos = new Vector3(graphics.PreferredBackBufferWidth / 2,graphics.PreferredBackBufferHeight / 2,0);
3 for (int x = 0; x < texture.Width; x++)
4 {
5 for (int y = 0; y < texture.Height; y++)
6 {
7 Vector3 v = new Vector3(x, y, 0);
8 float f = Vector3.Distance(v, vLightPos);
1 f = f > 255 ? 255 : f < 0 ? 0 : f;
这里,我从中心点向外倒转颜色去使它退色,并且用255去除以它们,使它们的数字在0和1之间。
1 f = (255 - f) / 255.0f;
最后,在这个纹理中,设置在相应位置上的颜色:
1 Color c = new Color(f, f, f);
2 rgba[x + y * texture.Width] = c;
现在,你已经修改了象素,再把它们放回表面。
2 rgba[x + y * texture.Width] = c;
1 texture.SetData<Color>(rgba);
确保你的纹理在UnloadContent期间被释放。因为这个纹理在没有使用内容管道(负责处理你的资源的)的情况下创建的。
1 protected override void UnloadContent()
2 {
3 texture.Dispose();
4 }
现在你只需要去绘制纹理在屏幕上,看看结果了!
2 {
3 texture.Dispose();
4 }
1 protected override void Draw(GameTime gameTime)
2 {
3 GraphicsDevice.Clear(Color.CornflowerBlue);
4 spriteBatch.Begin();
5 spriteBatch.Draw(texture, Vector2.Zero, Color.White);
6 spriteBatch.End();
7 base.Draw(gameTime);
8 }
2 {
3 GraphicsDevice.Clear(Color.CornflowerBlue);
4 spriteBatch.Begin();
5 spriteBatch.Draw(texture, Vector2.Zero, Color.White);
6 spriteBatch.End();
7 base.Draw(gameTime);
8 }
源代码:http://www.ziggyware.com/readarticle.php?article_id=41
(完)