有没有办法绘制带有多个彩色水平区域的文字? 作为一个例子,我想绘制文本“Hello”,下半部分为红色,上部为绿色。要使用的文本必须是动态的。 使用普通纹理,我只使用Draw方法并传递一个子矩形以绘制不同颜色的纹理部分,但是对于文本?
答案 0 :(得分:1)
最好的方法可能涉及自定义着色器。但是,您也应该能够使用剪刀矩形。
为了澄清,您的文本应该在同一时间绘制。
答案 1 :(得分:1)
我会用'Crappy Coding Guy'建议的自定义效果来做这个,它需要一些数据发送到效果,下面的代码是你需要逐个像素的HLSL淡化字符串的颜色在Color1和Color2之间。您可以通过从中减去.5并使用于lerp的值乘以10来使其变为纯色变换。
float4x4 Projection;
float4 Color1, Color2;
float FontHeight;
float2 Location;
Texture2D FontTexture;
sampler TextureSampler = sampler_state { texture = <FontTexture> ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = clamp; AddressV = clamp;};
struct VertexShaderInput
{
float4 Position : POSITION0;
float2 Texture : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 Texture : TEXCOORD0;
float2 OriginalPosition : TEXCOORD1;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
output.OriginalPosition = input.Position;
output.Texture = input.Texture;
output.Position = mul(input.Position, Projection);
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float4 fontColor = lerp (Color1, Color2, (1.0 / FontHeight) * (input.OriginalPosition.y - Location.y));
return tex2D(TextureSampler, input.Texture)* fontColor;
}
technique Technique1
{
pass Pass1
{
VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
和C#一起使用它。 (显然你不必每帧都设置效果的所有参数,我只是不想发布太多的方法,如果你需要完整的例子我很乐意通过电子邮件发送给你)
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
fontEffect.Parameters["Projection"].SetValue(Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 0, 1));
fontEffect.Parameters["Color1"].SetValue(Color.Red.ToVector4());
fontEffect.Parameters["Color2"].SetValue(Color.Blue.ToVector4());
fontEffect.Parameters["FontHeight"].SetValue(font.LineSpacing);
FieldInfo fontTexture = typeof(SpriteFont).GetField("textureValue", BindingFlags.NonPublic | BindingFlags.Instance);
fontEffect.Parameters["FontTexture"].SetValue((Texture2D)fontTexture.GetValue(font));
fontEffect.CurrentTechnique.Passes[0].Apply();
spriteBatch.Begin( SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullNone, fontEffect);
spriteBatch.DrawString(font, "abcdefghijklmnopqrstuvxyz", new Vector2(10, 100), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
编辑:您可能会注意到我必须从精灵字体中获取纹理,这是一个非常烦人的私有字段!如果有人知道更好的方法,请告诉我们!
答案 2 :(得分:1)
我知道这是一个老问题,但是这个tool将允许您创建具有各种效果的自定义位图字体,如阴影,浮雕,发光。它将为您生成字体纹理,然后您可以编辑并添加多种颜色或其他后处理效果。在XNA中使用它只需添加到您的Content项目,并将ContentProcessor设置为“Sprite Font Texture”。然后,您可以像加载普通的精灵字体一样在游戏中加载它。
答案 3 :(得分:0)
如果你想要更多的控制,你可以使用两种不同的spritefont纹理。使用位图字体制作器获取您的初始spritefont:http://create.msdn.com/en-US/education/catalog/utility/bitmap_font_maker。如果需要,修改纹理以使其看起来很漂亮(投影等)。制作字体纹理的副本,并用透明的洋红色覆盖文本的上半部分。然后你将文本绘制两次,第二次使用修改后的字体和不同的颜色。这种方法的优点是你的上半部分和下半部分不需要用直线描绘,也就是说上半部分可能是粘在顶部等上面。