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>>>>>>><>><>>>*tmin)>*tmin)> |
||
920 | |||
921 | |||
922 | |||
923 |