Mam standardowe okno 800x600 w moim projekcie XNA. Moim celem jest pokolorowanie każdego pojedynczego piksela na podstawie tablicy prostokątów, która przechowuje wartości logiczne. Obecnie używam tekstury 1x1 i rysuję każdy sprite w mojej tablicy.Jak używać Shadera w XNA do kolorowania pojedynczych pikseli?
Jestem bardzo nowy w XNA i pochodzę z tła GDI, więc robię to, co bym zrobił w GDI, ale nie skaluje się zbyt dobrze. W innym pytaniu powiedziano mi, żeby użyć Shadera, ale po wielu badaniach wciąż nie byłem w stanie dowiedzieć się, jak osiągnąć ten cel.
Moja aplikacja wykonuje pętle poprzez współrzędne X i Y mojej tablicy prostokątnej, wykonuje obliczenia na podstawie każdej wartości i ponownie przypisuje/przesuwa tablicę. Na koniec muszę zaktualizować moje "Canvas" o nowe wartości. Mniejszy przykład mojej tablicy będzie wyglądał następująco:
0,0,0,0,0,0,0
0,0,0,0,0,0,0
0,0,0,0,0,0,0
1,1,1,1,1,1,1
1,1,1,1,1,1,1
Jak mogę użyć modułu cieniującego do pokolorowania każdego piksela?
bardzo uproszczoną wersję obliczeń byłoby:
for (int y = _horizon; y >= 0; y--) // _horizon is my ending point
{
for (int x = _width; x >= 0; x--) // _width is obviously my x length.
{
if (grains[x, y] > 0)
{
if (grains[x, y + 1] == 0)
{
grains[x, y + 1] = grains[x, y];
grains[x, y] = 0;
}
}
}
}
..each razem Sposób aktualizacji zwany obliczenia są wykonywane w przykładzie powyżej pętli aktualizacji może wyglądać następująco:
początkowa:
0,0,0,1,0,0,0
0,0,0,0,0,0,0
0,0,0,0,0,0,0
1,1,1,0,1,1,1
1,1,1,1,1,1,1
pierwsze:
0,0,0,0,0,0,0
0,0,0,1,0,0,0
0,0,0,0,0,0,0
1,1,1,0,1,1,1
1,1,1,1,1,1,1
drugie:
0,0,0,0,0,0,0
0,0,0,0,0,0,0
0,0,0,1,0,0,0
1,1,1,0,1,1,1
1,1,1,1,1,1,1
końcowa:
0,0,0,0,0,0,0
0,0,0,0,0,0,0
0,0,0,0,0,0,0
1,1,1,1,1,1,1
1,1,1,1,1,1,1
Aktualizacja:
Po zastosowaniu kodu Render2DTarget i umieszczenie moich pikseli, ja skończyć z niechcianym granicy na moich pikseli, zawsze w lewo. Jak mogę to usunąć?
alt text http://www.refuctored.com/borders.png
alt text http://www.refuctored.com/fallingdirt.png
jedne z kodem do nakładania tekstur jest:
RenderTarget2D target;
Texture2D texture;
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
texture = Content.Load<Texture2D>("grain");
_width = this.Window.ClientBounds.Width - 1;
_height = this.Window.ClientBounds.Height - 1;
target = new RenderTarget2D(this.GraphicsDevice,_width, _height, 1, SurfaceFormat.Color,RenderTargetUsage.PreserveContents);
}
protected override void Draw(GameTime gameTime)
{
this.GraphicsDevice.SetRenderTarget(0, target);
this.GraphicsDevice.SetRenderTarget(0, null);
this.GraphicsDevice.Clear(Color.SkyBlue);
this.spriteBatch.Begin(SpriteBlendMode.None,SpriteSortMode.Deferred,SaveStateMode.None);
SetPixels(texture);
this.spriteBatch.End();
}
private void SetPixels(Texture2D texture)
{
for (int y = _grains.Height -1; y > 0; y--)
{
for (int x = _grains.Width-1; x > 0; x--)
{
if (_grains.GetGrain(x, y) >0)
{
this.spriteBatch.Draw(texture, new Vector2(x,y),null, _grains.GetGrainColor(x, y));
}
}
}
}
Czy mógłbyś dzielić się obliczeniami, które wykonujesz na macierzy prostokątnej? Jeśli możesz wykonać te obliczenia wewnątrz modułu cieniującego, może nie być zbyt trudne do wymyślenia. Mam problem z ustaleniem, jak przekazać tablicę o wymiarach 800x600 do modułu cieniującego, ponieważ tablice są ograniczone do 65536 indeksów (16-bitowy indeks), najwyraźniej; więc gdybyś mógł po prostu wykonać obliczenia wewnątrz modułu cieniującego bez konieczności przesuwania dużej tablicy za każdym razem, łatwiej byłoby to rozgryźć. – Venesectrix
Mam zaktualizowane pytanie z kilkoma dodatkowymi informacjami do zapytania. –
Właściwie, przepraszam, teraz, kiedy myślę o tym, że podejście nie jest dobrym pomysłem z wielu powodów. Wymaga to, aby tekstura reprezentowała początkowy stan twojej macierzy, pikselowy moduł cieniujący nie może modyfikować tekstury, może zwracać tylko różne wartości, więc za każdym razem, gdy został wywołany, będzie to jak rozpoczęcie od stanu początkowego, i to wszystko obliczenia w funkcji draw() zamiast funkcji update(), co prawdopodobnie nie jest dobrym pomysłem. – Venesectrix