Вход/Регистрация
DirectX 8. Начинаем работу с DirectX Graphics
вернуться

Поздняков Константин

Шрифт:

 Comments:

 *********************************************************************/

#include <stdio.h>

#include <math.h>

#include <windows.h>

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'ов и он работает как раз так, чтобы чуть-чуть тормозить на средней системе :)).

  • Читать дальше
  • 1
  • ...
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: