Subversion Repositories Kolibri OS

Rev

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