Subversion Repositories Kolibri OS

Rev

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