Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
5269 IgorA 1
align 4
2
sp128f dd 128.0
5153 IgorA 3
 
4
align 4
5256 IgorA 5
proc glopMaterial uses eax ebx ecx edi esi, context:dword, p:dword
6
; edi -> GLMaterial *m
7
	mov eax,[context]
8
	mov ebx,[p]
9
	mov ecx,[ebx+4] ;ecx = p[1]
5153 IgorA 10
 
5256 IgorA 11
	cmp ecx,GL_FRONT_AND_BACK ;if (mode == GL_FRONT_AND_BACK)
12
	jne @f
13
		mov dword[ebx+4],GL_FRONT ;p[1].i=GL_FRONT
14
		mov edi,ebp
15
		add edi,12
16
		stdcall glopMaterial,eax,edi
17
		mov ecx,GL_BACK
18
	@@:
5269 IgorA 19
	mov edi,eax
20
	add edi,offs_cont_materials
5256 IgorA 21
	cmp ecx,GL_FRONT ;if (mode == GL_FRONT) m=&context.materials[0]
22
	je @f
23
		add edi,sizeof.GLMaterial ;else m=&context.materials[1]
24
	@@:
5153 IgorA 25
 
5256 IgorA 26
	mov ecx,4
27
	mov esi,ebx ;esi = &p
28
	add esi,12 ;esi = &p[3]
29
	mov ebx,[ebx+8] ;ebx = p[2]
30
	cmp ebx,GL_EMISSION
31
	jne @f
32
		;add edi,offs_mate_emission ;offs_mate_emission=0
33
		rep movsd
34
		jmp .end_f
35
	@@:
36
	cmp ebx,GL_AMBIENT
37
	jne @f
38
		add edi,offs_mate_ambient
39
		rep movsd
40
		jmp .end_f
41
	@@:
42
	cmp ebx,GL_DIFFUSE
43
	jne @f
44
		add edi,offs_mate_diffuse
45
		rep movsd
46
		jmp .end_f
47
	@@:
48
	cmp ebx,GL_SPECULAR
49
	jne @f
50
		add edi,offs_mate_specular
51
		rep movsd
52
		jmp .end_f
53
	@@:
54
	cmp ebx,GL_SHININESS
55
	jne @f
56
		fld dword[esi]
57
		add edi,offs_mate_shininess
58
		movsd
59
		mov dword[edi],SPECULAR_BUFFER_RESOLUTION
5269 IgorA 60
		fdiv dword[sp128f]
5256 IgorA 61
		fimul dword[edi]
62
		fistp dword[edi] ;m.shininess_i = (v[0]/128.0f)*SPECULAR_BUFFER_RESOLUTION
63
		jmp .end_f
64
	@@:
65
	cmp ebx,GL_AMBIENT_AND_DIFFUSE
66
	jne @f
67
		add edi,offs_mate_ambient
68
		rep movsd
69
		sub esi,16
70
		;edi = &offs_mate_diffuse
71
		mov ecx,4
72
		rep movsd
73
		jmp .end_f
74
	@@: ;default
5153 IgorA 75
;    assert(0);
5256 IgorA 76
	.end_f:
5153 IgorA 77
	ret
78
endp
79
 
80
align 4
81
proc glopColorMaterial uses eax ebx ecx, context:dword, p:dword
82
	mov eax,[context]
83
	mov ebx,[p]
84
	mov ecx,[ebx+4] ;ecx = p[1]
85
	mov dword[eax+offs_cont_current_color_material_mode],ecx
86
	mov ecx,[ebx+8] ;ecx = p[2]
87
	mov dword[eax+offs_cont_current_color_material_type],ecx
88
	ret
89
endp
90
 
5218 IgorA 91
align 4
5256 IgorA 92
proc glopLight context:dword, p:dword
93
locals
94
	pos V4
95
endl
96
pushad
5218 IgorA 97
	mov eax,[context]
98
	mov ebx,[p]
99
	mov edx,[ebx+4] ;edx = p[1]
100
 
101
;  assert(edx >= GL_LIGHT0 && edx < GL_LIGHT0+MAX_LIGHTS );
102
 
103
	sub edx,GL_LIGHT0
104
	imul edx,sizeof.GLLight
105
	add edx,eax
106
	add edx,offs_cont_lights
107
 
