Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
5153 IgorA 1
; fill triangle profile
2
; #define PROFILE
3
 
4
CLIP_XMIN equ (1<<0)
5
CLIP_XMAX equ (1<<1)
6
CLIP_YMIN equ (1<<2)
7
CLIP_YMAX equ (1<<3)
8
CLIP_ZMIN equ (1<<4)
9
CLIP_ZMAX equ (1<<5)
10
 
11
offs_X equ 0
12
offs_Y equ 4
13
offs_Z equ 8
14
offs_W equ 12
15
 
16
align 4
17
proc gl_transform_to_viewport uses eax ebx ecx, context:dword,v:dword
18
locals
19
	point dd ?
20
endl
21
	mov eax,[context]
22
	mov ebx,[v]
23
 
24
	; coordinates
25
	fld1
26
	fdiv dword[ebx+offs_vert_pc+offs_W] ;st0 = 1/v.pc.W
27
 
28
	fld dword[ebx+offs_vert_pc+offs_X] ;st0 = v.pc.X
29
	fmul st0,st1
30
	fmul dword[eax+offs_cont_viewport+offs_vpor_scale+offs_X]
31
	fadd dword[eax+offs_cont_viewport+offs_vpor_trans+offs_X]
32
	fistp dword[ebx+offs_vert_zp] ;v.zp.x = st0, st0 = st1
33
 
34
	fld dword[ebx+offs_vert_pc+offs_Y] ;st0 = v.pc.Y
35
	fmul st0,st1
36
	fmul dword[eax+offs_cont_viewport+offs_vpor_scale+offs_Y]
37
	fadd dword[eax+offs_cont_viewport+offs_vpor_trans+offs_Y]
38
	fistp dword[ebx+offs_vert_zp+offs_zbup_y] ;v.zp.y = st0, st0 = st1
39
 
40
	fld dword[ebx+offs_vert_pc+offs_Z] ;st0 = v.pc.Z
41
	fmul st0,st1
42
	fmul dword[eax+offs_cont_viewport+offs_vpor_scale+offs_Z]
43
	fadd dword[eax+offs_cont_viewport+offs_vpor_trans+offs_Z]
44
	fistp dword[ebx+offs_vert_zp+offs_zbup_z] ;v.zp.z = st0, st0 = st1
45
 
46
	; color
47
	bt dword[eax+offs_cont_lighting_enabled],0
48
	jnc @f
49
		mov ecx,ebx
50
		add ecx,offs_vert_zp+offs_zbup_b
51
		push ecx
52
		add ecx,offs_zbup_g-offs_zbup_b
53
		push ecx
54
		add ecx,offs_zbup_r-offs_zbup_g
55
		push ecx
56
		stdcall RGBFtoRGBI, dword[ebx+offs_vert_color],dword[ebx+offs_vert_color+4],dword[ebx+offs_vert_color+8]
57
		jmp .end_if
58
	@@:
59
		; no need to convert to integer if no lighting : take current color
60
		push ecx
61
		mov ecx,[eax+offs_cont_longcurrent_color]
62
		mov dword[ebx+offs_vert_zp+offs_zbup_r],ecx
63
		mov ecx,[eax+offs_cont_longcurrent_color+4]
64
		mov dword[ebx+offs_vert_zp+offs_zbup_g],ecx
65
		mov ecx,[eax+offs_cont_longcurrent_color+8]
66
		mov dword[ebx+offs_vert_zp+offs_zbup_b],ecx
67
		pop ecx
68
	.end_if:
69
 
70
	; texture
71
	bt dword[eax+offs_cont_texture_2d_enabled],0
72
	jnc @f
73
		mov dword[point],dword(ZB_POINT_S_MAX - ZB_POINT_S_MIN)
74
		fild dword[point]
75
		fmul dword[ebx+offs_vert_tex_coord] ;st0 *= v.tex_coord.X
76
		fistp dword[ebx+offs_vert_zp+offs_zbup_s]
77
		add dword[ebx+offs_vert_zp+offs_zbup_s],ZB_POINT_S_MIN
78
 
79
		mov dword[point],dword(ZB_POINT_T_MAX - ZB_POINT_T_MIN)
80
		fild dword[point]
81
		fmul dword[ebx+offs_vert_tex_coord+4] ;st0 *= v.tex_coord.Y
82
		fistp dword[ebx+offs_vert_zp+offs_zbup_t]
83
		add dword[ebx+offs_vert_zp+offs_zbup_s],ZB_POINT_T_MIN
84
	@@:
85
if DEBUG ;gl_transform_to_viewport
86
push edi
87
	mov ecx,80
88
	mov eax,[ebx+offs_vert_zp]
89
	lea edi,[buf_param]
90
	stdcall convert_int_to_str,ecx
91
	stdcall str_n_cat,edi,txt_zp_sp,2
92
	stdcall str_len,edi
93
	add edi,eax
94
	sub ecx,eax
95
 
96
	mov eax,[ebx+offs_vert_zp+offs_zbup_y]
97
	stdcall convert_int_to_str,ecx
98
	stdcall str_n_cat,edi,txt_zp_sp,2
99
	stdcall str_len,edi
100
	add edi,eax
101
	sub ecx,eax
102
 
103
	mov eax,[ebx+offs_vert_zp+offs_zbup_z]
104
	stdcall convert_int_to_str,ecx
105
 
106
	stdcall str_n_cat,edi,txt_nl,2
107
	stdcall dbg_print,f_ttv,buf_param
108
pop edi
109
end if
110
	ret
