1,8 → 1,8 |
MAX_SPHERES = 5 |
MAX_LIGHTS = 3 |
;ray |
MAX_SPHERES = 4 ;8 |
MAX_LIGHTS = 6 |
|
main_loop: |
call normalize_surface |
xor eax,eax ; y |
.next_line: |
xor ebx,ebx ; x |
10,6 → 10,9 |
@@: |
push eax |
push ebx |
|
|
|
call find_intersection |
pop ebx |
pop eax |
22,16 → 25,33 |
jnz .next_line |
|
ret |
init_calc: ; do some intial calculations |
|
normalize_surface: |
movss xmm0,[surface+8] |
movlhps xmm0,xmm0 |
movlps xmm0,[surface] |
movaps xmm1,xmm0 |
mulps xmm0,xmm0 |
haddps xmm0,xmm0 |
haddps xmm0,xmm0 |
sqrtss xmm0,xmm0 |
shufps xmm0,xmm0,0 |
divps xmm1,xmm0 |
movaps xmm2,xmm1 |
pslldq xmm2,4 |
psrldq xmm2,4 |
movaps [surface_without_d],xmm2 |
movlps [surface],xmm1 |
movhlps xmm1,xmm1 |
movss [surface+8],xmm1 |
ret |
|
find_intersection: ;with for now single sphere |
find_intersection: |
; eax - y |
; ebx - x |
push ebp |
mov ebp,esp |
sub esp,128 |
sub esp,256 |
and ebp,0xfffffff0 |
.dz equ dword[ebp-8] |
.dy equ dword[ebp-12] |
48,12 → 68,21 |
.sph_xyz equ [ebp-80] |
.one_write equ byte [ebp-81] ;tells if sth written in 'nearest' data |
.sph_counter equ dword [ebp-85] |
.dx_sh equ [ebp-96] |
.a_sh equ [ebp-100] |
.b_sh equ [ebp-104] |
.c_sh equ [ebp-108] |
.delta_sh equ [ebp-112] |
.sph_counter_sh equ dword[ebp-116] |
.shadow_mark equ dword [ebp-120] |
.nearest_surface equ [ebp-144] |
.vd equ [ebp-148] ; denominator in plane inters. equation |
|
|
mov .iy,eax |
mov .ix,ebx |
|
mov .one_write,0 |
mov .shadow_mark,0 |
xorps xmm0,xmm0 |
cvtpi2ps xmm0,.ix |
mov ecx,XRES |
68,31 → 97,26 |
haddps xmm1,xmm1 |
movss .a,xmm1 |
mov .sph_counter,0 |
.next_sph: |
xorps xmm5,xmm5 |
.next_sph: ; intersection with sphere |
movaps xmm5,[camera] |
mov edx,.sph_counter |
shl edx,4 |
add edx,sphere |
subps xmm5,[edx] ;[sphere] ;;[edx] |
subps xmm5,[edx] |
mulps xmm5,[float2] |
movaps xmm0,.dx |
mulps xmm5,xmm0 |
mulps xmm5,.dx |
haddps xmm5,xmm5 |
haddps xmm5,xmm5 |
movss .b,xmm5 |
|
|
movaps xmm4,[edx] ;[sphere] ; [edx] |
movaps xmm4,[edx] |
mulps xmm4,xmm4 |
; haddps xmm4,xmm4 |
; haddps xmm4,xmm4 |
movaps xmm5,[camera] |
mulps xmm5,xmm5 |
addps xmm4,xmm5 |
haddps xmm4,xmm4 |
haddps xmm4,xmm4 |
; addss xmm4,xmm5 |
movaps xmm5,[edx] ;;[sphere] ;; [edx] |
mulps xmm5,[camera] |
haddps xmm5,xmm5 |
115,14 → 139,10 |
movss .delta,xmm5 |
xorps xmm6,xmm6 |
cmpnltss xmm5,xmm6 |
movd ecx,xmm5 ; ecx = -1 greater than 0.0 |
movd ecx,xmm5 ; ecx = -1 => greater than 0.0 |
cmp ecx,0 |
jnz @f |
jmp .next_s ; no intersection |
; add .sph_counter,1 |
; cmp .sph_counter,MAX_SPHERES |
; jnz .next_sph |
; jmp .put_pixel |
|
|
@@: |
139,44 → 159,66 |
divss xmm4,[float2] |
divss xmm4,.a |
movss .t2,xmm4 |
movss xmm5,xmm4 |
|
cmpnltss xmm4,.t1 |
movd ecx,xmm4 |
or ecx,ecx |
jne @f |
movss xmm5,.t2 |
@@: |
maxss xmm6,xmm4 |
cmp .one_write,0 ; test if sth in 'nearest' data is written |
jz @f |
movss xmm4,xmm5 |
movss xmm4,xmm6 ;5 |
cmpnltss xmm4,[smalest_t] |
movd ecx,xmm4 |
or ecx,ecx |
jz .next_s |
@@: |
movss [smalest_t],xmm5 |
; push .a |
; pop [smalest_a] |
; push .b |
; pop [smalest_b] |
; push .c |
; pop [smalest_c] |
; push .delta |
; pop [smalest_delta] |
movss [smalest_t],xmm6 ;5 |
movaps xmm0,[edx] |
movaps [nearest_sphere],xmm0 |
push dword[ebx] |
pop dword[nearest_radius] |
mov .one_write,1 |
|
mov .one_write,1 ; one_write - object index -> 1 = sphere |
.next_s: |
add .sph_counter,1 |
cmp .sph_counter,MAX_SPHERES |
jnz .next_sph |
|
if 1 |
movaps xmm0,[surface_without_d] ; find with plane intersection |
mulps xmm0,[camera] ; only one surface is computed |
haddps xmm0,xmm0 |
haddps xmm0,xmm0 |
addss xmm0,[surface+12] |
movaps xmm1,[surface_without_d] |
mulps xmm1,.dx |
haddps xmm1,xmm1 |
haddps xmm1,xmm1 |
xorps xmm2,xmm2 |
cmpnless xmm2,xmm1 |
movd ecx,xmm2 |
cmp ecx,0 ;-1 |
je .put_pixel ; denominator equal 'zero' - no intersection |
xorps xmm2,xmm2 ; denominator > 0 -> inters. not in screen area |
movss .vd,xmm1 ; write to memory this denom. |
divss xmm0,xmm1 |
subss xmm2,xmm0 |
cmp .one_write,0 |
jz @f |
movss xmm0,xmm2 |
cmpnltss xmm2,[smalest_t] |
movd ecx,xmm2 |
cmp ecx,0 |
je .put_pixel |
@@: |
movss [smalest_t],xmm0 |
; test [smalest_t],0x80000000 |
; jz @f |
; and [smalest_t],0x7fffffff |
; @@: |
movaps xmm2,[surface] |
movaps .nearest_surface,xmm2 |
mov .one_write,2 ; nearest object -> 2 = flat plane |
|
end if |
|
.put_pixel: |
cmp .one_write,0 |
cmp .one_write,0 ; end if no intersection |
je .end |
|
movss xmm5,[smalest_t] |
184,28 → 226,139 |
movaps xmm6,.dx |
mulps xmm6,xmm5 |
movaps xmm4,[camera] |
addps xmm4,xmm6 ; xmm4 - x,y,z on the sphere |
addps xmm4,xmm6 ; xmm4 - x,y,z on the sphere or on surface |
movaps .sph_xyz,xmm4 |
if 1 |
cmp .one_write,2 |
jne .shadow |
; movaps xmm4,.sph_xyz |
movaps xmm7,xmm4 |
lea ebx,.nearest_surface |
movss xmm4,[ebx+8] |
movlhps xmm4,xmm4 |
movlps xmm4,[ebx] ; xmm4 - normal to surface vector |
test dword .vd,0x80000000 |
jz @f |
andps xmm4,[positive_mask] ;0x7fffffff |
@@: |
|
jmp .calc_pix |
|
end if |
.shadow: |
if 1 |
; to find shadow intersect: |
; P0 - point on sphere |
; P1 - light |
; with every other sphere in scene if any intersection occured - |
; - point is in shadow |
; next_sph_shad: |
mov ecx,MAX_LIGHTS |
.next_light_sh: |
push ecx |
shl ecx,4 |
movaps xmm0,[ecx+light] ;xmm4 - point on nearest sphere |
subps xmm0,xmm4 |
movaps .dx_sh,xmm0 |
|
mulps xmm0,xmm0 |
haddps xmm0,xmm0 |
haddps xmm0,xmm0 |
movss .a_sh,xmm0 |
|
mov .sph_counter_sh,0 |
.next_sph_sh: ; be sure you not intersect nearest sphere with itself |
movaps xmm5,.sph_xyz ;[light] |
mov edx,.sph_counter_sh |
shl edx,4 |
add edx,sphere |
movaps xmm7,[edx] |
cmpeqps xmm7,[nearest_sphere] |
movmskps ecx,xmm7 |
and ecx,0111b |
cmp ecx,0 |
jne .next_s_sh |
|
subps xmm5,[edx] ; [edx] - cur sph |
mulps xmm5,[float2] |
mulps xmm5,.dx_sh |
haddps xmm5,xmm5 |
haddps xmm5,xmm5 |
movss .b_sh,xmm5 |
|
movaps xmm4,[edx] |
mulps xmm4,xmm4 |
movaps xmm5,.sph_xyz |
mulps xmm5,xmm5 |
addps xmm4,xmm5 |
haddps xmm4,xmm4 |
haddps xmm4,xmm4 |
movaps xmm5,.sph_xyz |
mulps xmm5,[edx] |
haddps xmm5,xmm5 |
haddps xmm5,xmm5 |
mulss xmm5,[float2] |
subss xmm4,xmm5 |
mov ebx,.sph_counter_sh |
shl ebx,2 |
add ebx,sph_radius |
movss xmm5,[ebx] |
mulss xmm5,xmm5 |
subss xmm4,xmm5 |
movss .c_sh,xmm4 |
|
movss xmm5,.b_sh |
mulss xmm5,xmm5 |
mulss xmm4,.a_sh |
mulss xmm4,[float4] |
subss xmm5,xmm4 |
movss .delta_sh,xmm5 |
xorps xmm6,xmm6 |
cmpnltss xmm5,xmm6 |
movd ecx,xmm5 ; ecx = -1 greater than 0.0 |
cmp ecx,0 |
jnz @f |
jmp .next_s_sh ; no intersection |
@@: |
add .shadow_mark,1 ; mark ->point in shadow |
pop ecx |
sub ecx,1 |
jnz .next_light_sh |
jmp .put_pix |
.next_s_sh: |
add .sph_counter_sh,1 |
cmp .sph_counter_sh,MAX_SPHERES |
jnz .next_sph_sh |
pop ecx |
sub ecx,1 |
jnz .next_light_sh |
|
end if |
|
|
|
|
|
|
.put_pix: |
movaps xmm4,.sph_xyz |
movaps xmm7,xmm4 |
subps xmm4,[nearest_sphere] |
; movaps xmm6,xmm7 |
; addps xmm6,[nearest_sphere] |
; movaps .sph_xyz,xmm6 |
|
movss xmm0,[nearest_radius] |
shufps xmm0,xmm0,0 |
divps xmm4,xmm0 ; xmm4 - normal to surface vector |
.calc_pix: ; normal computed |
movaps xmm1,xmm4 ; copy of normal in xmm1 |
xor eax,eax |
xorps xmm3,xmm3 |
movss xmm2,[light_factor] |
shufps xmm2,xmm2,0 |
; movss xmm2,[light_factor] ; other model of lighting |
; shufps xmm2,xmm2,0 |
|
.next_light: |
; push eax |
mov ebx,eax |
shl ebx,4 |
;add eax,light |
movaps xmm5,[light+ebx];[light] ;; [eax] |
movaps xmm5,[light+ebx] |
subps xmm5,xmm7 ; calc light unit vector |
movaps xmm6,xmm5 |
mulps xmm5,xmm5 |
212,6 → 365,7 |
haddps xmm5,xmm5 |
haddps xmm5,xmm5 |
sqrtss xmm5,xmm5 |
shufps xmm5,xmm5,0 |
divps xmm6,xmm5 ; xmm6 - normalized light vector |
; dot_product |
movaps xmm4,xmm1 ; xmm4 - normal to surface |
219,55 → 373,98 |
haddps xmm4,xmm4 |
haddps xmm4,xmm4 |
shufps xmm4,xmm4,0 |
; movaps xmm5,xmm4 |
; mulps xmm5,xmm5 |
; mulps xmm5,xmm5 |
; mulps xmm5,[color] |
mulps xmm4,[lights_color+ebx] ; xmm4 - computed col. light vector dep. |
; addps xmm4,xmm5 |
mulps xmm4,xmm2 |
addps xmm3,xmm4 |
; pop eax |
|
; mulps xmm4,xmm2 ; other model of lighting |
; addps xmm3,xmm4 |
|
maxps xmm3,xmm4 ; will be this better ? |
|
add eax,1 |
cmp eax,MAX_LIGHTS |
jnz .next_light |
if 0 |
; mix with texture |
movaps xmm0,.sph_xyz |
movss xmm1,[nearest_radius] |
shufps xmm1,xmm1,0 |
divps xmm0,xmm1 |
mulps xmm0,[correct_tex] ; f64 |
; addps xmm0,[correct_tex] |
cvtss2si eax,xmm0 |
psrldq xmm0,4 |
cvtss2si ebx,xmm0 |
imul ebx,[tex_x] |
add ebx,eax |
lea ebx,[ebx*3] |
add ebx,bitmap |
;mov eax,[ebx] |
movd xmm1,[ebx] |
xorps xmm7,xmm7 |
punpcklbw xmm1,xmm7 |
punpcklwd xmm1,xmm7 |
cvtdq2ps xmm1,xmm1 |
mulps xmm3,xmm1 |
divps xmm3,[float255] |
; divps xmm1,[float2] |
; divps xmm3,[float2] |
; addps xmm3,xmm1 |
end if |
|
minps xmm3,[float255] |
cmp .shadow_mark,0 |
je @f |
cvtsi2ss xmm2,.shadow_mark |
shufps xmm2,xmm2,0 |
mulps xmm2,[shadow_factor] |
subps xmm3,xmm2 |
xorps xmm0,xmm0 |
maxps xmm3,xmm0 |
@@: |
|
minps xmm3,[float255] |
cvtps2dq xmm3,xmm3 |
packssdw xmm3,xmm3 |
packuswb xmm3,xmm3 |
paddusb xmm3,[ambient_col] |
|
if 1 |
cmp .one_write,2 |
jne .perspective |
movaps xmm0,xmm3 ; calc texture on plane |
movaps xmm1,.sph_xyz |
mov ecx,XRES |
cvtsi2ss xmm4,ecx |
shufps xmm4,xmm4,0 |
mulps xmm1,xmm4 |
cvtps2dq xmm1,xmm1 |
movd ecx,xmm1 |
test ecx,0x8 |
jz @f |
mov ecx,0xffffffff |
jmp .next_tex_test |
@@: |
xor ecx,ecx |
.next_tex_test: |
psrldq xmm1,8 |
movd ebx,xmm1 |
test ebx,0x20 |
jz @f |
mov ebx,0xffffffff |
jmp .set_tex |
@@: |
xor ebx,ebx |
.set_tex: |
xor ebx,ecx |
shr ebx,28 |
mov bh,bl |
movd xmm7,ebx |
paddusb xmm3,xmm7 |
|
end if |
|
|
.perspective: |
movaps xmm0,.sph_xyz ; perspective correction |
subps xmm0,[camera] |
movss xmm1,[camera] |
movss xmm2,xmm0 |
movaps xmm4,xmm0 |
shufps xmm4,xmm4,00000010b |
divss xmm2,xmm4 |
mulss xmm2,[camera+8] |
subss xmm1,xmm2 ; xmm1 - x |
|
movaps xmm2,xmm0 |
shufps xmm2,xmm2,00000001b |
movaps xmm4,xmm0 |
shufps xmm4,xmm4,00000010b |
divss xmm2,xmm4 |
mulss xmm2,[camera+8] |
movss xmm4,[camera+4] |
subss xmm4,xmm2 ; xmm4 - y |
|
mov ebx,XRES |
cvtsi2ss xmm2,ebx |
mulss xmm1,xmm2 |
mulss xmm4,xmm2 |
cvtss2si ecx,xmm1 |
mov .ix,ecx |
cvtss2si edx,xmm4 |
mov .iy,edx |
|
mov edi,screen |
mov ecx,XRES |
imul ecx,.iy |
275,9 → 472,8 |
lea ecx,[ecx*3] |
add edi,ecx |
movd [edi],xmm3 |
|
.end: |
add esp,128 |
add esp,256 |
pop ebp |
|
ret |