GLdc/gl-sh4-light.S
2016-01-03 22:24:52 -05:00

210 lines
5.5 KiB
ArmAsm

/* KallistiGL for KallistiOS ##version##
libgl/gl-sh4-light.S
Copyright (C) 2013-2014 Josh Pearson
Dynamic Vertex Lighting
This Assembly file contains 2 functions:
_glKosSpotLight - This function computes diffuse / spotlight / attenuation
_glKosSpecular - This functions computes the Specular Term
*/
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!float _glKosSpecular( void * vertex6f, void * eyepos, void * Lvectorin );
.globl __glKosSpecular
!r4 = [arg][void*] = vertex
!r5 = [arg][void*] = eyepos
!r6 = [arg][void*] = L vector
!fr0 = return value
!fv0 = vertex position (P)(N)
!fv4 = eye position (E)
!fv8 = L vector (L)
__glKosSpecular:
fmov @r4+, fr0 ! load vertex x to fv0
fmov @r4+, fr1 ! load vertex y to fv0
fmov @r4+, fr2 ! load vertex z to fv0
fmov @r5+, fr4 ! load eye pos x to fv4
fmov @r5+, fr5 ! load eye pos y to fv4
fmov @r5+, fr6 ! load eye pos z to fv4
fmov @r6+, fr8 ! load L vector x to fv8
fmov @r6+, fr9 ! load L vector y to fv8
fmov @r6+, fr10 ! load L vector z to fv8
fsub fr0, fr4 ! fv4 = V = normalize ( E - P )
fsub fr1, fr5
fsub fr2, fr6
fldi0 fr3 ! load 0 for P w
fldi0 fr7 ! load 0 for E w
fipr fv4, fv4 ! Normalize V vector
fsrra fr7
fmul fr7, fr4
fmul fr7, fr5
fmul fr7, fr6
fadd fr4, fr8 ! fv8 = H = normalize( L + V )
fadd fr5, fr9
fadd fr6, fr10
fldi0 fr11 ! load 0 for H w
fipr fv8, fv8 ! Normalize H vector
fsrra fr11
fmul fr11, fr8
fmul fr11, fr9
fmul fr11, fr10
fmov @r4+, fr0 ! load N to fv0
fmov @r4+, fr1
fmov @r4+, fr2
fipr fv0, fv8 ! N dot H for specular term
rts
fmov fr11, fr0 ! move N dot H to fr0 for return
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!int _glKosSpotlight( void * glLight, void * vertex6f, void * Lvectorout );
.globl __glKosSpotlight
!r0 = return value | true or false
!r1 = boolean flag
!r2 = boolean false
!r4 = [arg] = light
!r5 = [arg] = vertex
!r6 = [arg] = output
!fv0 = vertex position
!fv4 = light position | L vector | normalize(light pos - vertex pos) | w = attenuation distance
!fv8 = light direction | N vector = Vertex Normal
!fv12 = Spot vector | normalize(vertex pos - light pos)
__glKosSpotlight:
mov #0, r1 ! load 0 for boolean flag
mov #0, r2 ! load 0 for boolean false
fmov @r4+, fr4 ! load light position x to fv4
fmov @r4+, fr5 ! load light position y to fv4
fmov @r4+, fr6 ! load light position z to fv4
fmov @r4+, fr7 ! load light position w to fv4
fmov @r4+, fr8 ! load light direction x to fv8
fmov @r4+, fr9 ! load light direction y to fv8
fmov @r4+, fr10 ! load light direction z to fv8
fmov @r5+, fr0 ! load vertex position x to fv0
fmov @r5+, fr1 ! load vertex position y to fv0
fmov @r5+, fr2 ! load vertex position z to fv0
fldi0 fr11 ! load 0 for light dir w
fcmp/gt fr11, fr7 ! light pos w component set = spot light
bf .VERTEXLIGHT0 ! light not a spot light - branch to vertex lighting
fschg
fmov dr0, dr12 ! copy vertex x,y to fv12
fschg
fmov fr2, fr14 ! copy vertex z to fv12
fsub fr4, fr12 ! fv12 = ( vertex position - light position)
fsub fr5, fr13
fsub fr6, fr14
fldi0 fr15 ! set fv12 w component to 0
fipr fv12, fv12 ! Normalize vector
fsrra fr15
fmul fr15, fr12
fmul fr15, fr13
fmul fr15, fr14
fldi0 fr15 ! set fv12 w component to 0
fipr fv12, fv8 ! fr11 now holds light cosDir
fmov @r4+, fr15 ! load light cutOff to fr15
mov #1, r1 ! load 1 for boolean flag = indicate light cutOff was read
fcmp/gt fr15, fr11 ! cosDir > cutOff ? 0 : 1
bt .RET0spot ! vertex outside of spotlight = return 0
.VERTEXLIGHT0:
fsub fr0, fr4 ! fv4 = L vector = ( light position - vertex position)
fsub fr1, fr5
fsub fr2, fr6
fldi0 fr7 ! load 0 for L w
fldi0 fr11 ! load 0 for N w
fipr fv4, fv4 ! Normalize L vector
fsrra fr7
fmul fr7, fr4
fmul fr7, fr5
fmul fr7, fr6 ! fv4 = Normalized L Vector
fmov fr7, fr3 ! copy L w to fr3
fldi0 fr7 ! load 0 for L w
fcmp/gt fr7, fr3
bf .RET0spot ! if L w < 0, return 0 now to avoid pointless computations
fmov @r5+, fr8 ! load normal to fv8
fmov @r5+, fr9 ! load normal to fv8
fmov @r5+, fr10 ! load normal to fv8
fipr fv8, fv4 ! N dot L
fcmp/gt fr11, fr7 ! L w < = 0 ? L w = 0
bf .RET0spot: ! if L w < 0, return 0 now to avoid pointless computations
.WRITEDi:
fschg
fmov dr4, @r6 ! write L vector x to output
fschg
add #8, r6
fmov fr6, @r6 ! write L vector z to output
add #4, r6
cmp/gt r2, r1
bt .READattenf
add #4, r4
.READattenf:
fmov @r4+, fr8 ! vertex normal gets overwritten by atten factors
fmov @r4+, fr9
fmov @r4+, fr10
fldi1 fr11
fmul fr3, fr9 ! calculate attenuation
fmul fr3, fr10
fmul fr3, fr10
fadd fr9, fr8
fadd fr10, fr8
fdiv fr8, fr11 ! fr11 = A
fmul fr7, fr11 ! D * A
fmov fr11, @r6 ! write D*A to output
.RET1spot:
rts
mov #1, r0
.RET0spot:
rts
mov #0, r0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!