Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab_7_asm.doc
Скачиваний:
4
Добавлен:
13.11.2019
Размер:
574.98 Кб
Скачать

Лабораторна робота №6

Тема: Використання GDI інтерфейсу для побудови графіки в ОС Windows.

Мета: Навчитися користуватися засобами GDI.

Теоретичні основи Основні поняття

Розпочнемо з того, що собою представляє GDI, і яку роль грає у ОС Windows.

GDI розшифровується як Graphics Device Interface, і є інтерфейсом, який Windows використовує для малювання 2d графіки. Також це найповільніший спосіб відображення графіки з тих, що існують, проте найпростіший для розуміння основ. Отже, спершу, поговоримо про основні поняття і терміни в GDI.

Почнемо з того, що GDI зазвичай не використовують для створення "крутих" графічних ефектів, для цього є DIRECTX, OPENGL. Проте, для створення простих ефектів з мінімальними зусиллями GDI цілком підходить.

Поняття графічний контекст

Для висвітлення або відтворення (наприклад, на папері) малюнка потрібен пристрій виводу(малювання). Наприклад, в моніторі зображення відтворює 3 лазерними пушками, які контролюються 4-ма магнітами, дякуючи їм, лазери будуються складні кольори та контори, що ми бачимо на екрані. Також цей "пристрій" може виступати як певний механізм, що оперує деякою палітрою компонентів. Якщо перейти до абстрактного мислення, то таким пристроєм можна назвати руку людини. Це геніальний пристрій, котрий може намалювати все що завгодно, починаючи від простої точки закінчуючи складною фігурою з тінями і у кольоровому супроводі. У технології GDI є свій пристрій малювання, який може реалізувати, практично все, його називають графічним контекстом або контекстом пристрою (DC - "Device Context").

Визначення dc для об’єктів типу вікно

У операційній системі Windows будь яке вікно, що відтворюється на екрані є малюнком. Виходячи з попереднього твердження, кожне вікно, це графічний об’єкт. Відповідно всі вікна мають свій DC. Щоб ним скористатися, потрібно його визначити (позичити). Це робиться за допомогою функції GetDC.

У функції є один параметр, хендл вікна. Якщо вікна оголошені як діалогові (див. попередню лабораторну), для визначення хенду контрола використовується функція GetDlgItem.

Функція GetDC позичає DC у вікна, тому після використання потрібно повернути DC власнику, тобто вікну. Це робиться за допомогою функції ReleaseDC. Для взяття DC робочого столу параметром функції GetDC має бути "0". Таке значення хендлу працює тільки у вище згаданій функції. В інших випадках може причинити помилку.

GetDC

hWnd // хендл вікна у котрого позичимо DC

Результат: хендл DC

ReleaseDC

hWnd // хендл вікна у кого позичали DC

hDC // хендл DC

Результат: TRUE (1) якщо повернувся DC вікну

Створити DC не можна його можна або позичити або скопіювати за допомогою функції CreateCompatibleDC. Параметр 1, хендл DC з кого копіюємо. Якщо графічний об’єкт з якого будемо чорно-білий, то "ново спечений" DC також буле чорно-білим.

Поняття растру та основні функції роботи з ним.

Перед тим як використовувати методи GDI, треба зрозуміти яким чином відтворюється графіка у комп‘ютері.

Почнемо з того, що таке растр. Растр - це є сукупність мінімальних одиниць зображення, що розміщено як матриця, де під мінімальною одиницею розуміється піксекль. Піксель це точка, але у комп‘ютерній графіці, точна не є круглою, як ми звикли уявляти, а на справді маленький квадратик. Відповідно сукупність пікселів розміщених послідовно ми будемо називати лінією.

Найпростішою і мабуть най повільнішою функцією у GDI є SetPixel.

SetPixel

HDC // хендл DC

X // координата Х

Y // координата Y

crColor // колір у колуванні RGB

Результат: значення встановленого кольору(RGB), або -1 якщо точка розміщена поза зоною видимості

Для взяття інформації про піксель використовується функції GetPixel

GetPixel

HDC // хендл DC

X // координата Х

Y // координата Y

Результат: значення встановленого кольору(RGB) у координатах Х,Y

Під RGB кодування розуміється представлення кольору у вигляді 3 компонентів R – червонного, G – зеленого та B – синього. Кожна компонента займає 1байт, і містить число у діапазоні [0..255]. Це кодування має іншу назву, 24бітний колір (24 bit Color). У ОС Windows використовується 5 типів:

  • 1 bit – чорно біле

  • 4 bit – палітра 16 кольорів (DOS)

  • 8 bit – палітра з 256 кольорів

  • 24 bit – RGB

  • 32 bit – RBG + Alpha (компонента прозорості)

Приклад, градієнт:

