Subversion Repositories Kolibri OS

Rev

Rev 5278 | Rev 5922 | 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
211
			fstp dword[edi+offs_ligh_spot_cutoff] ;l.cos_spot_cutoff=cos(a * M_PI / 180.0)
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
219
		mov ecx,[ebx+12]
220
		mov [edi+offs_ligh_attenuation],ecx ;l->attenuation[0]=p[3]
221
		jmp .end_f
222
	@@:
223
	cmp ecx,GL_LINEAR_ATTENUATION
224
		mov ecx,[ebx+12]
225
		mov [edi+offs_ligh_attenuation+4],ecx ;l->attenuation[1]=p[3]
226
		jmp .end_f
227
	@@:
228
	cmp ecx,GL_QUADRATIC_ATTENUATION
229
		mov ecx,[ebx+12]
230
		mov [edi+offs_ligh_attenuation+8],ecx ;l->attenuation[2]=p[3]
231
		jmp .end_f
232
	@@: ;default:
5153 IgorA 233
;    assert(0);
5218 IgorA 234
	.end_f:
5256 IgorA 235
popad
5218 IgorA 236
	ret
237
endp
238
 
5153 IgorA 239
 
240
align 4
241
proc glopLightModel uses ebx ecx esi edi, context:dword, p:dword
242
	mov edi,[context]
243
	mov ebx,[p]
5256 IgorA 244
	mov ebx,[ebx+4]
245
	mov esi,[ebp+12] ;&p[0]
246
	add esi,8 ;&p[2]
5153 IgorA 247
 
5256 IgorA 248
	cmp ebx,GL_LIGHT_MODEL_AMBIENT
5153 IgorA 249
	jne @f
250
		mov ecx,4
5256 IgorA 251
		add edi,offs_cont_ambient_light_model
5153 IgorA 252
		rep movsd ;for(i=0;i<4;i++) context.ambient_light_model.v[i]=v[i]
253
		jmp .end_f
254
	@@:
5256 IgorA 255
	cmp ebx,GL_LIGHT_MODEL_LOCAL_VIEWER
5153 IgorA 256
	jne @f
5256 IgorA 257
		fld dword[esi] ;st0 = p[2]
5153 IgorA 258
		fistp dword[edi+offs_cont_local_light_model]
259
		jmp .end_f
260
	@@:
5256 IgorA 261
	cmp ebx,GL_LIGHT_MODEL_TWO_SIDE
5153 IgorA 262
	jne @f
5256 IgorA 263
		fld dword[esi] ;st0 = p[2]
5153 IgorA 264
		fistp dword[edi+offs_cont_light_model_two_side]
265
		jmp .end_f
266
	@@: ;default:
5256 IgorA 267
;    tgl_warning("glopLightModel: illegal pname: 0x%x\n", ebx);
5153 IgorA 268
;    //assert(0);
269
	.end_f:
270
	ret
271
endp
272
 
5256 IgorA 273
macro clampf a, min, max
274
{
275
local .o_1
276
local .o_2
277
local .end_m
278
	fld dword a ;if (a<=0.0)
279
	ftst
280
	fstsw ax
281
	sahf
282
	ja .o_1
283
		ffree st0
284
		fincstp
285
		mov eax,0.0
286
		jmp .end_m ;return 0.0
287
	.o_1:
288
	fld1 ;else if (a>=1.0)
289
	fcompp
290
	fstsw ax
291
	sahf
5278 IgorA 292
	ja .o_2
5256 IgorA 293
		mov eax,1.0
294
		jmp .end_m ;return 1.0
295
	.o_2:
296
	mov eax,dword a ;else return a
297
	.end_m:
298
}
5153 IgorA 299
 
300
align 4
301
proc gl_enable_disable_light uses eax ebx ecx, context:dword, light:dword, v:dword
302
	mov eax,[context]
303
	mov ebx,[light]
304
	imul ebx,sizeof.GLLight
5256 IgorA 305
	add ebx,eax
306
	add ebx,offs_cont_lights
5153 IgorA 307
 
308
	xor ecx,ecx
309
	cmp dword[ebx+offs_ligh_enabled],0
310
	jne @f
311
		not ecx
312
	@@:
313
	and ecx,[v]
5256 IgorA 314
	or ecx,ecx
315
	jz @f
5153 IgorA 316
		;if (v && !l.enabled)
317
		mov dword[ebx+offs_ligh_enabled],1
