Subversion Repositories Kolibri OS

Rev

Rev 5387 | Rev 6013 | 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
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
 
5262 IgorA 358
if DEBUG
359
txt_mate db 'Material',0
360
txt_colo db 'Color',0
5278 IgorA 361
txt_rgba db 'R, G, B',0
5262 IgorA 362
end if
363
 
5153 IgorA 364
; non optimized lightening model
365
align 4
366
proc gl_shade_vertex, context:dword, v:dword
5256 IgorA 367
locals
5278 IgorA 368
	R dd ? ;float ebp-96
369
	G dd ? ;float ebp-92
370
	B dd ? ;float ebp-88
371
	A dd ? ;float ebp-84
372
	s V3 ;ebp-80
373
	d V3 ;ebp-68
5262 IgorA 374
	tmp dd ? ;float ebp-56
375
	att dd ? ;float ebp-52
376
	dot_spot dd ? ;float ebp-48
377
	lR dd ? ;float ebp-44
378
	lB dd ? ;float ebp-40
379
	lG dd ? ;float ebp-36
380
	twoside dd ? ;int ebp-32
381
	idx dd ? ;int ebp-28
5256 IgorA 382
	n V3 ;ebp-24
383
	vcoord V3 ;ebp-12
384
endl
385
pushad
386
; ebx -> GLLight *l
387
; ecx -> GLMaterial *m
388
; esi -> GLVertex *v
389
	mov esi,[v]
390
	mov edx,[context]
5269 IgorA 391
	mov ecx,edx
392
	add ecx,offs_cont_materials ;ecx(m) = &context.materials[0]
5256 IgorA 393
	mov eax,[edx+offs_cont_light_model_two_side]
394
	mov [twoside],eax
5153 IgorA 395
 
5256 IgorA 396
	add esi,offs_vert_normal
397
	mov edi,ebp
398
	sub edi,24 ;edi = &n
399
	movsd ;n.X=v.normal.X
400
	movsd ;n.Y=v.normal.Y
401
	movsd ;n.Z=v.normal.Z
402
	mov esi,[v]
5153 IgorA 403
 
5262 IgorA 404
if DEBUG ;offs_mate_emission, offs_mate_ambient, offs_mate_specular, offs_mate_diffuse
405
push ecx
406
	stdcall dbg_print,txt_mate,txt_nl
407
	add ecx,offs_mate_emission
408
	stdcall gl_print_matrix,ecx,1
409
	add ecx,offs_mate_ambient-offs_mate_emission
410
	stdcall gl_print_matrix,ecx,1
411
	add ecx,offs_mate_specular-offs_mate_ambient
412
	stdcall gl_print_matrix,ecx,1
413
	add ecx,offs_mate_diffuse-offs_mate_specular
414
	stdcall gl_print_matrix,ecx,1
415
pop ecx
416
end if
417
 
5256 IgorA 418
	fld dword[edx+offs_cont_ambient_light_model]
419
	fmul dword[ecx+offs_mate_ambient]
420
	fadd dword[ecx] ;offs_mate_emission=0
421
	fstp dword[R] ;R=m.emission.v[0]+m.ambient.v[0]*context.ambient_light_model.v[0]
422
	fld dword[edx+offs_cont_ambient_light_model+4]
423
	fmul dword[ecx+offs_mate_ambient+4]
424
	fadd dword[ecx+offs_mate_emission+4]
425
	fstp dword[G]
426
	fld dword[edx+offs_cont_ambient_light_model+8]
427
	fmul dword[ecx+offs_mate_ambient+8]
428
	fadd dword[ecx+offs_mate_emission+8]
429
	fstp dword[B]
430
	clampf [ecx+offs_mate_diffuse+12],0,1
431
	mov [A],eax ;A=clampf(m.diffuse.v[3],0,1)
5153 IgorA 432
 
5256 IgorA 433
	mov ebx,[edx+offs_cont_first_light]
434
	.cycle_0: ;for(l=context.first_light;l!=NULL;l=l.next)
435
		or ebx,ebx
436
		jz .cycle_0_end
5153 IgorA 437
 
