| netlib.narod.ru | < Назад | Оглавление | Далее > |
Трехмерный мир не будет завершенным без объектов. Поскольку вы используете трехмерный мир, в качестве игровых объектов хорошо использовать трехмерные сетки; однако, как вы видели в разделе «Сетки в качестве уровней», тупое рисование тысяч объектов (без какого-либо отбрасывания) вызовет существенные задержки в конвейере визуализации графики.
Здесь нам снова потребуется использовать пирамиду видимого пространства для быстрого определения того, какие объекты видимы, а какие нет. Чтобы определить видимость трехмерного объекта вы заключаете его в невидимую сферу, называемую ограничивающей сферой (bounding sphere), которая будет использоваться совместно с функцией CheckSphere класса пирамиды видимого пространства (смотрите раздел «Класс cFrustum» ранее в этой главе).
На рис. 8.7 показано использование ограничивающих сфер и пирамиды видимого пространства. На иллюстрации вы видите сцену с тремя объектами и пирамидой видимого пространства. У каждой сетки есть невидимая ограничивающая сфера, внутри которой она находится. Вспомните, что сфера считается находящейся в поле зрения, если она лежит перед всеми шестью плоскостями, образующими пирамиду видимого пространства.

Рис. 8.7. Вы можете проверить три объекта в сцене относительно пирамиды видимого пространства
На рис. 8.7 только два объекта находятся в пирамиде видимого пространства и видны зрителю. Один объект полностью находится вне пирамиды видимого пространства. Вы захотите иметь возможность рисовать только видимые объекты и пропускать те, которые расположены вне пирамиды. Для этого вы должны вычислить ограничивающую сферу каждого объекта и затем проверить ее, чтобы убедиться, находится ли она внутри пирамиды.
Если вы не используете класс сеток графического ядра, вам необходимо определить ограничивающую сферу сетки. Используя D3DX, вы можете обратиться к функции D3DXComputeBoundingSphere (именно она используется в графическом ядре):
HRESULT D3DXComputeBoundingSphere(
PVOID pvPointsFVF, // Буфер, содержащий вершины
DWORD NumVertices, // Количество вершин в буфере
DWORD FVF, // Дескриптор FVF
D3DXVECTOR3 *pCenter, // &D3DXVECTOR2(0.0f, 0.0f, 0.0f)
FLOAT *pRadius); // Указатель на переменную радиуса
Эта функция просто сканирует буфер вершин, запоминая какая вершина больше всего удалена от центра. Расстояние от центра до этой вершины и является радиусом сферы. Перед вызовом D3DXComputeBoundingSphere вам надо заблокировать буфер вершин с помощью следующего вызова:
HRESULT ID3DXMesh::LockVertexBuffer(
DWORD Flags, // Флаги блокировки. Используйте D3DLOCK_READONLY
BYTE **ppData); // Указатель на данные буфера вершин
Когда сетка загружена, все готово к вычислению ее ограничивающей сферы, как показано ниже:
// pMesh = ранее загруженный объект ID3DXMesh
float Radius; // Радиус объекта
BYTE **Ptr; // Указатель на буфер вершин
// Блокируем буфер вершин
if(SUCCEEDED(pMesh->LockVertexBuffer(D3DLOCK_READONLY,
(BYTE**)&Ptr))) {
// Вычисляем радиус ограничивающей сферы
D3DXComputeBoundingSphere((void*)Ptr,
pMesh->GetNumVertices(), pMesh->GetFVF(),
&D3DXVECTOR3(0.0f, 0.0f, 0.0f), &Radius);
// Разблокируем буфер вершин
pMesh->UnlockVertexBuffer();
}
Обратите внимание, что в вызове D3DXComputeBoundingSphere количество вершин и дескриптор FVF запрашиваются непосредственно у ID3DXMesh. За вызовом ID3DXMesh::LockVertexBuffer следует вызов ID3DXMesh::UnlockVertexBuffer. Вы должны разблокировать буфер вершин, закончив работу с ним, иначе последующие вызовы блокировки или визуализации буфера приведут к сбою.
Сейчас, когда у вас сконструирована пирамида видимого пространства и есть ограничивающая сфера, можно вызвать функцию cFrustum::CheckSphere, чтобы проверить видим ли объект:
// cFrustum *Frustum = ранее созданная пирамида видимого пространства
// Radius = ранее вычисленный радиус ограничивающей сферы
// XPos, YPos, ZPos = Мировые координаты объекта
if(Frustum->CheckSphere(XPos, YPos, ZPos, Radius) == TRUE) {
// Объект внутри пирамиды, переходим к его визуализации
} else {
// Объект вне пирамиды, пропускаем визуализацию
}
| netlib.narod.ru | < Назад | Оглавление | Далее > |