عرض نص شبه شفاف

تحديث الصفحة :
تاريخ إنشاء الصفحة :

ملخص

اجعل النص يبدو شبه شفاف.

半透明の文字を表示する

بيئة التشغيل

المتطلبات المسبقه

إصدارات XNA المدعومة
  • 4.0
المنصات المدعومة
  • Windows (XP SP2 أو أحدث، Vista، 7)
  • اكس بوكس 360
  • هاتف ويندوز 7
Windows المطلوب إصدار Vertex Shader 2.0
Windows المطلوب إصدار Pixel Shader 2.0

بيئة التشغيل

رصيف
  • نوافذ 7
  • اكس بوكس 360
  • ويندوز فون 7 المحاكي

مادة

من خلال تطبيق عتامة 0.0 ~ 1.0 على بنية اللون المحددة بواسطة طريقة SpriteBatch.DrawString ، يمكنك رسم النص في شبه شفافية. لم يتم تعيين معظم الألوان المحددة بالفعل في خصائص بنية اللون على معتمة ، لذلك يمكن جعلها شبه شفافة من خلال تطبيق التعتيم.

// 半透明の文字(75%)
this.spriteBatch.DrawString(this.font,
    "Draw transparent text. (75%)",
    new Vector2(50.0f, 100.0f), Color.White * 0.75f);

Color منشئ

اضبط اللون. يوجد أيضا منشئ تعويم 0.0 ~ 1.0.

r بايت حدد اللون الأحمر من 0 ~ 255.
g بايت حدد اللون الأخضر ك 0 ~ 255.
b بايت حدد اللون الأزرق من 0 ~ 255.
a بايت حدد التعتيم (مكون ألفا) من 0 ~ 255.

بالمناسبة ، لقد تغيرت طريقة تحديد اللون الشفاف للكائنات منذ XNA Framework 4.0 ، ومن أجل تحديد تنسيق مثل "new Color(255, 255, 255, 192)" المستخدم في XNA Framewrok 3.1 والإصدارات الأقدم ، تحتاج إلى تحديد حالة مزج SpriteBatch باستخدام "BlendState.NonPremultiplied".

// スプライトの描画準備
this.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);

// 半透明の文字(75%)
this.spriteBatch.DrawString(this.font,
    "Draw transparent text. (75%)",
    new Vector2(50.0f, 100.0f), new Color(255255255192));

ومع ذلك ، نظرا لأنه تم تغيير صيغة حساب لون الإخراج ، سيتم عرض حافة الحرف في حالة مظلمة.

حول لون الإخراج

في النصائح السابقة ، استخدمنا نمطين مزج لعرض النص كمثال. من ناحية أخرى ، تم عرض نص شفاف جميل كما هو متوقع. من ناحية أخرى ، كانت حواف النص مظلمة. وذلك لأن صيغة إخراج اللون تختلف حسب حالة المزج المستخدمة.

قم بتعيين معلمات التعبير إلى

  • النتيجة: لون الإخراج النهائي
  • المصدر : لون النسيج الذي تحاول رسمه
  • الوجهة : لون خلفية الوجهة
  • RGBA: مكونات R (أحمر) و G (أخضر) و B (أزرق) و A (ألفا (التعتيم)) على التوالي

وكما هو محدد ، فإن صيغة الحساب لحالتي المزج هي كما يلي.

BlendState.AlphaBlend (افتراضي فارغ) (ألفا مضروب)
النتيجة = source.rgb + destination.rgb * (1 - source.a) // ومع ذلك ، فإن source.rgb مطبق بالفعل على ألفا
BlendState.NonPremultiplied (ألفا مقحم)
النتيجة = source.rgb * source.a + destination.rgb * (1 - source.a)

في الواقع ، إذا وجدتها مع هذه الصيغة ، فستكون قيمة النتيجة هي نفسها في كلتا الحالتين. ومع ذلك ، إذا كنت تستخدم التصفية ثنائية الخط ، إجراء العمليات الحسابية المذكورة أعلاه بعد استيفاء الألوان مع وحدات البكسل المجاورة في تظليل البكسل ، وبالتالي ستكون نتيجة الإخراج النهائية مختلفة.