5256 IgorA 438
		; ambient
439
		fld dword[ecx+offs_mate_ambient]
5262 IgorA 440
		fmul dword[ebx] ;offs_ligh_ambient=0
5256 IgorA 441
		fstp dword[lR] ;lR=l.ambient.v[0] * m.ambient.v[0]
442
		fld dword[ecx+offs_mate_ambient+4]
443
		fmul dword[ebx+offs_ligh_ambient+4]
444
		fstp dword[lG] ;lG=l.ambient.v[1] * m.ambient.v[1]
445
		fld dword[ecx+offs_mate_ambient+8]
446
		fmul dword[ebx+offs_ligh_ambient+8]
447
		fstp dword[lB] ;lB=l.ambient.v[2] * m.ambient.v[2]
5153 IgorA 448
 
5269 IgorA 449
		fld dword[ebx+offs_ligh_position+offs_W]
450
		ftst ;if (l.position.v[3] == 0)
451
		fstsw ax
452
		sahf
5256 IgorA 453
		jne .els_0
454
			; light at infinity
5269 IgorA 455
			ffree st0 ;l.position.v[3]
456
			fincstp
5256 IgorA 457
			mov eax,[ebx+offs_ligh_position]
458
			mov [d],eax ;d.X=l.position.v[0]
5269 IgorA 459
			mov eax,[ebx+offs_ligh_position+offs_Y]
460
			mov [d+offs_Y],eax ;d.Y=l.position.v[1]
461
			mov eax,[ebx+offs_ligh_position+offs_Z]
462
			mov [d+offs_Z],eax ;d.Z=l.position.v[2]
5256 IgorA 463
			mov dword[att],1.0
464
			jmp .els_0_end
465
		.els_0:
466
			; distance attenuation
5269 IgorA 467
			ffree st0 ;l.position.v[3]
468
			fincstp
5256 IgorA 469
			fld dword[ebx+offs_ligh_position]
470
			fsub dword[esi+offs_vert_ec]
471
			fstp dword[d] ;d.X=l.position.v[0]-v.ec.v[0]
472
			fld dword[ebx+offs_ligh_position+offs_Y]
473
			fsub dword[esi+offs_vert_ec+offs_Y]
474
			fstp dword[d+offs_Y] ;d.Y=l.position.v[1]-v.ec.v[1]
475
			fld dword[ebx+offs_ligh_position+offs_Z]
476
			fsub dword[esi+offs_vert_ec+offs_Z]
477
			fstp dword[d+offs_Z] ;d.Z=l.position.v[2]-v.ec.v[2]
478
			fld dword[d]
479
			fmul st0,st0
480
			fld dword[d+offs_Y]
481
			fmul st0,st0
482
			faddp
483
			fld dword[d+offs_Z]
484
			fmul st0,st0
485
			faddp
5278 IgorA 486
			fsqrt ;dist=sqrt(d.X^2+d.Y^2+d.Z^2)
5256 IgorA 487
			fcom dword[fl_1e_3]
488
			fstsw ax
489
			sahf
490
			jbe @f ;if (dist>1.0e-3)
491
				fld1
492
				fdiv st0,st1
493
				fld dword[d]
494
				fmul st0,st1
495
				fstp dword[d]
496
				fld dword[d+offs_Y]
497
				fmul st0,st1
498
				fstp dword[d+offs_Y]
499
				fld dword[d+offs_Z]
500
				fmul st0,st1
501
				fstp dword[d+offs_Z]
502
				ffree st0 ;1.0/dist
503
				fincstp
504
			@@:
505
			fld dword[ebx+offs_ligh_attenuation+8]
506
			fmul st0,st1 ;st0 = dist * l.attenuation[2]
507
			fadd dword[ebx+offs_ligh_attenuation+4]
508
			fmul st0,st1
509
			fadd dword[ebx+offs_ligh_attenuation]
510
			fld1
511
			fdiv st0,st1
512
			fstp dword[att] ;att = 1.0f/(l.attenuation[0]+dist*(l.attenuation[1]+dist*l.attenuation[2]))
