Vykreslí textúru a otáčajúci sa štvorec
Delphi & Pascal (česká wiki)
Kategória: KMP (Klub mladých programátorov)
Autor: Ján Benkovič
web: www.tbteacher.host.sk
Program: Texure_p.pas
Súbor exe: Texure_p.exe
Autor: Ján Benkovič
web: www.tbteacher.host.sk
Program: Texure_p.pas
Súbor exe: Texure_p.exe
Vykreslí textúru a otáčajúci sa štvorec.
{ TEXURE_P.PAS } { Vykresli texturu a otacajuci sa stvorec. } { } { Datum:07.11.2000 http://www.trsek.com } {$r-,g+} program texure_poly; uses crt; Type TE = Record X : Integer; px, py : Byte; End; Table = Array[0..199] of TE; PTable = ^Table; Var Left, Right : Table; stab:array[0..255] of integer; polyz:array[0..7] of integer; pind:array[0..7] of byte; page,virscr:pointer; pageseg,virseg:word; Frame, St, Et : Longint; Time : Longint Absolute $0000:$046c; pxVal, pxStep : Integer; pyVal, pyStep : Integer; Count, res : Integer; O1 : Word; b:byte; Const Bitmap :Array[0..16*16-1] of Byte = ( 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,5,5,5,5,5,5,5,5,5,5,5,5,5,5,2, 2,5,5,1,1,1,1,1,1,1,1,1,1,5,5,2,2,5,1,5,1,1,1,1,1,1,1,1,5,1,5,2, 2,5,1,1,5,1,1,1,1,1,1,5,1,1,5,2,2,5,1,1,1,5,1,1,1,1,5,1,1,1,5,2, 2,5,1,1,1,1,5,1,1,5,1,1,1,1,5,2,2,5,1,1,1,1,1,5,5,1,1,1,1,1,5,2, 2,5,1,1,1,1,1,5,5,1,1,1,1,1,5,2,2,5,1,1,1,1,5,1,1,5,1,1,1,1,5,2, 2,5,1,1,1,5,1,1,1,1,5,1,1,1,5,2,2,5,1,1,5,1,1,1,1,1,1,5,1,1,5,2, 2,5,1,5,1,1,1,1,1,1,1,1,5,1,5,2,2,5,5,1,1,1,1,1,1,1,1,1,1,5,5,2, 2,5,5,5,5,5,5,5,5,5,5,5,5,5,5,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2); pointnum=11; planenum=7; border=false; vidseg:word=$a000; divd=128; dist=200; points:array[0..pointnum,0..2] of integer=( (-20,-20, 30),( 20,-20, 30),( 40,-40, 0),( 20,-20,-30), (-20,-20,-30),(-40,-40, 0),(-20, 20, 30),( 20, 20, 30), ( 40, 40, 0),( 20, 20,-30),(-20, 20,-30),(-40, 40, 0)); planes:array[0..planenum,0..3] of byte=( (1,2,8,7),(9,8,2,3),(10,4,5,11),(6,11,5,0), (0,1,2,5),(5,2,3,4),(6,7,8,11),(11,8,9,10)); { -------------------------------------------------------------------------- } Procedure TextureHLine(X1, X2, px1, py1, px2, py2, Y : Integer; Dim : Word); Begin pxStep := ((px2-px1) Shl 8) Div (x2-x1+1); pyStep := ((py2-py1) Shl 8) Div (x2-x1+1); asm mov bx, px1; shl bx, 8; mov pxval,bx; { pxVal := px1 Shl 8;} mov bx, py1; shl bx, 8; mov pyval,bx; { pyVal := py1 Shl 8;} mov ax,y; shl ax,6; mov di,ax; shl ax,2 add di,ax; add di,x1; mov o1, di; End; For Count := X1 to X2 do Begin b:= Bitmap[Hi(pxVal)+(Hi(pyVal)) Shl 4]; Asm mov ax,virseg; mov es,ax; mov ax,o1; mov di,ax; mov al, b; mov es:[di],al; mov ax, pxval; add ax, pxstep; mov pxval, ax; mov ax, pyval; add ax, pystep; mov pyval, ax; inc o1; end; End; End; Procedure Swap(Var A, B : Integer); Var t : Integer; Begin t := a; a := b; b := t; End; Procedure Texture4Poly(X1, Y1, X2, Y2, X3, Y3, X4, Y4 : Integer; Dim : Byte); Var yMin, yMax : Integer; xStart, xEnd : Integer; yStart, yEnd : Integer; pxStart, pxEnd : Integer; pyStart,pyEnd : Integer; XVal, XStep : Longint; pxVal, pxStep : Integer; pyVal, pyStep : Integer; Count : Integer; Side : PTable; Begin yMin := Y1; yMax := Y1; If Y2 > yMax Then yMax := Y2; If Y3 > yMax Then yMax := Y3; If Y4 > yMax Then yMax := Y4; If Y2 < yMin Then yMin := Y2; If Y3 < yMin Then yMin := Y3; If Y4 < yMin Then yMin := Y4; xStart := X1; yStart := Y1; xEnd := X2; yEnd := Y2; pxStart := 0; pyStart := 0; pxEnd := Dim-1; pyEnd := 0; If yStart > yEnd Then Begin Swap(xStart, xEnd); Swap(yStart, yEnd); Swap(pxStart, pxEnd); Side := @Left; End Else Side := @Right; XVal := Longint(xStart) Shl 8; XStep := (Longint(xEnd-xStart) Shl 8) Div (yEnd-yStart+1); pxVal := pxStart Shl 8; pxStep := ((pxEnd-pxStart) Shl 8) Div (yEnd-yStart+1); For Count := yStart to yEnd do Begin Side^[Count].x := XVal Shr 8; Side^[Count].px := pxVal Shr 8; Side^[Count].py := pyStart; XVal := XVal + XStep; pxVal := pxVal + pxStep; End; xStart := X2; yStart := Y2; xEnd := X3; yEnd := Y3; pxStart := Dim-1; pyStart := 0; pxEnd := Dim-1; pyEnd := Dim-1; If yStart > yEnd Then Begin Swap(xStart, xEnd); Swap(yStart, yEnd); Swap(pyStart, pyEnd); Side := @Left; End Else Side := @Right; XVal := Longint(xStart) Shl 8; XStep := (Longint(xEnd-xStart) Shl 8) Div (yEnd-yStart+1); pyVal := pyStart Shl 8; pyStep := ((pyEnd-pyStart) Shl 8) Div (yEnd-yStart+1); For Count := yStart to yEnd do Begin Side^[Count].x := XVal Shr 8; Side^[Count].py := pyVal Shr 8; Side^[Count].px := pxStart; XVal := XVal + XStep; pyVal := pyVal + pyStep; End; xStart := X3; yStart := Y3; xEnd := X4; yEnd := Y4; pxStart := Dim-1; pyStart := Dim-1; pxEnd := 0; pyEnd := Dim-1; If yStart > yEnd Then Begin Swap(xStart, xEnd); Swap(yStart, yEnd); Swap(pxStart, pxEnd); Side := @Left; End Else Side := @Right; XVal := Longint(xStart) Shl 8; XStep := (Longint(xEnd-xStart) Shl 8) Div (yEnd-yStart+1); pxVal := pxStart Shl 8; pxStep := ((pxEnd-pxStart) Shl 8) Div (yEnd-yStart+1); For Count := yStart to yEnd do Begin Side^[Count].x := XVal Shr 8; Side^[Count].px := pxVal Shr 8; Side^[Count].py := pyStart; XVal := XVal + XStep; pxVal := pxVal + pxStep; End; xStart := X4; yStart := Y4;xEnd := X1; yEnd := Y1; pxStart := 0; pyStart := Dim-1; pxEnd := 0; pyEnd := 0; If yStart > yEnd Then Begin Swap(xStart, xEnd); Swap(yStart, yEnd); Swap(pyStart, pyEnd); Side := @Left; End Else Side := @Right; XVal := Longint(xStart) Shl 8; XStep := (Longint(xEnd-xStart) Shl 8) Div (yEnd-yStart+1); pyVal := pyStart Shl 8; pyStep := ((pyEnd-pyStart) Shl 8) Div (yEnd-yStart+1); For Count := yStart to yEnd do Begin Side^[Count].x := XVal Shr 8; Side^[Count].py := pyVal Shr 8; Side^[Count].px := pxStart; XVal := XVal + XStep; pyVal := pyVal + pyStep; End; For Count := yMin to yMax do If Left[Count].x < Right[Count].x Then TextureHLine(Left[Count].x, Right[Count].x, Left[Count].px, Left[Count].py, Right[Count].px, Right[Count].py, Count, Dim) Else TextureHLine(Right[Count].x, Left[Count].x, Right[Count].px, Right[Count].py, Left[Count].px, Left[Count].py, Count, Dim); End; {Asi sa zastrelim..........} procedure setpal(c,r,g,b:byte); assembler; asm; mov dx,3c8h; mov al,[c]; out dx,al; inc dx; mov al,[r]; out dx,al mov al,[g]; out dx,al; mov al,[b]; out dx,al; end; procedure flip(src,dst:word); assembler; asm push ds; mov es,[dst]; mov ds,[src]; xor si,si; xor di,di; mov cx,320*200/2 rep movsw; pop ds; end; procedure quicksort(lo,hi:integer); procedure sort(l,r:integer); var i,j,x,y:integer; begin i:=l; j:=r; x:=polyz[(l+r) div 2]; repeat while polyz[i]<x do inc(i); while x<polyz[j] do dec(j); if i<=j then begin y:=polyz[i]; polyz[i]:=polyz[j]; polyz[j]:=y; y:=pind[i]; pind[i]:=pind[j]; pind[j]:=y; inc(i); dec(j); end; until i>j; if l<j then sort(l,j); if i<r then sort(i,r); end; begin sort(lo,hi); end; function sinus(i:byte):integer; begin sinus:=stab[i]; end; function cosinus(i:byte):integer; begin cosinus:=stab[(i+192) mod 255]; end; procedure rotate_cube; const xst=2; yst=3; zst=-4; var xp,yp,z:array[0..11] of integer; x,y,i,j,k:integer; n,Key,phix,phiy,phiz:byte; begin phix:=0; phiy:=0; phiz:=40; fillchar(xp,sizeof(xp),0); fillchar(yp,sizeof(yp),0); Frame := 0; St := Time; repeat flip(pageseg,virseg); for n:=0 to pointnum do begin i:=(cosinus(phiy)*points[n,0]-sinus(phiy)*points[n,2]) div divd; j:=(cosinus(phiz)*points[n,1]-sinus(phiz)*i) div divd; k:=(cosinus(phiy)*points[n,2]+sinus(phiy)*points[n,0]) div divd; x:=(cosinus(phiz)*i+sinus(phiz)*points[n,1]) div divd; y:=(cosinus(phix)*j+sinus(phix)*k) div divd; z[n]:=(cosinus(phix)*k-sinus(phix)*j) div divd+cosinus(phix) div 3; xp[n]:=160+sinus(phix) div 2+(-x*dist) div (z[n]-dist); yp[n]:=100+(-y*dist) div (z[n]-dist); end; for n:=0 to planenum do begin polyz[n]:=(z[planes[n,0]]+z[planes[n,2]]) div 2; pind[n]:=n; end; quicksort(0,planenum); for n:=0 to planenum do texture4poly(xp[planes[pind[n],0]],yp[planes[pind[n],0]], xp[planes[pind[n],1]],yp[planes[pind[n],1]], xp[planes[pind[n],2]],yp[planes[pind[n],2]], xp[planes[pind[n],3]],yp[planes[pind[n],3]],16); inc(phix,xst); inc(phiy,yst); inc(phiz,zst); flip(virseg,vidseg); inc(frame); delay(15); until keypressed; Et:=time; end; var i,j:word; {$Q-} begin asm mov ax,13h; int 10h; end; getmem(virscr,64000); virseg:=seg(virscr^); getmem(page,64000); pageseg:=seg(page^); for i:=0 to 255 do stab[i]:=round(sin(i*pi/128)*divd); for i:=1 to 104 do setpal(150+i,0,20+i div 4,30+i div 5); for i:=0 to 319 do for j:=0 to 199 do mem[pageseg:j*320+i]:=151+(i*i+j*j) mod 104; rotate_cube; freemem(page,64000); freemem(virscr,64000); textmode(lastmode); Writeln(Frame*18.2/(Et-St):5:2, ' fps'); end.