أود أن أقوم ببعض الحسابات من أجل ذلك. إذا كان لون النص أبيض (Color.White)، فسيكون كل مكون لون من مكونات البكسل الذي يتم عرض النص فيه هو (r:255، g:255، b:255، a:255). وحدات البكسل التي لا تعرض النص هي (r:0 وg:0 وb:0 وa:0). إذا جعلنا النص شبه شفاف بنسبة 50٪ واستيفناه بالقيمة الوسيطة لهذين البكسل (أي حافة الحرف) ، فكيف تغير المعادلتان أعلاه النتيجة؟

بالمناسبة ، لون الخلفية هو (r: 0 ، g: 0 ، b: 255 ، a: 255). (يتم إجراء العمليات الحسابية على نص أبيض وخلفية زرقاء)

الاستيفاء باستخدام BlendState.AlphaBlend (ألفا مضروب)

نظرا لأنه يتم تطبيق alpha على كل عنصر من عناصر لون النص مسبقا ، يتم تقليل لون النص إلى النصف بمقدار 255 (r: 128 ، g: 128 ، b: 128 ، a: 128) (Color.White * 0.5f"). يتم ترك وحدات البكسل التي لا تحتوي على نص معروض كما هي (r:0, g:0, b:0, a:0).

نظرا لأن صيغة المرشح ثنائية الخط يتم تنفيذها قبل أن تحسب حالة المزج لون الخلفية ، فإن لون حافة النص هو (r: 64 ، g: 64 ، b: 64 ، a: 64) ، وهي قيمة وسيطة بين (r: 128 ، g: 128 ، b: 128 ، a: 128) و (r: 0 ، g: 0 ، b: 0 ، a: 0).

هنا التعبير

  • النتيجة = source.rgb + destination.rgb * (1 - source.a)

إذا قمت بتطبيقه على:

  • النتيجة = (R: 64 ، G: 64 ، B: 64) + (R: 0 ، G: 0 ، B: 255) * (1 - 0.25)      // 0.25 يشير إلى أن A: 64 هو 25٪ من A: 255

واللون المركب النهائي مع لون الخلفية هو (R: 64 ، G: 64 ، B: 255).

الاستيفاء باستخدام BlendState.NonPremultiplied (ألفا المقحم)

لون النص أبيض (r: 255 ، g: 255 ، b: 255) ، ويتم تقليل alpha فقط إلى النصف لجعله شبه شفاف ، وبالتالي فإن قيمة البكسل الذي يتم عرض الحرف فيه هي (r: 255 ، g: 255 ، b: 255 ، a: 128) (لون جديد (255 ، 255 ، 255 ، 128)). تظل وحدات البكسل التي لا تعرض النص كما هي (r:0 وg:0 وb:0 وa:0).

نظرا لأن صيغة عامل التصفية ثنائية الخط يتم تنفيذها قبل أن تحسب حالة المزج لون الخلفية ، فإن لون حافة النص هو (r: 128 ، g: 128 ، b: 128 ، b: 128 ، a: 64) ، وهي قيمة وسيطة بين (r: 0 ، g: 0 ، b: 0 ، a: 0).

هنا التعبير

  • النتيجة = source.rgb * source.a + destination.rgb * (1 - source.a)

إذا قمت بتطبيقه على:

  • النتيجة = (R: 128 ، G: 128 ، B: 128) * 0.25 + (R: 0 ، G: 0 ، B: 255) * (1 - 0.25)

واللون المركب النهائي مع لون الخلفية هو (R: 32 ، G: 32 ، B: 224).

نظر

نظرا لأن لون الخلفية هو (r: 0 ، g: 0 ، b: 255) ، فإن الاستيفاء باستخدام BlendState.AlphaBlend (r: 64 ، g: 64 ، b: 255) يسمح بالتعبير عن اللون الشفاف للنص بشكل جميل دون فقدان صبغة لون الخلفية. ومع ذلك ، في حالة الاستيفاء باستخدام BlendState.NonPremultiplied (r: 32 ، g: 32 ، b: 224) ، يكون المكون الأزرق أغمق من لون الخلفية ، لذلك تبدو حواف النص مظلمة (بالطبع).
الأحمر والأخضر أغمق من BlendState.AlphaBlend.)

تم وصف هذا ألفا الافتراضي المضاعف من XNA Framework 4.0 بالتفصيل في مدونة "Hinikeni XNA" ، لذلك إذا كنت تريد معرفة المزيد ، فيرجى الرجوع إلى الرابط أدناه. هناك ، يوصف بأنه مثال على رسم عنصر أحمر على خلفية بيضاء.

