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 Разворачивание циклов
Обычно циклы разворачиваются. Наша цель максимально эффективно использовать кэш процессора, поэтому слишком глубокого разворачивания не нужно, достаточно повторений в цикле.
Для этого используем макросы, но оставляем возможность переключится на функции и не развернутые циклы для отладки (Отладка развернутых циклов сложна и неинформативна).
Опасайтесь разбухания кода!
Измеряйте производительность кода постоянно, причем желательно вести базу данных, в которой будут указываться не только изменения в коде, но и изменения в производительности. Особенно такие базы полезны при работе с несколькими программистами графического ядра приложения.
Благодатная тема для описания, существует огромное количество способов сделать неправильно и один способ сделать правильно (Это заявление не относится к операционной системе 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. Если вы обновляете данные в буфере каждый фрейм, используйте динамические буферы вершин.
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.