Autor Wątek: Biblioteka graficzna do tworzenia gier  (Przeczytany 9380 razy)

Offline Charibo

  • Redaktor

# Wrzesień 19, 2011, 12:20:41
Jednak ja chciałem tworzyc tekstury niestandartowo. Tu z pomocą przychodzi metoda FromFile/FromStream
Nie. Albo przynajmniej niekoniecznie. :) Z pomocą przychodzi odpowiednio napisany Content Processor/Loader :) Który to już zupełnie nie nastręcza problemów z wydajnością w runtime.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Isk

  • Użytkownik

# Wrzesień 19, 2011, 14:43:50
@Esidar

Dłuższy czas temu testowałem wczytywanie tekstury w XNA (dziesięć różnych obrazków z dziesięciu różnych plików). Oczywiście kod umieściłem w metodzie LoadContent a nie w Update czy Draw. Zanim odpaliła się aplikacja poczekałem sobie trochę - stąd teza o niezbyt wydajnej metodzie FromStream :)

@Charibo

Wszystko rozbija się o wymagania. W C# z XNA niby wszystko jest proste łatwe i przyjemne ale tylko na pierwszy rzut oka. W moim przypadku samo wczytywanie danych do struktury pokazało mi jak łatwo można to zrobić z C++ a jak dziwne to jest w C#.

Wszystko zależy od tego do czego biblioteka jest potrzebna. I tu wracam do tematu bo trochę offtop się zrobił :D Radził bym autorowi nie trzymać się kurczowo C# - C++ jest podobny i owszem może sprawić problemy, ale warto poświęcić chwilę czasu i sprawdzić co bardziej odpowiada, czego lepiej się używa. Jeśli jednak tylko C# wchodzi w grę, to XNA będzie najszybszy i najłatwiejszy.

Offline Charibo

  • Redaktor

# Wrzesień 19, 2011, 16:11:29
Dłuższy czas temu testowałem wczytywanie tekstury w XNA (dziesięć różnych obrazków z dziesięciu różnych plików). Oczywiście kod umieściłem w metodzie LoadContent a nie w Update czy Draw. Zanim odpaliła się aplikacja poczekałem sobie trochę - stąd teza o niezbyt wydajnej metodzie FromStream :)
A używałeś Content Processora? Czy wczytywałeś je samemu? Jeśli samemu to wyjątkowo bez sensu, bo content processor afaik kompiluje dane do gotowej do wczytania postaci binarnej, co jest dużo szybsze.

Wszystko rozbija się o wymagania. W C# z XNA niby wszystko jest proste łatwe i przyjemne ale tylko na pierwszy rzut oka. W moim przypadku samo wczytywanie danych do struktury pokazało mi jak łatwo można to zrobić z C++ a jak dziwne to jest w C#.
No nie wiem, rzucam okiem na to XNA już od jakiegoś czasu i im bardziej się wgłębiam, tym sensowniejsze mi się to wydaje, Z resztą, mi takie kombinowanie z wczytywaniem danych do struktury nigdy nie było potrzebne. Filozofia programowania w bardziej wysokopoziomowym języku jest - notabene - bardziej wysokopoziomowa. Po co wczytywać dane na pałę do struktury, skoro jest XmlSerializer działający w jednej linii kodu? A nawet jeśli trzeba robić coś takiego, to po co tracić czas w runtime, skoro jest cały content pipeline? :) A jeśli bardzo, bardzo chcesz, to dajesz unsafe i już mażesz jak masz chęć po pamięci. Tylko nie wiem czy to zadziała tak ładnie na x360. :)

Offline fn2000

  • Użytkownik

# Wrzesień 20, 2011, 00:05:30
Faktem że XNA jest dość łatwe, ale z moich obserwacji wydajne to to nie jest zbytnio ^^

A jak tę wydajność sprawdzałeś?

Wokół XNA jest mnóstwo mitów, głównie rozpowszechnianych przez amatorów, którzy zabierają się za tworzenie gier bez absolutnych podstaw. XNA to silnik 3D, który daje b. dobrą warstwę abstrakcji niskopoziomowego API DirectX, dodatkowo upraszczając / optymalizując kilka zagadnień, głównie w obszarze zarzązania zasobami - np.  nie musisz ręcznie odtwarzać zasobów po device lost - XNA ogarnia to za ciebie w 99% przypadków bez problemu. XNA ma wbudowaną świetną bibliotekę matematyczną, dostarcza świetne content procesory dla najbardziej popularnych typów contentu oraz łatwy i elastyczny framework do pisania wpłasnych procesorów np. pod nietypowy format modeli 3d etc.
 XNA ma super pomocne i aktywne community oraz jedną z największych firm software'owych, ktora wspiera te technologię i widzi w tym przyszłość gier.

Z różnych badań wydajności Xna vs. SlimDX vs. natywny silnik C++ DirectX różnica pomiędzy zarządzalnym kodem (XNA/SlimDX), a C++ to jest 5%, rzadko blisko 10% przy b. nietypowych zastosowaniach. W 99% przypadków pisania swojej technologii dla gier wąskim gardłem i tak będą shader'y lub transfer tekstur z/do pamięci GPU, coś co jest problemem także w natywnych silnikach. Overhead zarządzalnego kodu jest na samym końcu łancucha optymalizacji.

Jedyną wadą XNA jest brak wsparcia dla DX11 w obecnej wersji.