111
endp
112
 
113
align 4
114
proc gl_add_select1 uses eax ebx ecx, context:dword, z1:dword,z2:dword,z3:dword
115
	mov eax,[z1]
116
	mov ebx,eax
117
	cmp [z2],eax
118
	jge @f
119
		mov eax,[z2]
120
	@@:
121
	cmp [z3],eax
122
	jge @f
123
		mov eax,[z3]
124
	@@:
125
	cmp [z2],ebx
126
	jle @f
127
		mov ebx,[z2]
128
	@@:
129
	cmp [z3],ebx
130
	jle @f
131
		mov ebx,[z3]
132
	@@:
133
	mov ecx,0xffffffff
134
	sub ecx,ebx
135
	push ecx
136
	mov ecx,0xffffffff
137
	sub ecx,eax
138
	push ecx
139
	stdcall gl_add_select, [context] ;,0xffffffff-eax,0xffffffff-ebx
140
	ret
141
endp
142
 
143
; point
144
 
145
align 4
146
proc gl_draw_point uses eax ebx, context:dword, p0:dword
147
	mov ebx,[p0]
148
	cmp dword[ebx+offs_vert_clip_code],0 ;if (p0.clip_code == 0)
149
	jne @f
150
	mov eax,[context]
151
	cmp dword[eax+offs_cont_render_mode],GL_SELECT
152
	jne .els
153
		stdcall gl_add_select, eax,dword[ebx+offs_vert_zp+offs_zbup_z],dword[ebx+offs_vert_zp+offs_zbup_z] ;p0.zp.z,p0.zp.z
154
		jmp @f
155
	.els:
156
		add ebx,offs_vert_zp
157
		stdcall ZB_plot, dword[eax+offs_cont_zb],ebx
158
	@@:
159
	ret
160
endp
161
 
162
; line
163
 
164
align 4
165
proc interpolate uses eax ebx ecx, q:dword,p0:dword,p1:dword,t:dword
166
	mov eax,[q]
167
	mov ebx,[p0]
168
	mov ecx,[p1]
169
	fld dword[t]
170
 
171
	; интерполяция по координатам
5175 IgorA 172
	fld dword[ecx+offs_vert_pc+offs_X]
173
	fsub dword[ebx+offs_vert_pc+offs_X]
5153 IgorA 174
	fmul st0,st1
5175 IgorA 175
	fadd dword[ebx+offs_vert_pc+offs_X]
176
	fstp dword[eax+offs_vert_pc+offs_X]
5153 IgorA 177
 
5175 IgorA 178
	fld dword[ecx+offs_vert_pc+offs_Y]
179
	fsub dword[ebx+offs_vert_pc+offs_Y]
5153 IgorA 180
	fmul st0,st1
5175 IgorA 181
	fadd dword[ebx+offs_vert_pc+offs_Y]
182
	fstp dword[eax+offs_vert_pc+offs_Y]
5153 IgorA 183
 
5175 IgorA 184
	fld dword[ecx+offs_vert_pc+offs_Z]
185
	fsub dword[ebx+offs_vert_pc+offs_Z]
5153 IgorA 186
	fmul st0,st1
5175 IgorA 187
	fadd dword[ebx+offs_vert_pc+offs_Z]
188
	fstp dword[eax+offs_vert_pc+offs_Z]
5153 IgorA 189
 
5175 IgorA 190
	fld dword[ecx+offs_vert_pc+offs_W]
191
	fsub dword[ebx+offs_vert_pc+offs_W]
5153 IgorA 192
	fmul st0,st1
5175 IgorA 193
	fadd dword[ebx+offs_vert_pc+offs_W]
194
	fstp dword[eax+offs_vert_pc+offs_W]
5153 IgorA 195
 
196
	; интерполяция по цвету
197
	fld dword[ecx+offs_vert_color]
198
	fsub dword[ebx+offs_vert_color]
199
	fmul st0,st1
200
	fadd dword[ebx+offs_vert_color]
201
	fstp dword[eax+offs_vert_color]
202
 
203
	fld dword[ecx+offs_vert_color+4]
204
	fsub dword[ebx+offs_vert_color+4]
205
	fmul st0,st1
206
	fadd dword[ebx+offs_vert_color+4]
207
	fstp dword[eax+offs_vert_color+4]
208
 
209
	fld dword[ecx+offs_vert_color+8]
210
	fsub dword[ebx+offs_vert_color+8]
211
	fmul st0,st1
212
	fadd dword[ebx+offs_vert_color+8]
213
	fstp dword[eax+offs_vert_color+8]
214
	ret
215
endp
216
 
217
;
218
; Line Clipping
219
;
220
 
221
; Line Clipping algorithm from 'Computer Graphics', Principles and
222
; Practice
223
; tmin,tmax -> &float
224
align 4
225
proc ClipLine1 uses ebx, denom:dword,num:dword,tmin:dword,tmax:dword
226
	fldz
227
	fcom dword[denom]
228
	fstsw ax
229
	sahf
230
	je .u2
231
	jmp @f
232
	.u2:
233
		fcom dword[num]
234
		fstsw ax
235
		sahf
236
		jb .r0 ;if (denom==0 && num>0) return 0
237
		jmp .r1
238
	@@:
239
 
240
	fcom dword[denom]
241
	fstsw ax
242
	sahf
