netlib.narod.ru< Назад | Оглавление | Далее >

13.1. Карты высот

Мы используем карты высот, чтобы указать, где на нашем ландшафте находятся горы, а где — долины. Карта высот (heighmap) — это массив, в котором каждый элемент задает высоту отдельной вершины сетки ландшафта. (Существует и альтернативная реализация, в которой элемент карты высот соответствует квадрату ландшафта.) Обычно мы представляем карту высот в виде матрицы, каждый элемент которой однозначно соответствует вершине сетки ландшафта.

Когда мы сохраняем карту высот на диске, для каждого ее элемента обычно отводится один байт, так что значения высоты могут находиться в диапазоне от 0 до 255. Хотя диапазон от 0 до 255 достаточен для хранения перепадов высот нашего ландшафта, в приложении может потребоваться масштабирование этого значения, чтобы оно соответствовало масштабу нашего трехмерного мира. Предположим, что в качестве единиц измерения для нашего трехмерного мира мы выбрали сантиметры, тогда диапазона значений от 0 до 255 будет недостаточно, чтобы изобразить что-нибудь интересное. Поэтому при загрузке данных в приложение мы выделяем для каждого элемента карты высот переменную типа int или float. Это позволяет масштабировать значения за пределы диапазона от 0 до 255, чтобы они соответствовали любому требуемому масштабу.

Одним из возможных представлений карты высот является карта с градациями серого, где темные области соответствуют низинам, а светлые — возвышенностям. Такая карта показана на рис. 13.2.


Рис. 13.2. Карта высот в виде градаций серого

Рис. 13.2. Карта высот в виде градаций серого


13.1.1. Создание карты высот

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


Рис. 13.3. Карта градаций серого

Рис. 13.3. Карта градаций серого, созднная в Adobe Photoshop


Когда вы завершите рисование своей карты высот, сохраните ее как 8-разрядный файл RAW. Файлы RAW просто содержат байты изображения один за другим. Благодаря этому чтение данных изображения в приложении выполняется очень просто. Ваш графический редактор может спростить, сохранять ли изображение в файл RAW с заголовком. Укажите, что заголовок не нужен.

ПРИМЕЧАНИЕ
Вы не обязаны использовать для хранения информации о высотах формат RAW; применяйте любой формат, соответствующий вашим потребностям. Формат RAW — это только один пример формата, который можно использовать. Мы выбрали его по той причине, что большинство популярных графических редакторов могут выполнять экспорт изображения в этот формат и чтение данных из файла RAW в приложении реализуется очень просто. В примерах из этой главы используются 8-разрядные файлы RAW.

13.1.2. Загрузка файла RAW

Поскольку файл RAW — это всего лишь непрерывный массив байтов, мы можем просто прочитать его целиком с помощью приведенного ниже метода. Обратите внимание, что переменная _heightmap — это член класса Terrain, определеный следующим образом: std::vector<int> _heightmap;.

bool Terrain::readRawFile(std::string fileName)
{
     // Высота для каждой вершины
     std::vector<BYTE> in(_numVertices);

     std::ifstream inFile(fileName.c_str(), std::ios_base::binary);

     if(inFile == 0)
          return false;

     inFile.read(
          (char*)&in[0], // буффер
          in.size());    // количество читаемых в буфер байт

     inFile.close();

     // копируем вектор BYTE в вектор int
     _heightmap.resize(_numVertices);
     for(int i = 0; i < in.size(); i++)
          _heightmap[i] = in[i];

     return true;
}

Обратите внимание, что мы копируем вектор байтов в вектор целых чисел; это делается для того, чтобы потом мы могли масштабировать значения высот для выхода за пределы диапазона [0, 255].

Единственным ограничением данного метода является то, что количество байт в читаемом файле RAW должно быть не меньше количества вершин в сетке ландшафта. Следовательно, если вы считываете файл RAW размером 256 × 256, то должны создать ландшафт в котором будет не более 256 × 256 вершин.

13.1.3. Досуп к карте высот и ее модификация

Для доступа к элементам карты высот и их модификации класс Terrain предоставляет следующие два метода:

int Terrain::getHeightmapEntry(int row, int col)
{
     return _heightmap[row * _numVertsPerRow + col];
}

void Terrain::setHeightmapEntry(int row, int col, int value)
{
     _heightmap[row * _numVertsPerRow + col] = value;
}

Эти методы позволяют ссылаться на элемент карты, указывая номера строки и столбца, и скрывают выполняемое преобразование в индекс одномерного массива.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz