Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
OpublikowałKlaudia Samoraj Został zmieniony 11 lat temu
1
XNA Szybki start Kurs ITA-106 (Grafika i multimedia) – Moduł 1
Jacek Matulewski ( XNA Szybki start Wersja: 30 stycznia 2009
2
Visual Studio 2008/XNA GS 3.0 Typy projektów:
3
Visual Studio 2008/XNA GS 3.0 Własności projektu gry
Nie ma biblioteki gotowych komponentów Dostęp do platformy .NET 3.5 Język programowania: C# 3.0 Game1.cs zamiast Form1.cs
4
Visual Studio 2008/XNA GS 3.0 Plik Program.cs (analog z projektów WF)
Plik Game1.cs (analog Form1.cs), klasa Game1 pola typu GraphicsDeviceManager, SpriteBatch (pierwszy: kontrola okna gry, drugi: grafika 2D) konstruktor – inicjacja pól klasy gry metoda Initialize – inicjacja logiki gry metody LoadContent/UnloadContent – zasoby gry (tekstury, modele, dźwięki)
5
Visual Studio 2008/XNA GS 3.0 Plik Program.cs (analog z projektów WF)
Plik Game1.cs (analog Form1.cs), klasa Game1 metoda Update, wywoływana cyklicznie f = 60Hz aktualizacja logiki gry (np. położenia obiektów) Metoda Draw, wywoływana cyklicznie f = 60Hz renderowanie sceny (tu instrukcje rysowania)
6
Pierwszy program XNA W klasie Game1 definiujemy pole – zbiór werteksów typu VertexPositionColor: private VertexPositionColor[] werteksyTrojkata = new VertexPositionColor[3]{ new VertexPositionColor(new Vector3(0.5f, -0.5f, 0), Color.White), new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0), Color.White), new VertexPositionColor(new Vector3(0, 0.5f, 0), Color.White)}; Obiekt typu BasicEffect (filar prostej grafiki 3D) private BasicEffect efekt = null; protected override void Initialize() { efekt = new BasicEffect(graphics.GraphicsDevice, null); base.Initialize(); }
7
Pierwszy program XNA Metoda Draw (część 1):
protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); GraphicsDevice gd = graphics.GraphicsDevice; gd.Clear(Color.Black); gd.VertexDeclaration = new VertexDeclaration(gd, VertexPositionColor.VertexElements); efekt.Begin(); … efekt.End(); base.Draw(gameTime); } Czyszczenie bufora (kolor tła) Typ użytych werteksów (lista własności: pozycja, kolor)
8
Pętla po efektach i przebiegach (stały fragment gry)
Pierwszy program XNA Metoda Draw (część 1): protected override void Draw(GameTime gameTime) { … efekt.Begin(); foreach (EffectPass pass in efekt.CurrentTechnique.Passes) pass.Begin(); gd.DrawUserPrimitives<VertexPositionColor>( PrimitiveType.TriangleList, werteksyTrojkata, 0, 1); pass.End(); } efekt.End(); base.Draw(gameTime); Pętla po efektach i przebiegach (stały fragment gry)
9
Pierwszy program XNA Metoda Draw (część 2):
protected override void Draw(GameTime gameTime) { … efekt.Begin(); foreach (EffectPass pass in efekt.CurrentTechnique.Passes) pass.Begin(); gd.DrawUserPrimitives<VertexPositionColor>( PrimitiveType.TriangleList, werteksyTrojkata, 0, 1); pass.End(); } efekt.End(); base.Draw(gameTime); Rysowanie serii prymitywów (listy trójkątów) Pozycja pierwszego werteksu w tablicy Typ prymitywów Tablica werteksów Ilość prymitywów (tu: 1 prym. = 3 wert.)
10
Pierwszy program XNA Metoda Draw (część 3):
gd.DrawUserPrimitives<VertexPositionColor>( PrimitiveType.TriangleList, werteksyTrojkata, 0, 1); Zalety metody GraphicsDevice.DrawUserPrimitives: najprostsze możliwe rozwiązanie możliwość swobodnej zmiany własności werteksów tablicę werteksów można nawet zdefiniować inline Wada: brak buforowania werteksów w karcie graficznej!!!
11
Eksperymenty Nawijanie (gd.RenderState.CullMode)
Prymitywy (PrimitiveType.PointList, .LineStrip, itd.) PrimitiveType.PointList PrimitiveType.LineList PrimitiveType.LineStrip Prim..Type.TriangleList Pri..Type.TriangleStrip Prim..Type.TriangleFan
12
Kolor i cieniowanie Kolory, cieniowanie Gourauda, tablica werteksów
private VertexPositionColor[] werteksyTrojkata = new VertexPositionColor[3]{ new VertexPositionColor(new Vector3(0.5f, -0.5f, 0), Color.Red), new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0), Color.Green), new VertexPositionColor(new Vector3(0, 0.5f, 0), Color.Blue)}; efekt.VertexColorEnabled = true; Do metody Initialize należy dodać instrukcję:
13
Transformacje Zmiana macierzy świata (metoda Initialize):
Matrix macierzPrzeksztalcenia = Matrix.Identity; macierzPrzeksztalcenia *= Matrix.CreateScale(0.5f); macierzPrzeksztalcenia *= Matrix.CreateRotationZ(-MathHelper.PiOver2); macierzPrzeksztalcenia *= Matrix.CreateTranslation(0.5f, 0, 0); efekt.World = macierzPrzeksztalcenia; Matrix macierzPrzeksztalcenia = Matrix.Identity; macierzPrzeksztalcenia *= Matrix.CreateScale(0.5f); macierzPrzeksztalcenia *= Matrix.CreateRotationZ((float)-Math.PI/2.0f); macierzPrzeksztalcenia *= Matrix.CreateTranslation(0.5f, 0, 0); efekt.World = macierzPrzeksztalcenia; gd.RenderState.CullMode = CullMode.None; Jeżeli obrócimy trójkąt tyłem do nas: Spróbujmy zamiast macierzy świata zmieniać macierz widoku
14
Skalowanie do czasu rzeczywistego (wall time)
Animacja Metoda Update: Obrót 60 razy na sekundę efekt.World *= Matrix.CreateRotationZ( gameTime.ElapsedRealTime.Milliseconds/1000.0f); Skalowanie do czasu rzeczywistego (wall time) Widoczna deformacja trójkąta (zła macierz rzutowania) Animacja kolorów Usuńmy skalowanie
15
Korekta uwględniająca proporcje okna
Frustum Rzutowanie ortonormalne (izometryczne) Do metody Initialize: efekt.Projection = Matrix.CreateOrthographic( 2.0f, 0.0f, 100.0f); Do metody Initialize: efekt.Projection = Matrix.CreateOrthographic( 2.0f * graphics.GraphicsDevice.Viewport.AspectRatio, 2.0f, 0.0f, 100.0f); Korekta uwględniająca proporcje okna Szerokość frustum Wysokość frustum Bliż Dal
16
Korekta uwględniająca proporcje okna
Frustum Rzutowanie perspektywiczne Do metody Initialize: efekt.Projection = Matrix.CreatePerspective( 2.0f * graphics.GraphicsDevice.Viewport.AspectRatio 2.0f, 1.0f, 100.0f); Do metody Initialize: efekt.Projection = Matrix.CreatePerspective( 2.0f * graphics.GraphicsDevice.Viewport.AspectRatio 2.0f, 1.0f, 100.0f); Korekta uwględniająca proporcje okna Szerokość frustum Wysokość frustum Bliż Dal Współrzędna Z werteksów musi być teraz mniejsza od -1. Lub musimy odsunąć kamerę!
17
Frustum Rzutowanie perspektywiczne Do metody Initialize:
efekt.Projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.PiOver2, graphics.GraphicsDevice.Viewport.AspectRatio, 1.0f, 100.0f); Kąt widzenia Proporcje obrazu Bliż Dal Jawne uwzględnienie proporcji ekranu
18
Kamera Proste odsunięcie kamery: Zaawansowane ustawienie kamery:
efekt.View = Matrix.CreateTranslation(0, 0, -1); Zaawansowane ustawienie kamery: efekt.View = Matrix.CreateLookAt( new Vector3(0, 0, 1), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); efekt.View = Matrix.CreateLookAt( Vector3.UnitZ, Vector3.Zero, Vector3.Up); Położenie kamery Gdzie jest skierowana Polaryzacja
19
Buforowanie werteksów
Bufor werteksów (pole klasy Game1): VertexBuffer buforWerteksowTrojkata; Inicjacja bufora (metoda Initialize): buforWerteksowTrojkata = new VertexBuffer( graphics.GraphicsDevice, werteksyTrojkata.Count()*VertexPositionColor.SizeInBytes, BufferUsage.WriteOnly); Wypełnienie bufora (metoda Initialize): buforWerteksowTrojkata.SetData<VertexPositionColor>(werteksyTrojkata);
20
Buforowanie werteksów
Wykorzystanie bufora (metoda Draw): pass.Begin(); gd.Vertices[0].SetSource( buforWerteksowTrojkata, 0, VertexPositionColor.SizeInBytes); gd.DrawPrimitives(PrimitiveType.TriangleList, 0, 1); pass.End(); pass.Begin(); gd.DrawUserPrimitives<VertexPositionColor>( PrimitiveType.TriangleList, werteksyTrojkata, 0, 1); pass.End(); Wskazanie bufora Inna metoda niż wcześniej Po zdefiniowaniu bufora werteksów tablica werteksów nie jest potrzebna (można ją definiować lokalnie w Initialize) Dynamiczny bufor werteksów (przykład w skrypcie)
21
Różności
22
Częstość wywoływania Update
Częstość wywoływania metody Update: this.TargetElapsedTime = TimeSpan.FromSeconds(1.0f/75.0f); 75Hz (chyba, że gra się „zacina”) this.IsFixedTimeStep = false; albo Zawsze przed wywołaniem Draw
23
Dezaktywacja okna gry protected override void Update(GameTime gameTime) { if (!this.IsActive) return; … protected override void Draw(GameTime gameTime) { if (!this.IsActive) return; …
24
Tryb pełnoekranowy protected override void Initialize() { try
graphics.PreferredBackBufferWidth = 800; graphics.PreferredBackBufferHeight = 600; graphics.IsFullScreen = true; graphics.ApplyChanges(); } catch (Exception exc) System.Windows.Forms.MessageBox.Show( "Błąd podczas przełączania w tryb pełnoekranowy:\n" + exc.Message, Window.Title, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); Rozdzielczość ustalona na „sztywno” Tylko w Windows Odczytanie rozmiaru ekranu: graphics.GraphicsDevice.DisplayMode.Width graphics.GraphicsDevice.DisplayMode.Height
25
Zmiana wielkości okna protected override void Initialize() { try
graphics.PreferredBackBufferWidth = 800; graphics.PreferredBackBufferHeight = 600; graphics.IsFullScreen = true; graphics.ApplyChanges(); } catch (Exception exc) System.Windows.Forms.MessageBox.Show( "Błąd podczas przełączania w tryb pełnoekranowy:\n" + exc.Message, Window.Title, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); Rozdzielczość ustalona na „sztywno” Tylko w Windows Odczytanie rozmiaru ekranu: graphics.GraphicsDevice.DisplayMode.Width graphics.GraphicsDevice.DisplayMode.Height
26
Okno Zmiana tytułu okna: Klawisz Escape i spacja:
Window.Title = "Moduł 1. XNA - Szybki start"; Klawisz Escape i spacja: if (Keyboard.GetState().IsKeyDown(Keys.Escape)) this.Exit(); if (Keyboard.GetState().IsKeyDown(Keys.Space)) graphics.ToggleFullScreen();
27
Jedna instancja gry static class Program {
static void Main(string[] args) bool czyPierwszaInstancja; Mutex m = new Mutex(true,"MojaPierwszaGraXNA”,out czyPierwszaInstancja); if (!czyPierwszaInstancja) MessageBox.Show("Inna instancja tej gry jest już uruchomiona"); return; } using (Game1 game = new Game1()) game.Run(); m.ReleaseMutex();
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.