Михаил Краснов - Графика DirectX в Delphi

Тут можно читать онлайн Михаил Краснов - Графика DirectX в Delphi - бесплатно ознакомительный отрывок. Жанр: comp-programming. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    Графика DirectX в Delphi
  • Автор:
  • Жанр:
  • Издательство:
    неизвестно
  • Год:
    неизвестен
  • ISBN:
    нет данных
  • Рейтинг:
    3.56/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Михаил Краснов - Графика DirectX в Delphi краткое содержание

Графика DirectX в Delphi - описание и краткое содержание, автор Михаил Краснов, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Графика DirectX в Delphi - читать онлайн бесплатно ознакомительный отрывок

Графика DirectX в Delphi - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Михаил Краснов
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

tуре

TXY = packed record // Координаты точки на плоскости

X, У : Single;

end;

const

SIDES = 20; // Уровень детализации круга

К, SIZE = 5500; // Количество точек

var

points : Array [O..SIZE-1] of TXY; // Массив точек

Radius : Single = 0.03; // Размер отдельной точки

Массив заполняется в начале работы значениями из интервала [-1.0; 1.0]:

procedure TfrmD3D.FormCreate(Sender: TObject) ;

var

hRet : HRESULT;

i : Integer;

begin

Randomize;

for i := 0 to SIZE - 1 do begin // Заполнение массива точек

Points[i].X := random * 2 - 1.0;

Points[i].Y := random * 2 - 1.0;

end;

hRet := InitDSD;

if Failed (hRet) then ErrorOut ('InitD3D', hRet);

hRet := InitVB; // Буферы вершин под (SIDES + 1) вершину

if Failed (hRet) then ErrorOut ('InitVB', hRet);

hRet := InitTexture ('../Mandrill.bmp');

if Failed (hRet) then ErrorOut ('InitTexture1, hRet);

end;

При рисовании отдельного мазка текстурные координаты всех вершин одинаковы и связаны с координатами точки:

function TfrmD3D.DrawCircle (const inX, inY : Single) : HRESULT;

const

Step = 2 * Pi / SIDES;

var

Vertices : ATCustomVertex; hRet : HRESULT;

i : Integer; begin

hRet := FD3DVB.Lock(0, (SIDES + 1) * SizeOf(TCustornVertex),

PByte(Vertices), 0) ;

if Failed(hRet) then begin

Result := hRet;

Exit;

end;

// Первая точка, точка центра мазка

Vertices.X := inX;

Vertices.Y := inY;

Vertices.Z := 0.0;

Vertices.U := (inX +1.0) / 2;

Vertices.V := (inY + 1.0) / 2;

Inc(Vertices);

// Точки, лежащие на краю круга

for i := 0 to SIDES do begin

Vertices.X := inX + sin(i * Step) * Radius; // По часовой стрелке

Vertices.Y := inY + cos(i * Step) * Radius;

Vertices.Z := 0;

Vertices.U := (inX + 1.0) / 2;

Vertices.V := (inY + 1.0) / 2;

Inc(Vertices); end;

hRet := FD3DVB.Unlock; if Failed(hRet) then begin

Result := hRet;

Exit;

end;

// Связанные треугольники выстраиваются в полньм круг

Result := FDSDDevice.DrawPrimitive(D3DPTJTRIANGLEFAN, О, SIDES);

end;

Пользуемся мы этой функцией отдельно для каждого элемента массива:

for i := 0 to SIZE - 1 do begin

hRet := DrawCircle (Points [i].X, Points [i].Y);

Kif FAILED (hRet) then begin

Result := hRet;

Exit;

end;

end;

Размер мазков регулируется. Можно также получить новый набор точек, чтобы подобрать самую эффектную картинку:

procedure TfrmD3D.FormKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

var

i : Integer;

begin

if Key = VK_ESCAPE then Close else

if Key = VK_INSERT then Radius := Radius + 0.005 else

if Key = VKJ3ELETE then Radius := Radius - 0.005 else

if Key = VKJ3PACE then begin // Заново генерируем набор точек

for i := 0 to SIZE - 1 do begin

Points[i].X := random * 2 - 1.0;

Points[i].Y := random * 2 - 1.0;

end;

end;

end;

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

procedure TfrmD3D.FormMouseMove(Sender: TObject; Shift: TShiftState;

X, Y: Integer);

var

i : Integer;

begin

if Down then begin // Нажата ли кнопка мыши

// Сравниваем с предыдущим расположением курсора

if (X о LastX) and (Y <> LastY) then begin

for i := 1 to 20 do begin // Берется 20 точек облачка

// вокруг курсора

NumPoints := (NumPoints + 1) mod SIZE;

// Масштабируем точки для системы координат D3DFVF_XYZ

Points[NumPoints].X := ((X + random (7) - 3)/ ClientWidth) * 2 - 1.0;

Points[NumPoints].Y := ((ClientHeight -

(Y + random (7) - 3)) / ClientHeight) * 2 - 1.0;

LastX := X;

LastY := Y;

end;

end;

end;

end;

Для каждого мазка строится набор из 21 треугольника. Как следствие, имеем низкое значение FPS, уменьшающееся с каждым мазком. При маленьком размере кругов подобный подход неэффективен, и нам стоит поискать альтернативное решение такой задачи.

Альфа-составляющая текстуры

Формат текстуры D3DFMT_A8R8G8B8 позволяет для каждого пиксела образа заавать индивидуальное значение альфа-составляющей, чем можно воспольоваться для получения массы интересных эффектов. Так, проект каталога Ex12 решает задачу, сходную задаче предыдущего примера: курсор при своем вижении по поверхности окна оставляет след постепенно проступающего браза (рис. 8.9).

Но теперь образ проступает точка за точкой Мы не используем множество - фото 72

Но теперь образ проступает точка за точкой. Мы не используем множество римитивов, и работает пример гораздо быстрее предыдущего.

ри заполнении прямоугольника текстуры значение альфа-составляющей ш каждого пиксела задается явно, нулевым значением:

PDWORD (DWORD(d3dlr.pBits) + У * dwDstPitch + X * 4)^ :=

D3DCOLOR_ARGB(0, R, G, В);

То есть все точки образа текстуры первоначально задаются совершенно прозрачными.

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

with FDSDDevice do begin

SetTexture(0, FD3Texture); // Устанавливаем текстуру

// Операции с цветом пикселов текстуры

SetTextureStageStatefO, D3DTSS__COLOROP, D3DTAJTEXTURE);