513
			ffree st0 ;1.0
514
			fincstp
515
			ffree st0 ;dist
516
			fincstp
517
		.els_0_end:
518
		fld dword[d]
519
		fmul dword[n]
520
		fld dword[d+offs_Y]
521
		fmul dword[n+offs_Y]
522
		faddp
523
		fld dword[d+offs_Z]
524
		fmul dword[n+offs_Z]
525
		faddp ;dot = d.X*n.X+d.Y*n.Y+d.Z*n.Z
526
		cmp dword[twoside],0 ;if (twoside && dot < 0)
527
		je @f
528
		ftst ;if (dot<0)
529
		fstsw ax
530
		sahf
531
		jae @f
532
			fchs ;dot = -dot
533
		@@:
534
		ftst ;if (dot>0)
535
		fstsw ax
536
		sahf
5269 IgorA 537
		jbe .if0_end
5256 IgorA 538
			; diffuse light
539
			fld dword[ecx+offs_mate_diffuse]
540
			fmul dword[ebx+offs_ligh_diffuse]
541
			fmul st0,st1
542
			fadd dword[lR]
543
			fstp dword[lR] ;lR+=dot * l.diffuse.v[0] * m.diffuse.v[0]
544
			fld dword[ecx+offs_mate_diffuse+4]
545
			fmul dword[ebx+offs_ligh_diffuse+4]
546
			fmul st0,st1
547
			fadd dword[lG]
548
			fstp dword[lG] ;lG+=dot * l.diffuse.v[1] * m.diffuse.v[1]
549
			fld dword[ecx+offs_mate_diffuse+8]
550
			fmul dword[ebx+offs_ligh_diffuse+8]
551
			fmul st0,st1
552
			fadd dword[lB]
553
			fstp dword[lB] ;lB+=dot * l.diffuse.v[2] * m.diffuse.v[2]
554
			ffree st0 ;dot
555
			fincstp
5153 IgorA 556
 
5256 IgorA 557
			; spot light
558
			fld dword[ebx+offs_ligh_spot_cutoff]
559
			fcomp dword[an180f] ;if (l.spot_cutoff != 180)
560
			fstsw ax
561
			sahf
5278 IgorA 562
			je .if1_end
5256 IgorA 563
				fld dword[ebx+offs_ligh_norm_spot_direction]
564
				fmul dword[d]
565
				fld dword[ebx+offs_ligh_norm_spot_direction+4]
566
				fmul dword[d+offs_Y]
567
				faddp
568
				fld dword[ebx+offs_ligh_norm_spot_direction+8]
569
				fmul dword[d+offs_Z]
570
				faddp
571
				fchs
572
				fst dword[dot_spot]
573
				cmp dword[twoside],0 ;if (twoside && dot_spot < 0)
574
				je @f
575
				ftst ;if (dot_spot<0)
576
				fstsw ax
577
				sahf
578
				jae @f
579
					fchs ;dot_spot = -dot_spot
580
				@@:
581
				fcom dword[ebx+offs_ligh_cos_spot_cutoff] ;if (dot_spot < l.cos_spot_cutoff)
582
				fstsw ax
583
				sahf
584
				jae .els_1
585
					; no contribution
586
					ffree st0 ;dot_spot
587
					fincstp
588
					mov ebx,[ebx+offs_ligh_next]
589
					jmp .cycle_0 ;continue
590
				.els_1:
591
					; TODO: optimize
592
					fld dword[ebx+offs_ligh_spot_exponent]
593
					ftst ;if (l.spot_exponent > 0)
594
					fstsw ax
595
					sahf
596
					jbe @f
597
						fxch st1 ;dot_spot <--> l.spot_exponent
598
						;Вычисляем x^y
599
						;fld y
600
						;fld x
601
						fyl2x ;Стек FPU теперь содержит: st0=z=y*log2(x):
602
						;Теперь считаем 2**z:
603
						fld st0 ;Создаем еще одну копию z
604
						frndint ;Округляем
605
						fsubr st0,st1  ;st1=z, st0=z-trunc(z)
606
						f2xm1  ;st1=z, st0=2**(z-trunc(z))-1