Odradzam także budowania własnych gier w oparciu o sample dostępne z konkretną technologią - odradzam to ponieważ 99% amatorów zamiast pisać własny, przemyślany kod na podstawie tego, copy-paste'uje to wszystko w swój projekt, tworząc zlepka-potwora, z którego absolutnie nic nie rozumieją i później zaczynają spamować fora: a bo mi nie działa!


Podsumowując:

a) jeśli masz minimalne pojęcie o programowaniu, o architekturze silników 3D, ale masz ambicję to zmienić i chcesz pisać własną technologię dla gry i nie potrzebujesz ficzerów DX11, XNA jest najlepszym wyborem dla ciebie

b) jeśli masz więcej pojęcia o programowaniu, napisałeś kiedyś własny, najprostszy nawet renderer w C++, nie potrzebujesz ficzerów DX11 TYM BARDZIEJ bierz się za XNA - zarządzalny kod jest przyszłością programowania

c) jeśli spełniasz warunki b) ALE potrzebujesz ficzerów DX11 bierz się za SlimDX - pamiętaj jedynie, ze SlimDX jest na niższym poziomie abstrakcji niż XNA - tam wiele rzeczy musisz napisać sam, chociażby główną pętlę.

d) jeśli NIE MASZ POJĘCIA O PROGRAMOWANIU, jesteś totalnie zielony w tym, dopiero się uczysz i KONIECZNE chcesz zrobić grę wybierz technologie, które umożliwiają zapoznanie się z procesem tworzenia gry w mniej bolesny sposób, tj. nie wymagają od razu pisania kodu - np. Unity 3D

Patrząc na poziom dyskusji w tym wątku BARDZO MOCNO polecam wszystkim opcję d) - praktycznie wszyscy amatorzy, którzy zabierają się za tworzenie gier skupiają się na optymalizacji ultra prostego kodu (i szukania bibliotek na podstawie takich "benchmarków"), nie wiedząc co ich czeka dalej po drodze tworzenia gry 3D, np. zarządzanie zasobami: w jakim formacie trzymać tekstury, siatki 3D wewnątrz silnika, jak to ładować z dysku, później do GPU, wyzwania związane z budowaniem renderera HD (bo przecież musi być bloom!), integracja silników fizyki, zarządzanie sceną, itp. itd. To są wszystko poważne tematy, które wymagają solidnego przygotowania i dużej dozy determinacji i cierpliwości aby przedzierać się przez setki posótw na forach gamedev, setki snippetów kodu, dziesiątki whitepaperów - nie żartuje z tym! 80% pracy przy tworzeniu własnej technologii 3D to jest znajdowanie kompromisów pomiędzy wyidealizowanym modelem renderera, ogólnie silnka gry w głowie programisty, a wymaganiami grafików i przygotowywaniu pipeline'u dla zasilania gry contentem. Naprawdę, początkującym radzę d) bo to pozwoli im w miarę na miękko zmierzyć się z tematmai wymienionymi powyżej - na miękko tzn. bez gigantycznej frustracji.

MDX nie żyję - technologia oficjalnie porzucona przez MS, nie ma sensu w to brnąć.

Offline Pawelx156

  • Użytkownik

# Październik 21, 2012, 15:30:26
Bez przesady z tym ze XNA jest wolny ip...
A wczytywanie w Xna TextureFromFile fakt faktem jest wolne ale w Direct3D jest to samo :)
Za to xnb pliki są szybkie.
Jak by ktoś chciał szybsza metodę wczytania textury 2d w xna to poniżej daje przykład:

using System;
using System.IO;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

 private static Texture2D LoadBitmapST(string _FilePatch, GraphicsDevice _Device)
        {
            Texture2D _textura = null;
            try
            {
                System.Drawing.Bitmap bp;
                using (FileStream titleStream = new FileStream(_FilePatch, FileMode.Open))
                {
                    bp = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromStream(titleStream);

                    System.Drawing.Imaging.BitmapData bmpData = bp.LockBits(new System.Drawing.Rectangle(0, 0, bp.Width, bp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
                    unsafe
                    {                     
                        uint* byteData = (uint*)bmpData.Scan0;
                        int[] imgData = new int[bp.Width * bp.Height];

                       
                        for (int i = 0; i < imgData.Length; i++)
                        {
                            byteData[i] = (byteData[i] & 0x000000ff) << 16 | (byteData[i] & 0x0000FF00) | (byteData[i] & 0x00FF0000) >> 16 | (byteData[i] & 0xFF000000);
                        }
                                           
                       System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, imgData, 0, bp.Width * bp.Height);
                        _textura = new Texture2D(_Device, bp.Width, bp.Height, false, SurfaceFormat.Color);
                        bp.UnlockBits(bmpData);
                       _textura.SetData<int>(imgData);
                        bp.Dispose();
                        imgData = null;

                        return _textura;
                    }

                }

            }
            catch { return null; }
        }

Offline kubera

  • Użytkownik
    • Prywatna strona

# Październik 21, 2012, 15:48:20
Witam!

Bez przesady z tym ze XNA jest wolny ip...
A wczytywanie w Xna TextureFromFile fakt faktem jest wolne ale w Direct3D jest to samo :)
Od jakiegoś czasu odchodzi się w native DirectX od wczytywania tekstur z komponentu D3DX.
Tworzenie zawartości from scratch może być dużo szybsze, a przykłady rozwiązań są w DirectX SDK.
Takie rozwiązanie chodzi szybko nawet po starym AGP.
Klasyczne nie może być szybkie, gdyż czasami wykonuje konwersję lub weryfikację poprawności lub tworzy MipMapy.