РефератыКоммуникации и связьГрГрафика на языке Assembler

Графика на языке Assembler

Федеральное агентство по образованию


ГОУ ВПО


Уфимский государственный авиационный технический университет


Курсовая работа


по дисциплине «Микропрограммирование»


«Графика на языке Assembler»


Выполнил:


студент гр. ПО-228


Елизарьев Д.И.


Уфа


2008


1. Постановка задачи


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


Программа реализована на языке “Assembler”. Для вывода графики на экран используется прямое обращение к видеобуферу. Для достижения плавности прорисовки изображения применяется синхронизация с вертикальной развёрткой монитора.


Повороты вокруг осей производятся по следующим формулам:


· Вокруг оси X:


· Вокруг оси Y:


· Вокруг оси Z:


Для рисования линии используется алгоритм Брезенхэма.


Значения синуса и косинуса вычисляются при помощи таблицы синусов для углов от 0 до 90 градусов.


2.
Текст программы.


DATASSEGMENT


X DW 0 ;Промежуточнаякоордината X


Y DW 0 ;Промежуточная координата Y


Z DW 0 ;Промежуточная координата Z


ANX DW 0 ;Текущий угол поворота вокруг оси X


ANY DW 0 ;Текущий угол поворота вокруг оси Y


ANZ DW 0 ;Текущий угол поворота вокруг оси Z


DeltaX DW 2 ;Приращение угла поворота вокруг оси X


DeltaY DW 2 ;Приращение угла поворота вокруг оси Y


DeltaZ DW 2 ;Приращение угла поворота вокруг оси Z


X2D DW 0 ;Проекция трехмерной точки на плоскость


Y2D DW 0 ;


X1 DW 0 ;Координаты


Y1 DW 0 ;начала и


X2 DW 0 ;конца


Y2 DW 0 ;линии


DelX DW 0 ;Промежуточные


DelY DW 0 ;переменные,


LenX DW 0 ;используемые


LenY DW 0 ;в процедуре


Leng DW 0 ;рисования


D DW 0 ;линии


COLOR DB 10 ;Цвет фигуры


FULLCIRCLE DW 360 ;Константа = 360 градусов


POINTS DW 8 ;Количество вершин


WID DW 320 ;Ширина экрана


;Таблица синусов углов от 0 до 90 градусов.


;Каждое значение синуса умножено на 512


SINES DW 0, 9, 18, 27, 36, 45


DW 54, 62, 71, 80, 89


DW 98, 106, 115, 124, 133


DW 141, 150, 158, 167, 175


DW 183, 192, 200, 208, 216


DW 224, 232, 240, 248, 256


DW 264, 271, 279, 286, 294


DW 301, 308, 315, 322, 329


DW 336, 343, 349, 356, 362


DW 368, 374, 380, 386, 392


DW 398, 403, 409, 414, 419


DW 424, 429, 434, 439, 443


DW 448, 452, 456, 460, 464


DW 468, 471, 475, 478, 481


DW 484, 487, 490, 492, 495


DW 497, 499, 501, 503, 504


DW 506, 507, 508, 509, 510


DW 511, 511, 512, 512, 512


;Координаты вершин куба


CUBE DW 20, 20, 20


DW 20, 20, -20


DW 20, -20, -20


DW 20, -20, 20


DW -20, -20, 20


DW -20, 20, 20


DW -20, 20, -20


DW -20, -20, -20


DATAS ENDS


CODES SEGMENT


ASSUME DS:DATAS, CS:CODES


FIND_SIN PROC ;Нахождение синуса угла от 0 до 360 градусов


push ax


push cx


sub cx, cx


cmp ax, 181


jb SIN_POS


mov cx, 8000h


sub ax, 180


SIN_POS:


cmp ax, 91


jb GET_SIN


neg ax


add ax, 180


GET_SIN:


mov bx, ax


shl bx, 1


mov bx, sines[bx]


cmp cx, 8000h


jne NE1


neg bx


NE1:


pop cx


pop ax


ret


FIND_SIN ENDP


FIND_COS PROC ;Нахождение косинуса угла от 0 до 360 градусов


