0,0 → 1,481 |
gouraud_triangle: |
;------------------in - eax - x1 shl 16 + y1 --------- |
;---------------------- ebx - x2 shl 16 + y2 --------- |
;---------------------- ecx - x3 shl 16 + y3 --------- |
;---------------------- edi - pointer to screen buffer |
;---------------------- stack : colors---------------- |
;----------------- procedure don't save registers !!-- |
.col1r equ ebp+4 ; each color as word |
.col1g equ ebp+6 |
.col1b equ ebp+8 |
.col2r equ ebp+10 |
.col2g equ ebp+12 |
.col2b equ ebp+14 |
.col3r equ ebp+16 |
.col3g equ ebp+18 |
.col3b equ ebp+20 |
|
.x1 equ word[ebp-2] |
.y1 equ word[ebp-4] |
.x2 equ word[ebp-6] |
.y2 equ word[ebp-8] |
.x3 equ word[ebp-10] |
.y3 equ word[ebp-12] |
|
.dc12r equ dword[ebp-16] |
.dc12g equ dword[ebp-20] |
.dc12b equ dword[ebp-24] |
.dc13r equ dword[ebp-28] |
.dc13g equ dword[ebp-32] |
.dc13b equ dword[ebp-36] |
.dc23r equ dword[ebp-40] |
.dc23g equ dword[ebp-44] |
.dc23b equ dword[ebp-48] |
|
.c1r equ dword[ebp-52] |
.c1g equ dword[ebp-56] |
.c1b equ dword[ebp-60] |
.c2r equ dword[ebp-64] |
.c2g equ dword[ebp-68] |
.c2b equ dword[ebp-72] |
|
.dx12 equ dword[ebp-76] |
.dx13 equ dword[ebp-80] |
.dx23 equ dword[ebp-84] |
|
|
|
mov ebp,esp |
; sub esp,72 |
|
.sort3: ; sort triangle coordinates... |
cmp ax,bx |
jle .sort1 |
xchg eax,ebx |
mov edx,dword[.col1r] |
xchg edx,dword[.col2r] |
mov dword[.col1r],edx |
mov dx,word[.col1b] |
xchg dx,word[.col2b] |
mov word[.col1b],dx |
.sort1: |
cmp bx,cx |
jle .sort2 |
xchg ebx,ecx |
mov edx,dword[.col2r] |
xchg edx,dword[.col3r] |
mov dword[.col2r],edx |
mov dx,word[.col2b] |
xchg dx,word[.col3b] |
mov word[.col2b],dx |
jmp .sort3 |
.sort2: |
push eax ;store triangle coordinates in user friendly variables |
push ebx |
push ecx |
sub esp,72 ; set correctly value of esp |
|
mov edx,eax ; check only X triangle coordinate |
or edx,ebx |
or edx,ecx |
test edx,80000000h |
jne .gt_loop2_end |
shr eax,16 |
cmp ax,SIZE_X-1 |
jg .gt_loop2_end |
shr ebx,16 |
cmp bx,SIZE_X-1 |
jg .gt_loop2_end |
shr ecx,16 |
cmp cx,SIZE_X-1 |
jg .gt_loop2_end |
|
|
mov bx,.y2 ; calc deltas |
sub bx,.y1 |
jnz .gt_dx12_make |
mov .dx12,0 |
mov .dc12r,0 |
mov .dc12g,0 |
mov .dc12b,0 |
jmp .gt_dx12_done |
.gt_dx12_make: |
|
mov ax,.x2 |
sub ax,.x1 |
cwde |
movsx ebx,bx |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dx12,eax |
|
mov ax,word[.col2r] |
sub ax,word[.col1r] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dc12r,eax |
mov ax,word[.col2g] |
sub ax,word[.col1g] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dc12g,eax |
mov ax,word[.col2b] |
sub ax,word[.col1b] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dc12b,eax |
.gt_dx12_done: |
|
mov bx,.y3 |
sub bx,.y1 |
jnz .gt_dx13_make |
mov .dx13,0 |
mov .dc13r,0 |
mov .dc13g,0 |
mov .dc13b,0 |
jmp .gt_dx13_done |
.gt_dx13_make: |
mov ax,.x3 |
sub ax,.x1 |
cwde |
movsx ebx,bx |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dx13,eax |
|
mov ax,word[.col3r] |
sub ax,word[.col1r] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dc13r,eax |
mov ax,word[.col3g] |
sub ax,word[.col1g] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dc13g,eax |
mov ax,word[.col3b] |
sub ax,word[.col1b] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dc13b,eax |
.gt_dx13_done: |
|
mov bx,.y3 |
sub bx,.y2 |
jnz .gt_dx23_make |
mov .dx23,0 |
mov .dc23r,0 |
mov .dc23g,0 |
mov .dc23b,0 |
jmp .gt_dx23_done |
.gt_dx23_make: |
mov ax,.x3 |
sub ax,.x2 |
cwde |
movsx ebx,bx |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dx23,eax |
|
mov ax,word[.col3r] |
sub ax,word[.col2r] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dc23r,eax |
mov ax,word[.col3g] |
sub ax,word[.col2g] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dc23g,eax |
mov ax,word[.col3b] |
sub ax,word[.col2b] |
cwde |
shl eax,ROUND |
cdq |
idiv ebx |
mov .dc23b,eax |
.gt_dx23_done: |
|
movsx eax,.x1 |
shl eax,ROUND |
mov ebx,eax |
movsx edx,word[.col1r] |
shl edx,ROUND |
mov .c1r,edx |
mov .c2r,edx |
movsx edx,word[.col1g] |
shl edx,ROUND |
mov .c1g,edx |
mov .c2g,edx |
movsx edx,word[.col1b] |
shl edx,ROUND |
mov .c1b,edx |
mov .c2b,edx |
mov cx,.y1 |
cmp cx,.y2 |
jge .gt_loop1_end |
.gt_loop1: |
push eax ; eax - cur x1 |
push ebx ; ebx - cur x2 |
push cx ; cx - cur y |
push edi |
push ebp |
|
mov edx,.c2r ; c2r,c2g,c2b,c1r,c1g,c1b - current colors |
sar edx,ROUND |
push dx |
mov edx,.c2g |
sar edx,ROUND |
push dx |
mov edx,.c2b |
sar edx,ROUND |
push dx |
mov edx,.c1r |
sar edx,ROUND |
push dx |
mov edx,.c1g |
sar edx,ROUND |
push dx |
mov edx,.c1b |
sar edx,ROUND |
push dx |
push cx |
sar ebx,ROUND |
push bx |
sar eax,ROUND |
push ax |
call gouraud_line |
|
pop ebp |
pop edi |
pop cx |
pop ebx |
pop eax |
|
mov edx,.dc13r |
add .c1r,edx |
mov edx,.dc13g |
add .c1g,edx |
mov edx,.dc13b |
add .c1b,edx |
mov edx,.dc12r |
add .c2r,edx |
mov edx,.dc12g |
add .c2g,edx |
mov edx,.dc12b |
add .c2b,edx |
|
add eax,.dx13 |
add ebx,.dx12 |
inc cx |
cmp cx,.y2 |
jl .gt_loop1 |
.gt_loop1_end: |
|
mov cx,.y2 |
cmp cx,.y3 |
jge .gt_loop2_end |
movsx ebx,.x2 |
shl ebx,ROUND |
|
movsx edx,word[.col2r] |
shl edx,ROUND |
mov .c2r,edx |
movsx edx,word[.col2g] |
shl edx,ROUND |
mov .c2g,edx |
movsx edx,word[.col2b] |
shl edx,ROUND |
mov .c2b,edx |
.gt_loop2: |
push eax ; eax - cur x1 |
push ebx ; ebx - cur x2 |
push cx |
push edi |
push ebp |
|
mov edx,.c2r |
sar edx,ROUND |
push dx |
mov edx,.c2g |
sar edx,ROUND |
push dx |
mov edx,.c2b |
sar edx,ROUND |
push dx |
mov edx,.c1r |
sar edx,ROUND |
push dx |
mov edx,.c1g |
sar edx,ROUND |
push dx |
mov edx,.c1b |
sar edx,ROUND |
push dx |
push cx |
sar ebx,ROUND |
push bx |
sar eax,ROUND |
push ax |
call gouraud_line |
|
pop ebp |
pop edi |
pop cx |
pop ebx |
pop eax |
|
mov edx,.dc13r |
add .c1r,edx |
mov edx,.dc13g |
add .c1g,edx |
mov edx,.dc13b |
add .c1b,edx |
mov edx,.dc23r |
add .c2r,edx |
mov edx,.dc23g |
add .c2g,edx |
mov edx,.dc23b |
add .c2b,edx |
|
add eax,.dx13 |
add ebx,.dx23 |
inc cx |
cmp cx,.y3 |
jl .gt_loop2 |
.gt_loop2_end: |
|
; add esp,84 |
mov esp,ebp |
ret 18 |
gouraud_line: |
;-------------in - edi - pointer to screen buffer |
;----------------- stack - another parameters |
.x1 equ word [ebp+4] |
.x2 equ word [ebp+6] |
.y equ word [ebp+8] |
.col1b equ ebp+10 |
.col1g equ ebp+12 |
.col1r equ ebp+14 |
.col2b equ ebp+16 |
.col2g equ ebp+18 |
.col2r equ ebp+20 |
.dc_r equ dword[ebp-4] |
.dc_g equ dword[ebp-8] |
.dc_b equ dword[ebp-12] |
mov ebp,esp |
|
mov ax,.y |
or ax,ax |
jl .gl_quit |
cmp ax,SIZE_Y-1 |
jg .gl_quit |
|
mov ax,.x1 |
cmp ax,.x2 |
je .gl_quit |
jl .gl_ok |
|
xchg ax,.x2 |
mov .x1,ax |
mov eax,dword[.col1b] |
xchg eax,dword[.col2b] |
mov dword[.col1b],eax |
mov ax,word[.col1r] |
xchg ax,word[.col2r] |
mov word[.col1r],ax |
.gl_ok: |
; cmp .x1,SIZE_X-1 ;check |
; jg .gl_quit |
; cmp .x2,SIZE_X-1 |
; jl @f |
; mov .x2,SIZE_X-1 |
; @@: |
; cmp .x1,0 |
; jg @f |
; mov .x1,0 |
; @@: |
; cmp .x2,0 |
; jl .gl_quit |
|
movsx ecx,.y |
mov eax,SIZE_X*3 |
mul ecx |
movsx ebx,.x1 |
lea ecx,[ebx*2+eax] |
add edi,ecx |
add edi,ebx |
|
mov ax,word[.col2r] |
sub ax,word[.col1r] |
cwde |
shl eax,ROUND |
cdq |
mov cx,.x2 |
sub cx,.x1 |
movsx ecx,cx |
idiv ecx |
;mov .dc_r,eax ;first delta |
push eax |
|
mov ax,word[.col2g] |
sub ax,word[.col1g] |
cwde |
shl eax,ROUND |
cdq |
idiv ecx |
;mov .dc_g,eax |
push eax |
|
mov ax,word[.col2b] |
sub ax,word[.col1b] |
cwde |
shl eax,ROUND |
cdq |
idiv ecx |
; mov .dc_b,eax |
push eax |
|
movsx ebx,word[.col1r] |
shl ebx,ROUND |
movsx edx,word[.col1g] |
shl edx,ROUND |
movsx esi,word[.col1b] |
shl esi,ROUND |
.gl_draw: |
mov eax,ebx |
sar eax,ROUND |
stosb |
mov eax,edx |
sar eax,ROUND |
stosb |
mov eax,esi |
sar eax,ROUND |
stosb |
add ebx,.dc_r |
add edx,.dc_g |
add esi,.dc_b |
loop .gl_draw |
.gl_quit: |
; add esp,12 |
mov esp,ebp |
ret 18 |