forked from KolibriOS/kolibrios
d3fd66f14b
fix and clean code, fix and update examples git-svn-id: svn://kolibrios.org@8069 a494cfbc-eb01-0410-851d-a64ba20cac60
401 lines
9.1 KiB
NASM
401 lines
9.1 KiB
NASM
;
|
||
; Опции для функций:
|
||
;
|
||
;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'
|