ZX Power
#03
31 декабря 1997 |
|
Ликбез - новый алгоритм быстрой 3D графики на SPECCY.
Быстрая 3D-графика для SPECCY, реальноли это? Возможно, нижеследующая статьяраскроет для Вас ранее неизвестные воз-можности SPECCY и окажется полезной приработе с трехмерными объектами. Статьярасчитана на более-менее подготовленныхчитателей, но может оказаться полезнойдаже начинающим пользователям... (C) 1997 BY RUFF OF AVALON/RUSH/ASM _________________________________________ Прочитал я как-то статью в "ECHO 1"про вывод 3-D объектов. Там описан тради-ционный метод, который все (кто знаeт)используют. Это, конечно, очень интересно- поворачивать точки вокруг осей X, Y и Zпо специальным формулам. Для поворотавокруг оси X: Y'=COS(N)*Y-SIN(N)*Z Z'=SIN(N)*Y+COS(N)*Z вокруг оси Y: X'=SIN(N)*Z+COS(N)*X Z'=COS(N)*Z-SIN(N)*X вокруг оси Z: X'=COS(N)*X-SIN(N)*Y Y'=SIN(N)*X+COS(N)*T (N - Угол поворота) У этого способа есть недостатки. А ес- ли точнее, один очень большой недостаток - занимает много времени! На операции ум- ножения (какими б они быстрыми не были) и вычисления COS и SIN (даже по таблице) уходит немало времени. Если учесть проблему со знаками и то, что обычно объекты вращают сразу вокруг трех осей (некоторые вообще используют калькулятор BASIC'а), то тут ничего не остается, кроме как сперва рассчитывать координаты, а потом выводить graphix. Не- которые даже подгружают отдельно рассчи- танные на BASIC'е координаты. Это же la- mer'ство! (Кроме отдельных случаев) Правда, иногда встречаются программки с REAL-TIME 3D CALCULATING'ом. Но как они тормозят!!! ...Это было вступление. Теперь ближе к делу. Я придумал новый способ вывода 3D объектов. Вот его достоинства: - Он намного (!!!) быстрее вышеописанно- го способа. Чтобы вычислить координаты одной точки, нужно приблизительно 200 тактов (при желании можно сделать еще быстрее) - 3D объект можно не только поворачи- вать, но и деформировать (растягивать, сжимать и т.д.) Короче, скоро выйдет наша (AVA- LON'oвская) демка (а может и не выйдет (а, скорее всего, уже вышла)), в которой будет 3D эффектик с ROTATING'ом человеч- ка. Человечек состоит из 175 точек (если точнее, то из 175 векторов, правда, на человечке это не очень заметно, так как руки и ноги у него сравнительно ровные). Если б он состоял из линий, то эффект не влез бы в одно прерывание (точки ставить быстрее). Это, конечно же, мой REALTIME 3-D ROTATOR. Я не могу полностью привести здесь листинг этого эффекта, поэтому привожу все по кускам, которые вы сами соберете и дополните кому что надо. Вот первый кусок - сама процедура печати 3D объекта: PRINT LD (SAV+1),SP ; сохраняю SP LD SP,... ;... - Это начальный адрес координат то- ;чек 3D объекта. На одну точку 4 байта (3 ;байта - координаты X,Y,Z; 1 байт старший ;байт таблицы осей (про нее чуть попозже) ;он, кстати, дальше обозначается меткой ;TABAX). EXX LD HL,BUFER ;специальный буфер для ;очистки экрана (смотри ;ниже) LD B,175 ;кол-во точек LP1 ;дальше идет процедура печати одной точки EXX POP BC ;В BC - Y,X POP HL ;В HL - старш. байт таблицы ;осей, Z LDA,(HL) LDE,L LDL,B INC H ADD A,(HL) INC H LDL,C ADD A,(HL) ADD A,HX LDC,A INC H LDA,(HL) LDL,E INC H ADD A,(HL) LDL,B INC H ADD A,(HL) ADD A,LX LDL,A ;теперь координаты точек (X и Y на экра- ;не) вычислены и помещены в регистры C и ;L. дальше идет процедура печати точки по ;координатам в этих регистрах (69 тактов) ;для нее нужна специальная таблица, так ;что, кто такой процедурки не знает, мо- ;жет использовать свою. PLOT LDH,TABLE_P LDD,(HL) INC H LDA,(HL) INC H LDL,C ADD A,(HL) INC H LDE,A LDA,(DE) OR(HL) LD(DE),A ;ну, вот. Точку напечатали, теперь можно ;(если хотите) в специальный буфер помес- ;тить адрес в экране этой точки (для то- ;го, чтобы потом быстро очистить экран ;методом POP HL: LD (HL),0: POP HL: LD ;(HL),0: POP HL...) LDA,D EXX DEC HL ;адрес буфер растет вверх ;ногами (для удобства) LD(HL),A EXX LDA,E EXX DEC HL LD(HL),A DJNZ LP1 ;следующая точка SAV LDSP,0 RET Как-то непривычно смотрятся команды LD SP,0: RET. Зато экономит память. Вы, надеюсь, догадались, что эта про- цедура сама по себе ничего не даст. Еще нужно написать процедуру очистки экрана (look up) и процедуру создания таблиц осей. Здесь я их не привожу по причине большого объема (длины, массы), который они занимают. Очистку экрана я, конечно, мог бы написать, только насчет этого у каждого свои принципы (кто бы написал installer, кто поместил бы все в dup'ы, и т.д., и т.п.), короче, сами напишите. А насчет создания таблиц с координата- ми осей, то лучше я сперва расскажу прин- цип. Y рисунок 1 ________________ /!^ ! / !* ! / !>48 .А ! / !* ! ! !* ! ! !* ! ! !* ! ! !* ! ! !* ! ! !* ! ! !* 32 ! ! !*______^________! ! 30/****************>/ X ! ^/* / ! /* / !/<________________/ Z Посмотрите на рисунок 1. Как вы догадались, (а может и нет) это куб. Представьте, что внутри него нахо- дится 3D объект. Каждая точка этого об- ъекта имеет три координаты по осям Y, X и Z. Здесь оси не бесконечные. Например, в моем эффекте они состоят из 64 точек (ко- ординат). То есть, точку можно задать тремя числами от 0 до 64. А теперь самое интересное. Возьмем, например, точку а с координа- тами Y=48, X=32, Z=30. Как узнать ее ко- ординаты в экране, если учесть, что ось Z повернута так, как на рисунке? На каждой оси помечена точка с соот- ветствующей координатой. Главное, нужно узнать координаты Y и X этих точек и центра (точка пересечения осей) на экра- не. Допустим, мы их знаем: координаты от левого верхнего угла Y, X НА ОСИ Y-70,46 НА ОСИ X-172,140 НА ОСИ Z-180,40 ЦЕНТР -172,46 Чтобы вычислить координаты в экране точки "A" я придумал (может их и до меня кто-то придумал) две простые формулы: Обозначим координаты в экране (то же, что и выше, только вместо цифр буквы): НА ОСИ Y-Yy,Xy НА ОСИ X-Yx,Xx НА ОСИ Z-Yz,Xz ЦЕНТР -Yc,Xc Итак, формулы: Y= (Yy-Yc)+(Yx-Yc)+(Yz-Yc)+Yc X= (Xy-Xc)+(Xx-Xc)+(Xz-Xc)+Xc Подставляем значения: Y =(70-172)+(172-172)+(180-172)+172=78 X =(46-46)+(140-46)+(40-46)+46=134 Координаты точки "A" в экране 78,134. Вышеприведенная программка печати 3D объекта именно это и делала - подсчитыва- ла сумму (правда, немного по другому (lo- ok down)), печатала точку и запоминала адрес в экране. А что же должна делать программа рассчитывания координат осей? Конечно, рассчитывать координаты осей. Но давайте сперва разберемся с форму- лами. Вы, наверное, уже давно пораскрыва- ли скобки, посокращали лишние координаты центра и уверены, что я это не заметил. Так можно сделать, но в этом мало смысла. Вот в чем дело: тут от каждой координаты точки оси отнимается координата центра. Вернемся к координатам точек осей. Как вы догадались, придется рассчитывать коорди- наты всех 64 точек осей. А эти координаты мы будем рассчитывать не так, как они есть в экране, а с центром с координатами в экране 0,0. А потом останется только прибавить координаты центра. Сама процедура рассчитывания коорди- нат осей занимает не много времени. У ме- ня, например, (если процедуру поставить в начале прерывания) кадровая развертка не успеет дойти даже до первых строк экрана, то есть, полностью находится на бордюре. Но для координат осей нужен буфер. Посчитаем его длину: одна ось - 64 точки, то есть 128 координат. всего осей 3, значит, всего координат 128*3=384 ко- ординаты. Одна координата - один байт, 384 координаты - 384 байта. Но ради ускорения вывода 3D спрайта, лучше координаты одной оси хранить в 512 байтах (координаты Y-256 байт, координаты X-256 байт. Из 256-ти байт используются только 64). Всего буфер выйдет 512*3=1536 (байт). Тоже не очень много. Ну, а теперь сама программа. Принцип работы будет объясняться по ходу дела. Как уже писалось выше, мы будем рассчиты- вать координаты осей так, если бы центр имел координаты 0;0. А потом уже, при вы- воде, прибавим координаты центра. Это сэ- кономит время. Кстати, координаты центра в моей программке будут храниться в ре- гистровой паре IX, так что ее содержимое не меняйте, или сохраняйте, а потом восстанавливайте (моя программа рассчиты- вания координат осей связана с программой печати 3D спрайта парой IX и содержимым буфера координат осей). AX ; Процедура рассчитывания координат ;осей. Координаты (в экране) крайних ;точек осей (на рис.2 эти точки обоз- ;начены буквами Ky, Kz И Kx) задаются ;в регистрах HL', BC, HL. координаты ;центра в DE. кстати, для тех, кто не ;хочет, чтобы 3D объект сжимался и ;растягивался, то может для поворота ;этих 4-х точек использовать формулы ;3-D вращения (look up). TABAX EQU 250 (64000=250*256) ;Старший байт буфера, в который рас- ;считываются координаты осей. Адрес ;буфера кратный 256 (!!!) LDA,E SUB 32 LDE,A LDA,L SUB 32 LDL,A LDA,C SUB 32 LDC,A EXX LDA,L SUB 32 LDL,A EXX LD HX,D ;Имеется в виду ст.байт IX. LD LX,E ;Младший байт IX. ;(недокументированные ко- ;манды процессора Z-80. 6 ;тактов) LDA,L PUSH AF LDA,C PUSH AF EXX LDA,L PUSH AF EXX LDA,H PUSH AF LDA,B PUSH AF EXX LDA,TABAX LD(VAR),A LDA,H LDB,HX CALL K64 POP AF LDB,HX CALL K64 POP AF LDB,HX CALL K64 POP AF LDB,LX CALL K64 POP AF LDB,LX CALL K64 POP AF LDB,LX CALL K64 RET K64 ;К64 - самая основная процедура. Вызы- ;вается программой AX 6 раз. Просчитывает ;промежуточные 64 координаты.Координата - ;цель в регистре A,а источник в B. Источ- ;ник у нас центр, значит в B всегда коор- ;дината центра (Y или X). А вообще здесь ;она нужна только для получения разницы ;(A-B или B-A) и для определения направ- ;ления, (положительное или отрицательное) ;так как координаты центра у нас 0;0 ;(look up). ; Адрес таблицы в 64 байта (куда помес- ;тить все числа) кратный 256. Его старший ;байт задается по адресу VAR. Этот байт, ;кстати, программка в конце сама увеличи- ;вает на 1. ; Так, я рассчитывал сперва координаты ;Y, вызывая эту процедуру, а потом X-ы, ;вызывая ее еще раз. Осей у нас три, ;поэтому процедура K64 вызывается 6 раз. CPB JPC,LOOP1 SUB B LDL,A LDH,0 ADD HL,HL ADD HL,HL EXDE,HL LDHL,0 LOOP2 EXX LDA,(VAR) LDH,A INC A LD(VAR),A LDL,0 EXX DUP 64 ;Или какой-нибудь цикл, типа ;LD B,64:...: DJNZ ... LDA,H ADD HL,DE EXX LD(HL),A INC L EXX EDUP RET LOOP1 LDC,A LDA,B SUB C LDL,A LDH,0 ADD HL,HL ADD HL,HL EXDE,HL LDHL,0 LOOP3 EXX LDA,(VAR) LDH,A INC A LD(VAR),A LDL,0 EXX DUP 64 SBC HL,DE LDA,H EXX LD(HL),A INC L EXX EDUP RET CPB JPC,LOOP4 SUB B LDL,A LDH,0 ADD HL,HL ADD HL,HL EXDE,HL LDH,B LDL,0 JPLOOP2 LOOP4 LDC,A LDA,B SUB C LDL,A LDH,0 ADD HL,HL ADD HL,HL EXDE,HL ADD A,C LDH,A LDL,0 JPLOOP3 VAR NOP NOP Ну, вот и все. Для тех, кто не вник в эти все дела или не хочет дополнять (из- менять, совершенствовать) мою 3D идею, a хочет написать такой эффект, как мой: 1. Не забудьте про формат хранения ко- ординат 3D oбъекта. Не забудьте про буфе- ры (координат осей, delete buffer). 2. Координаты крайних точек осей (Kz, Kx, Ky и центр) считайте по формулам вра- щения или по синусоидной табличке (у ме- ня, кстати, есть крутой способ генериро- вания син. табличек. таблички рассчитыва- ются гораздо быстрей и удобнее, чем на бейсике и компрессируются где-то в 20 раз. моя табличка в килобайт заняла меньше 50 байт. И декомпрессировать ее можно по ходу дела. Займет это около 100-200 тактов в прерывании. В ближайшее время я про это все тоже что-нибудь напи- шу). 3. Алгоритм программы вывода должен быть где-то таким: EI HALT DI CALL PRINT Заносим в hl', bc, hl, de следующие значения из син.таблицы (нужно еще учесть, чтобы они не были слишком больши- ми, а то спрайт может вылезти за экран и залезть с другой стороны (рис.3)). CALL AX Очистка экрана с использованием delete buffer'а (look up). Желательно приспосо- бить для работы с двумя экранами (у кого 128кб, конечно). JP BEGIN THAT WERE ALL I WANTED TO TELL U. I WISH U SUCCESS. SO LONG ! . . . Прочитав эту статью нашего кодера RUFF'а, я (VIATOR), решил внести некото- рые коррективы в текст, для прояснения определенных нюансов... Во первых, должен сказать, что тут описан по-настоящему выдающийся способ работы с 3D объектами в реальном времени. Для тех, кто не понимает данного выраже- ния, скажу - REALTIME-программы и эффекты - это те, которые рассчитываются по ходу работы программы, а не просчитываются за- ранее. Часто под этим выражением ошибочно подразумевают, что программа работает за одно прерывание, что не имеет ничего об- щего с REALTIME и называется ONE INT, или ONE FRAME (одно прерывание/один кадр). Преимущество программ в реальном времени заключается в экономном использовании па- мяти и гибкости структуры, например можно заставить двигаться трехмерный объект не по заранее фиксированной траектории, а по траектории, задаваемой с клавиатуры. Описанная здесь процедура примеча- тельна тем, что работает очень быстро. Возьмем для примера вторую часть из всем известной словацкой демки "ECHOLOGY", векторные объекты там также вращаются в реальном времени. Понажимав цифровые кла- виши, можно убрать линии и оставить одни вектора. Проследите скорость работы эф- фектов. На моем Pentagon'е в одно преры- вание укладываются фигуры с количеством векторов, не превышающим 28, фигуры с ко- личеством векторов 29 и больше уже тормо- зят. Данный же способ позволяет вращать по всем трем осям + приближать/удалять/ рас- тягивать и т.д. аж 175 векторов и больше! Основная суть данного метода состоит в том, что вращается не каждая точка в от- дельности, а сразу целая плоскость. Этот метод может пригодиться не только для создания крутых векторных эффектов, но и для написания новых игрушек. А как rulez'но будут смотреться старые вектор- ные игры, переделанные с учетом последне- го слова техники?! Представьте, например, ELITE, работающую в 2-3 раза быстрее или плавнее! Так что дерзайте, GOOD LUCK! Коментарии (C) BY VIATOR/AVALON/RUSH/ASM
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября