Subversion Repositories Kolibri OS

Rev

Rev 5213 | Rev 5278 | 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_f2 ;if (t>*tmax) return 0
  256.  
  257.                 mov ebx,[tmin]
  258.                 fcom dword[ebx]
  259.                 fstsw ax
  260.                 sahf
  261.                 jbe .r1_f2
  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_f2 ;if (t<*tmin) return 0
  274.  
  275.                 mov ebx,[tmax]
  276.                 fcom dword[ebx]
  277.                 fstsw ax
  278.                 sahf
  279.                 jae .r1_f2
  280.                         fstp dword[ebx] ;if (t<*tmin) *tmax=t
  281.         jmp .r1
  282.  
  283.         .r0_f2: ;return 0 & free st0,st1
  284.                 ffree st0
  285.                 fincstp
  286.         .r0: ;return 0 & free st0
  287.                 xor eax,eax
  288.                 jmp .end_f
  289.         .r1_f2: ;return 1 & free st0,st1
  290.                 ffree st0
  291.                 fincstp
  292.         .r1: ;return 1 & free st0
  293.                 xor eax,eax
  294.                 inc eax
  295.         .end_f:
  296.         ffree st0
  297.         fincstp
  298.         ret
  299. endp
  300.  
  301. align 4
  302. proc gl_draw_line, 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. pushad
  318.         mov edx,[context]
  319.         mov edi,[p1]
  320.         mov esi,[p2]
  321.  
  322.         cmp dword[edi+offs_vert_clip_code],0
  323.         jne .els_i
  324.         cmp dword[esi+offs_vert_clip_code],0
  325.         jne .els_i
  326.                 ;if ( (p1.clip_code | p2.clip_code) == 0)
  327.                 cmp dword[edx+offs_cont_render_mode],GL_SELECT ;if (context.render_mode == GL_SELECT)
  328.                 jne .els_1
  329.                         stdcall gl_add_select1, edx,dword[edi+offs_vert_zp+offs_zbup_z],\
  330.                                 dword[esi+offs_vert_zp+offs_zbup_z],dword[esi+offs_vert_zp+offs_zbup_z]
  331.                         jmp .end_f
  332.                 .els_1:
  333.                         add edi,offs_vert_zp
  334.                         add esi,offs_vert_zp
  335.                         push esi
  336.                         push edi
  337.                         push dword[edx+offs_cont_zb]
  338.                         cmp dword[edx+offs_cont_depth_test],0
  339.                         je .els_2
  340.                                 ;if (context.depth_test)
  341.                                 call ZB_line_z ;, dword[edx+offs_cont_zb],edi,esi
  342.                                 jmp .end_f
  343.                         .els_2:
  344.                                 call ZB_line ;, dword[edx+offs_cont_zb],edi,esi
  345.                                 jmp .end_f
  346.         .els_i:
  347.                 ;else if ( (p1.clip_code & p2.clip_code) != 0 )
  348.                 mov eax,[edi+offs_vert_clip_code]
  349.                 and eax,[esi+offs_vert_clip_code]
  350.                 cmp eax,0
  351.                 jne .end_f
  352.         .els_0:
  353.  
  354.         fld dword[esi+offs_vert_pc+offs_X]
  355.         fsub dword[edi+offs_vert_pc+offs_X]
  356.         fstp dword[d_x] ;d_x = p2.pc.X - p1.pc.X
  357.         fld dword[esi+offs_vert_pc+offs_Y]
  358.         fsub dword[edi+offs_vert_pc+offs_Y]
  359.         fstp dword[d_y] ;d_y = p2.pc.Y - p1.pc.Y
  360.         fld dword[esi+offs_vert_pc+offs_Z]
  361.         fsub dword[edi+offs_vert_pc+offs_Z]
  362.         fstp dword[d_z] ;d_z = p2.pc.Z - p1.pc.Z
  363.         fld dword[esi+offs_vert_pc+offs_W]
  364.         fsub dword[edi+offs_vert_pc+offs_W]
  365.         fstp dword[d_w] ;d_w = p2.pc.W - p1.pc.W
  366.  
  367.         mov eax,[edi+offs_vert_pc+offs_X]
  368.         mov [x1],eax ;x1 = p1.pc.X
  369.         mov eax,[edi+offs_vert_pc+offs_Y]
  370.         mov [y1],eax ;y1 = p1.pc.Y
  371.         mov eax,[edi+offs_vert_pc+offs_Z]
  372.         mov [z1],eax ;z1 = p1.pc.Z
  373.         mov eax,[edi+offs_vert_pc+offs_W]
  374.         mov [w1],eax ;w1 = p1.pc.W
  375.  
  376.         mov dword[tmin],0.0
  377.         mov dword[tmax],1.0
  378.  
  379.         mov eax,ebp
  380.         sub eax,4
  381.         push eax ;толкаем в стек адрес &tmax
  382.         sub eax,4
  383.         push eax ;толкаем в стек адрес &tmin
  384.         fld dword[x1]
  385.         fadd dword[w1]
  386.         fchs
  387.         fstp dword[esp-4]
  388.         fld dword[d_x]
  389.         fadd dword[d_w]
  390.         fstp dword[esp-8]
  391.         sub esp,8
  392.         call ClipLine1 ;d_x+d_w,-x1-w1,&tmin,&tmax
  393.         bt eax,0
  394.         jnc .end_f
  395.  
  396.         sub esp,8 ;толкаем в стек адреса переменных &tmin и &tmax
  397.         fld dword[x1]
  398.         fsub dword[w1]
  399.         fstp dword[esp-4]
  400.         fld dword[d_w]
  401.         fsub dword[d_x]
  402.         fstp dword[esp-8]
  403.         sub esp,8
  404.         call ClipLine1 ;-d_x+d_w,x1-w1,&tmin,&tmax
  405.         bt eax,0
  406.         jnc .end_f
  407.  
  408.         sub esp,8 ;толкаем в стек адреса переменных &tmin и &tmax
  409.         fld dword[y1]
  410.         fadd dword[w1]
  411.         fchs
  412.         fstp dword[esp-4]
  413.         fld dword[d_y]
  414.         fadd dword[d_w]
  415.         fstp dword[esp-8]
  416.         sub esp,8
  417.         call ClipLine1 ;d_y+d_w,-y1-w1,&tmin,&tmax
  418.         bt eax,0
  419.         jnc .end_f
  420.  
  421.         sub esp,8 ;толкаем в стек адреса переменных &tmin и &tmax
  422.         fld dword[y1]
  423.         fsub dword[w1]
  424.         fstp dword[esp-4]
  425.         fld dword[d_w]
  426.         fsub dword[d_y]
  427.         fstp dword[esp-8]
  428.         sub esp,8
  429.         call ClipLine1 ;-d_y+d_w,y1-w1,&tmin,&tmax
  430.         bt eax,0
  431.         jnc .end_f
  432.  
  433.         sub esp,8 ;толкаем в стек адреса переменных &tmin и &tmax
  434.         fld dword[z1]
  435.         fadd dword[w1]
  436.         fchs
  437.         fstp dword[esp-4]
  438.         fld dword[d_z]
  439.         fadd dword[d_w]
  440.         fstp dword[esp-8]
  441.         sub esp,8
  442.         call ClipLine1 ;d_z+d_w,-z1-w1,&tmin,&tmax
  443.         bt eax,0
  444.         jnc .end_f
  445.  
  446.         sub esp,8 ;толкаем в стек адреса переменных &tmin и &tmax
  447.         fld dword[z1]
  448.         fsub dword[w1]
  449.         fstp dword[esp-4]
  450.         fld dword[d_w]
  451.         fsub dword[d_z]
  452.         fstp dword[esp-8]
  453.         sub esp,8
  454.         call ClipLine1 ;-d_z+d_w,z1-w1,&tmin,&tmax
  455.         bt eax,0
  456.         jnc .end_f
  457.  
  458.         mov eax,ebp
  459.         sub eax,8+2*sizeof.GLVertex ;eax = &q1
  460.         stdcall interpolate, eax,edi,esi,[tmin]
  461.         stdcall gl_transform_to_viewport, edx,eax
  462.         add eax,sizeof.GLVertex ;eax = &q2
  463.         stdcall interpolate, eax,edi,esi,[tmax]
  464.         stdcall gl_transform_to_viewport, edx,eax
  465.  
  466.         sub eax,sizeof.GLVertex ;eax = &q1
  467.         mov ebx,eax
  468.         add ebx,offs_vert_zp+offs_zbup_b
  469.         push ebx
  470.         add ebx,offs_zbup_g-offs_zbup_b
  471.         push ebx
  472.         add ebx,offs_zbup_r-offs_zbup_g
  473.         push ebx
  474.         stdcall RGBFtoRGBI, dword[eax+offs_vert_color],dword[eax+offs_vert_color+4],dword[eax+offs_vert_color+8]
  475.  
  476.         add eax,sizeof.GLVertex ;eax = &q2
  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,offs_vert_zp ;eax = &q2.zp
  487.         push eax
  488.         sub eax,sizeof.GLVertex ;eax = &q1.zp
  489.         push eax
  490.         push dword[edx+offs_cont_zb]
  491.         cmp dword[edx+offs_cont_depth_test],0
  492.         je .els_3
  493.                 call ZB_line_z ;(context.zb,&q1.zp,&q2.zp)
  494.                 jmp .end_f
  495.         .els_3:
  496.                 call ZB_line ;(context.zb,&q1.zp,&q2.zp)
  497.         .end_f:
  498. popad
  499.         ret
  500. endp
  501.  
  502. ; triangle
  503.  
  504. ;
  505. ; Clipping
  506. ;
  507.  
  508. ; We clip the segment [a,b] against the 6 planes of the normal volume.
  509. ; We compute the point 'c' of intersection and the value of the parameter 't'
  510. ; of the intersection if x=a+t(b-a).
  511. ;
  512. ; sign: 0 -> '-', 1 -> '+'
  513. macro clip_func sign,dir,dir1,dir2
  514. {
  515. locals
  516.         t dd ?
  517.         d_X dd ?
  518.         d_Y dd ?
  519.         d_Z dd ?
  520.         d_W dd ?
  521. endl
  522.         mov edx,[a]
  523.         mov ebx,[b]
  524.         mov ecx,[c]
  525.         fld dword[ebx+offs_X]
  526.         fsub dword[edx+offs_X]
  527.         fstp dword[d_X] ;d_X = (b.X - a.X)
  528.         fld dword[ebx+offs_Y]
  529.         fsub dword[edx+offs_Y]
  530.         fstp dword[d_Y] ;d_Y = (b.Y - a.Y)
  531.         fld dword[ebx+offs_Z]
  532.         fsub dword[edx+offs_Z]
  533.         fstp dword[d_Z] ;d_Z = (b.Z - a.Z)
  534.         fld dword[ebx+offs_W]
  535.         fsub dword[edx+offs_W]
  536.         fst dword[d_W] ;d_W = (b.W - a.W)
  537. if sign eq 0
  538.         fadd dword[d#dir]
  539. else
  540.         fsub dword[d#dir]
  541. end if
  542.  
  543.         ftst
  544.         fstsw ax
  545.         sahf
  546.         jne @f
  547.                 fldz
  548.                 fst dword[t] ;t=0
  549.                 jmp .e_zero
  550.         @@: ;else
  551.                 fld dword[edx+offs#dir]
  552. if sign eq 0           
  553.                 fchs
  554. end if
  555.                 fsub dword[edx+offs_W]
  556.                 fdiv st0,st1
  557.                 fst dword[t] ;t = ( sign a.dir - a.W) / den
  558.         .e_zero:
  559.  
  560.         fmul dword[d#dir1] ;st0 = t * d.dir1
  561.         fadd dword[edx+offs#dir1]
  562.         fstp dword[ecx+offs#dir1] ;c.dir1 = a.dir1 + t * d.dir1
  563.  
  564.         ffree st0
  565.         fincstp
  566.  
  567.         fld dword[t]
  568.         fmul dword[d#dir2] ;st0 = t * d.dir2
  569.         fadd dword[edx+offs#dir2]
  570.         fstp dword[ecx+offs#dir2] ;c.dir2 = a.dir2 + t * d.dir2
  571.  
  572.         fld dword[t]
  573.         fmul dword[d_W]
  574.         fadd dword[edx+offs_W]
  575.         fst dword[ecx+offs_W] ;c.W = a.W + t * d_W
  576.  
  577. if sign eq 0           
  578.                 fchs
  579. end if
  580.         fstp dword[ecx+offs#dir] ;c.dir = sign c.W
  581.         mov eax,[t]
  582. }
  583.  
  584. align 4
  585. proc clip_xmin uses ebx ecx edx, c:dword, a:dword, b:dword
  586.         clip_func 0,_X,_Y,_Z
  587.         ret
  588. endp
  589.  
  590. align 4
  591. proc clip_xmax uses ebx ecx edx, c:dword, a:dword, b:dword
  592.         clip_func 1,_X,_Y,_Z
  593.         ret
  594. endp
  595.  
  596. align 4
  597. proc clip_ymin uses ebx ecx edx, c:dword, a:dword, b:dword
  598.         clip_func 0,_Y,_X,_Z
  599.         ret
  600. endp
  601.  
  602. align 4
  603. proc clip_ymax uses ebx ecx edx, c:dword, a:dword, b:dword
  604.         clip_func 1,_Y,_X,_Z
  605.         ret
  606. endp
  607.  
  608. align 4
  609. proc clip_zmin uses ebx ecx edx, c:dword, a:dword, b:dword
  610.         clip_func 0,_Z,_X,_Y
  611.         ret
  612. endp
  613.  
  614. align 4
  615. proc clip_zmax uses ebx ecx edx, c:dword, a:dword, b:dword
  616.         clip_func 1,_Z,_X,_Y
  617.         ret
  618. endp
  619.  
  620. align 4
  621. clip_proc dd clip_xmin,clip_xmax, clip_ymin,clip_ymax, clip_zmin,clip_zmax
  622.  
  623. align 4
  624. proc updateTmp uses eax ebx ecx edx, context:dword, q:dword, p0:dword, p1:dword, t:dword
  625.         mov ebx,[q]
  626.         mov edx,[context]
  627.         mov eax,[p0]
  628.         cmp dword[edx+offs_cont_current_shade_model],GL_SMOOTH ;if (context.current_shade_model == GL_SMOOTH)
  629.         jne .els_0
  630.                 mov ecx,[p1]
  631.                 fld dword[ecx+offs_vert_color]
  632.                 fsub dword[eax+offs_vert_color]
  633.                 fmul dword[t]
  634.                 fadd dword[eax+offs_vert_color]
  635.                 fstp dword[ebx+offs_vert_color] ;q.color.v[0]=p0.color.v[0] + (p1.color.v[0]-p0.color.v[0])*t
  636.                 fld dword[ecx+offs_vert_color+4]
  637.                 fsub dword[eax+offs_vert_color+4]
  638.                 fmul dword[t]
  639.                 fadd dword[eax+offs_vert_color+4]
  640.                 fstp dword[ebx+offs_vert_color+4] ;q.color.v[1]=p0.color.v[1] + (p1.color.v[1]-p0.color.v[1])*t
  641.                 fld dword[ecx+offs_vert_color+8]
  642.                 fsub dword[eax+offs_vert_color+8]
  643.                 fmul dword[t]
  644.                 fadd dword[eax+offs_vert_color+8]
  645.                 fstp dword[ebx+offs_vert_color+8] ;q.color.v[2]=p0.color.v[2] + (p1.color.v[2]-p0.color.v[2])*t
  646.                 jmp @f
  647.         .els_0:
  648.                 mov ecx,[eax+offs_vert_color]
  649.                 mov [ebx+offs_vert_color],ecx ;q.color.v[0]=p0.color.v[0]
  650.                 mov ecx,[eax+offs_vert_color+4]
  651.                 mov [ebx+offs_vert_color+4],ecx ;q.color.v[1]=p0.color.v[1]
  652.                 mov ecx,[eax+offs_vert_color+8]
  653.                 mov [ebx+offs_vert_color+8],ecx ;q.color.v[2]=p0.color.v[2]
  654.         @@:
  655.  
  656.         cmp dword[edx+offs_cont_texture_2d_enabled],0 ;if (context.texture_2d_enabled)
  657.         je @f
  658.                 mov ecx,[p1]
  659.                 fld dword[ecx+offs_vert_tex_coord+offs_X]
  660.                 fsub dword[eax+offs_vert_tex_coord+offs_X]
  661.                 fmul dword[t]
  662.                 fadd dword[eax+offs_vert_tex_coord+offs_X]
  663.                 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
  664.                 fld dword[ecx+offs_vert_tex_coord+offs_Y]
  665.                 fsub dword[eax+offs_vert_tex_coord+offs_Y]
  666.                 fmul dword[t]
  667.                 fadd dword[eax+offs_vert_tex_coord+offs_Y]
  668.                 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
  669.         @@:
  670.  
  671.         stdcall gl_clipcode, [ebx+offs_vert_pc+offs_X],[ebx+offs_vert_pc+offs_Y],\
  672.                 [ebx+offs_vert_pc+offs_Z],[ebx+offs_vert_pc+offs_W]
  673.         mov dword[ebx+offs_vert_clip_code],eax
  674.         cmp eax,0 ;if (q.clip_code==0)
  675.         jne @f
  676.                 stdcall gl_transform_to_viewport,[context],ebx
  677.                 mov eax,ebx
  678.                 add eax,offs_vert_zp+offs_zbup_b
  679.                 push eax
  680.                 add eax,offs_zbup_g-offs_zbup_b
  681.                 push eax
  682.                 add eax,offs_zbup_r-offs_zbup_g
  683.                 push eax
  684.                 stdcall RGBFtoRGBI, dword[ebx+offs_vert_color],dword[ebx+offs_vert_color+4],dword[ebx+offs_vert_color+8]
  685.         @@:
  686.         ret
  687. endp
  688.  
  689. align 4
  690. proc gl_draw_triangle, context:dword, p0:dword, p1:dword, p2:dword
  691. locals
  692.         cc rd 3
  693.         front dd ?
  694.         norm dd ? ;float
  695. endl
  696. pushad
  697.         mov ebx,[p0]
  698.         mov ecx,[p1]
  699.         mov edx,[p2]
  700.  
  701.         mov edi,[ebx+offs_vert_clip_code]
  702.         mov dword[cc],edi
  703.         mov eax,[ecx+offs_vert_clip_code]
  704.         mov dword[cc+4],eax
  705.         or edi,eax
  706.         mov eax,[edx+offs_vert_clip_code]
  707.         mov dword[cc+8],eax
  708.         or edi,eax ;co = cc[0] | cc[1] | cc[2]
  709.  
  710.         ; we handle the non clipped case here to go faster
  711.         cmp edi,0 ;if (co==0)
  712.         jne .els_0
  713.                 mov edi,dword[edx+offs_vert_zp+offs_zbup_x]
  714.                 sub edi,dword[ebx+offs_vert_zp+offs_zbup_x]
  715.                 mov dword[norm],edi
  716.                 fild dword[norm]
  717.                 mov edi,dword[ecx+offs_vert_zp+offs_zbup_y]
  718.                 sub edi,dword[ebx+offs_vert_zp+offs_zbup_y]
  719.                 mov dword[norm],edi
  720.                 fimul dword[norm]
  721.                 mov edi,dword[ecx+offs_vert_zp+offs_zbup_x]
  722.                 sub edi,dword[ebx+offs_vert_zp+offs_zbup_x]
  723.                 mov dword[norm],edi
  724.                 fild dword[norm]
  725.                 mov edi,dword[edx+offs_vert_zp+offs_zbup_y]
  726.                 sub edi,dword[ebx+offs_vert_zp+offs_zbup_y]
  727.                 mov dword[norm],edi
  728.                 fimul dword[norm]
  729.                 fsubp
  730.  
  731.                 ;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)
  732.  
  733.                 mov dword[front],0
  734.                 fldz
  735.                 fcompp
  736.                 fstsw ax
  737.                 sahf
  738.                 je .end_f
  739.                 jb @f
  740.                         inc dword[front] ;front = 0.0 > norm
  741.                 @@:
  742.                 mov edi,[context]
  743.                 mov eax,dword[edi+offs_cont_current_front_face]
  744.                 xor dword[front],eax ;front ^= context.current_front_face
  745.  
  746.                 ; back face culling
  747.                 cmp dword[edi+offs_cont_cull_face_enabled],0
  748.                 je .els_1
  749.                         ; most used case first
  750.                         cmp dword[edi+offs_cont_current_cull_face],GL_BACK
  751.                         jne @f
  752.                                 cmp dword[front],0
  753.                                 je .end_f
  754.                                         stdcall dword[edi+offs_cont_draw_triangle_front], edi,ebx,ecx,edx
  755.                                 jmp .end_f
  756.                         @@:
  757.                         cmp dword[edi+offs_cont_current_cull_face],GL_FRONT
  758.                         jne .end_f
  759.                                 cmp dword[front],0
  760.                                 jne .end_f
  761.                                         stdcall dword[edi+offs_cont_draw_triangle_back], edi,ebx,ecx,edx
  762.                         jmp .end_f
  763.                 .els_1:
  764.                         ; no culling
  765.                         cmp dword[front],0
  766.                         je @f
  767.                                 stdcall dword[edi+offs_cont_draw_triangle_front], edi,ebx,ecx,edx
  768.                                 jmp .end_f
  769.                         @@:
  770.                                 stdcall dword[edi+offs_cont_draw_triangle_back], edi,ebx,ecx,edx
  771.                 jmp .end_f
  772.         .els_0:
  773.                 ;eax = cc[2]
  774.                 and eax,[cc]
  775.                 and eax,[cc+4] ;eax = c_and = cc[0] & cc[1] & cc[2]
  776.                 cmp eax,0 ;if (c_and==0)
  777.                 jne .end_f
  778.                         stdcall gl_draw_triangle_clip, [context],ebx,ecx,edx,0
  779.         .end_f:
  780. popad
  781.         ret
  782. endp
  783.  
  784. align 4
  785. proc gl_draw_triangle_clip, context:dword, p0:dword, p1:dword, p2:dword, clip_bit:dword
  786. locals
  787.         co dd ?
  788.         cc rd 3
  789.         edge_flag_tmp dd ?
  790.         clip_mask dd ?
  791.         q rd 3 ;GLVertex*
  792.         tmp1 GLVertex ?
  793.         tmp2 GLVertex ?
  794. endl
  795. pushad
  796.         mov ebx,[p0]
  797.         mov ecx,[p1]
  798.         mov edx,[p2]
  799.  
  800.         mov edi,[ebx+offs_vert_clip_code]
  801.         mov [cc],edi
  802.         mov eax,[ecx+offs_vert_clip_code]
  803.         mov [cc+4],eax
  804.         or edi,eax
  805.         mov eax,[edx+offs_vert_clip_code]
  806.         mov [cc+8],eax
  807.         or edi,eax
  808.         mov [co],edi ;co = cc[0] | cc[1] | cc[2]
  809.  
  810.         cmp edi,0 ;if (co == 0)
  811.         jne .els_0
  812.                 stdcall gl_draw_triangle, [context],ebx,ecx,edx
  813.                 jmp .end_f
  814.         .els_0:
  815.                 ;eax = cc[2]
  816.                 and eax,[cc]
  817.                 and eax,[cc+4] ;c_and = cc[0] & cc[1] & cc[2]
  818.  
  819.                 ; the triangle is completely outside
  820.                 cmp eax,0 ;if (c_and!=0) return
  821.                 jne .end_f
  822.  
  823.                 ; find the next direction to clip
  824.                 .cycle_0: ;while (clip_bit < 6 && (co & (1 << clip_bit)) == 0)
  825.                 cmp dword[clip_bit],6
  826.                 jge .cycle_0_end
  827.                 xor eax,eax
  828.                 inc eax
  829.                 mov ecx,[clip_bit]
  830.                 shl eax,cl
  831.                 and eax,[co]
  832.                 cmp eax,0
  833.                 jne .cycle_0_end
  834.                         inc dword[clip_bit]
  835.                         jmp .cycle_0
  836.                 .cycle_0_end:
  837.  
  838.         ; this test can be true only in case of rounding errors
  839.         cmp dword[clip_bit],6
  840. if 0
  841.         jne @f
  842. ;      printf("Error:\n");
  843. ;      printf("%f %f %f %f\n",p0->pc.X,p0->pc.Y,p0->pc.Z,p0->pc.W);
  844. ;      printf("%f %f %f %f\n",p1->pc.X,p1->pc.Y,p1->pc.Z,p1->pc.W);
  845. ;      printf("%f %f %f %f\n",p2->pc.X,p2->pc.Y,p2->pc.Z,p2->pc.W);
  846.                 jmp .end_f
  847.         @@:
  848. end if
  849. if 1
  850.         je .end_f
  851. end if
  852.  
  853.         xor eax,eax
  854.         inc eax
  855.         mov ecx,[clip_bit]
  856.         shl eax,cl
  857.         mov [clip_mask],eax ;1 << clip_bit
  858.         mov edi,[cc]
  859.         xor edi,[cc+4]
  860.         xor edi,[cc+8]
  861.         and eax,edi ;eax = co1 = (cc[0] ^ cc[1] ^ cc[2]) & clip_mask
  862.  
  863.         mov ecx,[p1] ;востанавливаем после shl ___,cl
  864.  
  865.         cmp eax,0 ;if (co1)
  866.         je .els_1
  867.                 ; one point outside
  868.                 mov eax,[cc]
  869.                 and eax,[clip_mask]
  870.                 cmp eax,0 ;if (cc[0] & clip_mask)
  871.                 je .els_2
  872.                         ;q[0]=p0 q[1]=p1 q[2]=p2
  873.                         mov [q],ebx
  874.                         mov [q+4],ecx
  875.                         mov [q+8],edx
  876.                         jmp .els_2_end
  877.                 .els_2:
  878.                 mov eax,[cc+4]
  879.                 and eax,[clip_mask]
  880.                 cmp eax,0 ;else if (cc[1] & clip_mask)
  881.                 je .els_3
  882.                         ;q[0]=p1 q[1]=p2 q[2]=p0
  883.                         mov [q],ecx
  884.                         mov [q+4],edx
  885.                         mov [q+8],ebx
  886.                         jmp .els_2_end
  887.                 .els_3:
  888.                         ;q[0]=p2 q[1]=p0 q[2]=p1
  889.                         mov [q],edx
  890.                         mov [q+4],ebx
  891.                         mov [q+8],ecx
  892.                 .els_2_end:
  893.  
  894.                 mov ebx,[q]
  895.                 add ebx,offs_vert_pc
  896.                 mov ecx,[q+4]
  897.                 add ecx,offs_vert_pc
  898.                 mov edx,[q+8]
  899.                 add edx,offs_vert_pc
  900.  
  901.                 lea eax,[clip_proc]
  902.                 mov edi,[clip_bit]
  903.                 shl edi,2
  904.                 add eax,edi
  905.                 mov edi,ebp
  906.                 sub edi,(2*sizeof.GLVertex)-offs_vert_pc
  907.                 stdcall dword[eax],edi,ebx,ecx ;clip_proc[clip_bit](&tmp1.pc,&q[0].pc,&q[1].pc)
  908.                 sub edi,offs_vert_pc
  909.  
  910.                 sub ebx,offs_vert_pc
  911.                 sub ecx,offs_vert_pc
  912.                 stdcall updateTmp,[context],edi,ebx,ecx,eax ;updateTmp(c,&tmp1,q[0],q[1],tt)
  913.                 add ebx,offs_vert_pc
  914.  
  915.                 lea eax,[clip_proc]
  916.                 mov edi,[clip_bit]
  917.                 shl edi,2
  918.                 add eax,edi
  919.                 mov edi,ebp
  920.                 sub edi,sizeof.GLVertex-offs_vert_pc
  921.                 stdcall dword[eax],edi,ebx,edx ;clip_proc[clip_bit](&tmp2.pc,&q[0].pc,&q[2].pc)
  922.                 sub edi,offs_vert_pc
  923.                 sub ebx,offs_vert_pc
  924.                 sub edx,offs_vert_pc
  925.                 stdcall updateTmp,[context],edi,ebx,edx,eax ;updateTmp(c,&tmp2,q[0],q[2],tt)
  926.  
  927.                 mov eax,[ebx+offs_vert_edge_flag]
  928.                 mov [tmp1+offs_vert_edge_flag],eax ;q[0].edge_flag
  929.                 mov eax,[edx+offs_vert_edge_flag]
  930.                 mov [edge_flag_tmp],eax ;q[2].edge_flag
  931.                 mov dword[edx+offs_vert_edge_flag],0 ;q[2].edge_flag=0
  932.                 mov eax,[clip_bit]
  933.                 inc eax
  934.                 push eax ;для вызова нижней функции
  935.                 mov edi,ebp
  936.                 sub edi,2*sizeof.GLVertex
  937.                 stdcall gl_draw_triangle_clip,[context],edi,ecx,edx,eax ;gl_draw_triangle_clip(c,&tmp1,q[1],q[2],clip_bit+1)
  938.  
  939.                 mov dword[tmp2.edge_flag],0
  940.                 mov dword[tmp1.edge_flag],0
  941.                 mov eax,[edge_flag_tmp]
  942.                 mov [edx+offs_vert_edge_flag],eax ;q[2].edge_flag=edge_flag_tmp
  943.                 push edx
  944.                 push edi
  945.                 add edi,sizeof.GLVertex ;edi = &tmp2
  946.                 stdcall gl_draw_triangle_clip,[context],edi ;gl_draw_triangle_clip(c,&tmp2,&tmp1,q[2],clip_bit+1)
  947.                 jmp .end_f
  948.         .els_1:
  949.                 ; two points outside
  950.                 mov eax,[cc]
  951.                 and eax,[clip_mask]
  952.                 cmp eax,0 ;if (cc[0] & clip_mask)==0
  953.                 jne .els_4
  954.                         ;q[0]=p0 q[1]=p1 q[2]=p2
  955.                         mov [q],ebx
  956.                         mov [q+4],ecx
  957.                         mov [q+8],edx
  958.                         jmp .els_4_end
  959.                 .els_4:
  960.                 mov eax,[cc+4]
  961.                 and eax,[clip_mask]
  962.                 cmp eax,0 ;else if (cc[1] & clip_mask)==0
  963.                 jne .els_5
  964.                         ;q[0]=p1 q[1]=p2 q[2]=p0
  965.                         mov [q],ecx
  966.                         mov [q+4],edx
  967.                         mov [q+8],ebx
  968.                         jmp .els_4_end
  969.                 .els_5:
  970.                         ;q[0]=p2 q[1]=p0 q[2]=p1
  971.                         mov [q],edx
  972.                         mov [q+4],ebx
  973.                         mov [q+8],ecx
  974.                 .els_4_end:
  975.  
  976.                 mov ebx,[q]
  977.                 add ebx,offs_vert_pc
  978.                 mov ecx,[q+4]
  979.                 add ecx,offs_vert_pc
  980.                 mov edx,[q+8]
  981.                 add edx,offs_vert_pc
  982.  
  983.                 lea eax,[clip_proc]
  984.                 mov edi,[clip_bit]
  985.                 shl edi,2
  986.                 add eax,edi
  987.                 mov edi,ebp
  988.                 sub edi,(2*sizeof.GLVertex)-offs_vert_pc
  989.                 stdcall dword[eax],edi,ebx,ecx ;clip_proc[clip_bit](&tmp1.pc,&q[0].pc,&q[1].pc)
  990.                 sub edi,offs_vert_pc
  991.                 stdcall updateTmp,[context],edi,[q],[q+4],eax
  992.  
  993.                 lea eax,[clip_proc]
  994.                 mov edi,[clip_bit]
  995.                 shl edi,2
  996.                 add eax,edi
  997.                 mov edi,ebp
  998.                 sub edi,sizeof.GLVertex-offs_vert_pc
  999.                 stdcall dword[eax],edi,ebx,edx ;clip_proc[clip_bit](&tmp2.pc,&q[0].pc,&q[2].pc)
  1000.                 sub edi,offs_vert_pc
  1001.                 stdcall updateTmp,[context],edi,[q],[q+8],eax
  1002.  
  1003.                 mov edx,[q+8]
  1004.  
  1005.                 mov dword[tmp1+offs_vert_edge_flag],1
  1006.                 mov eax,[edx+offs_vert_edge_flag]
  1007.                 mov dword[tmp1+offs_vert_edge_flag],eax ;tmp2.edge_flag = q[2].edge_flag
  1008.                 mov eax,[clip_bit]
  1009.                 inc eax
  1010.                 push eax
  1011.                 push edi
  1012.                 sub edi,sizeof.GLVertex
  1013.                 stdcall gl_draw_triangle_clip,[context],[q],edi ;gl_draw_triangle_clip(c,q[0],&tmp1,&tmp2,clip_bit+1)
  1014.         .end_f:
  1015. popad
  1016.         ret
  1017. endp
  1018.  
  1019. align 4
  1020. proc gl_draw_triangle_select uses eax, context:dword, p0:dword,p1:dword,p2:dword
  1021.         mov eax,[p2]
  1022.         push dword[eax+offs_vert_zp+offs_Z]
  1023.         mov eax,[p1]
  1024.         push dword[eax+offs_vert_zp+offs_Z]
  1025.         mov eax,[p0]
  1026.         push dword[eax+offs_vert_zp+offs_Z]
  1027.         stdcall gl_add_select1, [context] ;,p0.zp.z, p1.zp.z, p2.zp.z
  1028.         ret
  1029. endp
  1030.  
  1031. if PROFILE eq 1
  1032.         count_triangles dd ?
  1033.         count_triangles_textured dd ?
  1034.         count_pixels dd ?
  1035. end if
  1036.  
  1037. align 4
  1038. proc gl_draw_triangle_fill, context:dword, p0:dword,p1:dword,p2:dword
  1039. pushad
  1040. if PROFILE eq 1
  1041. ;    int norm;
  1042. ;    assert(p0->zp.x >= 0 && p0->zp.x < c->zb->xsize);
  1043. ;    assert(p0->zp.y >= 0 && p0->zp.y < c->zb->ysize);
  1044. ;    assert(p1->zp.x >= 0 && p1->zp.x < c->zb->xsize);
  1045. ;    assert(p1->zp.y >= 0 && p1->zp.y < c->zb->ysize);
  1046. ;    assert(p2->zp.x >= 0 && p2->zp.x < c->zb->xsize);
  1047. ;    assert(p2->zp.y >= 0 && p2->zp.y < c->zb->ysize);
  1048.    
  1049. ;    norm=(p1->zp.x-p0->zp.x)*(p2->zp.y-p0->zp.y)-
  1050. ;      (p2->zp.x-p0->zp.x)*(p1->zp.y-p0->zp.y);
  1051. ;    count_pixels+=abs(norm)/2;
  1052.         inc dword[count_triangles]
  1053. end if
  1054.  
  1055.         mov ebx,[p1]
  1056.         add ebx,offs_vert_zp
  1057.         mov ecx,[p2]
  1058.         add ecx,offs_vert_zp
  1059.         mov edx,[context]
  1060.         cmp dword[edx+offs_cont_texture_2d_enabled],0
  1061.         je .els_i
  1062.                 ;if (context.texture_2d_enabled)
  1063. if PROFILE eq 1
  1064.         inc dword[count_triangles_textured]
  1065. end if
  1066.                 mov eax,dword[edx+offs_cont_current_texture]
  1067.                 mov eax,[eax] ;переход по указателю
  1068.                 ;так как offs_text_images+offs_imag_pixmap = 0 то context.current_texture.images[0].pixmap = [eax]
  1069.                 stdcall ZB_setTexture, dword[edx+offs_cont_zb],dword[eax]
  1070.                 mov eax,[p0]
  1071.                 add eax,offs_vert_zp
  1072.                 stdcall ZB_fillTriangleMappingPerspective, dword[edx+offs_cont_zb],eax,ebx,ecx
  1073.                 jmp .end_f
  1074.         .els_i:
  1075.                 mov eax,[p0]
  1076.                 add eax,offs_vert_zp
  1077.                 cmp dword[edx+offs_cont_current_shade_model],GL_SMOOTH
  1078.                 jne .els
  1079.                         ;else if (context.current_shade_model == GL_SMOOTH)
  1080.                         stdcall ZB_fillTriangleSmooth, dword[edx+offs_cont_zb],eax,ebx,ecx
  1081.                         jmp .end_f
  1082.                 .els:
  1083.                         stdcall ZB_fillTriangleFlat, dword[edx+offs_cont_zb],eax,ebx,ecx
  1084.         .end_f:
  1085. popad
  1086.         ret
  1087. endp
  1088.  
  1089. ; Render a clipped triangle in line mode
  1090.  
  1091. align 4
  1092. proc gl_draw_triangle_line uses eax ebx ecx edx, context:dword, p0:dword,p1:dword,p2:dword
  1093.         mov edx,[context]
  1094.         cmp dword[edx+offs_cont_depth_test],0
  1095.         je .els
  1096.                 lea ecx,[ZB_line_z]
  1097.                 jmp @f
  1098.         .els:
  1099.                 lea ecx,[ZB_line]
  1100.         @@:
  1101.  
  1102.         ;if (p0.edge_flag) ZB_line_z(context.zb,&p0.zp,&p1.zp)
  1103.         mov eax,[p0]
  1104.         cmp dword[eax+offs_vert_edge_flag],0
  1105.         je @f
  1106.                 mov ebx,eax
  1107.                 add ebx,offs_vert_zp
  1108.                 mov eax,[p1]
  1109.                 add eax,offs_vert_zp
  1110.                 stdcall ecx,dword[edx+offs_cont_zb],ebx,eax
  1111.         @@:
  1112.         ;if (p1.edge_flag) ZB_line_z(context.zb,&p1.zp,&p2.zp)
  1113.         mov eax,[p1]
  1114.         cmp dword[eax+offs_vert_edge_flag],0
  1115.         je @f
  1116.                 mov ebx,eax
  1117.                 add ebx,offs_vert_zp
  1118.                 mov eax,[p2]
  1119.                 add eax,offs_vert_zp
  1120.                 stdcall ecx,dword[edx+offs_cont_zb],ebx,eax
  1121.         @@:
  1122.         ;if (p2.edge_flag) ZB_line_z(context.zb,&p2.zp,&p0.zp);
  1123.         mov eax,[p2]
  1124.         cmp dword[eax+offs_vert_edge_flag],0
  1125.         je @f
  1126.                 mov ebx,eax
  1127.                 add ebx,offs_vert_zp
  1128.                 mov eax,[p0]
  1129.                 add eax,offs_vert_zp
  1130.                 stdcall ecx,dword[edx+offs_cont_zb],ebx,eax
  1131.         @@:
  1132.  
  1133.         ret
  1134. endp
  1135.  
  1136. ; Render a clipped triangle in point mode
  1137. align 4
  1138. proc gl_draw_triangle_point uses eax ebx edx, context:dword, p0:dword,p1:dword,p2:dword
  1139.         mov edx,[context]
  1140.         mov eax,[p0]
  1141.         cmp dword[eax+offs_vert_edge_flag],0
  1142.         je @f
  1143.                 mov ebx,eax
  1144.                 add ebx,offs_vert_zp
  1145.                 stdcall ZB_plot,dword[edx+offs_cont_zb],ebx
  1146.         @@:
  1147.         mov eax,[p1]
  1148.         cmp dword[eax+offs_vert_edge_flag],0
  1149.         je @f
  1150.                 mov ebx,eax
  1151.                 add ebx,offs_vert_zp
  1152.                 stdcall ZB_plot,dword[edx+offs_cont_zb],ebx
  1153.         @@:
  1154.         mov eax,[p2]
  1155.         cmp dword[eax+offs_vert_edge_flag],0
  1156.         je @f
  1157.                 mov ebx,eax
  1158.                 add ebx,offs_vert_zp
  1159.                 stdcall ZB_plot,dword[edx+offs_cont_zb],ebx
  1160.         @@:
  1161.         ret
  1162. endp
  1163.  
  1164.  
  1165.  
  1166.  
  1167.