243
	ja .els_0 ;if (0
244
		fld dword[num]
245
		fdiv dword[denom]
246
 
247
		mov ebx,[tmax]
248
		fcom dword[ebx]
249
		fstsw ax
250
		sahf
251
		ja .r0 ;if (t>*tmax) return 0
252
 
253
		mov ebx,[tmin]
254
		fcom dword[ebx]
255
		fstsw ax
256
		sahf
257
		jbe .r1
258
			fstp dword[ebx] ;if (t>*tmin) *tmin=t
259
		jmp .r1
260
 
261
	.els_0: ;else if (0>denom)
262
		fld dword[num]
263
		fdiv dword[denom]
264
 
265
		mov ebx,[tmin]
266
		fcom dword[ebx]
267
		fstsw ax
268
		sahf
269
		jb .r0 ;if (t<*tmin) return 0
270
 
271
		mov ebx,[tmax]
272
		fcom dword[ebx]
273
		fstsw ax
274
		sahf
275
		jae .r1
276
			fstp dword[ebx] ;if (t<*tmin) *tmax=t
277
	jmp .r1
278
 
279
	.r0: ;return 0
280
		xor eax,eax
281
		jmp .end_f
282
	.r1: ;return 1
283
		xor eax,eax
284
		inc eax
285
	.end_f:
286
if DEBUG ;ClipLine1
287
push edi
288
	mov ecx,80
289
	lea edi,[buf_param]
290
	stdcall convert_int_to_str,ecx
291
 
292
	stdcall str_n_cat,edi,txt_nl,2
293
	stdcall dbg_print,f_cl1,buf_param
294
pop edi
295
end if
296
	ffree st0 ;профилактика для очистки стека
297
	fincstp   ;как минимум одно значение в стеке уже есть
298
	ret
299
endp
300
 
301
align 4
302
proc gl_draw_line uses eax ebx edx edi esi, context:dword, p1:dword, p2:dword
303
locals
304
	d_x dd ?
305
	d_y dd ?
306
	d_z dd ?
307
	d_w dd ?
308
	x1 dd ?
309
	y1 dd ?
310
	z1 dd ?
311
	w1 dd ?
312
	q1 GLVertex ?
313
	q2 GLVertex ?
314
	tmin dd ? ;ebp-8
315
	tmax dd ? ;ebp-4
316
endl
317
 
318
	mov edx,[context]
319
	mov edi,[p1]
320
	mov esi,[p2]
321
 
322
if DEBUG
323
	jmp @f
324
		f_1 db ' gl_draw_line',0
325
	@@:
326
	stdcall dbg_print,f_1,m_1
327
end if
328
	cmp dword[edi+offs_vert_clip_code],0
329
	jne .els_i
330
	cmp dword[esi+offs_vert_clip_code],0
331
	jne .els_i
332
		;if ( (p1.clip_code | p2.clip_code) == 0)
333
		cmp dword[edx+offs_cont_render_mode],GL_SELECT ;if (context.render_mode == GL_SELECT)
334
		jne .els_1
335
			stdcall gl_add_select1, edx,dword[edi+offs_vert_zp+offs_zbup_z],\
336
				dword[esi+offs_vert_zp+offs_zbup_z],dword[esi+offs_vert_zp+offs_zbup_z]
337
			jmp .end_f
338
		.els_1:
339
			add edi,offs_vert_zp
340
			add esi,offs_vert_zp
341
			push esi
342
			push edi
343
			push dword[edx+offs_cont_zb]
344
			cmp dword[edx+offs_cont_depth_test],0
345
			je .els_2
346
				;if (context.depth_test)
347
				call ZB_line_z ;, dword[edx+offs_cont_zb],edi,esi
348
				jmp .end_f
349
			.els_2:
350
				call ZB_line ;, dword[edx+offs_cont_zb],edi,esi
351
				jmp .end_f
352
	.els_i:
353
		;else if ( (p1.clip_code & p2.clip_code) != 0 )
354
		mov eax,[edi+offs_vert_clip_code]
355
		and eax,[esi+offs_vert_clip_code]
356
		cmp eax,0
357
		jne .end_f
358
	.els_0:
359
if DEBUG
360
	stdcall dbg_print,f_1,m_2
361
end if
362
 
363
	finit
364
	fld dword[esi+offs_vert_pc+offs_X]
365
	fsub dword[edi+offs_vert_pc+offs_X]
366
	fstp dword[d_x] ;d_x = p2.pc.X - p1.pc.X
367
	fld dword[esi+offs_vert_pc+offs_Y]
368
	fsub dword[edi+offs_vert_pc+offs_Y]
369
	fstp dword[d_y] ;d_y = p2.pc.Y - p1.pc.Y
370
	fld dword[esi+offs_vert_pc+offs_Z]
371
	fsub dword[edi+offs_vert_pc+offs_Z]
372
	fstp dword[d_z] ;d_z = p2.pc.Z - p1.pc.Z
373
	fld dword[esi+offs_vert_pc+offs_W]
374
	fsub dword[edi+offs_vert_pc+offs_W]
375
	fstp dword[d_w] ;d_w = p2.pc.W - p1.pc.W
376
 
377
	mov eax,[edi+offs_vert_pc+offs_X]
378
	mov [x1],eax ;x1 = p1.pc.X
379
	mov eax,[edi+offs_vert_pc+offs_Y]
380
	mov [y1],eax ;y1 = p1.pc.Y
381
	mov eax,[edi+offs_vert_pc+offs_Z]
382
	mov [z1],eax ;z1 = p1.pc.Z
383
	mov eax,[edi+offs_vert_pc+offs_W]
384
	mov [w1],eax ;w1 = p1.pc.W
385
 
386
	mov dword[tmin],0.0
387
	mov dword[tmax],1.0
388
 
389
	mov eax,ebp
390
	sub eax,4
391
	push eax ;толкаем в стек адрес &tmax
392
	sub eax,4
393
	push eax ;толкаем в стек адрес &tmin
394
	fld dword[x1]
395
	fadd dword[w1]
396
	fchs
397
	fstp dword[esp-4]
398
	fld dword[d_x]
399
	fadd dword[d_w]
400
	fstp dword[esp-8]
401
	sub esp,8
402
	call ClipLine1 ;d_x+d_w,-x1-w1,&tmin,&tmax
403
	bt eax,0
404
	jnc .end_f
405
 
406
	sub esp,8 ;толкаем в стек адреса переменных &tmin и &tmax
407
	fld dword[x1]
408
	fsub dword[w1]
409
	fstp dword[esp-4]
410
	fld dword[d_w]
411
	fsub dword[d_x]
412
	fstp dword[esp-8]
413
	sub esp,8
414
	call ClipLine1 ;-d_x+d_w,x1-w1,&tmin,&tmax
415
	bt eax,0
416
	jnc .end_f
417
 
418
	sub esp,8 ;толкаем в стек адреса переменных &tmin и &tmax
419
	fld dword[y1]
420
	fadd dword[w1]
421
	fchs
422
	fstp dword[esp-4]
423
	fld dword[d_y]
424
	fadd dword[d_w]
425
	fstp dword[esp-8]
426
	sub esp,8
427
	call ClipLine1 ;d_y+d_w,-y1-w1,&tmin,&tmax
428
	bt eax,0
429
	jnc .end_f
430
 
431
	sub esp,8 ;толкаем в стек адреса переменных &tmin и &tmax
432
	fld dword[y1]
433
	fsub dword[w1]
434
	fstp dword[esp-4]
435
	fld dword[d_w]
436
	fsub dword[d_y]
437
	fstp dword[esp-8]
438
	sub esp,8
439
	call ClipLine1 ;-d_y+d_w,y1-w1,&tmin,&tmax
440
	bt eax,0
441
	jnc .end_f
442
 
443
	sub esp,8 ;толкаем в стек адреса переменных &tmin и &tmax
444
	fld dword[z1]
445
	fadd dword[w1]
446
	fchs
447
	fstp dword[esp-4]
448
	fld dword[d_z]
449
	fadd dword[d_w]
450
	fstp dword[esp-8]
451
	sub esp,8
452
	call ClipLine1 ;d_z+d_w,-z1-w1,&tmin,&tmax
453
	bt eax,0
454
	jnc .end_f
455
 
456
	sub esp,8 ;толкаем в стек адреса переменных &tmin и &tmax
457
	fld dword[z1]
458
	fsub dword[w1]
459
	fstp dword[esp-4]
460
	fld dword[d_w]
461
	fsub dword[d_z]
462
	fstp dword[esp-8]
463
	sub esp,8
464
	call ClipLine1 ;-d_z+d_w,z1-w1,&tmin,&tmax
465
	bt eax,0
466
	jnc .end_f
467
 
468
	mov eax,ebp
469
	sub eax,8+2*sizeof.GLVertex ;eax = &q1
470
	stdcall interpolate, eax,edi,esi,[tmin]
471
	stdcall gl_transform_to_viewport, edx,eax
472
	add eax,sizeof.GLVertex ;eax = &q2
473
	stdcall interpolate, eax,edi,esi,[tmax]
474
	stdcall gl_transform_to_viewport, edx,eax
475
 
476
	sub eax,sizeof.GLVertex ;eax = &q1
477
	mov ebx,eax
478
	add ebx,offs_vert_zp+offs_zbup_b
479
	push ebx
480
	add ebx,offs_zbup_g-offs_zbup_b
481
	push ebx
482
	add ebx,offs_zbup_r-offs_zbup_g
483
	push ebx
484
	stdcall RGBFtoRGBI, dword[eax+offs_vert_color],dword[eax+offs_vert_color+4],dword[eax+offs_vert_color+8]
485
 
486
	add eax,sizeof.GLVertex ;eax = &q2
487
	mov ebx,eax
488
	add ebx,offs_vert_zp+offs_zbup_b
489
	push ebx
490
	add ebx,offs_zbup_g-offs_zbup_b
491
	push ebx
492
	add ebx,offs_zbup_r-offs_zbup_g
493
	push ebx
494
	stdcall RGBFtoRGBI, dword[eax+offs_vert_color],dword[eax+offs_vert_color+4],dword[eax+offs_vert_color+8]
495
 
496
	add eax,offs_vert_zp ;eax = &q2.zp
497
	push eax
498
	sub eax,sizeof.GLVertex ;eax = &q1.zp
499
	push eax
500
	push dword[edx+offs_cont_zb]
501
	cmp dword[edx+offs_cont_depth_test],0
502
	je .els_3
503
		call ZB_line_z ;(context.zb,&q1.zp,&q2.zp)
504
		jmp .end_f
505
	.els_3:
506
		call ZB_line ;(context.zb,&q1.zp,&q2.zp)
507
	.end_f:
508
	ret
509
endp
510
 
511
; triangle
512
 
513
;
514
; Clipping
515
;
516
 
517
; We clip the segment [a,b] against the 6 planes of the normal volume.
518
; We compute the point 'c' of intersection and the value of the parameter 't'
519
; of the intersection if x=a+t(b-a).
520
;
521
; sign: 0 -> '-', 1 -> '+'
522
macro clip_func sign,dir,dir1,dir2
523
{
524
locals
525
	t dd ?
526
	d_X dd ?
527
	d_Y dd ?
528
	d_Z dd ?
529
	d_W dd ?
530
endl
531
	mov edx,[a]
532
	mov ebx,[b]
533
	mov ecx,[c]
5175 IgorA 534
	fld dword[ebx+offs_X]
535
	fsub dword[edx+offs_X]
5153 IgorA 536
	fstp dword[d_X] ;d_X = (b.X - a.X)
5175 IgorA 537
	fld dword[ebx+offs_Y]
538
	fsub dword[edx+offs_Y]
5153 IgorA 539
	fstp dword[d_Y] ;d_Y = (b.Y - a.Y)
5175 IgorA 540
	fld dword[ebx+offs_Z]
541
	fsub dword[edx+offs_Z]
5153 IgorA 542
	fstp dword[d_Z] ;d_Z = (b.Z - a.Z)
5175 IgorA 543
	fld dword[ebx+offs_W]
544
	fsub dword[edx+offs_W]
5153 IgorA 545
	fst dword[d_W] ;d_W = (b.W - a.W)
546
if sign eq 0
547
	fadd dword[d#dir]
548
else
549
	fsub dword[d#dir]
550
end if
551
 
552
	fldz
5175 IgorA 553
	fcompp
5153 IgorA 554
	fstsw ax
555
	sahf
556
	ja @f
557
		fst dword[t] ;t=0
558
		jmp .e_zero
559
	@@: ;else
560
		fld dword[edx+offs#dir]
561
if sign eq 0
562
		fchs
563
end if
564
		fsub dword[edx+offs_W]
565
		fdiv st0,st1
566
		fst dword[t] ;t = ( sign a.dir - a.W) / den
567
	.e_zero:
568
 
569
	fmul dword[d#dir1] ;st0 = t * d.dir1
570
	fadd dword[edx+offs#dir1]
571
	fstp dword[ecx+offs#dir1] ;c.dir1 = a.dir1 + t * d.dir1
572
 
573
	fld dword[t]
574
	fmul dword[d#dir2] ;st0 = t * d.dir2
575
	fadd dword[edx+offs#dir2]
576
	fstp dword[ecx+offs#dir2] ;c.dir2 = a.dir2 + t * d.dir2
577
 
578
	fld dword[t]
579
	fmul dword[d_W]
580
	fadd dword[edx+offs_W]
581
	fst dword[ecx+offs_W] ;c.W = a.W + t * d_W
582
 
583
if sign eq 0
584
		fchs
585
end if
586
	fstp dword[ecx+offs#dir] ;c.dir = sign c.W
587
	mov eax,[t]
588
}
589
 
590
align 4
591
proc clip_xmin uses ebx ecx edx, c:dword, a:dword, b:dword
592
	clip_func 0,_X,_Y,_Z
593
	ret
594
endp
595
 
596
align 4
597
proc clip_xmax uses ebx ecx edx, c:dword, a:dword, b:dword
598
	clip_func 1,_X,_Y,_Z
599
	ret
600
endp
601
 
602
align 4
603
proc clip_ymin uses ebx ecx edx, c:dword, a:dword, b:dword
604
	clip_func 0,_Y,_X,_Z
605
	ret
606
endp
607
 
608
align 4
609
proc clip_ymax uses ebx ecx edx, c:dword, a:dword, b:dword
610
	clip_func 1,_Y,_X,_Z
611
	ret
612
endp
613
 
614
align 4
615
proc clip_zmin uses ebx ecx edx, c:dword, a:dword, b:dword
616
	clip_func 0,_Z,_X,_Y
617
	ret
618
endp
619
 
620
align 4
621
proc clip_zmax uses ebx ecx edx, c:dword, a:dword, b:dword
622
	clip_func 1,_Z,_X,_Y
623
	ret
624
endp
625
 
626
align 4
627
clip_proc dd clip_xmin,clip_xmax, clip_ymin,clip_ymax, clip_zmin,clip_zmax
628
 
5175 IgorA 629
align 4
630
proc updateTmp uses edx, context:dword, q:dword, p0:dword, p1:dword, t:dword
631
	mov eax,[context]
632
	cmp dword[edx+offs_cont_current_shade_model],GL_SMOOTH ;if (context.current_shade_model == GL_SMOOTH)
633
	jne .els_0
5153 IgorA 634
;    q->color.v[0]=p0->color.v[0] + (p1->color.v[0]-p0->color.v[0])*t;
635
;    q->color.v[1]=p0->color.v[1] + (p1->color.v[1]-p0->color.v[1])*t;
636
;    q->color.v[2]=p0->color.v[2] + (p1->color.v[2]-p0->color.v[2])*t;
5175 IgorA 637
		jmp @f
638
	.els_0:
5153 IgorA 639
;    q->color.v[0]=p0->color.v[0];
640
;    q->color.v[1]=p0->color.v[1];
641
;    q->color.v[2]=p0->color.v[2];
5175 IgorA 642
	@@:
5153 IgorA 643
 
5175 IgorA 644
	cmp dword[edx+offs_cont_texture_2d_enabled],0 ;if (context.texture_2d_enabled)
645
	je @f
5153 IgorA 646
;    q->tex_coord.X=p0->tex_coord.X + (p1->tex_coord.X-p0->tex_coord.X)*t;
647
;    q->tex_coord.Y=p0->tex_coord.Y + (p1->tex_coord.Y-p0->tex_coord.Y)*t;
5175 IgorA 648
	@@:
5153 IgorA 649
 
650
;  q->clip_code=gl_clipcode(q->pc.X,q->pc.Y,q->pc.Z,q->pc.W);
651
;  if (q->clip_code==0){
652
;    gl_transform_to_viewport(c,q);
653
;    RGBFtoRGBI(q->color.v[0],q->color.v[1],q->color.v[2],q->zp.r,q->zp.g,q->zp.b);
654
;  }
5175 IgorA 655
	ret
656
endp
5153 IgorA 657
 
5175 IgorA 658
align 4
659
proc gl_draw_triangle, context:dword, p0:dword, p1:dword, p2:dword
660
locals
661
	cc rd 3
662
	front dd ?
663
	norm dd ? ;float
664
endl
665
pushad
666
	mov ebx,[p0]
667
	mov ecx,[p1]
668
	mov edx,[p2]
669
 
670
	mov edi,[ebx+offs_vert_clip_code]
671
	mov dword[cc],edi
672
	mov eax,[ecx+offs_vert_clip_code]
673
	mov dword[cc+4],eax
674
	or edi,eax
675
	mov eax,[edx+offs_vert_clip_code]
676
	mov dword[cc+8],eax
677
	or edi,eax
5153 IgorA 678
 
5175 IgorA 679
	; we handle the non clipped case here to go faster
680
	cmp edi,0
681
	jne .els_0
682
		mov edi,dword[edx+offs_vert_zp+offs_zbup_x]
683
		mov edi,dword[ebx+offs_vert_zp+offs_zbup_x]
684
		mov dword[norm],edi
685
		fild dword[norm]
686
		mov esi,dword[ecx+offs_vert_zp+offs_zbup_y]
687
		mov esi,dword[ebx+offs_vert_zp+offs_zbup_y]
688
		mov dword[norm],edi
689
		fimul dword[norm]
690
		mov edi,dword[ecx+offs_vert_zp+offs_zbup_x]
691
		sub edi,dword[ebx+offs_vert_zp+offs_zbup_x]
692
		mov dword[norm],edi
693
		fild dword[norm]
694
		mov edi,dword[edx+offs_vert_zp+offs_zbup_y]
695
		mov edi,dword[ebx+offs_vert_zp+offs_zbup_y]
696
		mov dword[norm],edi
697
		fimul dword[norm]
698
		fsub st0,st1
5153 IgorA 699
 
5175 IgorA 700
		;st0 = (p1.zp.x-p0.zp.x)*(p2.zp.y-p0.zp.y) - (p2.zp.x-p0.zp.x)*(p1.zp.y-p0.zp.y)
5153 IgorA 701
 
5175 IgorA 702
		mov dword[front],0
703
		fldz
704
		fcom st1
705
		fstsw ax
706
		sahf
707
		je .end_f
708
		jb @f
709
			inc dword[front] ;front = 0.0 > norm
710
		@@:
711
		mov edi,[context]
712
		mov eax,dword[edi+offs_cont_current_front_face]
713
		xor dword[front],eax ;front ^= context.current_front_face
5153 IgorA 714
 
5175 IgorA 715
		; back face culling
716
		cmp dword[edi+offs_cont_cull_face_enabled],0
717
		je .els_1
718
			; most used case first
719
			cmp dword[edi+offs_cont_current_cull_face],GL_BACK
720
			jne @f
721
				cmp dword[front],0
722
				je .end_f
723
					stdcall dword[edi+offs_cont_draw_triangle_front], edi,ebx,ecx,edx
724
				jmp .end_f
725
			@@:
726
			cmp dword[edi+offs_cont_current_cull_face],GL_FRONT
727
			jne .end_f
728
				cmp dword[front],0
729
				jne .end_f
730
					stdcall dword[edi+offs_cont_draw_triangle_back], edi,ebx,ecx,edx
731
			jmp .end_f
732
		.els_1:
733
			; no culling
734
			cmp dword[front],0
735
			je @f
736
				stdcall dword[edi+offs_cont_draw_triangle_front], edi,ebx,ecx,edx
737
			@@:
738
				stdcall dword[edi+offs_cont_draw_triangle_back], edi,ebx,ecx,edx
739
		jmp .end_f
740
	.els_0:
741
		and eax,[cc]
742
		and eax,[cc+4]
743
		cmp eax,0
744
		jne @f
745
			stdcall gl_draw_triangle_clip, [context],ebx,ecx,edx,0
746
	.end_f:
747
	finit
748
	@@:
749
popad
750
	ret
751
endp
5153 IgorA 752
 
5175 IgorA 753
align 4
754
proc gl_draw_triangle_clip, context:dword, p0:dword, p1:dword, p2:dword, clip_bit:dword
755
locals
756
	co dd ?
757
	co1 dd ?
758
	cc rd 3
759
	edge_flag_tmp dd ?
760
	clip_mask dd ?
761
	tmp1 GLVertex ?
762
	tmp2 GLVertex ?
763
	q rd 3 ;GLVertex*
764
	tt dd ? ;float
765
endl
766
pushad
767
 
768
	mov ebx,[p0]
769
	mov ecx,[p1]
770
	mov edx,[p2]
771
 
772
	mov edi,[ebx+offs_vert_clip_code]
773
	mov dword[cc],edi
774
	mov eax,[ecx+offs_vert_clip_code]
775
	mov dword[cc+4],eax
776
	or edi,eax
777
	mov eax,[edx+offs_vert_clip_code]
778
	mov dword[cc+8],eax
779
	or edi,eax
780
	mov dword[co],edi
781
 
782
	cmp edi,0
783
	jne .els_0
784
		stdcall gl_draw_triangle, [context],ebx,ecx,edx
785
		jmp .end_f
786
	.els_0:
787
		and eax,[cc]
788
		and eax,[cc+4]
789
 
790
		; the triangle is completely outside
791
		cmp eax,0
792
		jne .end_f
793
 
794
	; find the next direction to clip
5153 IgorA 795
;    while (clip_bit < 6 && (co & (1 << clip_bit)) == 0)  {
796
;      clip_bit++;
797
;    }
798
 
5175 IgorA 799
	; this test can be true only in case of rounding errors
800
	cmp dword[clip_bit],6
801
if 0
802
	jne @f
5153 IgorA 803
;      printf("Error:\n");
804
;      printf("%f %f %f %f\n",p0->pc.X,p0->pc.Y,p0->pc.Z,p0->pc.W);
805
;      printf("%f %f %f %f\n",p1->pc.X,p1->pc.Y,p1->pc.Z,p1->pc.W);
806
;      printf("%f %f %f %f\n",p2->pc.X,p2->pc.Y,p2->pc.Z,p2->pc.W);
5175 IgorA 807
		jmp .end_f
808
	@@:
809
else
810
	je .end_f
811
end if
5153 IgorA 812
 
813
;    clip_mask = 1 << clip_bit;
814
;    co1=(cc[0] ^ cc[1] ^ cc[2]) & clip_mask;
815
 
816
;    if (co1)  {
817
;      /* one point outside */
818
 
819
;      if (cc[0] & clip_mask) { q[0]=p0; q[1]=p1; q[2]=p2; }
820
;      else if (cc[1] & clip_mask) { q[0]=p1; q[1]=p2; q[2]=p0; }
821
;      else { q[0]=p2; q[1]=p0; q[2]=p1; }
822
;
823
;      tt=clip_proc[clip_bit](&tmp1.pc,&q[0]->pc,&q[1]->pc);
824
;      updateTmp(c,&tmp1,q[0],q[1],tt);
825
;
826
;      tt=clip_proc[clip_bit](&tmp2.pc,&q[0]->pc,&q[2]->pc);
827
;      updateTmp(c,&tmp2,q[0],q[2],tt);
828
;
829
;      tmp1.edge_flag=q[0]->edge_flag;
830
;      edge_flag_tmp=q[2]->edge_flag;
831
;      q[2]->edge_flag=0;
832
;      gl_draw_triangle_clip(c,&tmp1,q[1],q[2],clip_bit+1);
833
;
834
;      tmp2.edge_flag=0;
835
;      tmp1.edge_flag=0;
836
;      q[2]->edge_flag=edge_flag_tmp;
837
;      gl_draw_triangle_clip(c,&tmp2,&tmp1,q[2],clip_bit+1);
838
;    } else {
839
;      /* two points outside */
840
 
841
;      if ((cc[0] & clip_mask)==0) { q[0]=p0; q[1]=p1; q[2]=p2; }
842
;      else if ((cc[1] & clip_mask)==0) { q[0]=p1; q[1]=p2; q[2]=p0; }
843
;      else { q[0]=p2; q[1]=p0; q[2]=p1; }
844
 
845
;      tt=clip_proc[clip_bit](&tmp1.pc,&q[0]->pc,&q[1]->pc);
846
;      updateTmp(c,&tmp1,q[0],q[1],tt);
847
 
848
;      tt=clip_proc[clip_bit](&tmp2.pc,&q[0]->pc,&q[2]->pc);
849
;      updateTmp(c,&tmp2,q[0],q[2],tt);
850
 
851
;      tmp1.edge_flag=1;
852
;      tmp2.edge_flag=q[2]->edge_flag;
853
;      gl_draw_triangle_clip(c,q[0],&tmp1,&tmp2,clip_bit+1);
854
;    }
855
;  }
5175 IgorA 856
	.end_f:
857
popad
858
	ret
859
endp
5153 IgorA 860
 
861
align 4
862
proc gl_draw_triangle_select uses eax, context:dword, p0:dword,p1:dword,p2:dword
863
	mov eax,[p2]
864
	push dword[eax+offs_vert_zp+offs_Z]
865
	mov eax,[p1]
866
	push dword[eax+offs_vert_zp+offs_Z]
867
	mov eax,[p0]
868
	push dword[eax+offs_vert_zp+offs_Z]
869
	stdcall gl_add_select1, [context] ;,p0.zp.z, p1.zp.z, p2.zp.z
870
	ret
871
endp
872
 
5175 IgorA 873
if PROFILE eq 1
874
	count_triangles dd ?
875
	count_triangles_textured dd ?
876
	count_pixels dd ?
877
end if
5153 IgorA 878
 
879
align 4
5175 IgorA 880
proc gl_draw_triangle_fill, context:dword, p0:dword,p1:dword,p2:dword
881
pushad
882
if PROFILE eq 1
5153 IgorA 883
;    int norm;
884
;    assert(p0->zp.x >= 0 && p0->zp.x < c->zb->xsize);
885
;    assert(p0->zp.y >= 0 && p0->zp.y < c->zb->ysize);
886
;    assert(p1->zp.x >= 0 && p1->zp.x < c->zb->xsize);
887
;    assert(p1->zp.y >= 0 && p1->zp.y < c->zb->ysize);
888
;    assert(p2->zp.x >= 0 && p2->zp.x < c->zb->xsize);
889
;    assert(p2->zp.y >= 0 && p2->zp.y < c->zb->ysize);
890
 
891
;    norm=(p1->zp.x-p0->zp.x)*(p2->zp.y-p0->zp.y)-
892
;      (p2->zp.x-p0->zp.x)*(p1->zp.y-p0->zp.y);
893
;    count_pixels+=abs(norm)/2;
5175 IgorA 894
	inc dword[count_triangles]
895
end if
5153 IgorA 896
 
5175 IgorA 897
	mov ebx,[p1]
898
	add ebx,offs_vert_zp
899
	mov ecx,[p2]
900
	add ecx,offs_vert_zp
5153 IgorA 901
	mov edx,[context]
902
	cmp dword[edx+offs_cont_texture_2d_enabled],0
903
	je .els_i
904
		;if (context.texture_2d_enabled)
5175 IgorA 905
if PROFILE eq 1
906
	inc dword[count_triangles_textured]
907
end if
5153 IgorA 908
		mov eax,dword[edx+offs_cont_current_texture]
909
		mov eax,[eax] ;переход по указателю
910
		;так как offs_text_images+offs_imag_pixmap = 0 то context.current_texture.images[0].pixmap = [eax]
911
		stdcall ZB_setTexture, dword[edx+offs_cont_zb],dword[eax]
5175 IgorA 912
		mov eax,[p0]
913
		add eax,offs_vert_zp
914
		stdcall ZB_fillTriangleMappingPerspective, dword[edx+offs_cont_zb],eax,ebx,ecx
5153 IgorA 915
		jmp .end_f
916
	.els_i:
5175 IgorA 917
		mov eax,[p0]
918
		add eax,offs_vert_zp
919
		cmp dword[edx+offs_cont_current_shade_model],GL_SMOOTH
920
		jne .els
921
			;else if (context.current_shade_model == GL_SMOOTH)
922
			stdcall ZB_fillTriangleSmooth, dword[edx+offs_cont_zb],eax,ebx,ecx
923
			jmp .end_f
924
		.els:
925
			stdcall ZB_fillTriangleFlat, dword[edx+offs_cont_zb],eax,ebx,ecx
5153 IgorA 926
	.end_f:
5175 IgorA 927
popad
5153 IgorA 928
	ret
929
endp
930
 
931
; Render a clipped triangle in line mode
932
 
933
align 4
934
proc gl_draw_triangle_line uses eax ebx ecx edx, context:dword, p0:dword,p1:dword,p2:dword
935
	mov edx,[context]
936
	cmp dword[edx+offs_cont_depth_test],0
937
	je .els
938
		lea ecx,[ZB_line_z]
939
		jmp @f
940
	.els:
941
		lea ecx,[ZB_line]
942
	@@:
943
 
944
	;if (p0.edge_flag) ZB_line_z(context.zb,&p0.zp,&p1.zp)
945
	mov eax,[p0]
946
	cmp dword[eax+offs_vert_edge_flag],0
947
	je @f
948
		mov ebx,eax
949
		add ebx,offs_vert_zp
950
		mov eax,[p1]
951
		add eax,offs_vert_zp
952
		stdcall ecx,dword[edx+offs_cont_zb],ebx,eax
953
	@@:
954
	;if (p1.edge_flag) ZB_line_z(context.zb,&p1.zp,&p2.zp)
955
	mov eax,[p1]
956
	cmp dword[eax+offs_vert_edge_flag],0
957
	je @f
958
		mov ebx,eax
959
		add ebx,offs_vert_zp
960
		mov eax,[p2]
961
		add eax,offs_vert_zp
962
		stdcall ecx,dword[edx+offs_cont_zb],ebx,eax
963
	@@:
964
	;if (p2.edge_flag) ZB_line_z(context.zb,&p2.zp,&p0.zp);
965
	mov eax,[p2]
966
	cmp dword[eax+offs_vert_edge_flag],0
967
	je @f
968
		mov ebx,eax
969
		add ebx,offs_vert_zp
970
		mov eax,[p0]
971
		add eax,offs_vert_zp
972
		stdcall ecx,dword[edx+offs_cont_zb],ebx,eax
973
	@@:
974
 
975
	ret
976
endp
977
 
978
; Render a clipped triangle in point mode
979
align 4
980
proc gl_draw_triangle_point uses eax ebx edx, context:dword, p0:dword,p1:dword,p2:dword
981
	mov edx,[context]
982
	mov eax,[p0]
983
	cmp dword[eax+offs_vert_edge_flag],0
984
	je @f
985
		mov ebx,eax
986
		add ebx,offs_vert_zp
987
		stdcall ZB_plot,dword[edx+offs_cont_zb],ebx
988
	@@:
989
	add eax,[p1]
990
	cmp dword[eax+offs_vert_edge_flag],0
991
	je @f
992
		mov ebx,eax
993
		add ebx,offs_vert_zp
994
		stdcall ZB_plot,dword[edx+offs_cont_zb],ebx
995
	@@:
996
	add eax,[p2]
997
	cmp dword[eax+offs_vert_edge_flag],0
998
	je @f
999
		mov ebx,eax
1000
		add ebx,offs_vert_zp
1001
		stdcall ZB_plot,dword[edx+offs_cont_zb],ebx
1002
	@@:
1003
	ret
1004
endp
1005
 
1006
 
1007
 
1008