So, you have interpolated x, u/z, v/z, 1/z along the left & right edges of your polygon:
lx= left x-coordinate of your scanline
lu= u/z on left side
lv= v/z on left side
lz= 1/z on left side
rx= right x-coordinate of your scanline
ru= u/z on right side
rv= v/z on right side
rz= 1/z on right side
What you want to find is the delta from one pixel's perspective correct texture-coordinates to the next:
mipu= log2( lu/lz - (lu+deltau)/(lz+deltaz) )
mipv= log2( lv/lz - (lv+deltau)/(lz+deltaz) )
Now that's computationally a bit expensive to do per pixel.
So let's do things properly:
Split the scanline into pieces of, let's say, 8 pixels and calculate deltas to get from one set of (u/z, v/z, 1/z) to the one eight pixels further:
inv= 8.0 / (rx-lx)
du= (ru-lu) * inv
dv= (rv-lv) * inv
dz= (rz-lz) * inv
Calculate one pair of perspective correct texture-coordinates for the left and right side of the 8-pixel-span. Let's also make them integers (we multiply by 2^16 to keep some precision):
u1= lu/lz*65536.0
v1= lv/lz*65536.0
advance to the end of 8-pixel-span:
lu+=du
lv+=dv
lz+=dz
u2= lu/lz*65536.0
v2= lv/lz*65536.0
you can now interpolate linearly across the coordinate-pair:
ldu= (u2-u1) shr 3
ldv= (v2-v1) shr 3
(beware of freebasic's shift function)
here you can read the mipmap-level from the upper-word of the deltas (find fast ways for log2
here).
Adjust the texture-coordinates depending on the miplevel (level 0 is the original texture).
Texture-tiling is for free with a simple bitmask.
masku= (1 shl (log2(texture_width) - miplevel))-1
maskv= (1 shl (log2(texture_height) - miplevel))-1
texshift= log2(texture_width) - miplevel
for x=0 to 7
u= (u1 shr (16+miplevel)) and masku
v= (v1 shr (16+miplevel)) and maskv
dest(x)= mipmap[ (v shl texshift) + u ]
u1+=ldu
v1+=ldv
(all without warranty)