318
		mov ecx,[eax+offs_cont_first_light]
319
		mov [ebx+offs_ligh_next],ecx
320
		mov [eax+offs_cont_first_light],ebx ;context.first_light = l
321
		mov dword[ebx+offs_ligh_prev],0 ;l.prev = NULL
322
		jmp .end_f
323
	@@:
324
	xor ecx,ecx
325
	cmp dword[v],0
326
	jne @f
327
		not ecx
328
	@@:
329
	and ecx,[ebx+offs_ligh_enabled]
5256 IgorA 330
	or ecx,ecx
331
	jz .end_f
5153 IgorA 332
		;else if (!v && l.enabled)
333
		mov dword[ebx+offs_ligh_enabled],0 ;l.enabled = 0
334
		mov ecx,[ebx+offs_ligh_next]
335
		cmp dword[ebx+offs_ligh_prev],0 ;if (l.prev == NULL)
336
		jne .els_0
337
			mov [eax+offs_cont_first_light],ecx	;context.first_light = l.next
338
			jmp @f
339
		.els_0:
340
			mov eax,[ebx+offs_ligh_prev]
341
			mov [eax+offs_ligh_next],ecx ;l.prev.next = l.next
342
		@@:
343
		cmp dword[ebx+offs_ligh_next],0
344
		je .end_f
345
			mov ecx,[ebx+offs_ligh_prev]
346
			mov eax,[ebx+offs_ligh_next]
347
			mov [eax+offs_ligh_prev],ecx ;l.next.prev = l.prev
348
	.end_f:
349
	ret
350
endp
351
 
5256 IgorA 352
align 4
353
fl_1e_3 dd 1.0e-3
354
 
5262 IgorA 355
if DEBUG
356
txt_mate db 'Material',0
357
txt_colo db 'Color',0
5278 IgorA 358
txt_rgba db 'R, G, B',0
5262 IgorA 359
end if
360
 
5153 IgorA 361
; non optimized lightening model
362
align 4
363
proc gl_shade_vertex, context:dword, v:dword
5256 IgorA 364
locals
5278 IgorA 365
	R dd ? ;float ebp-96
366
	G dd ? ;float ebp-92
367
	B dd ? ;float ebp-88
368
	A dd ? ;float ebp-84
369
	s V3 ;ebp-80
370
	d V3 ;ebp-68
5262 IgorA 371
	tmp dd ? ;float ebp-56
372
	att dd ? ;float ebp-52
373
	dot_spot dd ? ;float ebp-48
374
	lR dd ? ;float ebp-44
375
	lB dd ? ;float ebp-40
376
	lG dd ? ;float ebp-36
377
	twoside dd ? ;int ebp-32
378
	idx dd ? ;int ebp-28
5256 IgorA 379
	n V3 ;ebp-24
380
	vcoord V3 ;ebp-12
381
endl
382
pushad
383
; ebx -> GLLight *l
384
; ecx -> GLMaterial *m
385
; esi -> GLVertex *v
386
	mov esi,[v]
387
	mov edx,[context]
5269 IgorA 388
	mov ecx,edx
389
	add ecx,offs_cont_materials ;ecx(m) = &context.materials[0]
5256 IgorA 390
	mov eax,[edx+offs_cont_light_model_two_side]
391
	mov [twoside],eax
5153 IgorA 392
 
5256 IgorA 393
	add esi,offs_vert_normal
394
	mov edi,ebp
395
	sub edi,24 ;edi = &n
396
	movsd ;n.X=v.normal.X
397
	movsd ;n.Y=v.normal.Y
398
	movsd ;n.Z=v.normal.Z
399
	mov esi,[v]
5153 IgorA 400
 
5262 IgorA 401
if DEBUG ;offs_mate_emission, offs_mate_ambient, offs_mate_specular, offs_mate_diffuse
402
push ecx
403
	stdcall dbg_print,txt_mate,txt_nl
404
	add ecx,offs_mate_emission
405
	stdcall gl_print_matrix,ecx,1
406
	add ecx,offs_mate_ambient-offs_mate_emission
407
	stdcall gl_print_matrix,ecx,1
408
	add ecx,offs_mate_specular-offs_mate_ambient
409
	stdcall gl_print_matrix,ecx,1
410
	add ecx,offs_mate_diffuse-offs_mate_specular
411
	stdcall gl_print_matrix,ecx,1
