Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6388 → Rev 6506

/programs/demos/ray/ray.inc
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