╔═══════════════════════════════════════╗ | Coding... | ╚═══════════════════════════════════════╝ Emloyer/Alliance 2:5O8O/141.16 Dmitry Krylov subj: то Employer Вступление ---------- На сегодня создано достаточно программ, а в частности демух, с использованием 3D renderinga в реальном времени. В этой статье я попытаюсь рассказать, о том как максимально (!?) быстро обсчитать трехмерное пространство. Я буду считать, что вы знаете как представляется в прос- транстве 3D обьекты, линии, грани, точки и т.д. Расскажу лишь о том какquickly perform these calculations with examples on as- assembler. First, a few procedures on Asme: Print dots ------------ To construct a point, you need a procedure converting coordinates to screen address The INFORCOM procedure is too slow. My procedure requires 1kb to work memory. I will also note that the procedure INFORCOM eats xxx cycles, and mine 76-8O cycles. Here are 2 (two) procedures (76.8O cycles). For a procedure of 8O clock cycles in register B, C X,Y coordinates must be specified, and for 76 bars in C,L. The installer for both procedures is the same therefore, he comes first, and then, PLOT. : Install INST LD HL,#62OO: Table address LD В,4 LO1I PUSH Sun XOR A LD V,8LO2I PUSH Sun LD V,8 LOЗI LD (HL),A INC HL DJNZ LOЗI ADD A,#2O POP sun DJNZ LO2I POP BC DJNZ LO1I LD A,#4O : Segment address LD B,3: for printing LOCHI PUSH Sun LD V,8 LOSI PUSH VS,AF LD V,8 LObI LD (HL),A INC HL INC A DJNZ LObI POP AF,SUN DJNZ LOSI ADD A,8 POP sun DJNZ LOCHI LD D,H LD E,L INC DE LD BC,63 XOR A LD(HL),ALDIR 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): 7INC 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 of 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 OF 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 LINELD2EX 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),ALD 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,LINELUZ ADD A,D RLC C JP NC,LINELUZ DEC L LINELUZ EX AF,AF DJNZ LINELU1 RET LINER SR H LD L,A JR C,LINERU PUSH HL CALL GET_ADR POP DE LD B,E LD A,E INC D INC B 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 В,DLD 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,ASRL 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 Multiplication/division ----------------- You will have to multiply at every step because 3D graphics are, as you know, solid mathematics. In registers A,B there are multipliers You will receive the result in the A/HL register MUL_AB PUSH DE,HL LD C,A LD A,127 SR C JR NC,N2 SR B JR NC,N21 PUSH Sun LD A,B N.E.G. LD B,A LD A,C N.E.G. CALL MUL POP sun ADD HL,HL LD A,H JP OK N21 LD A,C N.E.G. CALL MUL ADD HL,HLXOR 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 ADDHL,DE RET This program works quite quickly because it was written not by anyone but by himself Sergey Kovinov, but it’s still possible faster. And in a faster way I will I'll tell you later. Speaking of division: According to the author of this procedure, she can only multiply, but I noticed one feature. If you multiply the coordinates natu on numbers from 128 to 255, then they will be divisible by numbers from 1 to 127 Using this, for example, you can scale capture a 3D object. SIN (x), COS (x) ---------------- Because SPECCY has no math coprocessor to implement these functions It is possible only programmatically, i.e. on Asm'e And this can be implemented in three ways. 1. expansion of functions in Fourier series. 2. use the built-in calculator. 3. calculate the table in advance. The first method will lead to a fatal accident. capabilities comparable to BASIC. Method 2 will not improve performance because the built-in calculator is also laid out puts these functions into a Fourier series.By the way, BASIC actively uses this the most calculator. The last method is preferable because You won’t have to count SIN and COS. Values are already ready for all angles. Because SIN and COS values are in the range not from O to 1 they will have to be multiplied by the amplitude you need. I give a program for calculating the table using cabbage soup built-in calculator. She is enough call exactly 1 time at the beginning of the program, and then use the resulting table. The program was pulled from 3D_LAME4k (personally I always uploaded a ready-made table, but 4k..) LD HL,#61OO: Address where DESIN1 PUSH HL: builds a table LD A,255 : faces CALL 1156O LD A,128 CALL 1156O POP HL PUSH HL LD A,L CALL 1156O RST #28: Calling the calculator DEFB #A3,4,1,5,#1F,4,#38 CALL 898O:^^^^^^^^^^^^^^ POP HL: Calculator codes. LD(HL),A INC L J.P.P,DESIN1 LD D,H LD E,L SNS DEC HL LD A,(HL) LD(DE),A INC E JR NZ,SNS RET Attention! a table will be built with 256 corners, not 36O To improve performance and convenience 256 is specially taken, not 36O. The calculation itself is carried out like this: LD H,#61: Let's say there is a table here LD L,N : N-Angle LD A,(HL): Take the value of the sine For cosine, a table is not needed because this is shifted sine by 96 degrees. Just add #6O to the angle and everything will be OK. Rotate x,y,z axes ------------------ Let me remind you of Euler's formulas for those who have forgotten around the x-axis:x'=x y'= y*cos(fi) - z*sin(fi) z'= y*sin(fi) + z*cos(fi) around the y axis: x'= x*cos(fi) + z*sin(fi) y'=y z'=-x*sin(fi) + z*cos(fi) around the z axis: x'= x*cos(fi) - y*sin(fi) y'= x*sin(fi) + y*cos(fi) z'=z fi - angle If you're not going to shortchange perspective projection, then the calculation of z' can- Feel free to discard it. Well, now everything seems to be... :)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З
Share your thoughts about the article