// Операции с альфа-компонентом пикселов текстуры

SetTextureStageStatefO, D3DTSS_ALPHAOP, D3DTA_TEXTURE);

// Разрешаем работу с альфа-составляющей

SetRenderState(D3DRS_ALPHABLENDENABLE, DWORD (True));

// Параметры альфа-смешения

SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);

SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

end;

// Квадрат, покрытый текстурой

hRet := FD3DDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

if FAILED(hRet) then begin

Result := hRet;

Exit;

end;

// Выключаем текстуру и альфа-смешение

with FDSDDevice do begin

SetTexture(0, nil) ;

SetRenderState(D3DRS_ALPHABLENDENABLE, DWORD (False));

end;

При движении курсора увеличиваем значение альфа-составляющей для пикселов растра текстуры так, чтобы они стали непрозрачными:

procedure TfrmD3D.FormMouseMove(Sender: TObject; Shift: TShiftState;

X, Y: Integer);

var

d3dlr : TD3DLOCKED_RECT;

dwDstPitch : DWORD;

i : Integer; wrkX, wrkY : DWORD;

begin

if Down then begin // Нажата ли кнопка мыши

FD3Texture.LockRect(0, d3dlr, nil, 0);

dwDstPitch := d3dlr.Pitch;

for i := 1 to 50 do begin //50 точек в районе курсора

repeat // Генерируем точку в пределах окна

wrkX := DWORD (X + random (7) - 3);

wrkY := DWORD (ClientHeight - Y + random (7) - 3);

until (wrkX < DWORD (ClientWidth)) and (wrkY < DWORD (ClientHeight))

and (wrkX > 0) and (wrkY > 0);

PDWORD (DWORD(d3dlr.pBits) + wrkY * dwDstPitch + wrkX * 4)^ :=

// Альфа-составляющую для точек задаем равной 255

PDWORD (DWORD(d3dlr.pBics) + wrkY * dwDstPitch + wrkX * 4)" +

SFF000000;

end;

FD3Texture.UnlockRect(0);

end;

end;

Несколько небольших замечаний:

* размер окна я установил равным размеру образа, поэтому нет необходимости соотносить координаты курсора и положение пикселов в растре; преобразование типа используется только для того, чтобы не появлялось замечание компилятора; нельзя допускать попытки записи за пределы прямоугольной области текстуры; при движении курсора по непрозрачным пикселам полагаемся на то, что исключение, связанное с переполнением, возникать не будет.

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

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Михаил Краснов читать все книги автора по порядку

Михаил Краснов - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Графика DirectX в Delphi отзывы


Отзывы читателей о книге Графика DirectX в Delphi, автор: Михаил Краснов. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x