412
pop ecx
413
end if
414
 
5256 IgorA 415
	fld dword[edx+offs_cont_ambient_light_model]
416
	fmul dword[ecx+offs_mate_ambient]
417
	fadd dword[ecx] ;offs_mate_emission=0
418
	fstp dword[R] ;R=m.emission.v[0]+m.ambient.v[0]*context.ambient_light_model.v[0]
419
	fld dword[edx+offs_cont_ambient_light_model+4]
420
	fmul dword[ecx+offs_mate_ambient+4]
421
	fadd dword[ecx+offs_mate_emission+4]
422
	fstp dword[G]
423
	fld dword[edx+offs_cont_ambient_light_model+8]
424
	fmul dword[ecx+offs_mate_ambient+8]
425
	fadd dword[ecx+offs_mate_emission+8]
426
	fstp dword[B]
427
	clampf [ecx+offs_mate_diffuse+12],0,1
428
	mov [A],eax ;A=clampf(m.diffuse.v[3],0,1)
5153 IgorA 429
 
5256 IgorA 430
	mov ebx,[edx+offs_cont_first_light]
431
	.cycle_0: ;for(l=context.first_light;l!=NULL;l=l.next)
432
		or ebx,ebx
433
		jz .cycle_0_end
5153 IgorA 434
 
5256 IgorA 435
		; ambient
436
		fld dword[ecx+offs_mate_ambient]
5262 IgorA 437
		fmul dword[ebx] ;offs_ligh_ambient=0
5256 IgorA 438
		fstp dword[lR] ;lR=l.ambient.v[0] * m.ambient.v[0]
439
		fld dword[ecx+offs_mate_ambient+4]
440
		fmul dword[ebx+offs_ligh_ambient+4]
441
		fstp dword[lG] ;lG=l.ambient.v[1] * m.ambient.v[1]
442
		fld dword[ecx+offs_mate_ambient+8]
443
		fmul dword[ebx+offs_ligh_ambient+8]
444
		fstp dword[lB] ;lB=l.ambient.v[2] * m.ambient.v[2]
5153 IgorA 445
 
5269 IgorA 446
		fld dword[ebx+offs_ligh_position+offs_W]
447
		ftst ;if (l.position.v[3] == 0)
448
		fstsw ax
449
		sahf
5256 IgorA 450
		jne .els_0
451
			; light at infinity
5269 IgorA 452
			ffree st0 ;l.position.v[3]
453
			fincstp
5256 IgorA 454
			mov eax,[ebx+offs_ligh_position]
455
			mov [d],eax ;d.X=l.position.v[0]
5269 IgorA 456
			mov eax,[ebx+offs_ligh_position+offs_Y]
457
			mov [d+offs_Y],eax ;d.Y=l.position.v[1]
458
			mov eax,[ebx+offs_ligh_position+offs_Z]
459
			mov [d+offs_Z],eax ;d.Z=l.position.v[2]
5256 IgorA 460
			mov dword[att],1.0
461
			jmp .els_0_end
462
		.els_0:
463
			; distance attenuation
5269 IgorA 464
			ffree st0 ;l.position.v[3]
465
			fincstp
5256 IgorA 466
			fld dword[ebx+offs_ligh_position]
467
			fsub dword[esi+offs_vert_ec]
468
			fstp dword[d] ;d.X=l.position.v[0]-v.ec.v[0]
469
			fld dword[ebx+offs_ligh_position+offs_Y]
470
			fsub dword[esi+offs_vert_ec+offs_Y]
471
			fstp dword[d+offs_Y] ;d.Y=l.position.v[1]-v.ec.v[1]
472
			fld dword[ebx+offs_ligh_position+offs_Z]
473
			fsub dword[esi+offs_vert_ec+offs_Z]
474
			fstp dword[d+offs_Z] ;d.Z=l.position.v[2]-v.ec.v[2]
475
			fld dword[d]
476
			fmul st0,st0
477
			fld dword[d+offs_Y]
478
			fmul st0,st0
479
			faddp
480
			fld dword[d+offs_Z]
481
			fmul st0,st0
482
			faddp
5278 IgorA 483
			fsqrt ;dist=sqrt(d.X^2+d.Y^2+d.Z^2)
5256 IgorA 484
			fcom dword[fl_1e_3]
485
			fstsw ax
486
			sahf
487
			jbe @f ;if (dist>1.0e-3)
488
				fld1
489
				fdiv st0,st1
490
				fld dword[d]
491
				fmul st0,st1
492
				fstp dword[d]
493
				fld dword[d+offs_Y]
494
				fmul st0,st1
495
				fstp dword[d+offs_Y]
496
				fld dword[d+offs_Z]
497
				fmul st0,st1
498
				fstp dword[d+offs_Z]
499
				ffree st0 ;1.0/dist
500
				fincstp
501
			@@:
502
			fld dword[ebx+offs_ligh_attenuation+8]
503
			fmul st0,st1 ;st0 = dist * l.attenuation[2]
504
			fadd dword[ebx+offs_ligh_attenuation+4]
505
			fmul st0,st1
506
			fadd dword[ebx+offs_ligh_attenuation]
507
			fld1
508
			fdiv st0,st1
509
			fstp dword[att] ;att = 1.0f/(l.attenuation[0]+dist*(l.attenuation[1]+dist*l.attenuation[2]))
510
			ffree st0 ;1.0
511
			fincstp
512
			ffree st0 ;dist
513
			fincstp
514
		.els_0_end:
515
		fld dword[d]
516
		fmul dword[n]
517
		fld dword[d+offs_Y]
518
		fmul dword[n+offs_Y]
519
		faddp
520
		fld dword[d+offs_Z]
521
		fmul dword[n+offs_Z]
522
		faddp ;dot = d.X*n.X+d.Y*n.Y+d.Z*n.Z
523
		cmp dword[twoside],0 ;if (twoside && dot < 0)
524
		je @f
525
		ftst ;if (dot<0)
526
		fstsw ax
527
		sahf
528
		jae @f
529
			fchs ;dot = -dot
530
		@@:
531
		ftst ;if (dot>0)
532
		fstsw ax
533
		sahf
5269 IgorA 534
		jbe .if0_end
5256 IgorA 535
			; diffuse light
536
			fld dword[ecx+offs_mate_diffuse]
537
			fmul dword[ebx+offs_ligh_diffuse]
538
			fmul st0,st1
539
			fadd dword[lR]
540
			fstp dword[lR] ;lR+=dot * l.diffuse.v[0] * m.diffuse.v[0]
541
			fld dword[ecx+offs_mate_diffuse+4]
542
			fmul dword[ebx+offs_ligh_diffuse+4]
543
			fmul st0,st1
544
			fadd dword[lG]
545
			fstp dword[lG] ;lG+=dot * l.diffuse.v[1] * m.diffuse.v[1]
546
			fld dword[ecx+offs_mate_diffuse+8]
547
			fmul dword[ebx+offs_ligh_diffuse+8]
548
			fmul st0,st1
549
			fadd dword[lB]
550
			fstp dword[lB] ;lB+=dot * l.diffuse.v[2] * m.diffuse.v[2]
551
			ffree st0 ;dot
552
			fincstp
5153 IgorA 553
 
5256 IgorA 554
			; spot light
555
			fld dword[ebx+offs_ligh_spot_cutoff]
556
			fcomp dword[an180f] ;if (l.spot_cutoff != 180)
557
			fstsw ax
558
			sahf
5278 IgorA 559
			je .if1_end
5256 IgorA 560
				fld dword[ebx+offs_ligh_norm_spot_direction]
561
				fmul dword[d]
562
				fld dword[ebx+offs_ligh_norm_spot_direction+4]
563
				fmul dword[d+offs_Y]
564
				faddp
565
				fld dword[ebx+offs_ligh_norm_spot_direction+8]
566
				fmul dword[d+offs_Z]
567
				faddp
568
				fchs
569
				fst dword[dot_spot]
570
				cmp dword[twoside],0 ;if (twoside && dot_spot < 0)
571
				je @f
572
				ftst ;if (dot_spot<0)
573
				fstsw ax
574
				sahf
575
				jae @f
576
					fchs ;dot_spot = -dot_spot
577
				@@:
578
				fcom dword[ebx+offs_ligh_cos_spot_cutoff] ;if (dot_spot < l.cos_spot_cutoff)
579
				fstsw ax
580
				sahf
581
				jae .els_1
582
					; no contribution
583
					ffree st0 ;dot_spot
584
					fincstp
585
					mov ebx,[ebx+offs_ligh_next]
586
					jmp .cycle_0 ;continue
587
				.els_1:
588
					; TODO: optimize
589
					fld dword[ebx+offs_ligh_spot_exponent]