push ax


push cx


sub cx, cx


cmp ax, 91 ;если угол 90 и меньше,


jb COS_POS ;то знак положительный


cmp ax, 269 ;если угол 270 и больше, то знак "плюс"


jg CP


mov cx, 8000h ;иначе ставим флаг в CX, что знак "минус"


sub ax, 90 ;делаем поправку на 90


cmp ax, 91


jb GET_COS ;если < 91


neg ax ;иначеугол = 180 - угол


add ax, 180


jmp GET_COS


CP:


sub ax, 270 ;угол = 270 - угол


jmp GET_COS


COS_POS:


neg ax


add ax, 90


cmp ax, 91


jb GET_COS


neg ax


add ax, 360


GET_COS: ;достаём значение косинуса из таблицы синусов


mov bx, ax


shl bx, 1


mov bx, sines[bx]


cmp cx, 8000h


jne NE2 ;если знак "минус",


neg bx ;то меняем знак


NE2:


pop cx


pop ax


ret


ENDP FIND_COS


PUTPIXEL PROC ;Рисование точки в X2D, Y2D, цветом COLOR


push ax


push di


mov ax, 100 ;Высота экрана/2


sub ax, Y2D


push dx


mul WID ;Index = Y * WIDTH


pop dx


add ax, X2D ;Index + X


add ax, 160


mov di, ax


mov al, COLOR


mov byte ptr ES:[di], al ;рисуемточку


pop di


pop ax


ret


ENDP PUTPIXEL


PROJECTPROC ;Проецирование трёхмерной точки на плоскость


push ax


mov ax, X


mov X2D, ax


mov ax, Y


mov Y2D, ax


pop ax


ret


ENDP PROJECT


ROTX PROC ;Поворот точки вокруг оси X


push cx


push ax


push bx


push dx


mov ax, ANX


CALL FIND_COS ;


mov ax, bx ;


imul Y ;


mov cx, ax ;


mov ax, ANX ;


CALL FIND_SIN ;YNEW = Y*COS(ANX) - Z*SIN(ANX)


mov ax, bx ;


imul Z ;


neg ax ;


add ax, cx ;


sar ax, 9


mov cx, Y


mov Y, ax


mov ax, ANX ;


CALL FIND_SIN ;


mov ax, bx ;


imul cx


mov cx, ax ;


mov ax, ANX ;ZNEW = Y*SIN(ANX) + Z*COS(ANX)


CALL FIND_COS ;


mov ax, bx ;


imul Z ;


add ax, cx ;


sar ax, 9


mov Z, ax


pop dx


pop bx


pop ax


pop cx


ret


ENDP ROTX


ROTY PROC ;Поворот точки вокруг оси Y


push cx


push ax


push bx


push dx


mov ax, ANY


CALL FIND_COS ;


mov ax, bx ;


imul X ;


mov cx, ax ;


mov ax, ANY ;


CALL FIND_SIN ;XNEW = X*COS(ANY) - Z*SIN(ANY)


mov ax, bx ;


imul Z ;


neg ax ;


add ax, cx ;


sar ax, 9


mov cx, X


mov X, ax


mov ax, ANY ;


CALL FIND_SIN ;


mov ax, bx ;


imul cx ;


mov cx, ax ;


mov ax, ANY ;ZNEW = X*SIN(ANY) + Z*COS(ANY)


CALL FIND_COS ;


mov ax, bx ;


imul Z ;


add ax, cx ;


sar ax, 9


mov Z, ax


pop dx


pop bx


pop ax


pop cx


ret


ENDP ROTY


ROTZ PROC ;Поворот точки вокруг оси Z


push cx


push ax


push bx


push dx


mov ax, ANZ


CALL FIND_COS ;


mov ax, bx ;


imul X ;


mov cx, ax ;


mov ax, ANZ ;


CALL FIND_SIN ;XNEW = X * COS(ANZ) - Y * SIN(ANZ)


mov ax, bx ;


imul Y ;


neg ax ;


add ax, cx ;


sar ax, 9


mov cx, X


mov X, ax


mov ax, ANZ ;


CALL FIND_SIN ;


