13.3.1. Процедурный подход
Альтернативным способом текстурирования ландшафта является программное вычисление текстуры; это означает, что мы создаем «пустую» текстуру и вычисляем цвет каждого ее текселя в коде на основании некоторых предопределенных параметров. В нашем примере таким параметром является высота вершины ландшафта.
Программная генерация текстуры выполняется в методе Terrain::genTexture. Сперва мы создаем пустую текстуру с помощью метода D3DXCreateTexture. Затем мы блокируем текстуру верхнего уровня (помните, что это детализируемая текстура и у нее есть несколько уровней детализации). После этого мы в цикле перебираем тексели и назначаем их цвет. Цвета текселей зависят от высоты вершин квадрата сетки, которому они принадлежат. Идея заключается в том, что низкие участки ландшафта окрашиваются в цвет песчанного пляжа, участки со средней высотой — в цвет травы, а высокие части ландшафта — в цвет снежных вершин. Мы считаем, что высота квадрата это высота его верхнего левого угла.
Назначив цвета всем текселям, мы должны сделать некоторые из них темнее или светлее в зависимости от того, под каким углом солнечный свет (моделируемый с помощью источника направленного света) падает на квадрат ландщафта, соответствующий данному текселю. Все это делается в методе Terrain::lightTerrain, реализация которого будет обсуждаться в следующием разделе.
В конце метода Terrain::genTexture осуществляется вычисление текселей остальных уровней детализируемой текстуры. Это делается с помощью функции D3DXFilterTexture. Вот как выглядит код генерации текстуры:
bool Terrain::genTexture(D3DXVECTOR3* directionToLight) { // Метод программно заполняет текстуру верхнего уровня. // Затем выполняется ее освещение. И, в конце, заполняются // остальные уровни детализируемой текстуры с помощью // D3DXFilterTexture.
HRESULT hr = 0;
// Тексель для каждого квадрата сетки int texWidth = _numCellsPerRow; int texHeight = _numCellsPerCol;
// Создаем пустую текстуру hr = D3DXCreateTexture( _device, texWidth, texHeight, // размеры 0, // создаем полную // цепочку детализации 0, // использование - нет D3DFMT_X8R8G8B8, // формат 32-разрядный XRGB D3DPOOL_MANAGED, // пул памяти &_tex);