108
	mov ecx,[ebx+8] ;ecx = p[2]
109
	cmp ecx,GL_AMBIENT
110
	jne @f
111
		mov esi,ebx
112
		add esi,12
113
		mov edi,edx
114
		;add edi,offs_ligh_ambient ;offs_ligh_ambient = 0
115
		mov ecx,4
116
		rep movsd ;l.ambient=v
117
		jmp .end_f
118
	@@:
119
	cmp ecx,GL_DIFFUSE
120
	jne @f
121
		mov esi,ebx
122
		add esi,12
123
		mov edi,edx
124
		add edi,offs_ligh_diffuse
125
		mov ecx,4
126
		rep movsd ;l.diffuse=v
127
		jmp .end_f
128
	@@:
129
	cmp ecx,GL_SPECULAR
130
	jne @f
131
		mov esi,ebx
132
		add esi,12
133
		mov edi,edx
134
		add edi,offs_ligh_specular
135
		mov ecx,4
136
		rep movsd ;l.specular=v
137
		jmp .end_f
138
	@@:
139
	cmp ecx,GL_POSITION
140
	jne @f
5256 IgorA 141
		mov edi,ebx ;ebx = [ebp+12] = [p] = &p[0]
142
		add edi,12 ;&p[3]
143
		mov esi,ebp
144
		sub esi,16 ;&pos
145
		stdcall gl_M4_MulV4, esi,dword[eax+offs_cont_matrix_stack_ptr],edi
146
		mov edi,edx
147
		add edi,offs_ligh_position
148
		mov ecx,4
149
		rep movsd ;l.position=pos
150
 
151
		fld dword[edi-4] ;if(l.position.v[3] == 0)
152
		ftst
153
		fstsw ax
154
		sahf
155
		jne .end_i
156
			;mov esi,ebp
157
			sub esi,16 ;&pos
158
			mov edi,edx
159
			add edi,offs_ligh_norm_position
160
			mov ecx,3
161
			rep movsd ;l.norm_position=pos[1,2,3]
162
 
163
			;mov edi,edx
164
			;add edi,offs_ligh_norm_position
165
			sub edi,12
166
			stdcall gl_V3_Norm,edi ;&l.norm_position
167
		.end_i:
168
		ffree st0
169
		fincstp
5218 IgorA 170
		jmp .end_f
171
	@@:
172
	cmp ecx,GL_SPOT_DIRECTION
173
	jne @f
5256 IgorA 174
		mov esi,ebx ;&p[0]
5218 IgorA 175
		add esi,12
176
		mov edi,edx
177
		add edi,offs_ligh_spot_direction
178
		mov ecx,3
179
		rep movsd ;l.spot_direction=v[0,1,2]
5269 IgorA 180
		;mov esi,ebx
181
		;add esi,12
182
		sub esi,12
183
		;mov edi,edx
184
		;add edi,offs_ligh_norm_spot_direction
185
		add edi,offs_ligh_norm_spot_direction-(offs_ligh_spot_direction+12)
5218 IgorA 186
		mov ecx,3
187
		rep movsd ;l.norm_spot_direction=v[0,1,2]
188
		add edx,offs_ligh_norm_spot_direction
189
		stdcall gl_V3_Norm,edx
190
		jmp .end_f
191
	@@:
192
	cmp ecx,GL_SPOT_EXPONENT
193
	jne @f
194
		mov ecx,[ebx+12]
195
		mov [edi+offs_ligh_spot_exponent],ecx ;l.spot_exponent=p[3]
196
		jmp .end_f
197
	@@:
198
	cmp ecx,GL_SPOT_CUTOFF
5256 IgorA 199
	jne .end_spot_c
200
		fld dword[ebp+12] ;float a=v.v[0]
5153 IgorA 201
;      assert(a == 180 || (a>=0 && a<=90));
5256 IgorA 202
		fst dword[edi+offs_ligh_spot_cutoff] ;l.spot_cutoff=a
203
		fcom dword[an180f] ;if (a != 180)
204
		fstsw ax
205
		sahf
5278 IgorA 206
		je @f
5256 IgorA 207
			fldpi
208
			fmulp
209
			fdiv dword[an180f]
210
			fcos
6013 IgorA 211
			fstp dword[edi+offs_ligh_cos_spot_cutoff] ;l.cos_spot_cutoff=cos(a * M_PI / 180.0)
