kolibrios/programs/develop/libraries/TinyGL/asm_fork/specbuf.asm
IgorA b096a68434 fix rev 6100 and optimize
git-svn-id: svn://kolibrios.org@6101 a494cfbc-eb01-0410-851d-a64ba20cac60
2016-01-26 19:28:56 +00:00

125 lines
3.3 KiB
NASM

;
; функции для вычисления зеркального цвета (блики)
;
align 4
proc calc_buf uses ebx ecx, buf:dword, shininess:dword
locals
val dd ? ;float
f_inc dd ? ;float
endl
mov dword[f_inc],SPECULAR_BUFFER_SIZE
mov ebx,[buf]
add ebx,offs_spec_buf
mov dword[ebx],0.0 ;buf.buf[0] = 0.0
xor ecx,ecx
inc ecx
fld dword[shininess] ;сначала берем y
fld1
fidiv dword[f_inc]
fst dword[f_inc] ;f_inc = 1.0f/SPECULAR_BUFFER_SIZE
fst dword[val]
align 4
.cycle_0: ;for (i = 1; i <= SPECULAR_BUFFER_SIZE; i++)
cmp ecx,SPECULAR_BUFFER_SIZE
jg @f
;Вычисляем x^y
fyl2x ;Стек FPU теперь содержит: st0=z=y*log2(x):
;Теперь считаем 2**z:
fld st0 ;Создаем еще одну копию z
frndint ;Округляем
fsubr st0,st1 ;st1=z, st0=z-trunc(z)
f2xm1 ;st1=z, st0=2**(z-trunc(z))-1
fld1
faddp ;st1=z, st0=2**(z-trunc(z))
fscale ;st1=z, st0=(2**trunc(z))*(2**(z-trunc(z)))=2**t
fxch st1
fstp st ;Результат остается на вершине стека st0
add ebx,4
fstp dword[ebx] ;buf.buf[i] = pow(val, shininess)
ffree st0 ;испорченный shininess
fincstp
fld dword[shininess] ;сначала берем y
fld dword[val]
fadd dword[f_inc]
fst dword[val] ;val += f_inc
inc ecx
jmp .cycle_0
@@:
ffree st0 ;val
fincstp
ffree st0 ;shininess
fincstp
ret
endp
align 4
proc specbuf_get_buffer uses ebx ecx edx, context:dword, shininess_i:dword, shininess:dword
locals
found dd ? ;GLSpecBuf *
oldest dd ? ;GLSpecBuf *
endl
mov edx,[context]
mov eax,[edx+offs_cont_specbuf_first]
mov [found],eax
mov [oldest],eax
mov ebx,[shininess_i]
.cycle_0:
or eax,eax ;while (found)
jz @f
cmp [eax+offs_spec_shininess_i],ebx ;while (found.shininess_i != shininess_i)
je @f
mov ecx,[oldest]
mov ecx,[ecx+offs_spec_last_used]
cmp [eax+offs_spec_last_used],ecx ;if (found.last_used < oldest.last_used)
jge .end_0
mov [oldest],eax ;oldest = found
.end_0:
mov eax,[eax+offs_spec_next] ;found = found.next
jmp .cycle_0
@@:
cmp dword[found],0 ;if (found) /* hey, found one! */
je @f
mov eax,[found]
mov ecx,[edx+offs_cont_specbuf_used_counter]
mov [eax+offs_spec_last_used],ecx ;found.last_used = context.specbuf_used_counter
inc dword[edx+offs_cont_specbuf_used_counter]
jmp .end_f ;return found
@@:
cmp dword[oldest],0 ;if (oldest == NULL || context.specbuf_num_buffers < MAX_SPECULAR_BUFFERS)
je @f
cmp dword[edx+offs_cont_specbuf_num_buffers],MAX_SPECULAR_BUFFERS
jge .end_1
@@:
; create new buffer
stdcall gl_malloc, sizeof.GLSpecBuf
or eax,eax
jnz @f
;gl_fatal_error("could not allocate specular buffer")
@@:
inc dword[edx+offs_cont_specbuf_num_buffers]
mov ecx,[edx+offs_cont_specbuf_first]
mov [eax+offs_spec_next],ecx
mov [edx+offs_cont_specbuf_first],eax
mov ecx,[edx+offs_cont_specbuf_used_counter]
mov [eax+offs_spec_last_used],ecx
inc dword[edx+offs_cont_specbuf_used_counter]
mov [eax+offs_spec_shininess_i],ebx
stdcall calc_buf, eax,dword[shininess]
jmp .end_f
.end_1:
; overwrite the lru buffer
;tgl_trace("overwriting spec buffer :(\n");
mov eax,[oldest]
mov [eax+offs_spec_shininess_i],ebx
mov ecx,[edx+offs_cont_specbuf_used_counter]
mov [eax+offs_spec_last_used],ecx
inc dword[edx+offs_cont_specbuf_used_counter]
stdcall calc_buf, eax,dword[shininess]
.end_f:
ret
endp