590
					ftst ;if (l.spot_exponent > 0)
591
					fstsw ax
592
					sahf
593
					jbe @f
594
						fxch st1 ;dot_spot <--> l.spot_exponent
595
						;Вычисляем x^y
596
						;fld y
597
						;fld x
598
						fyl2x ;Стек FPU теперь содержит: st0=z=y*log2(x):
599
						;Теперь считаем 2**z:
600
						fld st0 ;Создаем еще одну копию z
601
						frndint ;Округляем
602
						fsubr st0,st1  ;st1=z, st0=z-trunc(z)
603
						f2xm1  ;st1=z, st0=2**(z-trunc(z))-1
604
						fld1
605
						faddp  ;st1=z, st0=2**(z-trunc(z))
606
						fscale ;st1=z, st0=(2**trunc(z))*(2**(z-trunc(z)))=2**t
607
						fxch st1
608
						fstp st ;Результат остается на вершине стека st0
609
						fmul dword[att]
610
						fstp dword[att] ;att=att*pow(dot_spot,l.spot_exponent)
5387 IgorA 611
						jmp .if1_end_f1
5256 IgorA 612
					@@:
613
					ffree st0 ;l.spot_exponent
614
					fincstp
5387 IgorA 615
					.if1_end_f1:
5256 IgorA 616
					ffree st0 ;dot_spot
617
					fincstp
618
			.if1_end:
5153 IgorA 619
 
5256 IgorA 620
			; specular light
621
			cmp dword[edx+offs_cont_local_light_model],0 ;if (c.local_light_model)
622
			je .els_2
623
				mov eax,[esi+offs_vert_ec]
624
				mov [vcoord],eax ;vcoord.X=v.ec.X
625
				mov eax,[esi+offs_vert_ec+offs_Y]
626
				mov [vcoord+offs_Y],eax ;vcoord.Y=v.ec.Y
627
				mov eax,[esi+offs_vert_ec+offs_Z]
628
				mov [vcoord+offs_Z],eax ;vcoord.Z=v.ec.Z
629
				mov eax,ebp
630
				sub eax,12 ;eax = &vcoord
631
				stdcall gl_V3_Norm, eax
632
				fld dword[d]
633
				fsub dword[vcoord]
634
				fstp dword[s] ;s.X=d.X-vcoord.X
635
				fld dword[d+offs_Y]
636
				fsub dword[vcoord+offs_Y]
637
				fstp dword[s+offs_Y] ;s.Y=d.Y-vcoord.Y
638
				fld dword[d+offs_Z]
639
				fsub dword[vcoord+offs_Z]
640
				fstp dword[s+offs_Z] ;s.Z=d.Z-vcoord.Z
641
				jmp .els_2_end
642
			.els_2:
643
				mov eax,[d]
644
				mov [s],eax ;s.X=d.X
645
				mov eax,[d+offs_Y]
646
				mov [s+offs_Y],eax ;s.Y=d.Y
647
				fld1
648
				fadd dword[d+offs_Z]
649
				fstp dword[s+offs_Z] ;s.Z=d.Z+1.0
650
			.els_2_end:
651
			fld dword[n]
5387 IgorA 652
			fmul dword[s]
5256 IgorA 653
			fld dword[n+offs_Y]
5387 IgorA 654
			fmul dword[s+offs_Y]
5256 IgorA 655
			faddp
656
			fld dword[n+offs_Z]
5387 IgorA 657
			fmul dword[s+offs_Z]
658
			faddp ;dot_spec = n.X*s.X +n.Y*s.Y +n.Z*s.Z
5256 IgorA 659
			cmp dword[twoside],0 ;if (twoside && dot_spec < 0)
660
			je @f
661
			ftst ;if (dot_spec < 0)
662
			fstsw ax
663
			sahf
664
			jae @f
665
				fchs ;dot_spec = -dot_spec
666
			@@:
667
			ftst ;if (dot_spec > 0)
668
			fstsw ax
669
			sahf
5269 IgorA 670
			jbe .if0_end
5256 IgorA 671
				fld dword[s]
672
				fmul st0,st0
673
				fld dword[s+offs_Y]
674
				fmul st0,st0
675
				faddp
676
				fld dword[s+offs_Z]
677
				fmul st0,st0
5278 IgorA 678
				faddp ;st0 = s.X^2 +s.Y^2 +s.Z^2
