Subversion Repositories Kolibri OS

Rev

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