XNA Billboard(公告板技术)

XNA Billboard(公告板技术)

  公告板技术是3D游戏中用的非常多的一种技术,主要是用于控制场景中的Texture的方向,让他始终以一定的角度对着我们的镜头(一般是垂直于镜头)。
如我们在3D游戏中看到的怪物的蓝、红和怪物名字、一些花草树木等,无论我们在哪个方向看它总是对着我们。
如下图所示:

      

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
GraphicsDeviceManager graphics;
Texture2D texRedPanda;
 
//镜头信息参数
Vector3 pos, lookat, up;
//World,View,Project矩阵
Matrix world,view, project;
BasicEffect basicEffect;
//顶点结构
VertexPositionTexture[] vpt;
VertexDeclaration vertexDec;
 
public  GameMain()
{
     graphics = new  GraphicsDeviceManager( this );
     Content.RootDirectory = "Content" ;
}
 
protected  override void  Initialize()
{
     //初始化镜头信息
     pos = new  Vector3(0, 0,200);
     lookat = Vector3.Zero;
     up = Vector3.Up;
 
     //初始化变换矩阵
     world = Matrix.Identity;
     bbWorld = Matrix.Identity;
     view = Matrix.CreateLookAt(pos, lookat, up);
     project = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 800f/600f, 1, 1000);
 
     vpt = new  VertexPositionTexture[6];
     GraphicsDevice.RenderState.CullMode = CullMode.None;
     base.Initialize();
}
 
protected  override void  LoadContent()
{
 
     texRedPanda = Content.Load<Texture2D>( "RedPanda" );
 
     basicEffect = new  BasicEffect(GraphicsDevice, null);
     vertexDec = new  VertexDeclaration(GraphicsDevice, VertexPositionTexture.VertexElements);
 
     //定义三角形的各顶点坐标和纹理坐标
     vpt[0] = new  VertexPositionTexture( new  Vector3(-25,-25, 0), new  Vector2(0, 1));
     vpt[1] = new  VertexPositionTexture( new  Vector3(-25, 25, 0), new  Vector2(0, 0));
     vpt[2] = new  VertexPositionTexture( new  Vector3(25,-25, 0), new  Vector2(1, 1));
     vpt[3] = new  VertexPositionTexture( new  Vector3(-25, 25, 0), new  Vector2(0, 0));
     vpt[4] = new  VertexPositionTexture( new  Vector3(25, 25, 0), new  Vector2(1, 0));
     vpt[5] = new  VertexPositionTexture( new  Vector3(25,-25, 0), new  Vector2(1, 1));
}
 
protected  override void  Update(GameTime gameTime)
{
     // Allows the game to exit
     if  (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
         this .Exit();
     base.Update(gameTime);
}
 
protected  override void  Draw(GameTime gameTime)
{
     GraphicsDevice.Clear(Color.Black);
     //设置变换矩阵参数
     basicEffect.World = world;
     basicEffect.View = view;
     basicEffect.Projection = project;
     //设置绘制纹理
     basicEffect.TextureEnabled = true ;
     basicEffect.Texture = texRedPanda;
     basicEffect.Begin();
     foreach (var pass in basicEffect.CurrentTechnique.Passes)
     {
         pass.Begin();
         GraphicsDevice.VertexDeclaration = vertexDec;
         GraphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, vpt,0, 2);
         pass.End();
     }
     basicEffect.End();
     base.Draw(gameTime);
}

       texRedPanda的位置大概是在坐标原点,为了等会便于观察,将在Update加些内容。让镜头的位置通过键盘控制绕原点旋转(这里不是用World变换)。这里是在网上找的公式:
    x1 = x0 * cosB + y0 * sinB
    y1 = -x0 * sinB + y0 * cosB
 
       x0,y0表示镜头现在的位置,y1,y2表示绕原点旋转B弧度后的坐标。
       现在我们就呆以看到没有使用公告板技术时的效果了。把下面的代码加到Update方法的里:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