607
						fld1
608
						faddp  ;st1=z, st0=2**(z-trunc(z))
609
						fscale ;st1=z, st0=(2**trunc(z))*(2**(z-trunc(z)))=2**t
610
						fxch st1
611
						fstp st ;Результат остается на вершине стека st0
612
						fmul dword[att]
613
						fstp dword[att] ;att=att*pow(dot_spot,l.spot_exponent)
5387 IgorA 614
						jmp .if1_end_f1
5256 IgorA 615
					@@:
616
					ffree st0 ;l.spot_exponent
617
					fincstp
5387 IgorA 618
					.if1_end_f1:
5256 IgorA 619
					ffree st0 ;dot_spot
620
					fincstp
621
			.if1_end:
5153 IgorA 622
 
5256 IgorA 623
			; specular light
624
			cmp dword[edx+offs_cont_local_light_model],0 ;if (c.local_light_model)
625
			je .els_2
626
				mov eax,[esi+offs_vert_ec]
627
				mov [vcoord],eax ;vcoord.X=v.ec.X
628
				mov eax,[esi+offs_vert_ec+offs_Y]
629
				mov [vcoord+offs_Y],eax ;vcoord.Y=v.ec.Y
630
				mov eax,[esi+offs_vert_ec+offs_Z]
631
				mov [vcoord+offs_Z],eax ;vcoord.Z=v.ec.Z
632
				mov eax,ebp
633
				sub eax,12 ;eax = &vcoord
634
				stdcall gl_V3_Norm, eax
635
				fld dword[d]
636
				fsub dword[vcoord]
637
				fstp dword[s] ;s.X=d.X-vcoord.X
638
				fld dword[d+offs_Y]
639
				fsub dword[vcoord+offs_Y]
640
				fstp dword[s+offs_Y] ;s.Y=d.Y-vcoord.Y
641
				fld dword[d+offs_Z]
642
				fsub dword[vcoord+offs_Z]
643
				fstp dword[s+offs_Z] ;s.Z=d.Z-vcoord.Z
644
				jmp .els_2_end
645
			.els_2:
646
				mov eax,[d]
647
				mov [s],eax ;s.X=d.X
648
				mov eax,[d+offs_Y]
649
				mov [s+offs_Y],eax ;s.Y=d.Y
650
				fld1
651
				fadd dword[d+offs_Z]
652
				fstp dword[s+offs_Z] ;s.Z=d.Z+1.0
653
			.els_2_end:
654
			fld dword[n]
5387 IgorA 655
			fmul dword[s]
5256 IgorA 656
			fld dword[n+offs_Y]
5387 IgorA 657
			fmul dword[s+offs_Y]
5256 IgorA 658
			faddp
659
			fld dword[n+offs_Z]
5387 IgorA 660
			fmul dword[s+offs_Z]
661
			faddp ;dot_spec = n.X*s.X +n.Y*s.Y +n.Z*s.Z
5256 IgorA 662
			cmp dword[twoside],0 ;if (twoside && dot_spec < 0)
663
			je @f
664
			ftst ;if (dot_spec < 0)
665
			fstsw ax
666
			sahf
667
			jae @f
668
				fchs ;dot_spec = -dot_spec
669
			@@:
670
			ftst ;if (dot_spec > 0)
671
			fstsw ax
672
			sahf
5269 IgorA 673
			jbe .if0_end
5256 IgorA 674
				fld dword[s]
675
				fmul st0,st0
676
				fld dword[s+offs_Y]
677
				fmul st0,st0
678
				faddp
679
				fld dword[s+offs_Z]
680
				fmul st0,st0
5278 IgorA 681
				faddp ;st0 = s.X^2 +s.Y^2 +s.Z^2
5256 IgorA 682
				fsqrt
683
				fcom dword[fl_1e_3]
684
				fstsw ax
685
				sahf
686
				jbe @f ;if (tmp > 1.0e-3)
687
					fdiv st1,st0 ;dot_spec /= tmp
688
				@@:
689
				ffree st0 ;tmp
690
				fincstp