5256 IgorA 212
			jmp .end_f
213
		@@:
214
		ffree st0
215
		fincstp
5218 IgorA 216
		jmp .end_f
5256 IgorA 217
	.end_spot_c:
5218 IgorA 218
	cmp ecx,GL_CONSTANT_ATTENUATION
5922 IgorA 219
	jne @f
5218 IgorA 220
		mov ecx,[ebx+12]
221
		mov [edi+offs_ligh_attenuation],ecx ;l->attenuation[0]=p[3]
222
		jmp .end_f
223
	@@:
224
	cmp ecx,GL_LINEAR_ATTENUATION
5922 IgorA 225
	jne @f
5218 IgorA 226
		mov ecx,[ebx+12]
227
		mov [edi+offs_ligh_attenuation+4],ecx ;l->attenuation[1]=p[3]
228
		jmp .end_f
229
	@@:
230
	cmp ecx,GL_QUADRATIC_ATTENUATION
5922 IgorA 231
	jne @f
5218 IgorA 232
		mov ecx,[ebx+12]
233
		mov [edi+offs_ligh_attenuation+8],ecx ;l->attenuation[2]=p[3]
234
		jmp .end_f
235
	@@: ;default:
5153 IgorA 236
;    assert(0);
5218 IgorA 237
	.end_f:
5256 IgorA 238
popad
5218 IgorA 239
	ret
240
endp
241
 
5153 IgorA 242
 
243
align 4
244
proc glopLightModel uses ebx ecx esi edi, context:dword, p:dword
245
	mov edi,[context]
246
	mov ebx,[p]
5256 IgorA 247
	mov ebx,[ebx+4]
248
	mov esi,[ebp+12] ;&p[0]
249
	add esi,8 ;&p[2]
5153 IgorA 250
 
5256 IgorA 251
	cmp ebx,GL_LIGHT_MODEL_AMBIENT
5153 IgorA 252
	jne @f
253
		mov ecx,4
5256 IgorA 254
		add edi,offs_cont_ambient_light_model
5153 IgorA 255
		rep movsd ;for(i=0;i<4;i++) context.ambient_light_model.v[i]=v[i]
256
		jmp .end_f
257
	@@:
5256 IgorA 258
	cmp ebx,GL_LIGHT_MODEL_LOCAL_VIEWER
5153 IgorA 259
	jne @f
5256 IgorA 260
		fld dword[esi] ;st0 = p[2]
5153 IgorA 261
		fistp dword[edi+offs_cont_local_light_model]
262
		jmp .end_f
263
	@@:
5256 IgorA 264
	cmp ebx,GL_LIGHT_MODEL_TWO_SIDE
5153 IgorA 265
	jne @f
5256 IgorA 266
		fld dword[esi] ;st0 = p[2]
5153 IgorA 267
		fistp dword[edi+offs_cont_light_model_two_side]
268
		jmp .end_f
269
	@@: ;default:
5256 IgorA 270
;    tgl_warning("glopLightModel: illegal pname: 0x%x\n", ebx);
5153 IgorA 271
;    //assert(0);
272
	.end_f:
273
	ret
274
endp
275
 
5256 IgorA 276
macro clampf a, min, max
277
{
278
local .o_1
279
local .o_2
280
local .end_m
281
	fld dword a ;if (a<=0.0)
282
	ftst
283
	fstsw ax
284
	sahf
285
	ja .o_1
286
		ffree st0
287
		fincstp
288
		mov eax,0.0
289
		jmp .end_m ;return 0.0
290
	.o_1:
291
	fld1 ;else if (a>=1.0)
292
	fcompp
293
	fstsw ax
294
	sahf
5278 IgorA 295
	ja .o_2
5256 IgorA 296
		mov eax,1.0
297
		jmp .end_m ;return 1.0
298
	.o_2:
299
	mov eax,dword a ;else return a
300
	.end_m:
301
}
5153 IgorA 302
 
303
align 4
304
proc gl_enable_disable_light uses eax ebx ecx, context:dword, light:dword, v:dword
305
	mov eax,[context]
306
	mov ebx,[light]
307
	imul ebx,sizeof.GLLight
5256 IgorA 308
	add ebx,eax
309
	add ebx,offs_cont_lights
5153 IgorA 310
 
