kolibrios-gitea/programs/develop/libraries/TinyGL/asm_fork/matrix.asm
IgorA 62b33c4994 Fork for library tinygl, assembly version.
Can draw lines, and do some matrix operations.

git-svn-id: svn://kolibrios.org@5153 a494cfbc-eb01-0410-851d-a64ba20cac60
2014-10-31 21:28:24 +00:00

522 lines
11 KiB
NASM

if DEBUG
align 4
proc gl_print_matrix uses eax ebx ecx edi, m:dword, rows:dword
mov ecx,[rows]
cmp ecx,1
jl .end_f
mov ebx,[m]
mov word[NumberSymbolsAD],3
finit
@@:
lea edi,[buf_param]
mov byte[edi],0
fld dword[ebx]
fstp qword[Data_Double]
call DoubleFloat_to_String
stdcall str_cat, edi,Data_String
stdcall str_n_cat,edi,txt_zp_sp,2
stdcall str_len,edi
add edi,eax
fld dword[ebx+4]
fstp qword[Data_Double]
call DoubleFloat_to_String
stdcall str_cat, edi,Data_String
stdcall str_n_cat,edi,txt_zp_sp,2
stdcall str_len,edi
add edi,eax
fld dword[ebx+8]
fstp qword[Data_Double]
call DoubleFloat_to_String
stdcall str_cat, edi,Data_String
stdcall str_n_cat,edi,txt_zp_sp,2
stdcall str_len,edi
add edi,eax
fld dword[ebx+12]
fstp qword[Data_Double]
call DoubleFloat_to_String
stdcall str_cat, edi,Data_String
stdcall str_n_cat,edi,txt_nl,2
stdcall dbg_print,txt_sp,buf_param
add ebx,16
dec ecx
cmp ecx,0
jg @b
.end_f:
ret
endp
end if
macro gl_matrix_update context, reg
{
local .end_0
xor reg,reg
cmp dword[context+offs_cont_matrix_mode],1
jg .end_0
inc reg
.end_0:
mov dword[context+offs_cont_matrix_model_projection_updated],reg
}
align 4
proc glopMatrixMode uses eax ebx, context:dword, p:dword
mov eax,[context]
mov ebx,[p]
cmp dword[ebx+4],GL_MODELVIEW ;cmp p[1],...
jne @f
mov dword[eax+offs_cont_matrix_mode],0
jmp .end_f
@@:
cmp dword[ebx+4],GL_PROJECTION
jne @f
mov dword[eax+offs_cont_matrix_mode],1
jmp .end_f
@@:
cmp dword[ebx+4],GL_TEXTURE
jne .def
mov dword[eax+offs_cont_matrix_mode],2
jmp .end_f
.def:
;assert(0);
.end_f:
ret
endp
align 4
proc glopLoadMatrix uses eax edi esi, context:dword, p:dword
mov eax,[context]
mov edi,[eax+offs_cont_matrix_mode]
shl edi,2
add edi,eax
mov edi,dword[edi+offs_cont_matrix_stack_ptr]
mov esi,[p]
add esi,4
stdcall gl_M4_Transpose,edi,esi ;транспонируем входную матрицу в матрицу context.matrix_stack_ptr[context.matrix_mode]
gl_matrix_update eax,edi
ret
endp
align 4
proc glopLoadIdentity uses eax ebx, context:dword, p:dword
mov eax,[context]
mov ebx,[eax+offs_cont_matrix_mode]
shl ebx,2
add ebx,eax
stdcall gl_M4_Id,[ebx+offs_cont_matrix_stack_ptr]
if DEBUG ;glopLoadIdentity
stdcall gl_print_matrix,[ebx+offs_cont_matrix_stack_ptr],4
end if
gl_matrix_update eax,ebx
ret
endp
align 4
proc glopMultMatrix uses eax edi esi, context:dword, p:dword
locals
m M4
endl
mov esi,[p]
add esi,4
mov edi,ebp
sub edi,sizeof.M4
stdcall gl_M4_Transpose,edi,esi ;транспонируем входную матрицу в локальную матрицу m
mov eax,[context]
mov esi,[eax+offs_cont_matrix_mode]
shl esi,2
add esi,eax
stdcall gl_M4_MulLeft,dword[esi+offs_cont_matrix_stack_ptr],edi
gl_matrix_update eax,edi
ret
endp
align 4
proc glopPushMatrix uses eax ebx, context:dword, p:dword
mov eax,[context]
mov ebx,[eax+offs_cont_matrix_mode]
; assert( (c->matrix_stack_ptr[ebx] - c->matrix_stack[ebx] + 1 )
; < c->matrix_stack_depth_max[ebx] );
shl ebx,2
add ebx,eax
add ebx,offs_cont_matrix_stack_ptr
add dword[ebx],sizeof.M4
mov ebx,[ebx] ;ebx = ++context.matrix_stack_ptr[context.matrix_mode]
sub ebx,sizeof.M4
push ebx
add ebx,sizeof.M4
stdcall gl_M4_Move, ebx
gl_matrix_update eax,ebx
ret
endp
align 4
proc glopPopMatrix uses eax ebx, context:dword, p:dword
mov eax,[context]
mov ebx,[eax+offs_cont_matrix_mode]
; assert( c->matrix_stack_ptr[n] > c->matrix_stack[n] );
shl ebx,2
add ebx,eax
sub dword[ebx+offs_cont_matrix_stack_ptr],sizeof.M4
gl_matrix_update eax,ebx
ret
endp
align 4
proc glopRotate uses eax ebx ecx, context:dword, p:dword
locals
u0 dd ?
u1 dd ?
u2 dd ?
angle dd ?
cost dd ?
sint dd ?
m M4
endl
mov eax,[context]
mov ebx,[p]
mov ecx,ebp
sub ecx,sizeof.M4 ;ecx=&m
finit
fldpi
fmul dword[ebx+4]
fdiv dword[an180f]
fst dword[angle] ;angle = p[1].f * M_PI / 180.0
;st0 = angle
fldz
fild dword[ebx+8]
fstp dword[u0]
fild dword[ebx+12]
fstp dword[u1]
fild dword[ebx+16]
fst dword[u2]
; simple case detection
xor ebx,ebx
fcomp st1 ;u2 ... 0
fstsw ax
sahf
je @f
inc ebx
@@:
fcom dword[u1] ;0 ... u1
fstsw ax
sahf
je @f
or ebx,2
@@:
fcom dword[u0] ;0 ... u0
fstsw ax
sahf
je @f
or ebx,4
@@:
;st0 = 0, st1 = angle
;ebx = ((u0 != 0)<<2) | ((u1 != 0)<<1) | (u2 != 0)
cmp ebx,0
je .end_f ;если нет поворотов выход из функции
cmp ebx,4
jne @f
fcomp dword[u0] ;0 ... u0
fstsw ax
sahf
jae .u0ch
fchs
fstp dword[angle] ;if (u0 < 0) angle *= -1
.u0ch:
stdcall gl_M4_Rotate, ecx,[angle],0
jmp .end_sw
@@:
cmp ebx,2
jne @f
fcomp dword[u1] ;0 ... u1
fstsw ax
sahf
jae .u1ch
fchs
fstp dword[angle] ;if (u1 < 0) angle *= -1
.u1ch:
stdcall gl_M4_Rotate, ecx,[angle],1
jmp .end_sw
@@:
cmp ebx,1
jne @f
fcomp dword[u2] ;0 ... u2
fstsw ax
sahf
jae .u2ch
fchs
fstp dword[angle] ;if (u2 < 0) angle *= -1
.u2ch:
stdcall gl_M4_Rotate, ecx,[angle],2
jmp .end_sw
@@: ;default:
if DEBUG ;glopRotete
stdcall dbg_print,txt_sp,m_1
end if
; normalize vector
fld dword[u0]
fmul st0,st0
fld dword[u1]
fmul st0,st0
fld dword[u2]
fmul st0,st0
fadd st0,st1
fadd st0,st2
; fst dword[len] ;len = u0*u0+u1*u1+u2*u2
fcom st1
fstsw ax
sahf
je .end_f ;if (len == 0.0f) return
fsqrt
fld1
fdiv st0,st1
; fst dword[len] ;len = 1.0f / sqrt(len)
fld dword[u0]
fmul st0,st1
fstp dword[u0] ;u0 *= len
fld dword[u1]
fmul st0,st1
fstp dword[u1] ;u1 *= len
fld dword[u2]
fmul st0,st1
fstp dword[u2] ;u2 *= len
;st0 = len, st1=..., st2=..., st3 = 0, st4 = angle
; store cos and sin values
finit
fld dword[angle]
fcos
fst dword[cost] ;cost=cos(angle)
fld dword[angle]
fsin
fst dword[sint] ;sint=sin(angle)
; fill in the values
mov ebx,0.0
mov [ecx+3*16 ],ebx ;m[3][0]
mov [ecx+3*16 +4],ebx ;m[3][1]
mov [ecx+3*16 +8],ebx ;m[3][2]
mov [ecx+ 12],ebx ;m[0][3]
mov [ecx+ 16+12],ebx ;m[1][3]
mov [ecx+2*16+12],ebx ;m[2][3]
mov ebx,1.0
mov [ecx+3*16+12],ebx ;m[3][3]
; do the math
; m.m[0][0]=u[0]*u[0]+cost*(1-u[0]*u[0]);
; m.m[1][0]=u[0]*u[1]*(1-cost)-u[2]*sint;
; m.m[2][0]=u[2]*u[0]*(1-cost)+u[1]*sint;
; m.m[0][1]=u[0]*u[1]*(1-cost)+u[2]*sint;
; m.m[1][1]=u[1]*u[1]+cost*(1-u[1]*u[1]);
; m.m[2][1]=u[1]*u[2]*(1-cost)-u[0]*sint;
; m.m[0][2]=u[2]*u[0]*(1-cost)-u[1]*sint;
; m.m[1][2]=u[1]*u[2]*(1-cost)+u[0]*sint;
; m.m[2][2]=u[2]*u[2]+cost*(1-u[2]*u[2]);
.end_sw:
mov eax,[context]
mov ebx,[eax+offs_cont_matrix_mode]
shl ebx,2
add ebx,eax
stdcall gl_M4_MulLeft,dword[ebx+offs_cont_matrix_stack_ptr],ecx
if DEBUG ;glopRotete
stdcall gl_print_matrix,ecx,4
end if
gl_matrix_update eax,ebx
.end_f:
ret
endp
align 4
proc glopScale uses eax ebx ecx, context:dword, p:dword
mov ecx,[p]
mov eax,[context]
mov ebx,[eax+offs_cont_matrix_mode]
shl ebx,2
add ebx,eax
mov ebx,[ebx+offs_cont_matrix_stack_ptr] ;ebx = &m[0]
fld dword[ecx+ 4] ;x
fld dword[ecx+ 8] ;y
fld dword[ecx+12] ;z
mov ecx,4
@@:
fld dword[ebx] ;m[0]
fmul st0,st3 ;m[0] * x
fstp dword[ebx] ;m[0] *= x
fld dword[ebx+4] ;m[1]
fmul st0,st2 ;m[1] * y
fstp dword[ebx+4];m[1] *= y
fld dword[ebx+8] ;m[2]
fmul st0,st1 ;m[2] * z
fstp dword[ebx+8];m[2] *= z
add ebx,16
loop @b
if DEBUG ;glopScale
mov ebx,[eax+offs_cont_matrix_mode]
shl ebx,2
add ebx,eax
stdcall gl_print_matrix,[ebx+offs_cont_matrix_stack_ptr],4
end if
gl_matrix_update eax,ebx
ret
endp
align 4
proc glopTranslate uses eax ebx ecx, context:dword, p:dword
mov ecx,[p]
mov eax,[context]
mov ebx,[eax+offs_cont_matrix_mode]
shl ebx,2
add ebx,eax
mov ebx,[ebx+offs_cont_matrix_stack_ptr] ;ebx = &m[0]
fld dword[ecx+ 4] ;x
fld dword[ecx+ 8] ;y
fld dword[ecx+12] ;z
mov ecx,4
@@:
fld dword[ebx] ;m[0]
fmul st0,st3 ;m[0] * x
fld dword[ebx+4] ;m[1]
fmul st0,st3 ;m[1] * y
fld dword[ebx+8] ;m[2]
fmul st0,st3 ;m[2] * z
fadd st0,st1
fadd st0,st2
fadd dword[ebx+12] ;m[3]
fstp dword[ebx+12] ;m[3] = m[0] * x + m[1] * y + m[2] * z + m[3]
ffree st0
fincstp
ffree st0
fincstp
add ebx,16
loop @b
if DEBUG ;glopTranslate
mov ebx,[eax+offs_cont_matrix_mode]
shl ebx,2
add ebx,eax
stdcall gl_print_matrix,[ebx+offs_cont_matrix_stack_ptr],4
end if
gl_matrix_update eax,ebx
ret
endp
align 4
proc glopFrustum uses eax ebx ecx, context:dword, p:dword
locals
x dd ?
y dd ?
A dd ?
B dd ?
C dd ?
D dd ?
m M4
endl
mov eax,[context]
mov ebx,[p]
fld dword[ebx+8]
fsub dword[ebx+4] ;st0 = (right-left)
fld dword[ebx+20] ;st0 = near
fadd st0,st0
fdiv st0,st1
fstp dword[x] ;x = (2.0*near) / (right-left)
fld dword[ebx+16]
fsub dword[ebx+12] ;st0 = (top-bottom)
fld dword[ebx+20] ;st0 = near
fadd st0,st0
fdiv st0,st1
fstp dword[y] ;y = (2.0*near) / (top-bottom)
fld dword[ebx+8]
fadd dword[ebx+4] ;st0 = (right+left)
fdiv st0,st2 ;st2 = (right-left)
fstp dword[A] ;A = (right+left) / (right-left)
fld dword[ebx+16]
fadd dword[ebx+12] ;st0 = (top+bottom)
fdiv st0,st1 ;st1 = (top-bottom)
fstp dword[B] ;B = (top+bottom) / (top-bottom)
fld dword[ebx+24]
fsub dword[ebx+20] ;st0 = (farp-near)
fldz
fsub dword[ebx+24]
fsub dword[ebx+20] ;st0 = -(farp+near)
fdiv st0,st1
fstp dword[C] ;C = -(farp+near) / (farp-near)
fld dword[ebx+24]
fmul dword[ebx+20] ;st0 = farp*near
fadd st0,st0
fchs ;st0 = -(2.0*farp*near)
fdiv st0,st1
fstp dword[D] ;D = -(2.0*farp*near) / (farp-near)
mov ecx,ebp
sub ecx,sizeof.M4
mov ebx,[x]
mov dword[ecx],ebx
mov dword[ecx+4],0.0
mov ebx,[A]
mov dword[ecx+8],ebx
mov dword[ecx+12],0.0
mov dword[ecx+16],0.0
mov ebx,[y]
mov dword[ecx+20],ebx
mov ebx,[B]
mov dword[ecx+24],ebx
mov dword[ecx+28],0.0
mov dword[ecx+32],0.0
mov dword[ecx+36],0.0
mov ebx,[C]
mov dword[ecx+40],ebx
mov ebx,[D]
mov dword[ecx+44],ebx
mov dword[ecx+48],0.0
mov dword[ecx+52],0.0
mov dword[ecx+56],-1.0
mov dword[ecx+60],0.0
mov ebx,[eax+offs_cont_matrix_mode]
shl ebx,2
add ebx,eax
stdcall gl_M4_MulLeft,dword[ebx+offs_cont_matrix_stack_ptr],ecx
if DEBUG ;glopFrustum
stdcall gl_print_matrix,ecx,4
stdcall gl_print_matrix,dword[ebx+offs_cont_matrix_stack_ptr],4
end if
gl_matrix_update eax,ebx
ret
endp