Subversion Repositories Kolibri OS

Rev

Rev 5262 | Rev 6101 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6100 IgorA 1
;
2
; функции для вычисления зеркального цвета (блики)
3
;
5256 IgorA 4
 
5
align 4
6
proc calc_buf uses ebx ecx, buf:dword, shininess:dword
7
locals
8
	val dd ? ;float
9
	f_inc dd ? ;float
10
endl
11
	mov dword[val],0.0f
12
	mov dword[f_inc],SPECULAR_BUFFER_SIZE
13
	fld1
14
	fidiv dword[f_inc]
15
	fstp dword[f_inc] ;f_inc = 1.0f/SPECULAR_BUFFER_SIZE
5262 IgorA 16
	mov ebx,[buf]
17
	add ebx,offs_spec_buf
5256 IgorA 18
	xor ecx,ecx
19
align 4
20
	.cycle_0: ;for (i = 0; i <= SPECULAR_BUFFER_SIZE; i++)
21
	cmp ecx,SPECULAR_BUFFER_SIZE
22
	jg @f
23
		;Вычисляем x^y
6100 IgorA 24
		fld dword[val] ;сначала берем y
25
		fld dword[shininess] ;а потом x
5256 IgorA 26
		fyl2x ;Стек FPU теперь содержит: st0=z=y*log2(x):
27
		;Теперь считаем 2**z:
28
		fld st0 ;Создаем еще одну копию z
29
		frndint ;Округляем
30
		fsubr st0,st1  ;st1=z, st0=z-trunc(z)
31
		f2xm1  ;st1=z, st0=2**(z-trunc(z))-1
32
		fld1
33
		faddp  ;st1=z, st0=2**(z-trunc(z))
34
		fscale ;st1=z, st0=(2**trunc(z))*(2**(z-trunc(z)))=2**t
35
		fxch st1
36
		fstp st ;Результат остается на вершине стека st0
37
 
38
		fstp dword[ebx] ;buf.buf[i] = pow(val, shininess)
5262 IgorA 39
		add ebx,4
5256 IgorA 40
 
41
		fld dword[val]
42
		fadd dword[f_inc]
43
		fstp dword[val] ;val += f_inc
44
	inc ecx
45
	jmp .cycle_0
46
	@@:
47
	ret
48
endp
49
 
50
align 4
51
proc specbuf_get_buffer uses ebx ecx edx, context:dword, shininess_i:dword, shininess:dword
52
locals
53
	found dd ? ;GLSpecBuf *
54
	oldest dd ? ;GLSpecBuf *
55
endl
56
	mov edx,[context]
57
	mov eax,[edx+offs_cont_specbuf_first]
58
	mov [found],eax
59
	mov [oldest],eax
60
	mov ebx,[shininess_i]
61
	.cycle_0:
62
	or eax,eax ;while (found)
63
	jz @f
64
	cmp [eax+offs_spec_shininess_i],ebx ;while (found.shininess_i != shininess_i)
65
	je @f
66
		mov ecx,[oldest]
67
		mov ecx,[ecx+offs_spec_last_used]
68
		cmp [eax+offs_spec_last_used],ecx ;if (found.last_used < oldest.last_used)
69
		jge .end_0
70
			mov [oldest],eax ;oldest = found
71
		.end_0:
72
		mov eax,[eax+offs_spec_next] ;found = found.next
73
		jmp .cycle_0
74
	@@:
75
	cmp dword[found],0 ;if (found) /* hey, found one! */
76
	je @f
77
		mov eax,[found]
78
		mov ecx,[edx+offs_cont_specbuf_used_counter]
79
		mov [eax+offs_spec_last_used],ecx ;found.last_used = context.specbuf_used_counter
80
		inc dword[edx+offs_cont_specbuf_used_counter]
81
		jmp .end_f ;return found
82
	@@:
83
	cmp dword[oldest],0 ;if (oldest == NULL || context.specbuf_num_buffers < MAX_SPECULAR_BUFFERS)
84
	je @f
85
	cmp dword[edx+offs_cont_specbuf_num_buffers],MAX_SPECULAR_BUFFERS
6100 IgorA 86
	jge .end_1
5256 IgorA 87
	@@:
88
		; create new buffer
89
	stdcall gl_malloc, sizeof.GLSpecBuf
6100 IgorA 90
	or eax,eax
91
	jnz @f
92
;gl_fatal_error("could not allocate specular buffer")
93
	@@:
5256 IgorA 94
	inc dword[edx+offs_cont_specbuf_num_buffers]
95
	mov ecx,[edx+offs_cont_specbuf_first]
96
	mov [eax+offs_spec_next],ecx
97
	mov [edx+offs_cont_specbuf_first],eax
98
	mov ecx,[edx+offs_cont_specbuf_used_counter]
99
	mov [eax+offs_spec_last_used],ecx
100
	inc dword[edx+offs_cont_specbuf_used_counter]
101
	mov [eax+offs_spec_shininess_i],ebx
102
	stdcall calc_buf, eax,dword[shininess]
103
	jmp .end_f
104
	.end_1:
105
	; overwrite the lru buffer
106
	;tgl_trace("overwriting spec buffer :(\n");
107
	mov eax,[oldest]
108
	mov [eax+offs_spec_shininess_i],ebx
109
	mov ecx,[edx+offs_cont_specbuf_used_counter]
110
	mov [eax+offs_spec_last_used],ecx
111
	inc dword[edx+offs_cont_specbuf_used_counter]
112
	stdcall calc_buf, eax,dword[shininess]
113
	.end_f:
114
	ret
115
endp