Глава 8
Примеры использования классов языка C++
Рассмотрим пример графической программы, создающей изображения объектов на основе нескольких простых элементов (рис. 8.1).
!
Рис. 8.1. Трехмерные объекты в различных ракурсах показа
Используем объектно-ориентированную методологию. Каждый элемент будем считать объектом трехмерного пространства, а несколько таких объектов образовывают модель сложного объекта. Для описания объектов используем классы C++. Процитируем автора языка C++ Б. Страустрапа: "Определите, какие классы вам нужны; предусмотрите полный набор операций для каждо-
[ го класса; опишите общие черты явным образом, используя наследова-
! ние" [24].
Сложный пространственный объект в нашей программе построим с использованием таких элементов: куб, сфера и пирамида. Фундамент и колонны бу-
дем считать производными элементами, их определим как множество кубов, специальным образом располагающихся в пространстве (рис. 8.2).
Рис. 8.2. Иерархия классов
В качестве базового элемента определим абстрактный класс фигуры с такими свойствами: размер, цвет, расположение в пространстве, описываемое координатами ее центра. Также предусмотрим для фигур возможность перемещения, изменения размера, цвета и возможность быть нарисованной. Такие общие свойства выразим в классе shape. В этом классе также предусмотрим операцию преобразования координат для отображения в определенной проекции (функция-член PrepareVertex).
Теперь обсудим способ отображения объектов. Поскольку у нас есть элементы-многогранники (куб и пирамида), то можно было бы использовать достаточно быстродействующую функцию Polygon API Windows для рисования граней. А удаление невидимых точек осуществлять сортировкой граней по глубине. Однако такой способ отображения в нашем случае не приемлем, Чуть позже мы покажем почему, а пока что обсудим довольно интересные нюансы объектно-ориентированного стиля программирования. Если бы у нас все объекты были многогранниками, то сортировка граней по глубине означала бы определенную последовательность рисования граней. Например,) сначала одну грань одного объекта, потом соответствующую грань другого \ объекта и так далее. Последовательность рисования в этом случае должна быть от самых дальних граней к самым близким. Однако это усложняет объектно-ориентированную реализацию программы, поскольку желательно было бы, чтобы объект был самодостаточным с точки зрения каждой операции, | выполняемой над ним, — а это невозможно, так как операция сортировки граней должна обеспечивать доступ к отдельным граням, а не только к объекту в целом. Хотя объектно-ориентированная методология не накладывает столь жестких ограничений на реализацию объектов, однако, такое нарушение самодостаточности (инкапсуляции) выглядит не очень эстетично.
Поскольку среди элементов кроме многогранников есть сфера, то метод сор- j тировки граней по глубине нельзя использовать, так как сфера — это не мно- j
гогранник, и она рисуется по пикселам (хотя можно было бы определить ее как многогранник, закрашенный, например, по методу Гуро, однако это намного сложнее, и в данном примере программы не рассматривается). Необходимо использовать Z-буфер, а функция Polygon его не поддерживает. Более того, в составе функций API Windows нет ни одной функции рисования, рассчитанной на использование Z-буфера. Такие функции мы вынуждены сконструировать сами. Относительно объектной ориентированности— метод Z-буфера позволяет полностью инкапсулировать операцию рисования объекта в виде одной функции-члена (мы ее назовем :: Draw). Один вызов функции Draw обеспечивает полный цикл отображения объекта соответствующего класса.
Текст программы (studex34. срр):
!
Скомпилируйте и запустите программу studex34. Необходимо предупредить, что цикл показа может затянуться надолго. В программе выполняется полный оборот камеры на 360 градусов с шагом в один градус. Время создания и отображение всех 361 кадров в соответствующих ракурсах на компьютере с процессором AMD K6-2, 300 МГц, в 24-битном видеорежиме составляло 807 секунд. То есть, на один кадр расходуется в среднем 807/361 = 2.24 секунды. Размеры окна не изменялись после запуска программы, это отвечает размерам изображения 392 на 239 пикселов. Необходимо признать, что эта программа демонстрирует черепашью скорость рендеринга.