Subversion Repositories Kolibri OS

Rev

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

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