float  x0, z0;
x0=pos.X;
z0=pos.Z;
if  (Keyboard.GetState().IsKeyDown(Keys.Left))
{
     pos.X = x0 * ( float )Math.Cos(0.1d) + z0 * ( float )Math.Sin(0.1d);
     pos.Z = (-x0) * ( float )Math.Sin(0.1d) + z0 * ( float )Math.Cos(0.1d);
}
if  (Keyboard.GetState().IsKeyDown(Keys.Right))
{
     pos.X = x0 * ( float )Math.Cos(-0.1d) + z0 * ( float )Math.Sin(-0.1d);
     pos.Z = (-x0) * ( float )Math.Sin(-0.1d) + z0 * ( float )Math.Cos(-0.1d);
}
view = Matrix.CreateLookAt(pos, Vector3.Zero, Vector3.Up);
 
//将视点 位置显示在标题栏
Window.Title = pos.ToString();

       下面我们加一个用了公告板的World变换。主要代码如下,
    bbWorld = Matrix.CreateBillboard(Vector3.Zero, -pos, Vector3.Up, null);
       现在再来对比下 效果,发现无论我们控制镜头在哪个位置,小熊猫图片的下面始终对着我们。

这里已经实现了一个初级的公告板。当然也可以不用XNA的现有方法,我们可以把代码放到HLSL里面去,这里有个实现,但我帮他是数学原理没有推算过。所以只有套着用了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
float4x4 World;
float4x4 View;
float4x4 Projection;
texture Texture;
 
sampler textureSampler=sampler_state
{
     texture=<Texture>;
     magfilter = LINEAR;
     minfilter = LINEAR;
     mipfilter=LINEAR;
     AddressU = CLAMP;
     AddressV = CLAMP;
};
 
struct  VertexShaderInput
{
     float3 Pos:POSITION0;
     float2 TexCoord:TEXCOORD0;
};
 
struct  VertexShaderOutput
{
     float4 Position : POSITION0;
     float2 TexCoord:TEXCOORD0;
};
 
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
     VertexShaderOutput output;
 
     float4x4 worldViewMatrix = mul(World, View);  
     float3 positionVS = input.Pos + float3(worldViewMatrix._41, worldViewMatrix._42, worldViewMatrix._43);
     output.Position = mul(float4(positionVS, 1.0f), Projection);
     output.TexCoord=input.TexCoord;
 
     return  output;
}
 
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
     return  tex2D(textureSampler,input.TexCoord);
}
 
technique BillBoard
{
     pass BillBoard
     {
         VertexShader = compile vs_1_0 VertexShaderFunction();
         PixelShader = compile ps_1_0 PixelShaderFunction();
     }
    

      这里就实现了比较常用的公告板技术。到底是用XNA现有方法,还是HLSL,自己视情况面定吧。

浅墨出品,零资源分下载,分享精神至上~ 源码的配套博文是 《 【Visual C++】游戏开发五十四 浅墨DirectX教程二十一 视觉上的诡计:公告(Billboard)技术》 ,文章地址http://blog.csdn.net/poem_qianmo/article/details/13278851, 点击Release文件夹下的exe文件可以直接看到运行效果,运行需要DirectX运行库的支持。报缺少D3D的DLL系列错误的童鞋们请google/百度一下 “DirectX 9.0c runtime”,下载并装个最新版的。 报缺少MVCR100D.Dll错误的朋友们去下一个安装就可以了,或者直接点击sln打开工程再次编译一次。 背景音乐来自火影忍者疾风传 用键盘上W,A,S,D,I,J,K,L,↑,↓,←,→12个键加上鼠标在美丽的三维空间中翱翔。包括了Direct3D初始化,DirectInput输入处理,顶点缓存,文字输出,颜色,纹理贴图,四大变换,三维天空模拟,粒子系统等等知识。 另外,关于雪花粒子效果提醒大家一下,可在SnowParticleClass.h中的PARTICLE_NUMBER宏中改变雪花粒子数量,默认粒子数量为3000,1G显存的显卡取10万粒子数量帧数就只有8帧了。所以要自己改雪花粒子数量的话请根据自己的显卡性能酌情选择,如果你取个非常大的50万粒子数量,显卡吃不消烧了可别怪我- - 如果是想调试并运行源代码,但是报错了,请去下载最新版DirectX SDK并进行DirectX开发环境的配置。 编写环境:VS2010 我的博客地址是http://blog.csdn.net/zhmxy555,源码结合配套文章一起看效果更佳。 希望能和大家一起交流,共同学习,共同进步。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值