Subversion Repositories Kolibri OS

Rev

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