5256 IgorA 679
				fsqrt
680
				fcom dword[fl_1e_3]
681
				fstsw ax
682
				sahf
683
				jbe @f ;if (tmp > 1.0e-3)
684
					fdiv st1,st0 ;dot_spec /= tmp
685
				@@:
686
				ffree st0 ;tmp
687
				fincstp
5153 IgorA 688
 
5256 IgorA 689
				; TODO: optimize
690
				; testing specular buffer code
691
				; dot_spec= pow(dot_spec,m.shininess)
692
				stdcall specbuf_get_buffer, edx, dword[ecx+offs_mate_shininess_i], dword[ecx+offs_mate_shininess]
5262 IgorA 693
				mov edi,eax ;edi = specbuf
5269 IgorA 694
				mov dword[idx],SPECULAR_BUFFER_SIZE ;idx = SPECULAR_BUFFER_SIZE
5256 IgorA 695
				fld1
696
				fcomp
697
				fstsw ax
5269 IgorA 698
				fild dword[idx]
5256 IgorA 699
				sahf
5278 IgorA 700
				jbe @f ;if(dot_spec < 1.0) st0=1 st1=dot_spec
5269 IgorA 701
					fmul st0,st1 ;idx *= dot_spec
5256 IgorA 702
				@@:
5269 IgorA 703
				fistp dword[idx]
5256 IgorA 704
				ffree st0 ;dot_spec
705
				fincstp
706
				shl dword[idx],2
5262 IgorA 707
				add edi,dword[idx]
708
				fld dword[edi+offs_spec_buf] ;dot_spec = specbuf.buf[idx]
5256 IgorA 709
				fld dword[ebx+offs_ligh_specular]
710
				fmul st0,st1
711
				fmul dword[ecx+offs_mate_specular]
712
				fadd dword[lR]
713
				fstp dword[lR] ;lR+=dot_spec * l.specular.v[0] * m.specular.v[0]
5262 IgorA 714
				fld dword[ebx+offs_ligh_specular+4]
5256 IgorA 715
				fmul st0,st1
5262 IgorA 716
				fmul dword[ecx+offs_mate_specular+4]
5256 IgorA 717
				fadd dword[lG]
718
				fstp dword[lG] ;lG+=dot_spec * l.specular.v[1] * m.specular.v[1]
5262 IgorA 719
				fld dword[ebx+offs_ligh_specular+8]
5256 IgorA 720
				fmul st0,st1
5262 IgorA 721
				fmul dword[ecx+offs_mate_specular+8]
5256 IgorA 722
				fadd dword[lB]
723
				fstp dword[lB] ;lB+=dot_spec * l.specular.v[2] * m.specular.v[2]
724
		.if0_end:
725
		ffree st0 ;dot [or] dot_spec
726
		fincstp
727
		.if2_end:
5153 IgorA 728
 
5256 IgorA 729
		fld dword[att]
730
		fld dword[lR]
731
		fmul st0,st1
732
		fadd dword[R]
733
		fstp dword[R] ;R += att * lR
734
		fld dword[lG]
735
		fmul st0,st1
736
		fadd dword[G]
737
		fstp dword[G] ;G += att * lG
738
		fld dword[lB]
739
		fmul st0,st1
740
		fadd dword[B]
741
		fstp dword[B] ;B += att * lB
742
		ffree st0 ;att
743
		fincstp
744
		mov ebx,[ebx+offs_ligh_next]
745
		jmp .cycle_0
746
	.cycle_0_end:
5153 IgorA 747
 
5256 IgorA 748
	clampf [R],0,1
749
	mov [esi+offs_vert_color],eax ;v.color.v[0]=clampf(R,0,1)
750
	clampf [G],0,1
751
	mov [esi+offs_vert_color+4],eax ;v.color.v[1]=clampf(G,0,1)
752
	clampf [B],0,1
753
	mov [esi+offs_vert_color+8],eax ;v.color.v[2]=clampf(B,0,1)
754
	mov eax,[A]
755
	mov [esi+offs_vert_color+12],eax ;v.color.v[3]=A
5262 IgorA 756
if DEBUG ;offs_vert_color
757
push esi
758
	stdcall dbg_print,txt_colo,txt_nl
759
	add esi,offs_vert_color
760
	stdcall gl_print_matrix,esi,1
761
pop esi
762
end if
5256 IgorA 763
popad
5153 IgorA 764
	ret
765
endp
766