Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an alpha value that makes white go invisible?

If I use the following

for(int i = 255; i > 0; i--)
{
    Color transparentBlack = new Color(0, 0, 0, i);
}

I have the effect of the object using this color to draw with going from black to a light grey and then invisible when the alpha value goes to zero. However if I start with a white value:

new Color(255, 255, 255, i);

The objects never becomes invisible and only stays white. I've also noticed that if I use a value that is a bit lighter than black (say 50, 50, 50) the drawing goes from Dark, to invisible, to White.

I assume that I just don't understand how alpha blending mixing works but is there a way of making a white color fade to translucency?

Edit: The background I am drawing on is Color.CornflowerBlue (100,149,237,255)

Edit: Sample XNA program reproducing the explanation. To use; create a new XNA Game Studio 4.0 project - Windows Game (4.0), call it AlphaBlendTest - & In the content project add a new SpriteFont and call it testfont

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;

namespace AlphaBlendTest
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;


    SpriteFont font;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    /// <summary>
    /// Allows the game to perform any initialization it needs to before starting to run.
    /// This is where it can query for any required services and load any non-graphic
    /// related content.  Calling base.Initialize will enumerate through any components
    /// and initialize them as well.
    /// </summary>
    protected override void Initialize()
    {
        // TODO: Add your initialization logic here

        base.Initialize();
    }

    /// <summary>
    /// LoadContent will be called once per game and is the place to load
    /// all of your content.
    /// </summary>
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);

        font = Content.Load<SpriteFont>("testfont");
    }

    /// <summary>
    /// UnloadContent will be called once per game and is the place to unload
    /// all content.
    /// </summary>
    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }

    /// <summary>
    /// Allows the game to run logic such as updating the world,
    /// checking for collisions, gathering input, and playing audio.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        // TODO: Add your update logic here

        base.Update(gameTime);
    }

    /// <summary>
    /// This is called when the game should draw itself.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();

        //spriteBatch.Draw(tR, new Rectangle(100, 100, 100, 100), Color.Red);

        Vector2 v2 = new Vector2(0, 0);
        spriteBatch.DrawString(font, "Test - White", v2, Color.White);

        v2.Y = v2.Y + 50;

        spriteBatch.DrawString(font, "Test - Black", v2, Color.Black);

        v2.Y = v2.Y + 50;

        Color BlackTransparent = new Color(0, 0, 0, 0);
        spriteBatch.DrawString(font, "Test - Black Transparent", v2, BlackTransparent);

        v2.Y = v2.Y + 50;
        Color WhiteTransparent = new Color(255, 255, 255, 0);
        spriteBatch.DrawString(font, "Test - White Transparent", v2, WhiteTransparent);

        spriteBatch.End();

        base.Draw(gameTime);
    }
}
}

Edit: This is the image this code draws: alt text

Edit: One of the comments is concerned that this is a Text only related 'feature' of windows. I used text as an example to keep the demo program small; testing with an image gives the same result. alt text

To add the square box in to the demo program; create a square white PNG image and add it to the content directory (use the default values for the content pipeline). Then add this to the class:

Texture2D tWhiteBox;

Add this in to the load method:

tWhiteBox = Content.Load<Texture2D>("whitebox");

Then in the draw add the following below the other draw statements:

v2.Y = v2.Y + 50;
spriteBatch.Draw(tWhiteBox, v2, WhiteTransparent);
like image 777
Sebastian Gray Avatar asked Oct 03 '10 11:10

Sebastian Gray


1 Answers

Grey is what you'll get in XNA 4.0 (or full white if you try to just adjust the alpha channel without adjusting the RGB channels as well). Transparency is done (by default) using pre-multiplied alpha. If you're looking for the old non-pre-mul XNA 3.1 behavior, see this post from Shawn Hargreaves: http://blogs.msdn.com/b/shawnhar/archive/2010/04/08/premultiplied-alpha-in-xna-game-studio-4-0.aspx . At the bottom of the post it tells you how to do it.

I'd recommend reading all of his posts on pre-multiplied alpha before doing so though (you can use the "Blog Index" link on the left side near the top of his page) - pre-mul really is a lot better and a lot more logically consistent.

like image 155
MikeBMcL Avatar answered Nov 12 '22 01:11

MikeBMcL