Subversion Repositories Kolibri OS

Rev

Rev 5175 | Go to most recent revision | Details | 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
	; интерполяция по координатам
172
	fld dword[ecx+offs_vert_pc]
173
	fsub dword[ebx+offs_vert_pc]
174
	fmul st0,st1
175
	fadd dword[ebx+offs_vert_pc]
176
	fstp dword[eax+offs_vert_pc]
177
 
178
	fld dword[ecx+offs_vert_pc+4]
179
	fsub dword[ebx+offs_vert_pc+4]
180
	fmul st0,st1
181
	fadd dword[ebx+offs_vert_pc+4]
182
	fstp dword[eax+offs_vert_pc+4]
183
 
184
	fld dword[ecx+offs_vert_pc+8]
185
	fsub dword[ebx+offs_vert_pc+8]
186
	fmul st0,st1
187
	fadd dword[ebx+offs_vert_pc+8]
188
	fstp dword[eax+offs_vert_pc+8]
189
 
190
	fld dword[ecx+offs_vert_pc+12]
191
	fsub dword[ebx+offs_vert_pc+12]
192
	fmul st0,st1
193
	fadd dword[ebx+offs_vert_pc+12]
194
	fstp dword[eax+offs_vert_pc+12]
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]
534
	fld dword[ebx]
535
	fsub dword[edx]
536
	fstp dword[d_X] ;d_X = (b.X - a.X)
537
	fld dword[ebx+4]
538
	fsub dword[edx+4]
539
	fstp dword[d_Y] ;d_Y = (b.Y - a.Y)
540
	fld dword[ebx+8]
541
	fsub dword[edx+8]
542
	fstp dword[d_Z] ;d_Z = (b.Z - a.Z)
543
	fld dword[ebx+12]
544
	fsub dword[edx+12]
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
553
	fcomp st1
554
	fstsw ax
555
	sahf
556
	ja @f
557
		fincstp
558
		fst dword[t] ;t=0
559
		jmp .e_zero
560
	@@: ;else
561
		fincstp
