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

на главную - закладки

Жанры

Графика DirectX в Delphi

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

Шрифт:

Специально для этого случая я подготовил пример, иллюстрирующий, как можно эффектно комбинировать обычный вывод средствами GDI и DirectDraw. Это проект каталога Ex11, где посередине экрана отображается репродукция самого популярного шедевра живописи, а по бокам разбросаны стандартные интерфейсные элементы (рис. 5.11).

В программе задается режим 800x600 пикселов, уровень доступа - исключительный.

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

var

rgn : TRgnData; // Вспомогательная переменная, описьшает набор регионов

wrk : TRECT; // Прямоугольник, описывающий наш единственный регион

...

SetRect {wrk, 230, 0, 620, 600); // Задаем область вывода на экране

with rgn.rdh do begin // Заполняем поля структуры

dwSize := SizeOf (RGNDATAHEADER); // Это обязательно, как всегда

iType := RDH_RECTANGLES; // Единственно возможное значение поля

nCount := 1; // Количество задействованных регионов

nRgnSize := Sizeof(TRECT); // Размер единицы информации

end;

PRECT(@rgn.Buffer)Л := wrk; // Заносим в буфер наш единственный регион

if FDD.CreateClipper(0, FDDClipper, nil) = DD_OK then begin

FDDClipper.SetClipList (@rgn, 0); // Задаем область отсечения

FDDSPrimary.SetClipper (FDDClipper) ;

end;

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

Приведу еще один способ работы с методом SetciipList. Вот код, который способствует отсечению, аналогичному отсечению предыдущего примера:

var

hrg : HRGN; // Регион

rgnDataBuffer: Array [0..1023] of BYTE; // Массив списка регионов

...

hrg := CreateRectRgn (230, 0, 620, 600); // Создание нужного региона

// Заполняем массив данными

GetRegionData(hrg, SizeOf(rgnDataBuffer), @rgnDataBuffer);

DeleteObject(hrg);

if FDD.CreateClipper(0, FDDClipper, nil) = DD_OK then begin

FDDClipper.SetClipList (@rgnDataBuffer, 0); // Задаем отсечение

FDDSPrimary.SetClipper(FDDClipper);

end;

Отсечение для полноэкранных приложений может использоваться и для того, чтобы полностью решить проблему с выводом образов вблизи границ. В проекте каталога Ех12 курсор заменен логотипом DirectX, динамически меняющим свой размер. Для такой ситуации задание положения курсора становится трудной задачей. Мы не можем пользоваться решениями предыдущих примеров с замененным курсором приложения. Присовокупление отсечения к экрану позволяет совершенно не задумываться о текущем размере образа курсора и его положении, при его воспроизведении вблизи границ образ отсекается совершенно корректно (рис. 5.12).

Аналогично

предыдущему примеру, объект отсечения строится на основе региона, но здесь регион представляет собой простой прямоугольник, связанный с размерами экрана:

SetRect (wrk, О, О, 800, 600);

with rgn.rdh do begin

dwSize := SizeOf (RGNDATAHEADER);

Type := RDH_RECTANGLES;

nCount := 1;

nRgnSize := Sizeof(TRECT);

end;

PRECT(@rgn.Buffer)Л := wrk;

if FDD.CreateClipper(0, FDDClipper, nil) = DD_OK then begin

FDDClipper.SetClipList (@rgn, 0);

FDDSBac k.SetClipper(FDDC1ippe r);

end;

При перерисовке кадра образ курсора растягивается на величину Scale:

function TfrmDD.UpdateFrame : HRESULT;

var

hRet : HRESULT;

wrkRect : TRECT;

begin

// Вывод фона

hRet := FDDSBack.Blt (nil, FDDSBackGround, nil, DDBLT WAIT, nil);

if Failed (hRet) then begin Result := hRet; Exit; end;

// Прямоугольник области образа курсора

SetRect (wrkRect, mouseX, mouseY, mouseX + Scale, mouseY + Scale);

// Масштабирование образа курсора, используется цветовой ключ

hRet := FDDSBack.Blt (SwrkRect, FDDSImage, nil, DDBLT_WAIT or

DDBLT_fCEYSRC, nil) ; if Failed (hRet) then begin

Result := hRet;

Exit;

end;

Result := FDDSPrimary.Flip(nil, DDFLIP_WAIT)

end;

Библиотека CDX

Наверняка многие из читателей этой книги захотят создать собственную вспомогательную библиотеку, облегчающую программирование приложений на основе DirectDraw. Прежде чем приступать к этому мероприятию, стоит познакомиться с уже готовыми решениями. В данном разделе вас ждет краткий экскурс по функциям очень популярной библиотеки CDX, реализованной по лицензии GNU. Библиотека написана на С, и я перевел на Delphi лишь небольшую ее часть, а полностью библиотеку вы можете получить по адресу http://www.cdx.sk/.

Начнем с проекта каталога Ех13, простейшего примера, выводящего на экране по ходу своей работы разноцветные прямоугольники (рис. 5.13).

В списке uses добавилось подключение модуля coxscreenx, а перечень переменных, связанных с графикой, совсем короткий:

GameScreen : CDXScreen;

Вообще, код сильно упрощается, а инициализация графики сведена к одному оператору:

GameScreen := CDXScreen.CreateCDXScreenCustomBPP(Handle, ScreenWidth,

ScreenHeight, ScreenBitDepth);

Код перерисовки окна также состоит из одного действия:

GameScreen.GetAppFrontBuffer.Rect(random(ScreenWidth),

random(ScreenHeight),

random(ScreenWidth),

random(ScreenHeight),

random(254));

To есть, рисуем очередной прямоугольник прямо на переднем буфере.

Работа приложения завершается после нажатия любой клавиши. По окончании работы приложения удаляется наш единственный объект:

if Assigned (GameScreen) then GameScreen.Destroy;

Поделиться:
Популярные книги

Свадьба по приказу, или Моя непокорная княжна

Чернованова Валерия Михайловна
Любовные романы:
любовно-фантастические романы
5.57
рейтинг книги
Свадьба по приказу, или Моя непокорная княжна

Сборник коротких эротических рассказов

Коллектив авторов
Любовные романы:
эро литература
love action
7.25
рейтинг книги
Сборник коротких эротических рассказов

Отец моего жениха

Салах Алайна
Любовные романы:
современные любовные романы
7.79
рейтинг книги
Отец моего жениха

Вадбольский

Никитин Юрий Александрович
1. Вадбольский
Фантастика:
попаданцы
5.00
рейтинг книги
Вадбольский

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Повелитель механического легиона. Том VIII

Лисицин Евгений
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII

В зоне особого внимания

Иванов Дмитрий
12. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
В зоне особого внимания

Таня Гроттер и магический контрабас

Емец Дмитрий Александрович
1. Таня Гроттер
Фантастика:
фэнтези
8.52
рейтинг книги
Таня Гроттер и магический контрабас

Бастард Императора. Том 2

Орлов Андрей Юрьевич
2. Бастард Императора
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бастард Императора. Том 2

Кодекс Крови. Книга ХI

Борзых М.
11. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХI

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Потусторонний. Книга 1

Погуляй Юрий Александрович
1. Господин Артемьев
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Потусторонний. Книга 1