Jacek Matulewski
Skrypt MonoGame - ranking tropicieli błędów


Jednostka: +0.25 do oceny za jeden błąd (ozn. "*"); nagrody za konkursy grupowane są w nawiasach ("[**]")

Marcin Nowak: **** ***[*] [****] ****
Wojciech Szymecki: *
Łukasz Szulc: *
Łukasz Kiełczykowski: *


Znalezione błędy:

Marcin Nowak, rozdział 1, strona 5
Linia: gd.VertexDeclaration = new VertexDeclaration(gd,VertexPositionColor.VertexElements);
Postępując zgodnie z instrukcjami nie jestem w stanie przejść tego momentu. 

JM: 
Ta instrukcja nie jest potrzebna (klasa GraphicsDevice nie ma nawet pola VertexDeclaration). 
W zamian podaje się deklarację w metodzie gd.DrawUserPrimitives.

------------------------

Marcin Nowak, rozdział 1, w wielu miejscach
Jest: RasterizedState
Powinno być: RasterizerState

------------------------

Marcin Nowak, rozdział 1, strona 13, rys. 8
Po wyjściu z Shadera Pixeli otrzymujemy strumień pikseli zamiast strumienia werteksów.

------------------------

Marcin Nowak, rozdział 1, strona 13, rys. 8
Kod na stronie 14 jest:

gd.SetVertexBuffer(buforWerteksowTrojkata);

efekt.Begin();
foreach (EffectPass pass in efekt.CurrentTechnique.Passes)
{
   pass.Begin();
   gd.DrawUserPrimitives(PrimitiveType.TriangleList,werteksyTrojkata, 0, 1);
   gd.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
   pass.End();
}
efekt.End();

JM: 
To jest wersja z XNA 3.0, która jest niezgodna z XNA 4.0 i MonoGame 3.
Nie ma już metod Begin i End. Powinno być:

gd.SetVertexBuffer(buforWerteksowTrojkata);

foreach (EffectPass pass in efekt.CurrentTechnique.Passes)
{
   pass.Apply();
   gd.DrawUserPrimitives(PrimitiveType.TriangleList,werteksyTrojkata, 0, 1);
   gd.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
   pass.End();
}

----------------------------

Wojciech Szymecki
Informacje o interfejsie GUIDE

Jeśli chodzi o interfejs Guide to jest obecny w Monogame i używa się go identycznie jak w XNA, 
przy czym powinien działać głównie dla Androida, Windows Phone i iOS. Z tego co wiem na Windows 
Phone jak i na Modern UI (Windows 8) należy zadbać o to żeby metoda Guide.BeginShowMessageBox() 
została wywołana na wątku UI co w Windows Phone można zapewnić korzystając z:

Deployment.Current.Dispatcher.BeginInvoke(delegat_z_wywolaniem_messagebox)

a w Modern UI korzystając z własnej metody:

#pragma warning disable 4014
public static void runOnUiThread(Windows.UI.Core.DispatchedHandler delegat_z_wywolaniem)
{

    CoreWindow window = CoreWindow.GetForCurrentThread();
    window.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, delegat_z_wywolaniem);
}
#pragma warning restore 4014

bez tego funkcja callback zawierająca EndShowMessageBox wyrzuci dwa wyjątki bo będzie wywołana 
przed kliknięciem w jakikolwiek przycisk na MessageBoxie. Pomimo usunięcia głównej przyczyny 
błędu można go wywołać bardzo szybko klikając w kółko w wywoływanego w metodzie Game1.Update() 
MessageBoxa i jedyne co można zrobić aby temu zapobiec to pętla zwalniająca taka jak w rozwiązaniu 
pod linkiem:

http://stackoverflow.com/a/10568956

Jeśli chodzi o obiekt GamerServicesComponent (wspomniany na stronie) to na niektórych platformach 
istnieje a na niektórych nie jest zaimplementowany (Modern UI). Nie zauważyłem by niedołączenie 
tego komponentu powodowało błędy.

-------------------------------

Marcin Nowak, rozdział 2, strona 3
Problem: AllowUserResizing - problem ze zmianą rozdzielczości.

Należy dodać Event przechwytujący informację o zmianie rozmiaru okna
(opis w skrypcie).

Rozwiązanie znalezione na stronie:  
https://github.com/mono/MonoGame/issues/1069 (http://pastebin.com/gT8ehWgN)

-------------------------------

Łukasz Szulc, rozdział 2, strona 4
Potwierdzenie, ze MSAA nie jest dostępne w Monogame w wesji <= 3.2.

-------------------------------

Marcin Nowak, rozdział 1, strona 15

W kodzie

for(int i=0;i ElapsedGameTime
Nie można modyfikować składowej koloru

-------------------------------

Marcin Nowak, rozdział 1, strona 14

Count() -> Length
złe argumenty konstruktora DynamicVertexBuffer

-------------------------------

Marcin Nowak, rozdział 1 - konkurs dot. graphics.ToggleFullScreen (+0.25 do oceny)

if (Keyboard.GetState().IsKeyDown(Keys.Space))
{
    if (!graphics.IsFullScreen)
    {
        graphics.PreferredBackBufferWidth = graphics.GraphicsDevice.PresentationParameters.BackBufferWidth;
        graphics.PreferredBackBufferHeight = graphics.GraphicsDevice.PresentationParameters.BackBufferHeight;
    }
    graphics.GraphicsDevice.Viewport = new Viewport(0, 
        graphics.GraphicsDevice.DisplayMode.Height - graphics.PreferredBackBufferHeight, 
        graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);
    graphics.ToggleFullScreen();
    graphics.ApplyChanges();
}

-------------------------------

Marcin Nowak, rozdział 1 - konkurs dot. sfery z buforem indeksów (+1 do oceny)

kod źródłowy jest na stronie

-------------------------------

Marcin Nowak, rozdział 5, str. 2

nieodpowiednia klasa werteksu

-------------------------------

Marcin Nowak, rozdział 5, str. 5

nieprawidłowa instrukcja tworząca bufor

-------------------------------

Marcin Nowak, rozdział 5, str. 5

Kwestia macierzy rzutowania CreateShadowMatrix

-------------------------------

Łukasz Kiełczykowski

Kompilacja zasobów do formatu plików .xnb

Istnieje już kilka możliwości by kompilować swój content do formatu xnb:
https://github.com/mono/MonoGame/wiki/MonoGame-Content-Processing tutaj twórcy opisują jak należy to robić (w przypadku różnych platform).
Jeśli chodzi o Windowsa, to potrzebny jest niestety VS 2010. Do tego oczywiście potrzebujemy też XNA, ale w przypadku W8 jest pewien problem. Do XNA dostajemy się albo poprzez instalacje WP7 SDK albo jeśli dobrze pamiętam, najpierw instalujemy http://www.microsoft.com/pl-pl/download/details.aspx?id=5549 (Games for Windows Software) i później bez problemu możemy instalować XNA 4.0
Alternatywnie (ale nadal potrzebujemy VS10) możemy użyć:
http://sourceforge.net/projects/xnbbuilder/ , te proste narzędzie po prostu pominie krok odpalania VS10 i tworzenia “dummy projectu” z XNA.

-------------------------------

Porównując sytuację dla nieskończenie odległego światła doszedłem do wniosku, 
że jedynym problemem który może zaistnieć ( powodując miganie ) to pola 
macierzy: M14, M24, M34,  M44, gdzie używamy L.W ( czyli dla nieskończoności 
równych 0 ). Nasza  poprawka więc ( owe 0.00001f ) nie powinna dotyczyć 
wektora N.W, tylko L.W.
Tym samym zerując tylko i wyłącznie element M24 ( m.M24 = 0f; )  
uzyskałem to co na załączonym screen-1. Wpuszczając poprawkę na ten  
element ( m.24 = -N.Y * L.W * 0.99999f; ) uzyskałem to co na  
załączonym screen-2. W ostateczności dochodząc do funkcji:

         static Matrix CreateShadowMatrix(Vector3 lightPosition, Plane  
plane, float poprawka, bool nieskończenieOdległeŹródłoŚwiatła = true)
         {
             Vector4 N = new Vector4(plane.Normal, plane.D);
             Vector4 L = new Vector4(lightPosition,  
nieskończenieOdległeŹródłoŚwiatła ? 0 : 1);
             float alfa = Vector4.Dot(N, L);
             Matrix m = new Matrix();

             m.M11 = alfa - N.X * L.X;
             m.M22 = alfa - N.Y * L.Y;
             m.M33 = alfa - N.Z * L.Z;
             m.M44 = alfa - N.W * L.W * (1.0f - poprawka);
             m.M21 = -N.Y * L.X;
             m.M31 = -N.Z * L.X;
             m.M41 = -N.W * L.X;
             m.M12 = -N.X * L.Y;
             m.M32 = -N.Z * L.Y;
             m.M42 = -N.W * L.Y;
             m.M13 = -N.X * L.Z;
             m.M23 = -N.Y * L.Z;
             m.M43 = -N.W * L.Z;
             m.M14 = -N.X * L.W * (1.0f - poprawka);
             m.M24 = -N.Y * L.W * (1.0f - poprawka);
             m.M34 = -N.Z * L.W * (1.0f - poprawka);

             return m;
         }

i modyfikując linię inicjującą ową macierz:
static Matrix macierzRzutowaniaNaPodłoże =
         CreateShadowMatrix(new Vector3(3, 5, 3), new  
Plane(Vector3.Up, d), 0.00001f, false);

Projekt z zaimplementowanym rozwiązaniem znajduje się:  
http://fizyka.umk.pl/~254118/Monogame/MojaDrugaGraMonoGame_CreateShadow.zip