311
	xor ecx,ecx
312
	cmp dword[ebx+offs_ligh_enabled],0
313
	jne @f
314
		not ecx
315
	@@:
316
	and ecx,[v]
5256 IgorA 317
	or ecx,ecx
318
	jz @f
5153 IgorA 319
		;if (v && !l.enabled)
320
		mov dword[ebx+offs_ligh_enabled],1
321
		mov ecx,[eax+offs_cont_first_light]
322
		mov [ebx+offs_ligh_next],ecx
323
		mov [eax+offs_cont_first_light],ebx ;context.first_light = l
324
		mov dword[ebx+offs_ligh_prev],0 ;l.prev = NULL
325
		jmp .end_f
326
	@@:
327
	xor ecx,ecx
328
	cmp dword[v],0
329
	jne @f
330
		not ecx
331
	@@:
332
	and ecx,[ebx+offs_ligh_enabled]
5256 IgorA 333
	or ecx,ecx
334
	jz .end_f
5153 IgorA 335
		;else if (!v && l.enabled)
336
		mov dword[ebx+offs_ligh_enabled],0 ;l.enabled = 0
337
		mov ecx,[ebx+offs_ligh_next]
338
		cmp dword[ebx+offs_ligh_prev],0 ;if (l.prev == NULL)
339
		jne .els_0
340
			mov [eax+offs_cont_first_light],ecx	;context.first_light = l.next
341
			jmp @f
342
		.els_0:
343
			mov eax,[ebx+offs_ligh_prev]
344
			mov [eax+offs_ligh_next],ecx ;l.prev.next = l.next
345
		@@:
346
		cmp dword[ebx+offs_ligh_next],0
347
		je .end_f
348
			mov ecx,[ebx+offs_ligh_prev]
349
			mov eax,[ebx+offs_ligh_next]
350
			mov [eax+offs_ligh_prev],ecx ;l.next.prev = l.prev
351
	.end_f:
352
	ret
353
endp
354
 
5256 IgorA 355
align 4
356
fl_1e_3 dd 1.0e-3
357
 
5153 IgorA 358
; non optimized lightening model
359
align 4
360
proc gl_shade_vertex, context:dword, v:dword
5256 IgorA 361
locals
5278 IgorA 362
	R dd ? ;float ebp-96
363
	G dd ? ;float ebp-92
364
	B dd ? ;float ebp-88
365
	A dd ? ;float ebp-84
366
	s V3 ;ebp-80
367
	d V3 ;ebp-68
5262 IgorA 368
	tmp dd ? ;float ebp-56
369
	att dd ? ;float ebp-52
370
	dot_spot dd ? ;float ebp-48
371
	lR dd ? ;float ebp-44
372
	lB dd ? ;float ebp-40
373
	lG dd ? ;float ebp-36
374
	twoside dd ? ;int ebp-32
375
	idx dd ? ;int ebp-28
5256 IgorA 376
	n V3 ;ebp-24
377
	vcoord V3 ;ebp-12
378
endl
379
pushad
380
; ebx -> GLLight *l
381
; ecx -> GLMaterial *m
382
; esi -> GLVertex *v
6093 IgorA 383
 
384
;n = v.normal
385
;d = l.position
386
;   diffuse light
387
;dot = d*n
388
;dot_spot = d*l.norm_spot_direction
389
;   specular light
390
;s = d-v.ec
391
;dot_spec = n*s
392
 
5256 IgorA 393
	mov esi,[v]
394
	mov edx,[context]
5269 IgorA 395
	mov ecx,edx
396
	add ecx,offs_cont_materials ;ecx(m) = &context.materials[0]
5256 IgorA 397
	mov eax,[edx+offs_cont_light_model_two_side]
398
	mov [twoside],eax
5153 IgorA 399
 
5256 IgorA 400
	add esi,offs_vert_normal
401
	mov edi,ebp
402
	sub edi,24 ;edi = &n
403
	movsd ;n.X=v.normal.X
404
	movsd ;n.Y=v.normal.Y
405
	movsd ;n.Z=v.normal.Z
406
	mov esi,[v]
5153 IgorA 407
 
5256 IgorA 408
	fld dword[edx+offs_cont_ambient_light_model]
409
	fmul dword[ecx+offs_mate_ambient]
