Subversion Repositories Kolibri OS

Rev

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