複数の色付きの水平領域を持つテキストを描画する方法はありますか?例として、下半分を赤、上半分を緑にして「こんにちは」というテキストを描きたいと思います。使用するテキストは動的である必要があります。通常のテクスチャでは、Drawメソッドを使用し、サブ長方形を渡して、テクスチャの一部を異なる色で描画しますが、テキスト用ですか?
4 に答える
最良の方法は、おそらくカスタムシェーダーを使用することです。しかし、はさみの長方形でもできるはずです。
- 通常、上色(緑)でテキストを描画します
- テキストの下半分にのみ描画できるScissorRectangleを設定します
- 下の色(赤)を使用して、通常どおりテキストを描画します。緑のテキストがそこに残るように、上半分をクリップする必要があります。
明確にするために、テキストは両方の時間で同じ場所に描画する必要があります。
「CrappyCodingGuy」で提案されているカスタムエフェクトを使用してこれを行います。エフェクトに送信されるデータが少し必要です。以下のコードは、Color1とColor1の間の文字列の色をピクセルごとにフェードするために必要なHLSLです。 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);
}
編集:おそらく、スプライトフォントからテクスチャを取得する必要があることに気付くでしょう。これは、非常に煩わしいプライベートフィールドです。誰かがこれを取得するためのより良い方法を知っているなら、教えてください!
これは古い質問ですが、このツールを使用すると、シャドウ、エンボス、グローなど、あらゆる種類の効果を備えたカスタムビットマップフォントを作成できます。フォントテクスチャが生成され、複数の色やその他の後処理効果を編集および追加できます。XNAで使用するには、Contentプロジェクトに追加し、ContentProcessorを「SpriteFontTexture」に設定するだけです。その後、通常のスプライトフォントをロードするのと同じ方法でゲームにロードできます。
より詳細な制御が必要な場合は、2つの異なるスプライトフォントテクスチャを使用できます。ビットマップフォントメーカーを使用して、最初のスプライトフォントを取得します: http://create.msdn.com/en-US/education/catalog/utility/bitmap_font_maker 。必要に応じて、テクスチャを変更して見栄えを良くします(ドロップシャドウなど)。フォントテクスチャのコピーを作成し、テキストの上半分を透明なマゼンタ色で上書きします。次に、テキストを2回描画します。2回目は、変更されたフォントと異なる色を使用します。この方法の利点は、上半分と下半分を直線で描く必要がないことです。つまり、上半分が上から滴り落ちる可能性があります。