410
	fadd dword[ecx] ;offs_mate_emission=0
411
	fstp dword[R] ;R=m.emission.v[0]+m.ambient.v[0]*context.ambient_light_model.v[0]
412
	fld dword[edx+offs_cont_ambient_light_model+4]
413
	fmul dword[ecx+offs_mate_ambient+4]
414
	fadd dword[ecx+offs_mate_emission+4]
415
	fstp dword[G]
416
	fld dword[edx+offs_cont_ambient_light_model+8]
417
	fmul dword[ecx+offs_mate_ambient+8]
418
	fadd dword[ecx+offs_mate_emission+8]
419
	fstp dword[B]
420
	clampf [ecx+offs_mate_diffuse+12],0,1
421
	mov [A],eax ;A=clampf(m.diffuse.v[3],0,1)
5153 IgorA 422
 
5256 IgorA 423
	mov ebx,[edx+offs_cont_first_light]
424
	.cycle_0: ;for(l=context.first_light;l!=NULL;l=l.next)
425
		or ebx,ebx
426
		jz .cycle_0_end
5153 IgorA 427
 
5256 IgorA 428
		; ambient
429
		fld dword[ecx+offs_mate_ambient]
5262 IgorA 430
		fmul dword[ebx] ;offs_ligh_ambient=0
5256 IgorA 431
		fstp dword[lR] ;lR=l.ambient.v[0] * m.ambient.v[0]
432
		fld dword[ecx+offs_mate_ambient+4]
433
		fmul dword[ebx+offs_ligh_ambient+4]
434
		fstp dword[lG] ;lG=l.ambient.v[1] * m.ambient.v[1]
435
		fld dword[ecx+offs_mate_ambient+8]
436
		fmul dword[ebx+offs_ligh_ambient+8]
437
		fstp dword[lB] ;lB=l.ambient.v[2] * m.ambient.v[2]
5153 IgorA 438
 
5269 IgorA 439
		fld dword[ebx+offs_ligh_position+offs_W]
440
		ftst ;if (l.position.v[3] == 0)
441
		fstsw ax
442
		sahf
5256 IgorA 443
		jne .els_0
444
			; light at infinity
5269 IgorA 445
			ffree st0 ;l.position.v[3]
446
			fincstp
6093 IgorA 447
			mov eax,[ebx+offs_ligh_norm_position]
448
			mov [d],eax ;d.X=l.norm_position.v[0]
449
			mov eax,[ebx+offs_ligh_norm_position+offs_Y]
450
			mov [d+offs_Y],eax ;d.Y=l.norm_position.v[1]
451
			mov eax,[ebx+offs_ligh_norm_position+offs_Z]
452
			mov [d+offs_Z],eax ;d.Z=l.norm_position.v[2]
5256 IgorA 453
			mov dword[att],1.0
454
			jmp .els_0_end
455
		.els_0:
456
			; distance attenuation
5269 IgorA 457
			ffree st0 ;l.position.v[3]
458
			fincstp
5256 IgorA 459
			fld dword[ebx+offs_ligh_position]
460
			fsub dword[esi+offs_vert_ec]
461
			fstp dword[d] ;d.X=l.position.v[0]-v.ec.v[0]
462
			fld dword[ebx+offs_ligh_position+offs_Y]
463
			fsub dword[esi+offs_vert_ec+offs_Y]
464
			fstp dword[d+offs_Y] ;d.Y=l.position.v[1]-v.ec.v[1]
465
			fld dword[ebx+offs_ligh_position+offs_Z]
466
			fsub dword[esi+offs_vert_ec+offs_Z]
467
			fstp dword[d+offs_Z] ;d.Z=l.position.v[2]-v.ec.v[2]
468
			fld dword[d]
469
			fmul st0,st0
470
			fld dword[d+offs_Y]
471
			fmul st0,st0
472
			faddp
473
			fld dword[d+offs_Z]
474
			fmul st0,st0
475
			faddp
5278 IgorA 476
			fsqrt ;dist=sqrt(d.X^2+d.Y^2+d.Z^2)
5256 IgorA 477
			fcom dword[fl_1e_3]
478
			fstsw ax
479
			sahf
480
			jbe @f ;if (dist>1.0e-3)
481
				fld1
482
				fdiv st0,st1
483
				fld dword[d]
484
				fmul st0,st1
485
				fstp dword[d]
486
				fld dword[d+offs_Y]
487
				fmul st0,st1
488
				fstp dword[d+offs_Y]
489
				fld dword[d+offs_Z]
490
				fmul st0,st1
491
				fstp dword[d+offs_Z]
492
				ffree st0 ;1.0/dist
493
				fincstp
494
			@@:
495
			fld dword[ebx+offs_ligh_attenuation+8]
496
			fmul st0,st1 ;st0 = dist * l.attenuation[2]
497
			fadd dword[ebx+offs_ligh_attenuation+4]
498
			fmul st0,st1
499
			fadd dword[ebx+offs_ligh_attenuation]
500
			fld1
501
			fdiv st0,st1
502
			fstp dword[att] ;att = 1.0f/(l.attenuation[0]+dist*(l.attenuation[1]+dist*l.attenuation[2]))
503
			ffree st0 ;1.0
504
			fincstp
505
			ffree st0 ;dist
506
			fincstp
507
		.els_0_end:
508
		fld dword[d]
509
		fmul dword[n]
510
		fld dword[d+offs_Y]
511
		fmul dword[n+offs_Y]
512
		faddp
513
		fld dword[d+offs_Z]
514
		fmul dword[n+offs_Z]
515
		faddp ;dot = d.X*n.X+d.Y*n.Y+d.Z*n.Z
516
		cmp dword[twoside],0 ;if (twoside && dot < 0)
517
		je @f
518
		ftst ;if (dot<0)
519
		fstsw ax
520
		sahf
521
		jae @f
522
			fchs ;dot = -dot
523
		@@:
524
		ftst ;if (dot>0)
525
		fstsw ax
526
		sahf
5269 IgorA 527
		jbe .if0_end
5256 IgorA 528
			; diffuse light
529
			fld dword[ecx+offs_mate_diffuse]
530
			fmul dword[ebx+offs_ligh_diffuse]
531
			fmul st0,st1
532
			fadd dword[lR]
533
			fstp dword[lR] ;lR+=dot * l.diffuse.v[0] * m.diffuse.v[0]
534
			fld dword[ecx+offs_mate_diffuse+4]
535
			fmul dword[ebx+offs_ligh_diffuse+4]
536
			fmul st0,st1
537
			fadd dword[lG]
538
			fstp dword[lG] ;lG+=dot * l.diffuse.v[1] * m.diffuse.v[1]
539
			fld dword[ecx+offs_mate_diffuse+8]
540
			fmul dword[ebx+offs_ligh_diffuse+8]
541
			fmul st0,st1
542
			fadd dword[lB]
543
			fstp dword[lB] ;lB+=dot * l.diffuse.v[2] * m.diffuse.v[2]
544
			ffree st0 ;dot
545
			fincstp
5153 IgorA 546
 
5256 IgorA 547
			; spot light
548
			fld dword[ebx+offs_ligh_spot_cutoff]
549
			fcomp dword[an180f] ;if (l.spot_cutoff != 180)
550
			fstsw ax
551
			sahf
5278 IgorA 552
			je .if1_end
5256 IgorA 553
				fld dword[ebx+offs_ligh_norm_spot_direction]
554
				fmul dword[d]
6093 IgorA 555
				fld dword[ebx+offs_ligh_norm_spot_direction+offs_Y]
5256 IgorA 556
				fmul dword[d+offs_Y]
557
				faddp
6093 IgorA 558
				fld dword[ebx+offs_ligh_norm_spot_direction+offs_Z]
5256 IgorA 559
				fmul dword[d+offs_Z]
560
				faddp
561
				fchs
562
				fst dword[dot_spot]
563
				cmp dword[twoside],0 ;if (twoside && dot_spot < 0)
564
				je @f
565
				ftst ;if (dot_spot<0)
566
				fstsw ax
567
				sahf
568
				jae @f
569
					fchs ;dot_spot = -dot_spot
570
				@@:
571
				fcom dword[ebx+offs_ligh_cos_spot_cutoff] ;if (dot_spot < l.cos_spot_cutoff)
572
				fstsw ax
573
				sahf
574
				jae .els_1
575
					; no contribution
576
					ffree st0 ;dot_spot
577
					fincstp
578
					mov ebx,[ebx+offs_ligh_next]
579
					jmp .cycle_0 ;continue
