|
╔═══════════════════════════════════════╗ | Coding... | ╚═══════════════════════════════════════╝ Emloyer/Alliance 2:5O8O/141.16 Dmitry Krylov subj: то Employer Вступление ---------- На сегодня создано достаточно программ, а в частности демух, с использованием 3D renderinga в реальном времени. В этой статье я попытаюсь рассказать, о том как максимально (!?) быстро обсчитать трехмерное пространство. Я буду считать, что вы знаете как представляется в прос- транстве 3D обьекты, линии, грани, точки и т.д. Расскажу лишь о том как быстро выполнить эти расчеты с примерами на ас- семблере. Для начала несколько процедур на Asme: Печать точек ------------ Для построения точки нужна процедура преобразования координат в адресс экрана Процедура ИНФОРКОМ'а слишком медленна. Для работы моей процедуры требуется 1кб памяти. Еще замечу что процедура ИНФОРКОМ'а сьедает xxx тактов, а моя 76-8O тактов. Здесь представлены 2(две) процедуры (76,8O тактов). Для процедуры в 8O тактов в регистре В,C должны быть заданы X,Y координаты, а для 76 тактов в C,L. Инсталлятор у обеих процедур одинаковый поэтому, сначала идет он, а потом, PLOT. : Install INST LD HL,#62OO: Адрес таблицы LD В,4 LO1I PUSH ВС XOR A LD В,8 LO2I PUSH ВС LD В,8 LOЗI LD (HL),A INC HL DJNZ LOЗI ADD A,#2O POP ВС DJNZ LO2I POP ВС DJNZ LO1I LD A,#4O : Адресс сегмента LD В,3 : для печати LOЧI PUSH ВС LD В,8 LOSI PUSH ВС,AF LD В,8 LOбI LD (HL),A INC HL INC A DJNZ LOбI POP AF,ВС DJNZ LOSI ADD A,8 POP ВС DJNZ LOЧI LD D,H LD E,L INC DE LD ВС,63 XOR A LD (HL),A LDIR INC HL LD В,#2O LO7I PUSH ВС LD В,8 LO8I LD (HL),A INC HL DJNZ LO8I INC A POP ВС DJNZ LO7I LD A,#8O LD В,#2O LO9I PUSH ВС,AF LD В,8 LOAI LD (HL),A SRL A INC HL DJNZ LOAI POP AF,ВС DJNZ LO9I RET : FAST PLOT 8O takts LD ВС,#OOOO CALL PLOT RET PLOT LD H,#62: 7 LD L,В: 4 LD A,(HL): 7 INC H: 4 LD D,(HL): 7 INC H: 4 LD L,C: 4 ADD A,(HL): 7 LD E,A: 4 INC H: 4 LD A,(DE): 7 OR (HL): 7 LD (DE),A: 7 RET : FAST PLOT 76 takts LD C,O:OR (HL): 7 LD (DE),A: 7 RET Построение линии ---------------- bc x1y1 de x2y2 LINE LD A,H SUB D JR NC,LINE1 EX DE,HL NEG LINE1 LD H,A LD A,L SUB E JR NC,LINER NEG СР H LD L,A JR C,LINELU PUSH HL CALL GET_ADR POP DE LD В,E LD A,E INC D INC В EX AF,AF LINELD1 LD A,(HL) OR C LD (HL),A RLC C JP NC,LINELD2 DEC L LINELD2 EX AF,AF SUB D JR NC,LINELDЧ ADD A,E EX AF,AF LD A,H DEC H AND 7 JP NZ,LINELDЗ LD A,L SUB #2O LD L,A JR C,LINELDЗ LD A,H ADD A,8 LD H,A LINELDЗ DJNZ LINELD1 RET LINELDЧ EX AF,AF DJNZ LINELD1 RET LINELU PUSH HL CALL GET_ADR POP DE LD В,D LD A,D INC E INC В EX AF,AF LINELU1 LD A,(HL) OR C LD (HL),A LD A,H DEC H AND 7 JP NZ,LINELU2 LD A,L SUB #2O LD L,A JR C,LINELU2 LD A,H ADD A,8 LD H,A LINELU2 EX AF,AF SUB E JR NC,LINELUЗ ADD A,D RLC C JP NC,LINELUЗ DEC L LINELUЗ EX AF,AF DJNZ LINELU1 RET LINER СР H LD L,A JR C,LINERU PUSH HL CALL GET_ADR POP DE LD В,E LD A,E INC D INC В EX AF,AF LINERD1 LD A,(HL) OR C LD (HL),A RRC C JP NC,LINERD2 INC L LINERD2 EX AF,AF SUB D JR NC,LINERDЧ ADD A,E EX AF,AF LD A,H DEC H AND 7 JP NZ,LINERDЗ LD A,L SUB #2O LD L,A JR C,LINERDЗ LD A,H ADD A,8 LD H,A LINERDЗ DJNZ LINERD1 RET LINERDЧ EX AF,AF DJNZ LINERD1 RET LINERU PUSH HL CALL GET_ADR POP DE LD В,D LD A,D INC E INC В EX AF,AF LINERU1 LD A,(HL) OR C LD (HL),A LD A,H DEC H AND 7 JP NZ,LINERU2 LD A,L SUB #2O LD L,A JR C,LINERU2 LD A,H ADD A,8 LD H,A LINERU2 EX AF,AF SUB E JR NC,LINERUЗ ADD A,D RRC C JP NC,LINERUЗ INC L LINERUЗ EX AF,AF DJNZ LINERU1 RET GET_ADR LD A,#BF SUB D LD D,A SRL A SCF RRA SRL A XOR D AND #F8 XOR D LD H,A LD A,E RLCA RLCA RLCA XOR D AND #C7 XOR D RLCA RLCA LD L,A LD A,E AND 7 INC A LD C,В LD В,A LD A,1 GETADR1 RRCA DJNZ GETADR1 LD В,C LD C,A RET Умножение/деление ----------------- Умножать прийдется на каждом шагу т.к. 3D графика это, как известно, сплошная матемтика. В регистрах A,В множители Результат получите в регистре A/HL MUL_АВ PUSH DE,HL LD C,A LD A,127 СР C JR NC,N2 СР В JR NC,N21 PUSH ВС LD A,В NEG LD В,A LD A,C NEG CALL MUL POP ВС ADD HL,HL LD A,H JP OK N21 LD A,C NEG CALL MUL ADD HL,HL XOR A SUB L LD L,A LD A,O SBC A,H LD H,A JP OK N2 СР В JR NC,N22 PUSH ВС LD A,В NEG LD В,A LD A,C CALL MUL POP ВС ADD HL,HL XOR A SUB L LD L,A LD A,O SBC A,H LD H,A JP OK N22 LD A,C CALL MUL ADD HL,HL LD A,H OK POP HL,DE RET MUL LD D,O LD E,В LD HL,O RLA JP NC,М1 ADD HL,DE М1 ADD HL,HL RLA JP NC,М2 ADD HL,DE М2 ADD HL,HL RLA JP NC,М3 ADD HL,DE М3 ADD HL,HL RLA JP NC,М4 ADD HL,DE М4 ADD HL,HL RLA JP NC,М5 ADD HL,DE М5 ADD HL,HL RLA JP NC,М6 ADD HL,DE М6 ADD HL,HL RLA JP NC,М7 ADD HL,DE М7 ADD HL,HL RLA RET NC ADD HL,DE RET Эта программка работает давольно быстро т.к. написал ее не кто-нибудь а сам Сергей Ковинов, но все-же можно еще быстрее. А более быстром способе я рас- скажу позже. Кстати о делении: Как утверждает автор этой процедуры она способна только умножать, но я заметил одну особенность. Если умножать коорди- нату на числа от 128 до 255, то они будут делится на числа от 1 до 127 При помощи этого например можно масшта- бировать 3D обьект. SIN (x), COS (x) ---------------- Т.к. SPECCY не имеет математического сопроцессора эти функции реализовать можно только програмно т.е. на Asm'e А реализовать это можно тремя способами. 1. разложение функций в ряд Фурье. 2. использовать встроенный калькулятор. 3. заранее расчитать таблицу. 1ый способ приведет к фатальному тор- можению сравнимому с BASIC'ом. 2ой способ быстродействия не прибавит т.к. встроенный калькулятор тоже раскла- дывает эти функции в ряд Фурье. Кстати BASIC активно использует этот самый калькулятор. Последний метод предпочтительнее т.к. считать SIN и COS вам и не прийдется. На все углы уже готовы значения. Т.к. значения SIN и COS лежат в диапозо- не от O до 1 их прийдется умножить на необходимую вам амплитуду. Даю прогу для расчета таблицы при помо- щи встроенного калькулятора. Ее доста- точно вызвать 1 раз в начале программы,а потом пользоваться полученной таблицей. Программа вытащина из 3D_LAME4k (лично я всегда грузил готовую таблицу,но 4к..) LD HL,#61OO: Адресс где по- DESIN1 PUSH HL : строится таб- LD A,255 : лица CALL 1156O LD A,128 CALL 1156O POP HL PUSH HL LD A,L CALL 1156O RST #28: Вызов калькулятора DEFB #A3,4,1,5,#1F,4,#38 CALL 898O:^^^^^^^^^^^^^^ POP HL : Коды калькулятора. LD (HL),A INC L JP Р,DESIN1 LD D,H LD E,L SNS DEC HL LD A,(HL) LD (DE),A INC E JR NZ,SNS RET Внимание! построится таблица в 256 углов, а не 36O Для повышения быстродействия и для удоб- ства специально берется 256, не 36O. Сам расчет ведется так: LD H,#61: Допустим здесь таблица LD L,N : N-Угол LD A,(HL): Берем значение синуса Для косинуса таблица не нужна т.к. это сдвинутый синус на 96 градусов. Просто прибавте к углу #6O и все будет OK. Поворот осей x,y,z ------------------ Напомню формулы Эйлера для тех кто забыл вокруг оси x: x'= x y'= y*cos(fi) - z*sin(fi) z'= y*sin(fi) + z*cos(fi) вокруг оси y: x'= x*cos(fi) + z*sin(fi) y'= y z'=-x*sin(fi) + z*cos(fi) вокруг оси z: x'= x*cos(fi) - y*sin(fi) y'= x*sin(fi) + y*cos(fi) z'= z fi - угол Если вы не собираетесь обсчитывать перспективную проекцию, то расчет z' мо- жете смело отбрасывать. Ну теперь вроде все... :)
Other articles:
|
|
|
|
|
|
|
|
Similar articles:
В этот день... 23 November