Навигация
· XNA FAQ
· С чего начать
· Конкурсы
· Обратная связь
· XNA Блоги
Сейчас на сайте
· Гостей: 1

· Пользователей: 0

· Всего пользователей: 3,684
· Новый пользователь: headron
Последние фото
Эх, чуть не проспал закрытие.
Эх, чуть не проспал ...
Альбом: XNA Engine

GB
GB
Альбом: XNA Engine

South Park Coon & Friends
South Park Coon & Fr...
Альбом: XNA Games

Блоги
yavshoke
» XboxOne - интерес...
dampirik
» Push уведомления ...
dampirik
» Реклама,статистик...
Chort
» XNA и StartCoroutine
Chort
» Curve Class
dampirik
» Реклама, статисти...
dampirik
» Увеличение скорос...
dampirik
» Реклама, статисти...
general
» Распаковка DxtCom...
general
» Как работать с XN...
Поддержка
microsoft.com
1gb.ru - Дом для вашего сайта
Статистика посещений:

Как включить антиальясинг
Тут мы немного рассмотрим антиальясинг (AntiAliasing) а конкретнее его частную реализацию мультисемплинг (MultiSampling). Я не буду вдаваться в детали теории, математические обоснования и понятия, всё это прекрасно расписано вот тут. Я же сразу перейду к практической стороне вопроса, ибо лучше один раз увидеть, чем…

Итак создаем новый проект Windows Game и чтобы не терять времени на решение рутинных задач в Solution Explorer добавьте в проект класс Camera из архива с ресурсами к статье, данный класс полностью реализует функционал 3D камеры и готов к использованию. В классе игры объявите экземпляр класса камеры

 

1
private Camera camera;

А в методе Initialize() иницализируйте его и добавьте в компоненты нашего проекта

1
2
3
4
5
6
7
8
        protected override void Initialize()
        {
            camera = new Camera(this);
            Components.Add(camera);
 
            base.Initialize();
        }

При вызове конструктора без дополнительных параметров камера распологается в пространстве в координатах 0,0,10 и направлена в центр координат 0,0,0. Управление камерой клавишами WASD, вращение мышкой.

Двигаемся дальше, в подпроекте Content добавьте папку Models и добавьте в нее модель AK74U.FBX. Это модель автомата которую я скачал с TurboSquid и сконвертировал при помощи 3DS MAX, на ней-то мы и будем рассматривать альясинг. Теперь надо нарисовать нашу модель.

В классе игры объявляем экземпляр класса Model

1
private Model modelAK74U;

и в методе LoadContent() загружаем его

 

1
2
3
4
5
6
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
 
            modelAK74U = Content.Load<Model>(@"Models\AK74U");
        }

Далее напишем метод для визуализации нашей модели, за основу возмем реализацию из справки к XNA GS и немного модифицируем под наши реалии

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        private void DrawModel(Model model, Vector3 position, Matrix scaleMatrix)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);
 
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
 
                    effect.View = camera.ViewMatrix;
                    effect.Projection = camera.ProjectionMatrix;
                    effect.World = Matrix.Multiply(Matrix.Multiply(transforms[mesh.ParentBone.Index], scaleMatrix), Matrix.CreateTranslation(position));
                }
                mesh.Draw();
            }
        }

Как видите орисовка идет при помощи BasicEffect без лишних усложнений, матрицы вида и проекции беруться из объекта камеры, мировая же матрица расчитывается на основе местоположеня модели и ее масштабирования. Теперь в методе Draw вызываем на отрисовку наш автомат

1
2
3
4
5
6
7
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            DrawModel(modelAK74U, new Vector3(0f, 0f, -20f),  Matrix.CreateScale(0.05f));
 
            base.Draw(gameTime);
        }

    Япоместил модель автомата немного «назад» и уменьшил ее масштаб, т.к. модель получилась довольно большой.

Прежде чем запустить приложение в методе Update(GameTime gameTime) добавьте следущий код, иначе не сможете выйти из приложения кроме как по Alt+F4.

1
2
3
4
5
6
7
8
9
10
11
12
13
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
 
            KeyboardState keyboardState = Keyboard.GetState();
            if (keyboardState.IsKeyDown(Keys.Escape))
            {
                this.Exit();
            }
 
            base.Update(gameTime);
        }

Запускаем приложение и любуемся автоматом, обратите внимание на приклад автомата, а точнее «лесенку» которой он отрисовывается – это и есть эффект альясинга с которым мы сейчас и будем бороться.

Для начала напишем один вспомогательный метод, который будет получать массив элементов перечисления (enum).

Добавьте в проект новый класс Helpers и добавьте в него пространство имен using System.Reflection; далее метод который будет возвращать массив элементов перечисления

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
        public static T[] GetEnumValues<T>()
        {
            if (!typeof(T).IsEnum)
            {
                return null;
            }
 
            FieldInfo[] fields = typeof(T).GetFields(BindingFlags.Static | BindingFlags.Public);
            T[] values = new T[fields.Length];
            for (int i = 0; i < fields.Length; i++)
            {
                values[i] = (T)fields[i].GetValue(null);
            }
 
            return values;
        }