mov ax, bx ;


imul cx ;


mov cx, ax ;


mov ax, ANZ ;YNEW = X * SIN(ANZ) + Y * COS(ANZ)


CALL FIND_COS ;


mov ax, bx ;


imul Y ;


add ax, cx ;


sar ax, 9


mov Y, ax


pop dx


pop bx


pop ax


pop cx


ret


ENDP ROTZ


WAITVRT PROC ;Ждётвертикальнуюразвёрткумонитора.


mov dx,3dah ;3DAh - Номер порта экрана


Vrt:


in al,dx


test al,8


jnz Vrt ;Ждать пока развёртка начнётся


NoVrt:


in al,dx


test al,8


jz NoVrt ;Ждать, пока развёртка закончится


ret


ENDP WAITVRT


;Процедура рисования куба.


;Здесь последовательно вычисляются координаты двух соседних ;вершин, и проводится линия между ними.


;Всего 16 линий.


DRAWCUBE PROC


push cx


push ax


push bx


push dx


mov cx, POINTS


mov si, 0


DRC:


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X1, ax


mov Y1, bx


add si, 6


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X2, ax


mov Y2, bx


add si, 6


CALL LINE


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


/>

mov bx, Y2D


mov X1, ax


mov Y1, bx


add si, 6


CALL LINE


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X2, ax


mov Y2, bx


add si, 6


CALL LINE


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X1, ax


mov Y1, bx


add si, 6


CALL LINE


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X2, ax


mov Y2, bx


add si, 6


CALL LINE


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X1, ax


mov Y1, bx


add si, 6


CALL LINE


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X2, ax


mov Y2, bx


add si, 6


CALL LINE


mov si, 12


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X1, ax


mov Y1, bx


CALL LINE


mov si, 24


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X1, ax


mov Y1, bx


mov si, 0


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X1, ax


mov Y1, bx


mov si, 30


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X2, ax


mov Y2, bx


CALL LINE


mov si, 18


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X2, ax


mov Y2, bx


CALL LINE


mov si, 6


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X1, ax


mov Y1, bx


mov si, 36


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X2, ax


mov Y2, bx


CALL LINE


mov si, 42


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X1, ax


mov Y1, bx


mov si, 24


mov ax, CUBE[si]


mov bx, CUBE[si+2]


mov dx, CUBE[si+4]


mov X, ax


mov Y, bx


mov Z, dx


CALL ROTX


CALL ROTY


CALL ROTZ


CALL PROJECT


mov ax, X2D


mov bx, Y2D


mov X2, ax


mov Y2, bx


CALL LINE


pop dx


pop bx


pop ax


pop cx


ret


ENDP DRAWCUBE


;Алгоритм Брезенхэма для линии.


;Суть алгоритма заключается в том, что мы на каждом шаге ;увеличиваем координату Xна единицу, и прибавляем к так ;называемой «Ошибке» значение DelY, которое равно “Y2 – Y1. Если ;ошибка превышает LenX, то увеличиваем координату Y (X) на ;единицу. Данный алгоритм пригоден только в том случае, если ;X2 > X1 и расстояние по горизонтали (X2 – X1) больше расстояния ;по вертикали (Y2 – Y1). Иначе же, если X2 < X1, то к координате ;X не прибавляем единицу, а наоборот, отнимаем. Если ;вертикальное расстояние больше горизонтального, то переменные ;Xи Yменяются ролями: на каждом шаге увеличиваем Yна единицу, ;а Xувеличивается в зависимости от «Ошибки».


LINE PROC


pushcx


pushax


pushbx


push dx


mov DelX, 1 ;Приращение X = 1


mov DelY, 1 ;Приращение Y = 1


mov ax, x2


cmp ax, x1


jge X2GX1 ;если X2 < X1


neg DelX ;DelX = -1


X2GX1:


mov ax, Y2


cmp ax, Y1


jge Y2GY1 ;Если Y2 < Y1


neg DelY ;DelY = -1


Y2GY1:


mov ax, X2


sub ax, x1


jns LENXG0


neg ax


LENXG0:


mov LenX, ax


