0,0 → 1,610 |
;TEX_X = 512 |
;TEX_Y = 512 |
;ROUND equ 8 |
;SIZE_X = 512 |
;SIZE_Y = 512 |
;TEX_SHIFT = 9 |
CATMULL_SHIFT equ 8 |
|
;------------------------------------------------------------------------ |
;- Procedure drawing textured triangle using Catmull Z-buffer algorithm - |
;------------------------------------------------------------------------ |
tex_triangle_z: |
;----------in - eax - x1 shl 16 + y1 |
;-------------- ebx - x2 shl 16 + y2 |
;---------------ecx - x3 shl 16 + y3 |
;---------------edx - pointer to Z-buffer |
;---------------esi - pointer to texture buffer |
;---------------edi - pointer to screen buffer |
;-------------stack - texture coordinates |
;------------------ - z coordinates |
.tex_x1 equ ebp+4 |
.tex_y1 equ ebp+6 |
.tex_x2 equ ebp+8 |
.tex_y2 equ ebp+10 |
.tex_x3 equ ebp+12 |
.tex_y3 equ ebp+14 |
.z1 equ word[ebp+16] |
.z2 equ word[ebp+18] |
.z3 equ word[ebp+20] |
|
.tex_ptr equ dword[ebp-4] ; pointer to texture |
.z_ptr equ dword[ebp-8] ; pointer to z-buffer |
.x1 equ word[ebp-10] |
.y1 equ word[ebp-12] |
.x2 equ word[ebp-14] |
.y2 equ word[ebp-16] |
.x3 equ word[ebp-18] |
.y3 equ word[ebp-20] |
|
.dx12 equ dword[ebp-24] |
.tex_dx12 equ dword[ebp-28] |
.tex_dy12 equ dword[ebp-32] |
.dz12 equ dword[ebp-36] |
|
.dx13 equ dword[ebp-40] |
.tex_dx13 equ dword[ebp-44] |
.tex_dy13 equ dword[ebp-48] |
.dz13 equ dword[ebp-52] |
|
.dx23 equ dword[ebp-56] |
.tex_dx23 equ dword[ebp-60] |
.tex_dy23 equ dword[ebp-64] |
.dz23 equ dword[ebp-68] |
|
.scan_x1 equ dword[ebp-72] |
.scan_x2 equ dword[ebp-76] |
.scan_y1 equ dword[ebp-80] |
.scan_y2 equ dword[ebp-84] |
.cz1 equ dword[ebp-88] |
.cz2 equ dword[ebp-92] |
|
if Ext >= MMX |
emms |
end if |
mov ebp,esp |
push esi ; store memory pointers |
push edx |
.tt_sort3: |
cmp ax,bx ;sort all parameters |
jle .tt_sort1 |
xchg eax,ebx |
mov edx,dword [.tex_x1] |
xchg edx,dword [.tex_x2] |
mov dword[.tex_x1],edx |
mov dx,.z1 |
xchg dx,.z2 |
mov .z1,dx |
.tt_sort1: |
cmp bx,cx |
jle .tt_sort2 |
xchg ebx,ecx |
mov edx,dword [.tex_x2] |
xchg edx,dword [.tex_x3] |
mov dword [.tex_x2],edx |
mov dx,.z2 |
xchg dx,.z3 |
mov .z2,dx |
jmp .tt_sort3 |
.tt_sort2: |
|
push eax ; and store to user friendly variables |
push ebx |
push ecx |
|
mov edx,80008000h ; eax,ebx,ecx are ANDd together into edx which means that |
and edx,ebx ; if *all* of them are negative a sign flag is raised |
and edx,ecx |
and edx,eax |
test edx,80008000h ; Check both X&Y at once |
jne .tt_loop2_end |
cmp ax,SIZE_Y |
jl @f |
cmp bx,SIZE_Y |
jl @f |
cmp cx,SIZE_Y |
jl @f |
ror eax,16 |
ror ebx,16 |
ror ecx,16 |
cmp ax,SIZE_X |
jl @f |
cmp bx,SIZE_X |
jl @f |
cmp cx,SIZE_X |
jl @f |
jmp .tt_loop2_end |
@@: |
mov eax,dword[.tex_x1] ; texture coords must be in [0..TEX_X(Y)] |
mov ebx,dword[.tex_x2] |
mov ecx,dword[.tex_x3] |
mov edx,eax |
or edx,ebx |
or edx,ecx |
test edx,80008000h |
jne .tt_loop2_end |
cmp ax,TEX_X |
jge .tt_loop2_end |
cmp bx,TEX_X |
jge .tt_loop2_end |
cmp cx,TEX_X |
jge .tt_loop2_end |
ror eax,16 |
ror ebx,16 |
ror ecx,16 |
cmp ax,TEX_Y |
jge .tt_loop2_end |
cmp bx,TEX_Y |
jge .tt_loop2_end |
cmp cx,TEX_Y |
jge .tt_loop2_end |
|
|
movsx ebx,.y2 ; calc delta |
sub bx,.y1 |
jnz .tt_dx12_make |
xor edx,edx |
mov ecx,4 |
@@: |
push edx |
loop @b |
jmp .tt_dx12_done |
.tt_dx12_make: |
mov ax,.x2 |
sub ax,.x1 |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
; mov .dx12,eax ; dx12 = (x2-x1)/(y2-y1) |
push eax |
|
mov ax,word[.tex_x2] |
sub ax,word[.tex_x1] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
; mov [.tex_dx12],eax ; tex_dx12 = (tex_x2-tex_x1)/(y2-y1) |
push eax |
|
mov ax,word[.tex_y2] |
sub ax,word[.tex_y1] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
; mov [.tex_dy12],eax ; tex_dy12 = (tex_y2-tex_y1)/(y2-y1) |
push eax |
|
mov ax,.z2 |
sub ax,.z1 |
cwde |
shl eax,CATMULL_SHIFT |
cdq |
idiv ebx |
push eax |
.tt_dx12_done: |
|
movsx ebx,.y3 ; calc delta |
sub bx,.y1 |
jnz .tt_dx13_make |
xor edx,edx |
mov ecx,4 |
@@: |
push edx |
loop @b |
jmp .tt_dx13_done |
.tt_dx13_make: |
mov ax,.x3 |
sub ax,.x1 |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
; mov .dx12,eax ; dx13 = (x3-x1)/(y3-y1) |
push eax |
|
mov ax,word[.tex_x3] |
sub ax,word[.tex_x1] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
; mov [.tex_dx12],eax ; tex_dx13 = (tex_x3-tex_x1)/(y3-y1) |
push eax |
|
mov ax,word[.tex_y3] |
sub ax,word[.tex_y1] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
; mov [.tex_dy12],eax ; tex_dy13 = (tex_y3-tex_y1)/(y3-y1) |
push eax |
|
mov ax,.z3 |
sub ax,.z1 |
cwde |
shl eax,CATMULL_SHIFT |
cdq |
idiv ebx |
push eax |
.tt_dx13_done: |
|
mov bx,.y3 ; calc delta |
sub bx,.y2 |
jnz .tt_dx23_make |
xor edx,edx |
mov ecx,4 |
@@: |
push edx |
loop @b |
jmp .tt_dx23_done |
.tt_dx23_make: |
mov ax,.x3 |
sub ax,.x2 |
cwde |
shl eax,ROUND |
cdq |
movzx ebx,bx |
idiv ebx |
; mov .dx23,eax ; dx23 = (x3-x2)/(y3-y2) |
push eax |
|
mov ax,word[.tex_x3] |
sub ax,word[.tex_x2] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
; mov [.tex_dx23],eax ; tex_dx23 = (tex_x3-tex_x2)/(y3-y2) |
push eax |
|
mov ax,word[.tex_y3] |
sub ax,word[.tex_y2] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
; mov [.tex_dy23],eax ; tex_dy23 = (tex_y3-tex_y2)/(y3-y2) |
push eax |
|
mov ax,.z3 |
sub ax,.z2 |
cwde |
shl eax,CATMULL_SHIFT |
cdq |
idiv ebx |
push eax |
.tt_dx23_done: |
|
movsx eax,.x1 ;eax - cur x1 |
shl eax,ROUND ;ebx - cur x2 |
mov ebx,eax |
|
movsx edx, word[.tex_x1] |
shl edx,ROUND |
; mov [.scan_x1],edx |
; mov [.scan_x2],edx |
push edx |
push edx |
movsx edx, word[.tex_y1] |
shl edx,ROUND |
; mov [.scan_y1],edx |
; mov [.scan_y2],edx |
push edx |
push edx |
movsx edx,.z1 |
shl edx,CATMULL_SHIFT |
push edx |
push edx |
mov cx,.y1 |
cmp cx,.y2 |
jge .tt_loop1_end |
|
.tt_loop1: |
pushad |
|
push .z_ptr |
push .cz1 ; z coords shifted shl catmull_shift |
push .cz2 |
push .scan_y2 |
push .scan_x2 |
push .scan_y1 |
push .scan_x1 |
push esi ;[.tex_ptr] |
|
push cx |
sar ebx,ROUND |
push bx |
sar eax,ROUND |
push ax |
call textured_line_z |
|
popad |
mov edx,.dz13 |
add .cz1,edx |
mov edx,.dz12 |
add .cz2,edx |
|
mov edx, .tex_dx13 |
add .scan_x1, edx |
mov edx, .tex_dx12 |
add .scan_x2, edx |
mov edx, .tex_dy13 |
add .scan_y1, edx |
mov edx, .tex_dy12 |
add .scan_y2, edx |
|
add eax, .dx13 |
add ebx, .dx12 |
inc cx |
cmp cx,.y2 |
jl .tt_loop1 |
|
.tt_loop1_end: |
|
|
mov cx,.y2 |
cmp cx,.y3 |
jge .tt_loop2_end |
|
movsx ebx,.x2 |
shl ebx,ROUND |
movsx edx,.z2 |
shl edx,CATMULL_SHIFT |
mov .cz2,edx |
movzx edx, word [.tex_x2] |
shl edx,ROUND |
mov .scan_x2,edx |
movzx edx, word[.tex_y2] |
shl edx,ROUND |
mov .scan_y2,edx |
|
.tt_loop2: |
|
pushad |
|
push .z_ptr |
push .cz1 ; z coords shifted shl catmull_shift |
push .cz2 |
|
push .scan_y2 |
push .scan_x2 |
push .scan_y1 |
push .scan_x1 |
push esi ;[.tex_ptr] |
|
push cx |
sar ebx,ROUND |
push bx |
sar eax,ROUND |
push ax |
call textured_line_z |
|
popad |
|
|
mov edx,.dz13 |
add .cz1,edx |
mov edx,.dz23 |
add .cz2,edx |
|
mov edx, .tex_dx13 |
add .scan_x1, edx |
mov edx, .tex_dx23 |
add .scan_x2, edx |
mov edx, .tex_dy13 |
add .scan_y1, edx |
mov edx, .tex_dy23 |
add .scan_y2, edx |
|
add eax, .dx13 |
add ebx, .dx23 |
inc cx |
cmp cx,.y3 |
jl .tt_loop2 |
|
.tt_loop2_end: |
|
.tt_end: |
mov esp,ebp |
ret 18 |
|
textured_line_z: |
;-----in -edi screen buffer pointer |
;------------ stack: |
.x1 equ word [ebp+4] |
.x2 equ word [ebp+6] |
.y equ word [ebp+8] |
|
.tex_ptr equ dword [ebp+10] |
.tex_x1 equ ebp+14 |
.tex_y1 equ ebp+18 |
.tex_x2 equ ebp+22 |
.tex_y2 equ ebp+26 |
.z2 equ dword [ebp+30] ;z1, z2 coords shifted shl CATMULL_SHIFT |
.z1 equ dword [ebp+34] |
.z_ptr equ dword [ebp+38] |
|
.tex_dy equ dword [ebp-4] |
.tex_dx equ dword [ebp-8] |
.dz equ dword [ebp-12] |
.cz equ dword [ebp-16] |
.c_tex_x equ dword [ebp-20] ; current tex x |
.m_sft1 equ ebp-28 |
.m_sft2 equ ebp-32 |
; .c_tex_xM equ ebp+14 |
.tex_dxM equ ebp-8 |
|
mov ebp,esp |
|
mov ax,.y |
or ax,ax |
jl .tl_quit |
cmp ax,SIZE_Y |
jge .tl_quit |
|
mov ax,.x1 |
cmp ax,.x2 |
je .tl_quit |
jl .tl_ok |
|
xchg ax,.x2 ; sort params |
mov .x1,ax |
if Ext >= MMX |
movq mm0,[.tex_x1] |
movq mm1,[.tex_x2] |
movq [.tex_x2],mm0 |
movq [.tex_x1],mm1 |
|
else |
mov eax,dword[.tex_x1] |
xchg eax,dword[.tex_x2] |
mov dword[.tex_x1],eax |
|
mov eax,dword[.tex_y1] |
xchg eax,dword[.tex_y2] |
mov dword[.tex_y1],eax |
|
end if |
|
mov eax,.z1 |
xchg eax,.z2 |
mov .z1,eax |
|
.tl_ok: |
cmp .x1,SIZE_X |
jge .tl_quit |
cmp .x2,0 |
jle .tl_quit |
|
mov bx,.x2 |
sub bx,.x1 |
movsx ebx,bx |
|
mov eax,dword[.tex_y2] ; calc .dty |
sub eax,dword[.tex_y1] |
cdq |
idiv ebx |
push eax |
|
mov eax,dword[.tex_x2] ; calc .dtx |
sub eax,dword[.tex_x1] |
cdq |
idiv ebx |
push eax |
|
mov eax,.z2 ; calc .dz |
sub eax,.z1 |
cdq |
idiv ebx |
push eax |
|
cmp .x1,0 ; clipping |
jg @f |
|
movsx ebx,.x1 |
neg ebx |
imul ebx ; eax = .dz * abs(.x1) |
add .z1,eax |
mov .x1,0 |
|
mov eax,.tex_dy |
imul ebx |
add dword[.tex_y1],eax |
|
mov eax,.tex_dx |
imul ebx |
add dword[.tex_x1],eax |
|
@@: |
cmp .x2,SIZE_X |
jl @f |
mov .x2,SIZE_X |
@@: |
|
movsx ebx,.y ; calc mem begin in buffers |
mov eax,SIZE_X |
mul ebx |
movsx ebx,.x1 |
add eax,ebx |
mov ebx,eax |
|
lea eax,[eax*3] |
add edi,eax ; edi - scr buff |
shl ebx,2 |
add .z_ptr,ebx ; z buffer pointer |
|
mov cx,.x2 |
sub cx,.x1 |
movzx ecx,cx |
|
;if Ext >= MMX |
; movq mm0,[.tex_x1] |
; movq mm4,mm0 |
; movq mm1,qword[.tex_dxM] |
; mov ebx,.z1 |
; mov eax,.dz |
;else |
mov eax,dword[.tex_x1] |
mov ebx,dword[.tex_y1] |
push .z1 ; .cz |
push eax ;.c_tex_x |
;end if |
mov edx,.z_ptr |
|
.tl_loop: |
|
;if Ext >= MMX |
; cmp ebx,[edx] ; ebx - current z |
; jge @f |
; movq mm2,mm0 |
; psrad mm2,ROUND |
; movq mm3,mm2 |
; psrlq mm2,32-TEX_SHIFT |
; paddd mm3,mm2 |
; movd esi,mm3 |
; mov dword[edx],ebx ; renew z buffer |
;else |
; eax - temp |
mov eax,.cz ; ebx - cur tex y shl ROUND |
cmp eax,[edx] ; ecx - l.lenght |
jge @f ; ebx - cur tex_y ; edx - temp |
mov esi,ebx ; edi - scr buff |
sar esi,ROUND ; esi - tex_ptr temp |
shl esi,TEX_SHIFT ; .z_ptr - cur pointer to z buff |
mov eax,.c_tex_x ; .cz - cur z coord shl CATMULL_SHIFT |
sar eax,ROUND |
add esi,eax |
mov eax,.cz |
mov dword[edx],eax ; renew z buffer |
;end if |
and esi,TEXTURE_SIZE |
lea esi,[esi*3] |
add esi,.tex_ptr |
movsd |
dec edi |
jmp .no_skip |
@@: |
add edi,3 |
.no_skip: |
add edx,4 |
;if Ext >= MMX |
; add ebx,eax |
; paddd mm0,mm1 |
;else |
mov eax,.dz |
add .cz,eax |
mov eax,.tex_dx |
add .c_tex_x,eax |
add ebx,.tex_dy |
;end if |
loop .tl_loop |
.tl_quit: |
|
mov esp,ebp |
|
ret 30+8 |
|