2010-10-03 9 views
7

Jeśli użyję następującychCzy istnieje wartość alfa, która powoduje, że biały staje się niewidoczny?

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

mam wpływu obiektu przy użyciu tego koloru czerpaka przechodząc od czerni do jasnoszarego i wtedy niewidzialny gdy wartość alfa wychodzi na zero. Jeśli jednak zacznę od wartości białej:

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

Obiekty nigdy nie stają się niewidoczne i pozostają białe. Zauważyłem też, że jeśli użyję wartości nieco jaśniejszej niż czarna (powiedzmy: 50, 50, 50), rysunek przechodzi od Ciemnej, do niewidocznej, do Białej.

Zakładam, że po prostu nie rozumiem, jak działa miksowanie z mieszaniem alfa, ale czy istnieje sposób na przekształcenie białego koloru w półprzezroczystość?

Edycja: tła ja na rysunku jest Color.CornflowerBlue (100149237255)

Edit: Próbka XNA Program odtwarzając wyjaśnienia. Używać; utworzyć nowy XNA Game Studio 4.0 projektu - Windows gry (4.0), nazywamy to AlphaBlendTest - & W projekcie zawartości dodać nowy SpriteFont i nazywają to 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: Jest to obraz ten kod rysuje: alt text

Edytuj: Jeden z komentarzy dotyczy faktu, że jest to związana z tekstem "funkcja" systemu Windows. Użyłem tekstu jako przykładu, aby utrzymać program demo mały; testowanie z obrazem daje taki sam wynik. alt text

Aby dodać kwadratowe okno do programu demonstracyjnego; utwórz kwadratowy biały obraz PNG i dodaj go do katalogu zawartości (użyj domyślnych wartości dla potoku treści). Następnie dodać do klasy:

Texture2D tWhiteBox; 

dodać to do sposobu obciążenia:

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

następnie w losowaniu należy dodać następujące poniżej pozostałych sprawozdań Draw:

v2.Y = v2.Y + 50; 
spriteBatch.Draw(tWhiteBox, v2, WhiteTransparent); 
+0

Teraz masz lepsze odpowiedzi, mam ochotę usunąć moje ... ale żeby sprawdzić, czy dzieje się to również z obiektami * innymi niż tekst *? –

+0

Tak; Po prostu użyłem Draw String w przykładzie, więc nie musiałem wgrywać tekstury dla prostego programu testowego ;-) Aby to przetestować, użyłem obrazu, który jest tylko białym pudełkiem, a następnie narysowałem go, używając różnych kolorów w wyciąg zostanie następnie zmieniony na kolor. –

Odpowiedz

11

Szary jest to, co otrzymasz w XNA 4.0 (lub pełny biały, jeśli próbujesz po prostu dostosować kanał alfa, nie regulując również kanałów RGB). Przejrzystość jest wykonywana (domyślnie) przy użyciu wstępnie pomnożonej alfa. Jeśli szukasz starego nie-pre-mul zachowania XNA 3.1, zobacz ten post z Shawn Hargreaves: http://blogs.msdn.com/b/shawnhar/archive/2010/04/08/premultiplied-alpha-in-xna-game-studio-4-0.aspx. U dołu postu znajduje się instrukcja, jak to zrobić.

Zalecam lekturę wszystkich jego postów na wstępnie pomnożonej alfa, zanim jednak to zrobię (możesz użyć linku "Blog Index" po lewej stronie u góry jego strony) - pre-mul naprawdę jest dużo lepiej i logicznie spójniej.

+2

Dzięki, że post miał odpowiedź. Jeśli zamieniam kod, którego używam, to: WhiteTransparent = Color.White * 0.5f; Otrzymuję przezroczysty biały obraz o 50%. 0f całkowicie przezroczysty i 1f całkowicie biały. Z postu Shawn wskazuje, że kod definiujący kolory przezroczystości został zmieniony, a stary kod powinien wywołać błąd kompilatora; jednak nie zostanie zgłoszony błąd kompilatora podczas definiowania wartości alfa wraz z resztą koloru, zgodnie z kodem, z którym miałem problem. Dzięki za pomoc. –

+0

Dzięki @SebastianGray za sprecyzowanie tego. –

0

Jeśli czarny staje się "jasnoszary", gdy jest półprzezroczysty, co sugeruje, że masz białe tło ... w którym momencie, w pełni przezroczysty biały kolor nałożony na wierzch wciąż będzie biały.

Spróbuj użyć białego obiektu na innym kolorowym tle - na przykład na czerwono, co powinno sprawić, że zmieni kolor z białego (alfa = 255) na różowy (alfa = 127) na czerwony (alfa = 0).

+0

Do testowania tła, na którym rysuję, jest Color.CornflowerBlue (100,149,237,255). Próbuję uzyskać coś działającego, czego mogę użyć na wielobarwnym tle. –

+0

Również przetestowałem na czerwonym tle i użyłem stałej wartości koloru (255, 255, 255, 0); Kolor rysowanego obiektu był biały. –

+0

@Sebastian: Mógłbym * się spodziewać *, że będzie w porządku. Czy możesz podać krótki, ale kompletny program testowy, abyśmy mogli sprawdzić, czy nic więcej się nie dzieje? Gdybyś mógł spróbować na prostszym interfejsie API (np. WPF), byłoby to również pomocne ... chociaż rozumiem, że oczywiście będziemy musieli uruchomić go również na WP7. –

2

To jest historyczne ograniczenie, przynajmniej w systemie Windows. Prymitywy GDI, takie jak DrawTextEx, nie obsługują przezroczystości. Po prostu zignorują kanał alfa. Ograniczenie to rozwiązują biblioteki graficzne, takie jak GDI + i Milcore. Ale jest tylko jeden renderer TrueType i wykonuje on zbyt mało pracy, aby można go było łatwo wymienić. Zrzut ekranu pokazuje, że działa on w zwykłym oknie systemu Windows, więc ograniczenie jest bardzo prawdopodobne. Nie wiem, czy jest inaczej na konsoli.

Możliwe obejście polega na użyciu funkcji podobnej do funkcji GraphicsPath.AddString(). Utracisz jednak efekt antyaliasingu ClearType. Nie jestem tego taki pewien w XNA.Nie znam go wystarczająco dobrze, aby zasugerować odpowiednik GraphicsPath.

+0

Nie sądzę, że ograniczenie, o którym mówisz, jest obecne w XNA. Dodałem zaktualizowany zrzut ekranu i kod testu, aby również użyć obrazu. Oryginalnie zauważyłem to zachowanie na obrazie, ale przykład tekstowy jest najmniejszym projektem demonstracyjnym, który mógłbym szybko połączyć, i tak dziękuję. –

1

Myślę, że ma to coś wspólnego z ustawieniami wykrwawienia Alfa dla SpriteBatch.

Wartość domyślna to BlendState.AplhaBlend. To ma formułę BackgroundColor * (1-Alpha) + ForegroundColor. To tłumaczyłoby to, czym jest bahaviour z czernią i bielą.

Spróbuj użyć innej metody spriteBatch.Begin z BlendState.NonPremultiplied, aby uzyskać pożądany wynik. Spowoduje to: BackgroundColor * (1-Alpha) + ForegroundColor * Aplha, dzięki czemu nawet biały będzie całkowicie przezroczysty.

+0

Uruchamianie spriteBatch.Draw z BlendState.NonPremultiplied sprawiło, że sprite są w pełni niewidoczne z kanałem alfa ustawionym na 255. –

Powiązane problemy