2012-02-14 5 views
2

Я хотел создать полупрозрачный накладку для моего экрана и решил динамически создавать пользовательский объект Texture2D, используя следующий код:Динамического создания Texture2D

const int TEX_WIDTH = 640; 
const int TEX_HEIGHT = 480 
Texture2D redScreen; 

void GenerateTextures(GraphicsDevice device) 
{ 
    redScreen = new Texture2D(device, TEX_WIDTH, TEX_HEIGHT); 
    uint[] red = new uint[TEX_WIDTH * TEX_HEIGHT]; 
    for (int i = 0; i < TEX_WIDTH * TEX_HEIGHT; i++) 
     red[i] = 0x1A0000ff; 
    redScreen.SetData<uint>(red); 
} 

И это только, кажется, не работает ожидается! Глядя на этот код, я ожидаю, что значение альфа будет около 10%. (0x1A/0xFF = ~ 10)

, но в итоге это намного больше. Мне кажется, что uint представляет значение ARGB, но значение прозрачности никогда не будет таким, каким я его устанавливал. он либо «несколько прозрачен», либо вообще не прозрачен.

Мне не нравятся задавать смутные вопросы,
Но что я делаю неправильно?
Что случилось с этим фрагментом кода?

Edit: В конце концов, я мог бы только получить нужный результат, установив BlendState.NonPremultiplied в spriteBatch.Begin() вызова.

ответ

3

XNA по умолчанию использует предварительно умноженный альфа, так что вы должны умножить все значения цвета по значению альфа. Также есть color struct, что может показаться вам удобным. Поэтому я предлагаю ниже. Альфа должна быть между 0 и 1 включительно.

const int TEX_WIDTH = 640; 
const int TEX_HEIGHT = 480 
Texture2D redScreen; 

void GenerateTextures(GraphicsDevice device) 
{ 
    redScreen = new Texture2D(device, TEX_WIDTH, TEX_HEIGHT); 
    uint[] red = new uint[TEX_WIDTH * TEX_HEIGHT]; 
    for (int i = 0; i < TEX_WIDTH * TEX_HEIGHT; i++) 
     red[i] = new Color(255, 0, 0) * Alpha; 
    redScreen.SetData<uint>(red); 
} 
+0

Уг, это также вызвало неожиданные результаты. В конце концов, установка 'BlendState.NonPremultiplied' в' 'spriteBatch.Begin()' call' фиксирует «все». – Acidic

+0

Просто вы знаете, что BlendState.NonPremultiplied приведет к небольшому результативному результату по сравнению с любым другим режимом смешивания. – ClassicThunder

+0

Это несчастливо, но если я не смогу найти способ добиться этого в обычном режиме BlendState, я боюсь, что у меня нет другого выбора. – Acidic

3

Я не вижу, чтобы вы указали формат поверхности/пикселя. Вы уверены, что каждый пиксель является uint?

Чтобы быть уверенными, создать текстуру с заданным макетом, а затем вычислить значение в нем для данного R, G, B и A.

+0

хорошо, 'SetData' является общей функцией, поэтому я решил, что передача' uint' в качестве общего параметра будет устанавливать такой формат. – Acidic

+0

@Acidic единственный, который гарантированно работает правильно, использует «Цвет» - если только вы не делаете свою собственную упаковку цветов. –

+0

@Acidic. Нет, формат текстуры задается при создании и не может быть изменен. Используйте Color.FromArgb и Color.ToArgb, если формат поверхности AARRGGBB. В противном случае определите структуру с правильной компоновкой и [StructLayout (LayoutKind.Sequential)] и оперируйте ее. – Ani

Смежные вопросы