Subversion Repositories Kolibri OS

Rev

Rev 5187 | Rev 5213 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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