Subversion Repositories Kolibri OS

Rev

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