Краснов Михаил
Шрифт:
При инициализации создаем два блока установок для различных размеров точек. Идентификаторами являются переменные типа DWORD, значения которых задаются системой:
PointSize := 4.0; // Устанавливаемый размер точек
with FD3DDevice do begin
BeginStateBlock; // Начало описания блока установок
SetRenderState(D3DRS_POINTSIZE, PDWORD (@PointSize)^);
EndStateBlock (PointSize4); // Конец описания блока установок
end;
PointSize := 3.0; // Второй блок установок, другой размер точек
with FDSDDevice do begin
BeginStateBlock;
SetRenderState(D3DRS_POINTSIZE, PDWORD (@PointSize)^);
EndStateBlock (PointSizeS);
end;
Обратите внимание, что само создание блоков установок никак не влияет на режимы воспроизведения, т. е. в данном случае размеры точек пока остаются первоначальными.
Массив вершин примитивов заполняется беспрерывно случайными координатами, а перед воспроизведением первой половины точек вызываем метод ApplyStateBiock и устанавливаем режимы воспроизведения в нужный набор состояний. Единственным аргументом метода является имя нужного блока:
// Задаем режим 3-кратного размера точек
hRet := FD3DDevice.ApplyStateBiock (PointSize3);
// Рисуем первую половину точек
hRet := FDSDDevice.DrawPrimitive(D3DPT_POINTLIST, 0, MAXPOINTS div 2);
// Устанавливаем режим 4-кратного размера точек
hRet := FDSDDevice.ApplyStateBiock (PointSize4);
// Рисуем вторую половину точек
hRet := FDSDDevice.DrawPrimitive(D3DPT_POINTLIST,
(MAXPOINTS div 2) - 1, MAXPOINTS div 2);
Надеюсь, что все понятно, лишь ограничусь небольшим замечанием. Разработчики рекомендуют вызывать метод ApplyStateBiock, как и все другие методы, влияющие на режим воспроизведения, при установленном состоянии воспроизведения.
Окрашенные вершины
В предыдущих примерах рисовались точки белого цвета, теперь мы научимся окрашивать наши примитивы. Для этого необходимо задавать цвет каждой вершины примитива и использовать соответствующий FVF-флаг.
В проекте каталога Ех13 экран заполняется хаотически расположенными разноцветными точками (рис. 7.6).
Запись формата вершин дополнилась полем, хранящим цвет вершины, тип ее DWORD:
type
TCUSTOMVERTEX = packed record
X, Y, Z, RHW : Single;
Color : DWORD; // Добавлено новое поле
end;
Поскольку FVF-флаг задается в нескольких местах кода, вводим пользовательскую константу, хранящую нужную нам комбинацию:
const
D3DFVF_COSTOMVERTEX = D3DFVF_XYZRHW or D3DFVF_DIFFUSE;
Порядок, в котором перечисляются эти константы, безразличен, но порядок перечисления полей в записи формата вершин предопределен графической системой. При считывании данных из потока будет подразумеваться, что первыми идут координаты вершин, за ними следует цвет (диффузная составляющая).
Итак, теперь прибавляется дополнительная константа, которую будем трактовать пока как включение режима окрашивания вершин примитивов.
При инициализации массива вершин поле цвета заполняется случайным значением:
for i := 0 to MAXPOINTS - 1 do
with VPoints [i] do begin
Z := 0.0;
RHW := 0.0;
Color := D3DCOLOR_XRGB(random (256), random (256), random (256));
end;
В остальном код примера не содержит ничего для нас нового, поэтому разбирать его здесь не будем.
В следующем примере (проект каталога Ех14) окрашивание вершин используется для создания черно-белого изображения. Пример весьма занятный: из облака хаотически располагающихся точек выстраивается упорядоченный образ (рис. 7.7).
Изображение формируют 20 898 отдельных примитивов. Первоначально координаты их задаются хаотически, для каждой точки вычисляется шаг смещения. Текстовый файл содержит координаты окончательного положения точки. За 100 шагов каждая точка должна достичь финишного положения:
type
TStep = packed record // Тип для хранения скорости точки по осям
StepX, StepY : Single;
end;
var
Steps : Array [0..MAXPOINTS - 1] of TStep; // Шаги для каждой точки
function TfrmD3D.InitPoints : HRESULT;
var
pVertices : PByte;
hRet : HRESULT;
i : Integer;
t : TextFile;
wrkX, wrkY : Integer;
begin
AssignFile (t, 'points.txt');
Reset (t);
for i := 0 to MAXPOINTS - 1 do begin