Технология reflection конечно не отличается производительносью, с другой стороны мы могли бы воспользоваться статичным методом GetValues класса Enum, он возвращает массив объектов типа Object, а при конвертации значимого типа в ссылочный и обратно производятся операции boxing/unboxing (упаковка/распаковка), что в свою очередь тоже не есть хорошо.

Теперь собственно включаем мультисемплинг (антиальясинг) и подписываемся на событе которое будет срабатывать в момент подготовки графического устройства к созданию, где мы можем управлять параметрами создания устройства. В методе Initialize() пишем следующий код

1
2
3
4
5
6
7
8
9
10
11
        protected override void Initialize()
        {
            graphics.PreferMultiSampling = true;
            graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);
            graphics.ApplyChanges();
 
            camera = new Camera(this);
            Components.Add(camera);
 
            base.Initialize();
        }

Теперь напишем обработчик события подготовки графического устройства

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        private void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
        {
            // получаем массив типов антиальясинга
            MultiSampleType[] types = Helpers.GetEnumValues<MultiSampleType>();
            GraphicsAdapter adapter = e.GraphicsDeviceInformation.Adapter;
 
            // обходим массив в обратном порядке с наибольшего и проверяем возможности видеокарты по 
            // поддержке данного типа сглаживания
            for (int i = types.Length - 1; i >= 0; i--)
            {
                if(adapter.CheckDeviceMultiSampleType(DeviceType.Hardware, 
              	adapter.CurrentDisplayMode.Format, false, types[i]))
                {
                    e.GraphicsDeviceInformation.PresentationParameters.MultiSampleQuality = 0;
                    e.GraphicsDeviceInformation.PresentationParameters.MultiSampleType = types[i];
                    break;
                }
            }
        }

Запускаем приложение. Моя текущая видеокарта поддерживает четырехкратный антиальясинг, но уже на таком уровне заметно значительное улучшение картинки.


Должен предупредить операция антиальясинга не является бесплатной, на тяжелых сценах может наблюдаться значительное замедление визуализации. В современных играх хорошим тоном считается позволить пользователю самому указать уровень мультисамплинга.

Написано по материалам статьи http://www.xnasociety.com/articles

Комментарии
#1 | Chort 19.02.2009 16:46:05
И чем метод Enum.GetValues не понравился?Frown Он же лучше рефлекшена и никакого boxing/unboxing не будет, если сразу привести результат к типизированному массиву.
#2 | SolarWind 19.02.2009 17:17:37
Специально сейчас слазил рефлектором в класс Enum и скажу, что метод GetValues тоже не подарок, в определенных случаях использует тот же рефлекшен
#3 | SolarWind 19.02.2009 17:37:42
И все-таки я докопался до причины использования отражения: In this sample, I am looking to find the number of elements in the enum. Enum.GetValues and Enum.GetNames are not implemented in the .NET Compact Framework, so I cannot use those methods.
На XBOX 360 просто невозможно использовать Enum.GetValues() Smile
#4 | Chort 19.02.2009 17:38:55
В большинстве случаев идет вызов екстернального метода.

Просто как человек который несколько лет сидит на супорте, я негативно отношусь к кастомной реализации базовых классов и методов. Так как их писали люди куда умнее нас ( про авторов вспомогательных либ я ничего не говорил Smile ). И лучше пользоваться готовым, оптимизированый, хорошо протестированым и не боятся когда у тебя что-то вылезет Smile
#5 | Chort 19.02.2009 17:42:23
Ну да, .NET Compact Framework тот еще прикол. Хуже только SilverLight в сравнении с WPF'ом. Sad
Добавить комментарий
Пожалуйста, залогиньтесь для добавления комментария.
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Авторизация
Логин

Пароль



Вы не зарегистрированы?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Мини-чат
Вы должны авторизироваться, чтобы добавить сообщение.

27.08.2014
Я умею немного на asp.net + html и css

22.08.2014
на ASP mvc 3 есть пару проектов. Могу помочь, если нужно. Обидно, если закроется Frown

21.08.2014
я тоже ноль

21.08.2014
Я в вебе только с php занимался да и то на уровне чтоб работало.

21.08.2014
Я в вебе полный ноль…

21.08.2014
Переводить его надо, хоть на ту же азуру. И двиг менять на что-то современное. Если есть веб-разрабы - можем скооперироваться. Один делать не буду.

21.08.2014
не знаю всех нюансов по оплате и все хорошее когда нибудь заканчивается

21.08.2014
А что случилось?

21.08.2014
похоже сайт будет работать до 28го числа

09.08.2014
Апи пока не видел. Но есть приложение в магазине Live Lock Screen BETA, так что думаю скоро будет

08.08.2014
Я про API для Update1. На нем работает это

08.08.2014
А что именно нужно? Чтото и сейчас открыто http://msdn.micro.
...105).aspx

06.08.2014
Кто-нибудь слышал об открытии доступа к Lock Screen Api?

31.07.2014
VPDExpress на базе MVS 2012, ни в какую не ловит исключения. Даже если их сам создаешь. И всех так?

25.07.2014
С днем системного администратора причастных к этой профессии! По случаю - тортик от жены

RSS каналы сайта
XNA - Новости
XNA - Статьи
XNA - Форум
XNA - Галерея
XNA - Файлы
Время загрузки: 0,08 секунд 8,709,721 уникальных посетителей