mov ax, Y2


sub ax, Y1


jns LENYG0


neg ax


LENYG0:


mov LenY, ax


mov bx, LenX


cmp ax, bx


jg LenYGLenX


mov Leng, bx


jmp C1


LenYGLenX:


mov Leng, ax


C1:


cmp ax, bx


jg LYGLX ;Если ABS(X2-X1) > ABS(Y2-Y1)


mov ax, X1


mov bx, Y1


mov dx, LenX


neg dx


inc Leng


mov cx, Leng


shl LenX, 1


shl LenY, 1


CYCLE1:


mov X2D, ax ;X = X1


mov Y2D, bx ;Y = Y1


CALL PUTPIXEL ;Рисуемточку


add ax, DelX ;X = X + DelX


add dx, LenY ;D = D + 2*(Y2-Y1)


cmp dx, 0 ;Если D > 0


jle DL01 ;


sub dx, LenX ;D = D - 2*(X2-X1)


add bx, DelY ;Y = Y + DelY


DL01:


loop CYCLE1


jmp EXITLINE


LYGLX: ;Если ABS(X2-X1) <= ABS(Y2-Y1)


mov ax, X1


mov bx, Y1


mov dx, LenY


neg dx


inc Leng


mov cx, Leng


shl LenX, 1


shl LenY, 1


CYCLE2:


mov X2D, ax ;X = X1


mov Y2D, bx ;Y = Y1


CALL PUTPIXEL ;Рисуемточку


add bx, DelY ;Y = Y + DelY


add dx, LenX ;D = D + 2*(X2-X1)


cmp dx, 0 ;Если D > 0


jle DL02


sub dx, LenY ;D = D - 2*(Y2-Y1)


add ax, DelX ;X = X + DelX


DL02:


loop CYCLE2


EXITLINE:


pop dx


pop bx


pop ax


pop cx


ret


ENDP LINE


MAIN PROC


mov ax, datas


mov ds, ax ;Инициализация сегментов данных


mov ax, 0A000h ;A000h - сегмент видеобуфера


mov es, ax


mov ah, 00h ;Установка видеорежима


mov al, 13h ;Mode = 13h (320x200x256)


int 10h


MainLoop:


mov COLOR, 15 ;Рисованиеточки


CALL DRAWCUBE ;Рисуемкуб


CALL WAITVRT ;Ждёмразвёрткуэкрана


mov COLOR, 0 ;


CALL DRAWCUBE ;Стираемкуб


in al,60h ;Читаемскан-кодклавиатуры


cmp al, 4bh ;Есликлавиша "Left"


jne DONTROTL


mov ax, DeltaY


sub ANY, ax ;уменьшаем ANY на DeltaY


jns DONTROTD


add ANY, 360


jmp DONTROTD


DONTROTL:


cmp al, 4dh ;Есликлавиша "Right"


jne DONTROTR


mov ax, DeltaY


add ANY, ax ;увеличиваем ANY на DeltaY


cmp ANY, 360


jb DONTROTD


sub ANY, 360


jmp DONTROTD


DONTROTR:


cmp al, 48h ;Есликлавиша "Up"


jne DONTROTU


mov ax, DeltaX


add ANX, ax ;увеличиваем ANX на DeltaX


cmp ANX, 360


jb DONTROTD


sub ANX, 360


jmp DONTROTD


DONTROTU:


cmp al, 50h ;Есликлавиша "Down"


jne DONTROTD ;


mov ax, DeltaX ;


sub ANX, ax ;уменьшаем ANX на DeltaX


jns DONTROTD ;


add ANX, 360 ;


DONTROTD:


cmp al, 01h ;еслине Escape


jne MainLoop ;делаемцикл


EXIT:


movah, 00h ;Установка текстового видеорежима


mov al, 02h ;Mode - 02h


int 10h


mov ax, 4C00h ;Terminate


int 21h


ENDP MAIN


CODES ENDS


END MAIN

Сохранить в соц. сетях:
Обсуждение:
comments powered by Disqus

Название реферата: Графика на языке Assembler

Слов:3105
Символов:22519
Размер:43.98 Кб.