5153 IgorA 691
 
5256 IgorA 692
				; TODO: optimize
693
				; testing specular buffer code
694
				; dot_spec= pow(dot_spec,m.shininess)
695
				stdcall specbuf_get_buffer, edx, dword[ecx+offs_mate_shininess_i], dword[ecx+offs_mate_shininess]
5262 IgorA 696
				mov edi,eax ;edi = specbuf
5269 IgorA 697
				mov dword[idx],SPECULAR_BUFFER_SIZE ;idx = SPECULAR_BUFFER_SIZE
5256 IgorA 698
				fld1
699
				fcomp
700
				fstsw ax
5269 IgorA 701
				fild dword[idx]
5256 IgorA 702
				sahf
5278 IgorA 703
				jbe @f ;if(dot_spec < 1.0) st0=1 st1=dot_spec
5269 IgorA 704
					fmul st0,st1 ;idx *= dot_spec
5256 IgorA 705
				@@:
5269 IgorA 706
				fistp dword[idx]
5256 IgorA 707
				ffree st0 ;dot_spec
708
				fincstp
709
				shl dword[idx],2
5262 IgorA 710
				add edi,dword[idx]
711
				fld dword[edi+offs_spec_buf] ;dot_spec = specbuf.buf[idx]
5256 IgorA 712
				fld dword[ebx+offs_ligh_specular]
713
				fmul st0,st1
714
				fmul dword[ecx+offs_mate_specular]
715
				fadd dword[lR]
716
				fstp dword[lR] ;lR+=dot_spec * l.specular.v[0] * m.specular.v[0]
5262 IgorA 717
				fld dword[ebx+offs_ligh_specular+4]
5256 IgorA 718
				fmul st0,st1
5262 IgorA 719
				fmul dword[ecx+offs_mate_specular+4]
5256 IgorA 720
				fadd dword[lG]
721
				fstp dword[lG] ;lG+=dot_spec * l.specular.v[1] * m.specular.v[1]
5262 IgorA 722
				fld dword[ebx+offs_ligh_specular+8]
5256 IgorA 723
				fmul st0,st1
5262 IgorA 724
				fmul dword[ecx+offs_mate_specular+8]
5256 IgorA 725
				fadd dword[lB]
726
				fstp dword[lB] ;lB+=dot_spec * l.specular.v[2] * m.specular.v[2]
727
		.if0_end:
728
		ffree st0 ;dot [or] dot_spec
729
		fincstp
730
		.if2_end:
5153 IgorA 731
 
5256 IgorA 732
		fld dword[att]
733
		fld dword[lR]
734
		fmul st0,st1
735
		fadd dword[R]
736
		fstp dword[R] ;R += att * lR
737
		fld dword[lG]
738
		fmul st0,st1
739
		fadd dword[G]
740
		fstp dword[G] ;G += att * lG
741
		fld dword[lB]
742
		fmul st0,st1
743
		fadd dword[B]
744
		fstp dword[B] ;B += att * lB
745
		ffree st0 ;att
746
		fincstp
747
		mov ebx,[ebx+offs_ligh_next]
748
		jmp .cycle_0
749
	.cycle_0_end:
5153 IgorA 750
 
5256 IgorA 751
	clampf [R],0,1
752
	mov [esi+offs_vert_color],eax ;v.color.v[0]=clampf(R,0,1)
753
	clampf [G],0,1
754
	mov [esi+offs_vert_color+4],eax ;v.color.v[1]=clampf(G,0,1)
755
	clampf [B],0,1
756
	mov [esi+offs_vert_color+8],eax ;v.color.v[2]=clampf(B,0,1)
757
	mov eax,[A]
758
	mov [esi+offs_vert_color+12],eax ;v.color.v[3]=A
5262 IgorA 759
if DEBUG ;offs_vert_color
760
push esi
761
	stdcall dbg_print,txt_colo,txt_nl
762
	add esi,offs_vert_color
763
	stdcall gl_print_matrix,esi,1
764
pop esi
765
end if
5256 IgorA 766
popad
5153 IgorA 767
	ret
768
endp
769