Графика DirectX в Delphi
Шрифт:
const
HalfPi = Pi / 2; // Небольшая оптимизация
function TfrmD3D.Draw2DQuad (const inX, inY : Single) : HRESULT;
var
pVertices : PByte;
hRet : HRESULT;
begin
with VQuad [0] do begin // Левый нижний угол квадрата
X := inX + Radius * cos (Angle / 2 - HalfPi);
Y := inY + Radius * sin (Angle / 2 - HalfPi);
end;
with VQuad [1] do begin // Левый верхний угол квадрата
X := inX + Radius * cos (Angle /2);
Y := inY + Radius * sin (Angle / 2);
end;
with VQuad [2] do begin //
X := inX + Radius * cos (Angle / 2 + Pi);
Y := inY + Radius * sin (Angle / 2 + Pi);
end;
with VQuad [3] do begin // Правый верхний угол квадрата
X := inX + Radius * cos (Angle / 2 + HalfPi);
Y := inY + Radius * sin (Angle / 2 + HalfPi);
end;
// Заполняем вершинный буфер данными о вершинах квадрата
hRet := FD3DVB.Lock(0, SizeOf(VQuad), pVertices, 0);
if Failed (hRet) then begin
Result := hRet;
Exit;
end;
Move (VQuad, pVertices", SizeOf(VQuad));
hRet := FD3DVB.Unlock;
if Failed (hRet) then begin
Result := hRet;
Exit;
end;
// Квадрат образован двумя связанными треугольниками
Result := FD3DDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
end;
При перерисовке кадра перед отображением квадрата включаем режим полупрозрачности, а после рисования треугольника его отключаем:
function TfrmD3D.Render : HRESULT;
var
hRet : HRESULT;
begin
if FD3DDevice = nil then begin Result := E_FAIL;
Exit;
end;
// Очистка экрана и окрашивание его в черный цвет
hRet := FD3DDevice.Clear(0, nil, D3DCLEAR_TARGET, 0, 0.0, 0);
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
hRet := FDSDDevice.BeginScene;
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
// Первыми рисуются точки фона
hRet := DrawPoints;
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
// Включаем режим полупрозрачности
with FDSDDevice do begin
SetRenderState(D3DRS_ALPHABLENDENABLE, DWORD(True));
SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
end;
// Полупрозрачный квадрат
hRet := Draw2DQuad (HalfScreenWidth, HalfScreenHeight);
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
// Полупрозрачный треугольник
hRet := Draw2DTriangle (HalfScreenWidth, HalfScreenHeight);
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
//
FDSDDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, DWORD(False));
hRet := FDSDDevice.EndScene;
if FAILED(hRet) then begin
Result := hRet;
Exit ;
end;
Result := FDSDDevice.Present(nil, nil, 0, nil) ;
end;
Чтобы примитив оказался полупрозрачным, необходимо, во-первых, включить режим D3DRS_ALPHABLENDENABLE. Вторым аргументом для этого режима
задается преобразованная в DWORD (или cardinal) булева константа. Для простоты можно использовать просто нуль или единицу. И во-вторых, следует задать параметры источника и приемника. Для простейшего случая, когда все примитивы одинаково полупрозрачны, этим параметром назначается константа DSDBLEND ONE.
В случае одинаковой полупрозрачности примитивов достаточно задавать параметр приемника, значение для DSDRS^SRCBLEND по умолчанию установлено В D3DBLEND_ONE.
При включенном режиме ОЗОЕЗ_АЪРНАВЬЕЫОЕЫАВЬЕ примитивы как бы рисуются на кальке: в местах наложения листов кальки плотность цветовых компонентов увеличивается.
Для оптимизации сразу же после того, как нарисованы все полупрозрачные примитивы, режим полупрозрачности необходимо отключить.
Альфа-составляющая цвета
Рассмотренный в предыдущем разделе пример полупрозрачности является частным случаем работы с четвертой составляющей цвета, так называемым альфа-компонентом или альфа-составляющей цвета. Этот компонент позволяет регулировать степень прозрачности. По умолчанию установлено значение 255, т. е. примитивы совершенно не прозрачны. Нулевое значение имитирует полную прозрачность. Все промежуточные значения соответствуют градации прозрачности.
Рассмотрим простой пример на эту тему (проект каталога Ех02), где на фоне непрозрачного красного квадрата вращается сложная геометрическая композиция зеленого цвета, которую для простоты назовем звездой (рис. 8.2).
Звезда сначала абсолютно прозрачна, но со временем становится плотнее. Цвета квадрата и звезды накладываются точно, образуя оттенки желтого, пока звезда не станет совершенно непрозрачной.
Вспомогательная переменная Alpha последовательно принимает значения от 0 до 255 и используется в функции рисования звезды, при задании цветовой составляющей вершин:
for i := 0 to High (VStar) do