جميع الرموز

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
#if WINDOWS_PHONE
using Microsoft.Xna.Framework.Input.Touch;
#endif

namespace TransparentText
{
    /// <summary>
    /// ゲームメインクラス
    /// </summary>
    public class GameMain : Microsoft.Xna.Framework.Game
    {
        /// <summary>
        /// グラフィックデバイス管理クラス
        /// </summary>
        private GraphicsDeviceManager graphics = null;

        /// <summary>
        /// スプライトのバッチ化クラス
        /// </summary>
        private SpriteBatch spriteBatch = null;

        /// <summary>
        /// スプライトでテキストを描画するためのフォント
        /// </summary>
        private SpriteFont font = null;


        /// <summary>
        /// GameMain コンストラクタ
        /// </summary>
        public GameMain()
        {
            // グラフィックデバイス管理クラスの作成
            this.graphics = new GraphicsDeviceManager(this);

            // ゲームコンテンツのルートディレクトリを設定
            this.Content.RootDirectory = "Content";

#if WINDOWS_PHONE
            // Windows Phone のデフォルトのフレームレートは 30 FPS
            this.TargetElapsedTime = TimeSpan.FromTicks(333333);

            // バックバッファサイズの設定
            this.graphics.PreferredBackBufferWidth = 480;
            this.graphics.PreferredBackBufferHeight = 800;

            // フルスクリーン表示
            this.graphics.IsFullScreen = true;
#endif
        }

        /// <summary>
        /// ゲームが始まる前の初期化処理を行うメソッド
        /// グラフィック以外のデータの読み込み、コンポーネントの初期化を行う
        /// </summary>
        protected override void Initialize()
        {
            // TODO: ここに初期化ロジックを書いてください

            // コンポーネントの初期化などを行います
            base.Initialize();
        }

        /// <summary>
        /// ゲームが始まるときに一回だけ呼ばれ
        /// すべてのゲームコンテンツを読み込みます
        /// </summary>
        protected override void LoadContent()
        {
            // テクスチャーを描画するためのスプライトバッチクラスを作成します
            this.spriteBatch = new SpriteBatch(this.GraphicsDevice);

            // フォントをコンテンツパイプラインから読み込む
            this.font = this.Content.Load<SpriteFont>("Font");
        }

        /// <summary>
        /// ゲームが終了するときに一回だけ呼ばれ
        /// すべてのゲームコンテンツをアンロードします
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: ContentManager で管理されていないコンテンツを
            //       ここでアンロードしてください
        }

        /// <summary>
        /// 描画以外のデータ更新等の処理を行うメソッド
        /// 主に入力処理、衝突判定などの物理計算、オーディオの再生など
        /// </summary>
        /// <param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
        protected override void Update(GameTime gameTime)
        {
            // Xbox 360 コントローラ、Windows Phone の BACK ボタンを押したときに
            // ゲームを終了させます
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.Exit();
            }

            // TODO: ここに更新処理を記述してください

            // 登録された GameComponent を更新する
            base.Update(gameTime);
        }

        /// <summary>
        /// 描画処理を行うメソッド
        /// </summary>
        /// <param name="gameTime">このメソッドが呼ばれたときのゲーム時間</param>
        protected override void Draw(GameTime gameTime)
        {
            // 画面を指定した色でクリアします
            this.GraphicsDevice.Clear(Color.CornflowerBlue);

            // スプライトの描画準備
            this.spriteBatch.Begin();

            // 通常の文字
            this.spriteBatch.DrawString(this.font,
                "Draw normal text.",
                new Vector2(50.0f, 50.0f), Color.White);

            // 半透明の文字(75%)
            this.spriteBatch.DrawString(this.font,
                "Draw transparent text. (75%)",
                new Vector2(50.0f, 100.0f), Color.White * 0.75f);

            // 半透明の文字(50%)
            this.spriteBatch.DrawString(this.font,
                "Draw transparent text. (50%)",
                new Vector2(50.0f, 150.0f), Color.White * 0.5f);

            // 半透明の文字(25%)
            this.spriteBatch.DrawString(this.font,
                "Draw transparent text. (25%)",
                new Vector2(50.0f, 200.0f), Color.White * 0.25f);

            // スプライトの一括描画
            this.spriteBatch.End();

            // 登録された DrawableGameComponent を描画する
            base.Draw(gameTime);
        }
    }
}