Чтение онлайн

ЖАНРЫ

Графика DirectX в Delphi

Краснов Михаил

Шрифт:

begin

R := GetRValue (Canvas.Pixels [X, Y]);

G := GetGValue (Canvas.Pixels [X, Y]);

В := GetBValue (Canvas.Pixels [X, Y] ) ;

if R = 0

then ShowMessage ('Под курсором звездочка')

else ShowMessage ('Под курсором фон')

end;

Фон в примере белый, поэтому доля чистого красного (или зеленого) цвета будет нулевой только для пикселов звездочки.

Этот простой прием выбора по цвету можно использовать для более тонкого отделения цветов. Например, нам необходимо рассмотреть вариант, когда пользователь выбирает луч звезды. Окрасим вершины треугольников, образующие лучи, в оттенок синего:

Color := D3DCOLOR_XRGB(0, 0, 254);

А

внутренний Пентагон по-прежнему будем заполнять чистым синим цветом. Столь малая разница в оттенках зрителем совершенно не будет ощущаться и позволит нам точнее разделять две группы объектов для выбора:

if R = О then begin

if В = 255 // Чистым синий - у лучей звезды

then ShowMessage ('Под курсором луч')

else ShowMessage ('Под курсором Пентагон')

end

else ShowMessage ('Под курсором фон');

Аналогично, если надо различать выбор для каждого отдельного луча звезды, окрашиваем их в индивидуальные оттенки, по значению которых и ориентируемся в выборе пользователя. Таким образом, можно предлагать для выбора очень много комплексных или одиночных объектов, предел на их количество - чувствительность зрителя.

Позже мы вернемся к теме выбора объектов, а сейчас немного поговорим на тему закрашивания примитивов.

Посмотрите работу примера из каталога Ех23, возвращающего нас к предыдущему проекту с одиночным треугольником. Небольшое отличие в коде данного примера заключается в том, что вершины треугольника окрашены в различные чистые цвета. Интересно же в примере то, что цвета вершин треугольника интерполируются, отчего при окрашивании получается красивый градиентный переход (рис. 7.13).

Direct3D по умолчанию назначает закраску Гуро - быстрый алгоритм интерполяции цветов вершин треугольника. Также зарезервирована возможность использования закраски Фонга, но пока этот способ системой не поддерживается.

Поменять схему окрашивания или тонирования примитивов возможно с помощью знакомого уже метода задания режимов воспроизведения. Например, чтобы отказаться от интерполяции цветов, надо записать следующую строку:

FD3DDevice.SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FIAT);

В этом случае цвет первой вершины треугольника будет определять цвет всего примитива.

Вторым аргументом для указанного режима могут использоваться также константы D3DSHADE_COURAUD и D3DSHADE_PHONG. Второй случай пока аналогичен отказу от интерполяции.Еще одним режимом воспроизведения, на который необходимо обязательно обратить внимание, является режим D3DRS_FiLLMODE. По умолчанию действует твердотельный режим, примитивы выводятся заполненными. Этому режиму соответствует константа DSDFILL^SOLID. Для установления проволочного, каркасного режима воспроизведения необходимо вторым аргументом метода setRenderState задавать другую константу:

FD3DDevice.SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);

При проволочном режиме вложенные в треугольник объекты не воспроизводятся, рисуются только отрезки, образующие их контуры. Иллюстрацией применения этого метода служит проект каталога Ех24 - простое продолжение примера со звездой (рис. 7.14).

Если

для этого режима использовать константу D3DFiLL_POiNT, то при воспроизведении станут выводиться только точки вершин примитивов.

Продолжаем изучать примитивы DirectSD. Группе связанных треугольников соответствует флаг DSDPTJTRIANGLESTRIP. Первые три вершины задают первый треугольник, вторая, третья и четвертая определяют второй треугольник, третья, четвертая и пятая - третий и т. д. Получается лента соприкасающихся треугольников (рис. 7.15).

Использование связанных треугольников - самый экономный и эффективный способ построений. К примеру, если для рисования прямоугольника независимыми треугольниками потребуется задать координаты шести точек, то при использовании связанных треугольников достаточно задать четыре точки.

Для закрепления изученного материала решим следующую задачу: требуется нарисовать диск; значение константы Level определяет количество используемых в разбиении треугольников.

Поскольку лента в этой задаче замкнута, вершин потребуется на пару больше, чем значение Level:

VPoints : Array [0..Level + 1] of TCUSTOMVERTEX;

Для построения диска берем попарно точки, лежащие на внутренней и внешней границах диска:

i := 0;

repeat

with VPoints [i] do begin // Внутренняя граница диска

X := 150 + cos (Angle + i * 2 * Pi / Level) * Radius / 2;

Y := 150 + sin (Angle + i * 2 * Pi / Level) * Radius / 2;

Color := D3DCOLOR_XRGB(255, 0, 0); // Красного цвета

end;

with VPoints [i + 1] do begin // Внешняя граница диска

X := 150 + cos (Angle + i * 2 * Pi / Level) * Radius;

Y := 150 + sin (Angle + i * 2 * Pi / Level) * Radius;

Color := D3DCOLOR_XRGB(0, 0, 255); // Синего цвета

end;

Inc (i, 2); // Переходим к следующей паре вершин

until i > Level;

Окончательное решение задачи можете посмотреть в каталоге Ех25, результат работы которого в проволочном режиме представлен на рис. 7.16.

Раз мы умеем строить закрашенный прямоугольник, то мы можем попробовать свои силы в решении классической задачи компьютерной графики - рисование пламени. Проект, располагающийся в каталоге Ех26, является решением этой задачи, во время его работы внизу экрана поднимаются языми пламени, в верхней части экрана появляется падающая горящая частица.

Изображение строится по отдельным квадратикам, размеры которых можно варьировать:

type

TRGB = packed record // Запись цвета

R, G, В : BYTE;

end;

const

Size =2; // Размер отдельного квадратика, "пиксела"

Fade =4; // Степень затухания пламени

NumX = 150; // Количество квадратиков по горизонтали

NumY = 150; // Количество квадратиков по вертикали

var

Fire : Array [L.NumX, L.NumY + 1] of TRGB; // Цвета узлов сетки

Поделиться с друзьями: