[翻译]XNA 3.0 Game Programming Recipes之thirteen
3-3 使用图层渲染透明图片
问题
在大多数情况下,您会希望在彼此之间上部多绘制些图片。现在的主要问题是,所有的图片都是完整的矩形,所以他们将覆盖早些时候提供的图片。您还需要确认您提供的背景的第一副图片。
解决方案
使用XNA,你可以指定层,或者图象即将绘制的深度。当你调用SpriteBatch.Draw方法,XNA可以帮你排列图象,所以图象上最深的就是第一个被绘制。
大多树图片的格式都支持透明。意思是说除了红,绿,蓝颜色的信息,他们还带有alpha信息。 当透明度已启用, 透明区域的图像将显示下面的图片。
在XNA,你可以指定一个颜色,可以作为透明处理。这对图片非常有用,没有任何透明度信息编码。
它是如何工作的
简单透明
SpriteBatch类具有处理图象的能力和透明的信息。成功运用于很多情况,如当你绘制绿草地的2D图象时,你想绘制一块岩石到它的上面。这样说,岩石的形象是石头在其中心一个简单的白色形象。如果您绘制岩石图在草的上面,你也看到岩石的白色背景图像上有草!
所以,你需要设置图象的背景的透明度。这种方法,当你绘制石头在草地的上面时,岩石图象的透明区域将得到草下面的颜色。请注意,图像的每个像素需要指定是否该像素应该是否透明。这一额外的信息被称为Alpha值是存储旁边的红色,绿色和蓝色通道的alpha通道。
如果你想使XNA带有一定的透明度,你需要使用SpriteBatch.Begin()方法中混合alpha来使用。
2 spriteBatch.Draw(myTexture,Vector2.Zero,Color.White);
3 spriteBatch.End();
如果你想混合多个图像,你不知要说明哪些图片应该是在顶端。在XNA中,每个图象的绘制,您可以指定层(或图像深度)为数字0和1之间。第1层表明底层,会被一个绘制出来,而0层将会被最后绘制,再加上所有其他层。您可以指定此值作为最后参数在SpriteBathc.Draw方法中。
在SpriteBatch.Begin方法中保存相应的SpriteSortMode的值,在下面的代码中会呈现。
作为一个例子,下面的代码将用草首先覆盖整个屏幕。因为这是底部的纹理,你可以设置这些图像层的值为1 。接下来,您会绘制一些悬崖,应该把它们放在草的上面。因此,你应该使他们一层小于1 ,在这里,您可以指定任何浮点值介于0和1 :
代码略
100草砖是使用绘制的双重循环。9个图像组成悬崖,以及草片区,都存储在一个图像文件,其中部分显示在左侧的图3-4 。因此,代码首先宣布矩形图像文件在此情况下每个subimages是可以找到。通过指定这样一个长方形的第三个参数, XNA将从完整图像中减去被遮挡的子图象。最终的结果显示在正确的形象里。
因为草的层的值是1.0f,悬崖图层的值是0.5f,XNA知道先绘制的是草层,接下来是悬崖。
确认把SpriteSortMode设置成BackToFront在SpriteBatch.Begin方法中,所以XNA知道它应该层的排列顺序在绘制它们前:
Alpha混合
像素的透明度没有得到“全有或全无” ,就属于这种情况的悬崖图像,在一个像素都已经可以得出自己的颜色或是完全透明的。 一个像素还可以有一个透明的值,例如,百分之七十。在这个例子中的一辆汽车驶到你的草地上,你车的灰色窗口可能是百分之七十透明度。 这样一来,当你绘制汽车在草层的上面时,窗口的最终颜色将是百分之30的灰色和在它后面的百分之七十的草层的颜色。你可以找到更多的信息关于这个在2-13节。这就是所谓的alpha混合,混合两种颜色获得的最后颜色。
SpriteBlendModes
默认情况下,当使用SpriteBatch类绘制时alpha混合器是可以使用的。尽管,你可以关闭alpha混合器或者设置Additive混合器的模式。
在后一种情况下,每一个颜色为您提供添加到颜色的一个像素已经在目前该像素中。因此,使用这种模式下,如果你画一个蓝色的像素覆盖红色像素,您会获得一个紫色像素。如果你画一个绿色的长方形覆盖这个紫色像素,你就会得到一个绿色的长方形包含有白色像素。这种模式是用于,如火灾或爆炸的效果,这是由许多精灵,并相加混合,因为你可以阅读的3-12节。
XNA允许你设置SpriteBatch类的混合模式,作为一个参数在SpriteBatch.Begin方法中,指定SpriteBlendMode状态中的一个:
1.SpriteBlendMode.None关闭混合器,并将使图像的屏幕忽视任何信息的透明度,从而进行覆写任何已经绘制的深层次的图象。
2.SpriteBlendMode.AlphaBlend使用一个而外的颜色属性和部分包含在新的图象中,相应的Alpha值中指定在图象中。正如这个例子中的车窗所示。
3.SpriteBlendMode.Additive添加新图象的颜色到祯缓冲中已经出现的。
代码
参看上面的代码。