580
				.els_1:
581
					; TODO: optimize
582
					fld dword[ebx+offs_ligh_spot_exponent]
583
					ftst ;if (l.spot_exponent > 0)
584
					fstsw ax
585
					sahf
586
					jbe @f
587
						fxch st1 ;dot_spot <--> l.spot_exponent
588
						;Вычисляем x^y
589
						;fld y
590
						;fld x
591
						fyl2x ;Стек FPU теперь содержит: st0=z=y*log2(x):
592
						;Теперь считаем 2**z:
593
						fld st0 ;Создаем еще одну копию z
594
						frndint ;Округляем
595
						fsubr st0,st1  ;st1=z, st0=z-trunc(z)
596
						f2xm1  ;st1=z, st0=2**(z-trunc(z))-1
597
						fld1
598
						faddp  ;st1=z, st0=2**(z-trunc(z))
599
						fscale ;st1=z, st0=(2**trunc(z))*(2**(z-trunc(z)))=2**t
600
						fxch st1
601
						fstp st ;Результат остается на вершине стека st0
602
						fmul dword[att]
603
						fstp dword[att] ;att=att*pow(dot_spot,l.spot_exponent)
5387 IgorA 604
						jmp .if1_end_f1
5256 IgorA 605
					@@:
606
					ffree st0 ;l.spot_exponent
607
					fincstp
5387 IgorA 608
					.if1_end_f1:
5256 IgorA 609
					ffree st0 ;dot_spot
610
					fincstp
611
			.if1_end:
5153 IgorA 612
 
5256 IgorA 613
			; specular light
614
			cmp dword[edx+offs_cont_local_light_model],0 ;if (c.local_light_model)
615
			je .els_2
616
				mov eax,[esi+offs_vert_ec]
617
				mov [vcoord],eax ;vcoord.X=v.ec.X
618
				mov eax,[esi+offs_vert_ec+offs_Y]
619
				mov [vcoord+offs_Y],eax ;vcoord.Y=v.ec.Y
620
				mov eax,[esi+offs_vert_ec+offs_Z]
621
				mov [vcoord+offs_Z],eax ;vcoord.Z=v.ec.Z
622
				mov eax,ebp
623
				sub eax,12 ;eax = &vcoord
624
				stdcall gl_V3_Norm, eax
625
				fld dword[d]
626
				fsub dword[vcoord]
627
				fstp dword[s] ;s.X=d.X-vcoord.X
628
				fld dword[d+offs_Y]
629
				fsub dword[vcoord+offs_Y]
630
				fstp dword[s+offs_Y] ;s.Y=d.Y-vcoord.Y
631
				fld dword[d+offs_Z]
632
				fsub dword[vcoord+offs_Z]
633
				fstp dword[s+offs_Z] ;s.Z=d.Z-vcoord.Z
634
				jmp .els_2_end
635
			.els_2:
636
				mov eax,[d]
637
				mov [s],eax ;s.X=d.X
638
				mov eax,[d+offs_Y]
639
				mov [s+offs_Y],eax ;s.Y=d.Y
640
				fld1
641
				fadd dword[d+offs_Z]
642
				fstp dword[s+offs_Z] ;s.Z=d.Z+1.0
643
			.els_2_end:
644
			fld dword[n]
5387 IgorA 645
			fmul dword[s]
5256 IgorA 646
			fld dword[n+offs_Y]
5387 IgorA 647
			fmul dword[s+offs_Y]
5256 IgorA 648
			faddp
649
			fld dword[n+offs_Z]
5387 IgorA 650
			fmul dword[s+offs_Z]
651
			faddp ;dot_spec = n.X*s.X +n.Y*s.Y +n.Z*s.Z
5256 IgorA 652
			cmp dword[twoside],0 ;if (twoside && dot_spec < 0)
653
			je @f
654
			ftst ;if (dot_spec < 0)
655
			fstsw ax
656
			sahf
657
			jae @f
658
				fchs ;dot_spec = -dot_spec
659
			@@:
660
			ftst ;if (dot_spec > 0)
661
			fstsw ax
662
			sahf
5269 IgorA 663
			jbe .if0_end
5256 IgorA 664
				fld dword[s]
665
				fmul st0,st0
666
				fld dword[s+offs_Y]
667
				fmul st0,st0
