DirectX 8. Начинаем работу с DirectX Graphics - [20]

Шрифт
Интервал

> This file is provided without support, instruction, or implied warranty of any kind.

> NVIDIA makes no guarantee of its fitness for a particular purpose and is not liable under any circumstances for any damages or loss whatsoever arising from the use or inability to use this file or items derived from it.

> Comments:

> *********************************************************************/

>#include

>#include

>#include


>static float _0_47 = 0.47f;

>static float _1_47 = 1.47f;


>float__fastcall ulrsqrt(float x) {

> DWORD y;

> float r;

> _asm {

>  mov eax, 07F000000h+03F800000h // (ONE_AS_INTEGER<<1) + ONE_AS_INTEGER

>  sub eax, x

>  sar eax, 1

>  mov y, eax // y

>  fld _0_47 // 0.47

>  fmul DWORD PTR x // x*0.47

>  fld DWORD PTR y

>  fld st(0) // y y x*0.47

>  fmul st(0), st(1) // y*y y x*0.47

>  fld _1_47 // 1.47 y*y y x*0.47

>  fxch st(3) // x*0.47 y*y y 1.47

>  fmulp st(1), st(0) // x*0.47*y*y y 1.47

>  fsubp st(2), st(0) // y 1.47-x*0.47*y*y

>  fmulp st(1), st(0) // result

>  fstp y

>  and y, 07FFFFFFFh

> }

> r = *( float *)&y;

> // optional

> r = (3.0f - x * (r * r)) * r * 0.5f; // remove for low accuracy

> return r;

>}


>/*

> sqrt(x) = x / sqrt(x)

>*/

>float __fastcall ulsqrt(float x) {

> return x * ulrsqrt(x);

>}

3 Нормализация векторов. Обычно делают неправильно, но сначала код:

>//Обычно делают так:

>void normaliseNormalise(Vector *v) >{

> float L, L_squared, one_over_L;

> L_squared = (v->x * v->x) + (v->y * v->y) + (v->z * v->z);

> L = sqrt(L_squared);

> one_over_L = 1.0 / L;

> v->x = v->x * one_over_L;

> v->y = v->y * one_over_L;

> v->z = v->z * one_over_L;

>}


>// А можно так:

>#define ONE_AS_INTEGER ((DWORD)(0x3F800000))

>float __fastcall InvSqrt(const float & x) >{

> DWORD   tmp = ((ONE_AS_INTEGER << 1) + ONE_AS_INTEGER - *(DWORD*)&x) >> 1;

> float y = *(float*)&tmp;

> return y * (1.47f - 0.47f * x * y * y);

>}


>void Normalise(Vector *v) >{

> float L_squared, one_over_L;

> L_squared = (v->x * v->x) + (v->y * v->y) + (v->z * v->z);

> one_over_L = InvSqrt(L_squared);

> v->x = v->x * one_over_L;

> v->y = v->y * one_over_L;

> v->z = v->z * one_over_L;

>}

По-моему комментарии излишни :).

4 Разворачивание циклов

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

Для этого используем макросы, но оставляем возможность переключится на функции и не развернутые циклы для отладки (Отладка развернутых циклов сложна и неинформативна).

Опасайтесь разбухания кода!

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

1. Оптимизация рендеринга

Благодатная тема для описания, существует огромное количество способов сделать неправильно и один способ сделать правильно (Это заявление не относится к операционной системе Windows, для нее правильнее другое: Существует огромное количество способов сделать правильно, но они устарели и их лучше не использовать, а самый лучший способ — это как раз тот, в который мы недавно добавили большое количество NOP'ов и он работает как раз так, чтобы чуть-чуть тормозить на средней системе :)).

DirectX 8 и, в частности, Direct3D8 - это безусловно самая лучшая разработка Корпорации (ведь мы уже смело можем ТАК ее называть).

Итак, следуйте следующим указаниям:

1. Не используйте "тяжелые" функции в цикле рендеринга. Всегда функции

>ValidateDevice(), CreateVB(), CreateIB(), DestroyVB(), Optimize(), Clone(), CreateStateBlock(), AssembleVertexShader()

помещайте в загрузку сцены и НИКОГДА в цикл рендеринга приложения. Создание буфера вершин может занять до 100 ms!

2. Использование DrawPrimitiveUP() является ошибкой, вызывает задержки в работе процессора и всегда вызывает дополнительное копирование вершин.

3. Не позволяйте художникам контролировать ваш код. Если вам необходимо рисовать по 200+ вершин за проход, то геометрия должна удовлетворять этому требованию. Позволите себе рисовать по 2 вершины за вызов — и вы ТРУП :(.

4. Сортируйте по текстурам и по шейдерам. Если сложно сортировать по обоим параметрам, используйте кэширование. Создаем большую текстуру 4K×4K, в нее копируем текстуры, используемые в сцене, подправляем текстурные координаты геометрии и рисуем большой кусок с одной текстурой сортированный по шейдерам. Либо готовим геометрию таким образом, чтобы это кэширование не требовалось.

5. Стараемся использовать как можно меньшее количество буферов вершин. Смена буфера очень "тяжелая" операция и дорого нам стоит. Поэтому

6. Загружаем модели в сцене в минимальное количество буферов.

7. Используем минимальное количество разновидностей FVF, если возможно — то один общий FVF (Максимального размера).

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

9. Всегда считайте данные в видеокарте, как доступные только для записи.

10. Если вам необходимо восстанавливать состояние буфера, храните две копии.

11. Если вы обновляете данные в буфере каждый фрейм, используйте динамические буферы вершин.


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.