; ; Опции для функций: ; ;INTERP_Z - использование Z буфера (всегда включено) ;INTERP_RGB - сглажевание цветов ;INTERP_ST - наложение текстуры в ортогональной проэкции ;INTERP_STZ - наложение текстуры в перспективной проэкции ; ; Функции рисования треугольников: ; ;ZB_fillTriangleFlat - треугольник одного цвета ;ZB_fillTriangleSmooth - треугольник с разными цветами вершин ;ZB_fillTriangleMapping - треугольник с текстурой в ортогональной проэкции ;ZB_fillTriangleMappingPerspective - треугольник с текстурой в перспективной проэкции ; macro calc_d1d2 f, r1, r2 { fld dword[fdy2] fmul st0,st2 fld dword[fdy1] fmul st0,st2 fsubp f#stp dword[r1] ;r1 = (fdy2*d1 - fdy1*d2) fld dword[fdx1] fmulp fld dword[fdx2] fmul st0,st2 fsubp f#stp dword[r2] ;r2 = (fdx1*d2 - fdx2*d1) ffree st0 ;d1 fincstp } INTERP_Z equ 1 macro DRAW_INIT { if TGL_FEATURE_RENDER_BITS eq 24 mov ecx,[p2] mov eax,[ecx+ZBufferPoint.r] mov [colorB],ah ;colorB=p2.r>>8 mov eax,[ecx+ZBufferPoint.g] mov [colorG],ah ;colorG=p2.g>>8 mov eax,[ecx+ZBufferPoint.b] mov [colorR],ah ;colorR=p2.b>>8 ;else ;color=RGB_TO_PIXEL(p2.r,p2.g,p2.b) end if } macro PUT_PIXEL _a { local .end_0 if _a eq 0 mov ebx,[dzdx] end if mov eax,[z] shr eax,ZB_POINT_Z_FRAC_BITS cmp ax,word[esi+2*_a] ;if (zz >= pz[_a]) jl .end_0 ;edi = pp mov word[esi+2*_a],ax ;пишем в буфер глубины новое значение if TGL_FEATURE_RENDER_BITS eq 24 mov ax,word[colorB] ;сохраняем colorB и colorG mov word[edi+3*_a],ax mov al,[colorR] mov byte[edi+3*_a +2],al ;else ;pp[_a]=color end if .end_0: add [z],ebx } align 16 proc ZB_fillTriangleFlat, zb:dword, p0:dword, p1:dword, p2:dword locals if TGL_FEATURE_RENDER_BITS eq 24 colorB db ? colorG db ? colorR db ? ;unsigned char else color dd ? ;int end if include 'ztriangle.inc' ; ; Smooth filled triangle. ; The code below is very tricky :) ; INTERP_Z equ 1 INTERP_RGB equ 1 macro DRAW_INIT { } macro PUT_PIXEL _a { local .end_0 mov eax,[z] shr eax,ZB_POINT_Z_FRAC_BITS cmp ax,word[esi+2*_a] ;if (zz >= pz[_a]) jl .end_0 ;edi = pp mov word[esi+2*_a],ax ;пишем в буфер глубины новое значение if TGL_FEATURE_RENDER_BITS eq 24 mov eax,[og1] mov al,byte[or1+1] mov word[edi+3*_a],ax mov eax,[ob1] mov byte[edi+3*_a +2],ah end if ;if TGL_FEATURE_RENDER_BITS eq 32 ;pp[_a] = RGB_TO_PIXEL(or1, og1, ob1) ;end if .end_0: if _a eq 0 mov ebx,[dzdx] mov ecx,[dgdx] mov edx,[drdx] end if add [z],ebx add [og1],ecx add [or1],edx mov eax,[dbdx] add [ob1],eax } align 16 proc ZB_fillTriangleSmooth, zb:dword, p0:dword, p1:dword, p2:dword locals include 'ztriangle.inc' align 16 proc ZB_setTexture uses eax ebx, zb:dword, texture:dword,\ s_bound:dword, t_bound:dword, s_log2:dword mov eax,[zb] mov ebx,[texture] mov dword[eax+ZBuffer.current_texture],ebx mov ebx,[s_log2] mov dword[eax+ZBuffer.s_log2],ebx mov ebx,[s_bound] mov dword[eax+ZBuffer.s_bound],ebx mov ebx,[t_bound] mov dword[eax+ZBuffer.t_bound],ebx ret endp INTERP_Z equ 1 INTERP_ST equ 1 macro DRAW_INIT { mov eax,[zb] mov ebx,[eax+ZBuffer.current_texture] mov [texture],ebx mov ebx,[eax+ZBuffer.s_log2] mov [s_log2],ebx ;s_log2 = zb.s_log2 mov ebx,[eax+ZBuffer.s_bound] mov [s_bound],ebx ;s_bound = zb.s_bound mov ebx,[eax+ZBuffer.t_bound] mov [t_bound],ebx ;t_bound = zb.t_bound } macro PUT_PIXEL _a { local .end_0 mov eax,[z] shr eax,ZB_POINT_Z_FRAC_BITS cmp ax,word[esi+2*_a] ;if (zz >= pz[_a]) jl .end_0 ;edi = pp mov word[esi+2*_a],ax ;пишем в буфер глубины новое значение if TGL_FEATURE_RENDER_BITS eq 24 mov ebx,[t] and ebx,[t_bound] mov ecx,[s_log2] shr ebx,cl ;(t & t_bound) >> s_log2 mov eax,[s] and eax,[s_bound] shr eax,ZB_POINT_TEXEL_SIZE or ebx,eax lea ebx,[ebx+2*ebx] add ebx,[texture] ;ptr = texture + (((t & 0x3fc00000) | s) >> 14) * 3 mov ax,word[ebx] mov word[edi+3*_a],ax ;pp[3 * _a]= ptr[0,1] mov al,byte[ebx+2] mov byte[edi+3*_a +2],al ;pp[3 * _a + 2]= ptr[2] else ;pp[_a]=texture[((t & 0x3FC00000) | s) >> 14] end if .end_0: mov eax,[dzdx] add [z],eax mov eax,[dsdx] add [s],eax mov eax,[dtdx] add [t],eax } align 16 proc ZB_fillTriangleMapping, zb:dword, p0:dword, p1:dword, p2:dword locals texture dd ? ;PIXEL* s_log2 dd ? ;unsigned int s_bound dd ? ;unsigned int t_bound dd ? ;unsigned int include 'ztriangle.inc' ; ; Texture mapping with perspective correction. ; We use the gradient method to make less divisions. ; TODO: pipeline the division ; INTERP_Z equ 1 INTERP_STZ equ 1 NB_INTERP equ 8 macro DRAW_INIT { mov eax,[zb] mov ebx,[eax+ZBuffer.current_texture] mov [texture],ebx mov ebx,[eax+ZBuffer.s_log2] mov [s_log2],ebx ;s_log2 = zb.s_log2 mov ebx,[eax+ZBuffer.s_bound] mov [s_bound],ebx ;s_bound = zb.s_bound mov ebx,[eax+ZBuffer.t_bound] mov [t_bound],ebx ;t_bound = zb.t_bound mov dword[esp-4],NB_INTERP fild dword[esp-4] fild dword[dzdx] fst dword[fdzdx] ;fdzdx = (float)dzdx fmul st0,st1 fstp dword[fndzdx] ;fndzdx = NB_INTERP * fdzdx fld dword[fdzdx] fmul st0,st1 fstp dword[ndszdx] ;ndszdx = NB_INTERP * dszdx fmul dword[dtzdx] fstp dword[ndtzdx] ;ndtzdx = NB_INTERP * dtzdx } macro PUT_PIXEL _a { local .end_0 mov eax,[z] shr eax,ZB_POINT_Z_FRAC_BITS cmp ax,word[esi+2*_a] ;if (zz >= pz[_a]) jl .end_0 ;edi = pp mov word[esi+2*_a],ax ;пишем в буфер глубины новое значение if TGL_FEATURE_RENDER_BITS eq 24 mov ebx,[t] and ebx,[t_bound] mov ecx,[s_log2] shr ebx,cl ;(t & t_bound) >> s_log2 mov eax,[s] and eax,[s_bound] shr eax,ZB_POINT_TEXEL_SIZE or ebx,eax lea ebx,[ebx+2*ebx] add ebx,[texture] ;ptr = texture + (((t & 0x3fc00000) | (s & 0x003FC000)) >> 14) * 3 mov ax,word[ebx] mov word[edi+3*_a],ax ;pp[3 * _a]= ptr[0,1] mov al,byte[ebx+2] mov byte[edi+3*_a +2],al ;pp[3 * _a + 2]= ptr[2] else ; pp[_a]=*(PIXEL *)((char *)texture+ ; (((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH))); end if .end_0: mov eax,[dzdx] add [z],eax mov eax,[dsdx] add [s],eax mov eax,[dtdx] add [t],eax } DRAW_LINE_M equ 1 macro DRAW_LINE { if TGL_FEATURE_RENDER_BITS eq 24 mov eax,[x2] sar eax,16 mov edi,[x1] sub eax,edi mov [n],eax ;n = (x2 >> 16) - x1 fld1 fild dword[z1] fst dword[f_z] ;fz = (float)z1 fdivp fstp dword[zinv] ;zinv = 1.0 / fz imul edi,PSZB add edi,[pp1] ;pp = (pp1 + x1 * PSZB) mov esi,[x1] shl esi,1 add esi,[pz1] ;pz = pz1 + x1 mov eax,[z1] mov [z],eax ;z = z1 mov eax,[sz1] mov [s_z],eax ;sz = sz1 mov eax,[tz1] mov [t_z],eax ;tz = tz1 align 4 .cycle_2: ;while (n>=(NB_INTERP-1)) cmp dword[n],NB_INTERP-1 jl .cycle_2_end fld dword[zinv] fld st0 fmul dword[s_z] ;ss = (sz * zinv) fist dword[s] ;s = (int) ss fmul dword[fdzdx] fchs fadd dword[dszdx] fmul dword[zinv] fistp dword[dsdx] ;dsdx = (int)( (dszdx - ss*fdzdx)*zinv ) fmul dword[t_z] ;tt = (tz * zinv) fist dword[t] ;t = (int) tt fmul dword[fdzdx] fchs fadd dword[dtzdx] fmul dword[zinv] fistp dword[dtdx] ;dtdx = (int)( (dtzdx - tt*fdzdx)*zinv ) fld1 fld dword[f_z] fadd dword[fndzdx] fst dword[f_z] ;fz += fndzdx fdivp fstp dword[zinv] ;zinv = 1.0 / fz PUT_PIXEL 0 PUT_PIXEL 1 PUT_PIXEL 2 PUT_PIXEL 3 PUT_PIXEL 4 PUT_PIXEL 5 PUT_PIXEL 6 PUT_PIXEL 7 add esi,2*NB_INTERP ;pz += NB_INTERP add edi,NB_INTERP*PSZB ;pp += NB_INTERP * PSZB sub dword[n],NB_INTERP ;n -= NB_INTERP fld dword[ndszdx] fadd dword[s_z] fstp dword[s_z] ;sz += ndszdx fld dword[ndtzdx] fadd dword[t_z] fstp dword[t_z] ;tz += ndtzdx jmp .cycle_2 align 4 .cycle_2_end: fld dword[zinv] fld st0 fmul dword[s_z] ;ss = (sz * zinv) fist dword[s] ;s = (int) ss fmul dword[fdzdx] fchs fadd dword[dszdx] fmul dword[zinv] fistp dword[dsdx] ;dsdx = (int)( (dszdx - ss*fdzdx)*zinv ) fmul dword[t_z] ;tt = (tz * zinv) fist dword[t] ;t = (int) tt fmul dword[fdzdx] fchs fadd dword[dtzdx] fmul dword[zinv] fistp dword[dtdx] ;dtdx = (int)( (dtzdx - tt*fdzdx)*zinv ) align 4 .cycle_3: ;while (n>=0) cmp dword[n],0 jl .cycle_3_end PUT_PIXEL 0 add esi,2 ;pz += 1 add edi,PSZB ;pp += PSZB dec dword[n] jmp .cycle_3 align 4 .cycle_3_end: end if } align 16 proc ZB_fillTriangleMappingPerspective, zb:dword, p0:dword, p1:dword, p2:dword locals texture dd ? ;PIXEL * fdzdx dd ? ;float fndzdx dd ? ;float ndszdx dd ? ;float ndtzdx dd ? ;float zinv dd ? ;float f_z dd ? ;float - переменная отвечающая за геометрию текстуры s_log2 dd ? ;unsigned int s_bound dd ? ;unsigned int t_bound dd ? ;unsigned int include 'ztriangle.inc'