668
				faddp
669
				fld dword[s+offs_Z]
670
				fmul st0,st0
5278 IgorA 671
				faddp ;st0 = s.X^2 +s.Y^2 +s.Z^2
5256 IgorA 672
				fsqrt
673
				fcom dword[fl_1e_3]
674
				fstsw ax
675
				sahf
676
				jbe @f ;if (tmp > 1.0e-3)
677
					fdiv st1,st0 ;dot_spec /= tmp
678
				@@:
679
				ffree st0 ;tmp
680
				fincstp
5153 IgorA 681
 
5256 IgorA 682
				; TODO: optimize
683
				; testing specular buffer code
684
				; dot_spec= pow(dot_spec,m.shininess)
685
				stdcall specbuf_get_buffer, edx, dword[ecx+offs_mate_shininess_i], dword[ecx+offs_mate_shininess]
5262 IgorA 686
				mov edi,eax ;edi = specbuf
5269 IgorA 687
				mov dword[idx],SPECULAR_BUFFER_SIZE ;idx = SPECULAR_BUFFER_SIZE
6101 IgorA 688
 
689
				;idx = (int)(dot_spec*SPECULAR_BUFFER_SIZE)
690
				fimul dword[idx]
691
				fistp dword[idx]
692
				;if (idx > SPECULAR_BUFFER_SIZE) idx = SPECULAR_BUFFER_SIZE
693
				cmp dword[idx],SPECULAR_BUFFER_SIZE
694
				jle @f
695
					mov dword[idx],SPECULAR_BUFFER_SIZE
5256 IgorA 696
				@@:
697
				shl dword[idx],2
5262 IgorA 698
				add edi,dword[idx]
699
				fld dword[edi+offs_spec_buf] ;dot_spec = specbuf.buf[idx]
5256 IgorA 700
				fld dword[ebx+offs_ligh_specular]
701
				fmul st0,st1
702
				fmul dword[ecx+offs_mate_specular]
703
				fadd dword[lR]
704
				fstp dword[lR] ;lR+=dot_spec * l.specular.v[0] * m.specular.v[0]
5262 IgorA 705
				fld dword[ebx+offs_ligh_specular+4]
5256 IgorA 706
				fmul st0,st1
5262 IgorA 707
				fmul dword[ecx+offs_mate_specular+4]
5256 IgorA 708
				fadd dword[lG]
709
				fstp dword[lG] ;lG+=dot_spec * l.specular.v[1] * m.specular.v[1]
5262 IgorA 710
				fld dword[ebx+offs_ligh_specular+8]
5256 IgorA 711
				fmul st0,st1
5262 IgorA 712
				fmul dword[ecx+offs_mate_specular+8]
5256 IgorA 713
				fadd dword[lB]
714
				fstp dword[lB] ;lB+=dot_spec * l.specular.v[2] * m.specular.v[2]
715
		.if0_end:
716
		ffree st0 ;dot [or] dot_spec
717
		fincstp
718
		.if2_end:
5153 IgorA 719
 
5256 IgorA 720
		fld dword[att]
721
		fld dword[lR]
722
		fmul st0,st1
723
		fadd dword[R]
724
		fstp dword[R] ;R += att * lR
725
		fld dword[lG]
726
		fmul st0,st1
727
		fadd dword[G]
728
		fstp dword[G] ;G += att * lG
729
		fld dword[lB]
730
		fmul st0,st1
731
		fadd dword[B]
732
		fstp dword[B] ;B += att * lB
733
		ffree st0 ;att
734
		fincstp
735
		mov ebx,[ebx+offs_ligh_next]
736
		jmp .cycle_0
737
	.cycle_0_end:
5153 IgorA 738
 
5256 IgorA 739
	clampf [R],0,1
740
	mov [esi+offs_vert_color],eax ;v.color.v[0]=clampf(R,0,1)
741
	clampf [G],0,1
742
	mov [esi+offs_vert_color+4],eax ;v.color.v[1]=clampf(G,0,1)
743
	clampf [B],0,1
744
	mov [esi+offs_vert_color+8],eax ;v.color.v[2]=clampf(B,0,1)
745
	mov eax,[A]
746
	mov [esi+offs_vert_color+12],eax ;v.color.v[3]=A
747
popad
5153 IgorA 748
	ret
749
endp
750