Задача: Якщо по вертикалі, в позиції 0 колір буде рівний 0, а в позиції "висота" = 255, то який колір буде в позиції y?

сol = y * 255 / висоту.

;Код 1

.data

hdc1 dd 0

x dd 0

y dd 0

.code

........

.if wParam == 1001

invoke GetDC,hWin

mov hdc1,eax

mov x,0

mov y,0

.while y<270

.while x<500

invoke MulDiv,y,0ffh,270

invoke SetPixel,hdc1,x,y,eax

inc x

.endw

inc y

mov x,0

.endw

invoke ReleaseDC,hWin,hdc1

........

Прапор:

;Код 2

.data

hdc1 dd 0

x dd 0

y dd 0

.code

........

.if wParam == 1001

invoke GetDC,hWin

mov hdc1,eax

mov x,0

mov y,0

.while y<270

.while x<500

; синій зменшується, а червоний та зелений збільшуються

invoke MulDiv,y,0ffh,270

mov ecx,0ffh ; ecx = 255

sub ecx,eax ; ecx – "pos gradient"

shl ecx,16 ; ecx -> blue (<< 16)

mov ebx,eax ; ebx= red

shl eax,8 ; eax = green

or eax,ebx ; mix

or eax,ecx

invoke SetPixel,hdc1,x,y,eax

inc x

.endw

inc y

mov x,0

.endw

invoke ReleaseDC,hWin,hdc1

........

Код1 Код2

Мал. 1. Приклад роботи з пікселями

Для малювання прямих використовується функція LineTo

LineTo

hdc // хендл DC

nXEnd, // координата Х кінця малювання прямої

nYEnd // координата Y кінця малювання прямої

Результат: не нуль, в позитивному випадку

Зверніть увагу, колір, тип та товщина лінії залежить від інструменту (Pen), який використовує на час виконання функції DC, якщо є потреба малювати іншим пером, треба підмінити його новим, про це пізніше.

Початкові координати прямої будуть кінцем попередньої функції, тому якщо є потреба під коректувати це значення використовується функція MoveToEx

MoveToEx

hdc // хендл DC

nXNew, // координата Х

nYNew // координата Y

lpPoint // вказівник на структуру POINT де будуть записані старі координати початку малювання прямої. Цей параметр може бути 0 (NULL)

Результат: не нуль, в позитивному випадку

Наступний приклад ілюструє малювання лінії за рухом мишки.

DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

mov eax,uMsg

.if eax==WM_INITDIALOG

invoke GetDC,hWin

mov hdc1,eax

.elseif eax == WM_MOUSEMOVE

; в lParam знаходить х та у [y= HiWord(lParam);x = LoWORD(lParam)]

mov ecx,lParam ; ecx – буде y

mov eax,ecx ; eax - буде x

shr ecx,16

and eax,0ffffh

invoke LineTo,hdc1,eax,ecx

.elseif eax==WM_CLOSE

invoke ReleaseDC,hWin,hdc1

invoke EndDialog,hWin,0

.else

mov eax,FALSE

ret

.endif

mov eax,TRUE

ret

DlgProc endp

Мал 2. Приклад малювання лінії

Можна безкінечно удосконалювати програму, зробивши, наприклад, малювання тільки тоді, коли натиснута кнопка Ctrl (це можна визначити за допомогою функції GetKeyState), але на цьому зупинятися не будемо. Спробуйте реалізувати це самі.

Для побудови ламаної лінії у виді фігури, наприклад трикутника, можна намалювати послідовність ліній з відповідними координатами або скористатися однією з функцій для побудові полі-ліній, наприклад PolylineTo.

PolylineTo

hdc // хендл DC

*lppt // вказівник на масив структур POINT, в яких буде міститися координати вершин ламаної

cCount // к-сть вершин

Результат: не нуль, в позитивному випадку

Переглянути функції :

  • Polyline

  • PolyPolyline

  • PolyBezierTo

  • PolyDraw

  • Polygon

Приклад побудови трикутника за допомогою ліній:

.data

Hdc1 dd 0

.code

.....

.if wParam == 1001

invoke GetDC,hWin

mov hdc1,eax

invoke MoveToEx,hdc1,100,100,0

invoke LineTo,hdc1,150,150

invoke LineTo,hdc1,250,100

invoke LineTo,hdc1,100,100

invoke ReleaseDC,hWin,hdc1

.endif

......

За допомогою полі-ліній:

.data

hdc1 dd 0

x POINT <150,150>

POINT <250,100>

POINT <100,100>

.code

........

.if wParam == 1001

invoke GetDC,hWin

mov hdc1,eax

invoke MoveToEx,hdc1,100,100,0

invoke PolylineTo,hdc1,addr x,3

invoke ReleaseDC,hWin,hdc1

.endif

........

Результат:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]