562
		fld dword[edx+offs#dir]
563
if sign eq 0
564
		fchs
565
end if
566
		fsub dword[edx+offs_W]
567
		fdiv st0,st1
568
		fst dword[t] ;t = ( sign a.dir - a.W) / den
569
	.e_zero:
570
 
571
	fmul dword[d#dir1] ;st0 = t * d.dir1
572
	fadd dword[edx+offs#dir1]
573
	fstp dword[ecx+offs#dir1] ;c.dir1 = a.dir1 + t * d.dir1
574
 
575
	fld dword[t]
576
	fmul dword[d#dir2] ;st0 = t * d.dir2
577
	fadd dword[edx+offs#dir2]
578
	fstp dword[ecx+offs#dir2] ;c.dir2 = a.dir2 + t * d.dir2
579
 
580
	fld dword[t]
581
	fmul dword[d_W]
582
	fadd dword[edx+offs_W]
583
	fst dword[ecx+offs_W] ;c.W = a.W + t * d_W
584
 
585
if sign eq 0
586
		fchs
587
end if
588
	fstp dword[ecx+offs#dir] ;c.dir = sign c.W
589
	mov eax,[t]
590
}
591
 
592
align 4
593
proc clip_xmin uses ebx ecx edx, c:dword, a:dword, b:dword
594
	clip_func 0,_X,_Y,_Z
595
	ret
596
endp
597
 
598
align 4
599
proc clip_xmax uses ebx ecx edx, c:dword, a:dword, b:dword
600
	clip_func 1,_X,_Y,_Z
601
	ret
602
endp
603
 
604
align 4
605
proc clip_ymin uses ebx ecx edx, c:dword, a:dword, b:dword
606
	clip_func 0,_Y,_X,_Z
607
	ret
608
endp
609
 
610
align 4
611
proc clip_ymax uses ebx ecx edx, c:dword, a:dword, b:dword
612
	clip_func 1,_Y,_X,_Z
613
	ret
614
endp
615
 
616
align 4
617
proc clip_zmin uses ebx ecx edx, c:dword, a:dword, b:dword
618
	clip_func 0,_Z,_X,_Y
619
	ret
620
endp
621
 
622
align 4
623
proc clip_zmax uses ebx ecx edx, c:dword, a:dword, b:dword
624
	clip_func 1,_Z,_X,_Y
625
	ret
626
endp
627
 
628
align 4
629
clip_proc dd clip_xmin,clip_xmax, clip_ymin,clip_ymax, clip_zmin,clip_zmax
630
 
631
;static inline void updateTmp(GLContext *c, GLVertex *q,GLVertex *p0,GLVertex *p1,float t)
632
;{
633
;  if (c->current_shade_model == GL_SMOOTH) {
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;
637
;  } else {
638
;    q->color.v[0]=p0->color.v[0];
639
;    q->color.v[1]=p0->color.v[1];
640
;    q->color.v[2]=p0->color.v[2];
641
;  }
642
 
643
;  if (c->texture_2d_enabled) {
644
;    q->tex_coord.X=p0->tex_coord.X + (p1->tex_coord.X-p0->tex_coord.X)*t;
645
;    q->tex_coord.Y=p0->tex_coord.Y + (p1->tex_coord.Y-p0->tex_coord.Y)*t;
646
;  }
647
 
648
;  q->clip_code=gl_clipcode(q->pc.X,q->pc.Y,q->pc.Z,q->pc.W);
649
;  if (q->clip_code==0){
650
;    gl_transform_to_viewport(c,q);
651
;    RGBFtoRGBI(q->color.v[0],q->color.v[1],q->color.v[2],q->zp.r,q->zp.g,q->zp.b);
652
;  }
653
;}
654
 
655
;static void gl_draw_triangle_clip(GLContext *c, GLVertex *p0,GLVertex *p1,GLVertex *p2,int clip_bit);
656
 
657
;void gl_draw_triangle(GLContext *c, GLVertex *p0,GLVertex *p1,GLVertex *p2)
658
;{
659
;  int co,c_and,cc[3],front;
660
;  float norm;
661
;
662
;  cc[0]=p0->clip_code;
663
;  cc[1]=p1->clip_code;
664
;  cc[2]=p2->clip_code;
665
;
666
;  co=cc[0] | cc[1] | cc[2];
667
;
668
;  /* we handle the non clipped case here to go faster */
669
;  if (co==0) {
670
;
671
;      norm=(float)(p1->zp.x-p0->zp.x)*(float)(p2->zp.y-p0->zp.y)-
672
;        (float)(p2->zp.x-p0->zp.x)*(float)(p1->zp.y-p0->zp.y);
673
;
674
;      if (norm == 0) return;
675
;
676
;      front = norm < 0.0;
677
;      front = front ^ c->current_front_face;
678
;
679
;      /* back face culling */
680
;      if (c->cull_face_enabled) {
681
;        /* most used case first */
682
;        if (c->current_cull_face == GL_BACK) {
683
;          if (front == 0) return;
684
;          c->draw_triangle_front(c,p0,p1,p2);
685
;        } else if (c->current_cull_face == GL_FRONT) {
686
;          if (front != 0) return;
687
;          c->draw_triangle_back(c,p0,p1,p2);
688
;        } else {
689
;          return;
690
;        }
691
;      } else {
692
;        /* no culling */
693
;        if (front) {
694
;          c->draw_triangle_front(c,p0,p1,p2);
695
;        } else {
696
;          c->draw_triangle_back(c,p0,p1,p2);
697
;        }
698
;      }
699
;  } else {
700
;    c_and=cc[0] & cc[1] & cc[2];
701
;    if (c_and==0) {
702
;      gl_draw_triangle_clip(c,p0,p1,p2,0);
703
;    }
704
;  }
705
;}
706
 
707
;static void gl_draw_triangle_clip(GLContext *c, GLVertex *p0,GLVertex *p1,GLVertex *p2,int clip_bit)
708
;{
709
;  int co,c_and,co1,cc[3],edge_flag_tmp,clip_mask;
710
;  GLVertex tmp1,tmp2,*q[3];
711
;  float tt;
712
 
713
;  cc[0]=p0->clip_code;
714
;  cc[1]=p1->clip_code;
715
;  cc[2]=p2->clip_code;
716
 
717
;  co=cc[0] | cc[1] | cc[2];
718
;  if (co == 0) {
719
;    gl_draw_triangle(c,p0,p1,p2);
720
;  } else {
721
;    c_and=cc[0] & cc[1] & cc[2];
722
;    /* the triangle is completely outside */
723
;    if (c_and!=0) return;
724
 
725
;    /* find the next direction to clip */
726
;    while (clip_bit < 6 && (co & (1 << clip_bit)) == 0)  {
727
;      clip_bit++;
728
;    }
729
 
730
;    /* this test can be true only in case of rounding errors */
731
;    if (clip_bit == 6) {
732
;#if 0
733
;      printf("Error:\n");
734
;      printf("%f %f %f %f\n",p0->pc.X,p0->pc.Y,p0->pc.Z,p0->pc.W);
735
;      printf("%f %f %f %f\n",p1->pc.X,p1->pc.Y,p1->pc.Z,p1->pc.W);
736
;      printf("%f %f %f %f\n",p2->pc.X,p2->pc.Y,p2->pc.Z,p2->pc.W);
737
;#endif
738
;      return;
739
;    }
740
 
741
;    clip_mask = 1 << clip_bit;
742
;    co1=(cc[0] ^ cc[1] ^ cc[2]) & clip_mask;
743
 
744
;    if (co1)  {
745
;      /* one point outside */
746
 
747
;      if (cc[0] & clip_mask) { q[0]=p0; q[1]=p1; q[2]=p2; }
748
;      else if (cc[1] & clip_mask) { q[0]=p1; q[1]=p2; q[2]=p0; }
749
;      else { q[0]=p2; q[1]=p0; q[2]=p1; }
750
;
751
;      tt=clip_proc[clip_bit](&tmp1.pc,&q[0]->pc,&q[1]->pc);
752
;      updateTmp(c,&tmp1,q[0],q[1],tt);
753
;
754
;      tt=clip_proc[clip_bit](&tmp2.pc,&q[0]->pc,&q[2]->pc);
755
;      updateTmp(c,&tmp2,q[0],q[2],tt);
756
;
757
;      tmp1.edge_flag=q[0]->edge_flag;
758
;      edge_flag_tmp=q[2]->edge_flag;
759
;      q[2]->edge_flag=0;
760
;      gl_draw_triangle_clip(c,&tmp1,q[1],q[2],clip_bit+1);
761
;
762
;      tmp2.edge_flag=0;
763
;      tmp1.edge_flag=0;
764
;      q[2]->edge_flag=edge_flag_tmp;
765
;      gl_draw_triangle_clip(c,&tmp2,&tmp1,q[2],clip_bit+1);
766
;    } else {
767
;      /* two points outside */
768
 
769
;      if ((cc[0] & clip_mask)==0) { q[0]=p0; q[1]=p1; q[2]=p2; }
770
;      else if ((cc[1] & clip_mask)==0) { q[0]=p1; q[1]=p2; q[2]=p0; }
771
;      else { q[0]=p2; q[1]=p0; q[2]=p1; }
772
 
773
;      tt=clip_proc[clip_bit](&tmp1.pc,&q[0]->pc,&q[1]->pc);
774
;      updateTmp(c,&tmp1,q[0],q[1],tt);
775
 
776
;      tt=clip_proc[clip_bit](&tmp2.pc,&q[0]->pc,&q[2]->pc);
777
;      updateTmp(c,&tmp2,q[0],q[2],tt);
778
 
779
;      tmp1.edge_flag=1;
780
;      tmp2.edge_flag=q[2]->edge_flag;
781
;      gl_draw_triangle_clip(c,q[0],&tmp1,&tmp2,clip_bit+1);
782
;    }
783
;  }
784
;}
785
 
786
align 4
787
proc gl_draw_triangle_select uses eax, context:dword, p0:dword,p1:dword,p2:dword
788
	mov eax,[p2]
789
	push dword[eax+offs_vert_zp+offs_Z]
790
	mov eax,[p1]
791
	push dword[eax+offs_vert_zp+offs_Z]
792
	mov eax,[p0]
793
	push dword[eax+offs_vert_zp+offs_Z]
794
	stdcall gl_add_select1, [context] ;,p0.zp.z, p1.zp.z, p2.zp.z
795
	ret
796
endp
797
 
798
;#ifdef PROFILE
799
;int count_triangles,count_triangles_textured,count_pixels;
800
;#endif
801
 
802
align 4
803
proc gl_draw_triangle_fill uses eax edx, context:dword, p0:dword,p1:dword,p2:dword
804
;#ifdef PROFILE
805
;  {
806
;    int norm;
807
;    assert(p0->zp.x >= 0 && p0->zp.x < c->zb->xsize);
808
;    assert(p0->zp.y >= 0 && p0->zp.y < c->zb->ysize);
809
;    assert(p1->zp.x >= 0 && p1->zp.x < c->zb->xsize);
810
;    assert(p1->zp.y >= 0 && p1->zp.y < c->zb->ysize);
811
;    assert(p2->zp.x >= 0 && p2->zp.x < c->zb->xsize);
812
;    assert(p2->zp.y >= 0 && p2->zp.y < c->zb->ysize);
813
 
814
;    norm=(p1->zp.x-p0->zp.x)*(p2->zp.y-p0->zp.y)-
815
;      (p2->zp.x-p0->zp.x)*(p1->zp.y-p0->zp.y);
816
;    count_pixels+=abs(norm)/2;
817
;    count_triangles++;
818
;  }
819
;#endif
820
 
821
	mov edx,[context]
822
	cmp dword[edx+offs_cont_texture_2d_enabled],0
823
	je .els_i
824
		;if (context.texture_2d_enabled)
825
;#ifdef PROFILE
826
;    count_triangles_textured++;
827
;#endif
828
		mov eax,dword[edx+offs_cont_current_texture]
829
		mov eax,[eax] ;переход по указателю
830
		;так как offs_text_images+offs_imag_pixmap = 0 то context.current_texture.images[0].pixmap = [eax]
831
		stdcall ZB_setTexture, dword[edx+offs_cont_zb],dword[eax]
832
;    ZB_fillTriangleMappingPerspective, dword[edx+offs_cont_zb],&p0->zp,&p1->zp,&p2->zp);
833
		jmp .end_f
834
	.els_i:
835
	cmp dword[edx+offs_cont_current_shade_model],GL_SMOOTH
836
	jne .els
837
		;else if (context.current_shade_model == GL_SMOOTH)
838
;    ZB_fillTriangleSmooth, dword[edx+offs_cont_zb],&p0->zp,&p1->zp,&p2->zp);
839
		jmp .end_f
840
	.els:
841
;    ZB_fillTriangleFlat, dword[edx+offs_cont_zb],&p0->zp,&p1->zp,&p2->zp);
842
	.end_f:
843
	ret
844
endp
845
 
846
; Render a clipped triangle in line mode
847
 
848
align 4
849
proc gl_draw_triangle_line uses eax ebx ecx edx, context:dword, p0:dword,p1:dword,p2:dword
850
	mov edx,[context]
851
	cmp dword[edx+offs_cont_depth_test],0
852
	je .els
853
		lea ecx,[ZB_line_z]
854
		jmp @f
855
	.els:
856
		lea ecx,[ZB_line]
857
	@@:
858
 
859
	;if (p0.edge_flag) ZB_line_z(context.zb,&p0.zp,&p1.zp)
860
	mov eax,[p0]
861
	cmp dword[eax+offs_vert_edge_flag],0
862
	je @f
863
		mov ebx,eax
864
		add ebx,offs_vert_zp
865
		mov eax,[p1]
866
		add eax,offs_vert_zp
867
		stdcall ecx,dword[edx+offs_cont_zb],ebx,eax
868
	@@:
869
	;if (p1.edge_flag) ZB_line_z(context.zb,&p1.zp,&p2.zp)
870
	mov eax,[p1]
871
	cmp dword[eax+offs_vert_edge_flag],0
872
	je @f
873
		mov ebx,eax
874
		add ebx,offs_vert_zp
875
		mov eax,[p2]
876
		add eax,offs_vert_zp
877
		stdcall ecx,dword[edx+offs_cont_zb],ebx,eax
878
	@@:
879
	;if (p2.edge_flag) ZB_line_z(context.zb,&p2.zp,&p0.zp);
880
	mov eax,[p2]
881
	cmp dword[eax+offs_vert_edge_flag],0
882
	je @f
883
		mov ebx,eax
884
		add ebx,offs_vert_zp
885
		mov eax,[p0]
886
		add eax,offs_vert_zp
887
		stdcall ecx,dword[edx+offs_cont_zb],ebx,eax
888
	@@:
889
 
890
	ret
891
endp
892
 
893
; Render a clipped triangle in point mode
894
align 4
895
proc gl_draw_triangle_point uses eax ebx edx, context:dword, p0:dword,p1:dword,p2:dword
896
	mov edx,[context]
897
	mov eax,[p0]
898
	cmp dword[eax+offs_vert_edge_flag],0
899
	je @f
900
		mov ebx,eax
901
		add ebx,offs_vert_zp
902
		stdcall ZB_plot,dword[edx+offs_cont_zb],ebx
903
	@@:
904
	add eax,[p1]
905
	cmp dword[eax+offs_vert_edge_flag],0
906
	je @f
907
		mov ebx,eax
908
		add ebx,offs_vert_zp
909
		stdcall ZB_plot,dword[edx+offs_cont_zb],ebx
910
	@@:
911
	add eax,[p2]
912
	cmp dword[eax+offs_vert_edge_flag],0
913
	je @f
914
		mov ebx,eax
915
		add ebx,offs_vert_zp
916
		stdcall ZB_plot,dword[edx+offs_cont_zb],ebx
917
	@@:
918
	ret
919
endp
920
 
921
 
922
 
923