First off, this is very slow, but pretty easy to understand. I wouldn't use this in any games. Just make a 256x256 bitmap called texture.bmp. Use a tscale of about .50 to speed things up.
sync on
sync rate 0
set display mode 1024,768,16
global tscale as float `the higher this is the higher the quality the texture
tscale = 1.25
type face
b as float `brightness of face 0-255 darkest - brightest
u1 as float `u/v coords for texture
v1 as float
u2 as float
v2 as float
u3 as float
v3 as float
dax as float
day as float
blength as float `length between the base points (2 and 3)
endtype
dim face(1) as face
load image "c:\temp\texture.bmp",1
make memblock from image 1,1
makeface(.50,0,1,1,0,1,128,1)
do
cls
text 1,1,str$(screen fps())
texturetriangle(100,100,200,200,50,300,1)
sync
loop
function makeface(u1#,v1#,u2#,v2#,u3#,v3#,bright#,nface)
face(nface).u1 = u1#
face(nface).v1 = v1#
face(nface).u2 = u2#
face(nface).v2 = v2#
face(nface).u3 = u3#
face(nface).v3 = v3#
dax# = u2#*256-u3#*256 `change these to what ever your texture size is.
day# = v2#*256-v3#*256
face(nface).blength = sqrt(dax#*dax#+day#*day#)
dax# = dax# / face(nface).blength
day# = day# / face(nface).blength
face(nface).dax = dax#
face(nface).day = day#
face(nface).b = bright#
endfunction
Function texturetriangle(ttx1#,tty1#,ttx2#,tty2#,ttx3#,tty3#,face)
lines as float
stp as float
`this is the distance between tpoints 2 and 3 of the triangle being drawn to the screen
tdist# = Sqrt(((ttx2#-ttx3#)*(ttx2#-ttx3#))+((tty2#-tty3#)*(tty2#-tty3#)))
deltax# = ttx2# - ttx3#
deltay# = tty2# - tty3#
deltax# = deltax# / tdist#
deltay# = deltay# / tdist#
stp = 1/(tdist#*tscale) `use a scale on this to minimize the amount of time it takes to texture an object
lock backbuffer
For lines = 0 to 1 step stp
lbline2(ttx1#,tty1#,ttx2#-(deltax# * lines*tdist#),tty2#-(deltay# * lines*tdist#),lines,face)
Next lines
unlock backbuffer
`ink rgb(255,255,255),0
EndFunction
Function lbline2(bx1#,by1#,bx2#,by2#,timeline#,face)`,x2,y2,vx2,vy2)
ptr = get backbuffer ptr()
pitch = get backbuffer pitch()
t as float `the time step going from first point to destination point along base of triangle
stp as float
`this is how many steps it will take to get through all the positions in the line
stp = 1/(sqrt((bx1#-bx2#)^2+(by1#-by2#)^2)*tscale)
`stepping through time , going from the first point down to the point somewhere in between points 2 and 3
For t = 0 to 1 Step stp
` pointx# = x1*(1-t)^3 + 3*vx1*(1-t)^2*t + 3*vx2*(1-t)*t^2 + x2*t^3
` pointy# = y2*(1-t)^3 + 3*vy1*(1-t)^2*t + 3*vy2*(1-t)*t^2 + y2*t^3
px = bx1#*(1-t) + bx2#*t
py = by1#*(1-t) + by2#*t
`must get the position of the screen to be drawn to
buf = ptr + pitch * py + px * 4
`make sure the screen point doesn't go before the originating point or past the screen height
if px > 0 and px < screen width() and py > 0 and py < screen height()
`go get the color from the texture base on the time
`timeline is the time across the base (points 2 and 3) t is the time going to the base
*buf = getbline2(face(face).u1*256,face(face).v1*256,1,timeline#,t,face)
endif
Next
EndFunction
Function getbline2(bx1#,by1#,mem,timeline#,t#,face)
`get the baseline positions based off the texture u/v and time
`that's points 3-2
` u# = vertex(face(face).vo2).u*256-vertex(face(face).vo3).u*256
` v# = vertex(face(face).vo2).v*256-vertex(face(face).vo3).v*256
`dax# = face(face).u2*256-face(face).u3*256 `the 256 parts in here are for expanding the u/v texture coords from 0 to 1, to 0 to 256
`day# = face(face).v2*256-face(face).v3*256 `how many steps in the x/y direction
dax# = face(face).dax
day# = face(face).day
`tdis# = sqrt(u#*u#+v#*v#)
`tdis# = sqrt(dax#*dax#+day#*day#) `standard distance formula
tdis# = face(face).blength
`dax# = u#
`day# = v#
`dax# = dax# / tdis# `normalize
`day# = day# / tdis#
`getting the point where the line is drawn to, based on the timeline for the base points.
`no lines are being drawn on the texture, just picking up the texture point
`to be draw to the screen. timeline# is the time betweeen points 2 and 3
`when its multiplied by tdist# if give the real point in time along the baseline.
bx2# = face(face).u2*256-(dax# * timeline#*tdis#) `bx2 is the start point of point 2 (this is the base line, points p2,p3)
by2# = face(face).v2*256-(day# * timeline#*tdis#) `depending on the time, you move towards point 3 by that amount
`now we know where the line was being sent to, and based on the time to the base points (t#),
`we get the pixel spot on the texture, making sure the points don't go out of the texture
`bounds
px = bx1#*(1-t#) + bx2#*t# `t# is passed to us from bline2()
py = by1#*(1-t#) + by2#*t# `which tells up how far down the line to draw the next point
if px > 255 then px = 255
if py > 255 then py = 255
if px < 1 then px = 1
if py < 1 then py = 1
`NOTE add routine to take each pixel color and compare it to light source positions
`at this time, we have already calculated the brightness of the face depending
`and the direction of where it's facing from or to the camera. Because this is software mode
`we are not bound to only 8 lights.
fc# = face(face).b/255.0 `face color percentage, will be used to subtract from the color values pulled
c3# = memblock byte(mem,12+py*1024+px*4) `/ face(face).c`blue 1024 is the pitch of the texture
c2# = memblock byte(mem,12+py*1024+px*4+1) `/ face(face).c`green 256 wide * 4 bytes per pixel
c1# = memblock byte(mem,12+py*1024+px*4+2) `/ face(face).c`red
if blendcolor = 1
bc1# = memblock byte(mem,12+(py-1)*1024+(px-1)*4+2)
bc2# = memblock byte(mem,12+(py-1)*1024+(px-1)*4+1)
bc3# = memblock byte(mem,12+(py-1)*1024+(px-1)*4)
bc11# = memblock byte(mem,12+(py-1)*1024+(px+1)*4+2)
bc22# = memblock byte(mem,12+(py-1)*1024+(px+1)*4+1)
bc33# = memblock byte(mem,12+(py-1)*1024+(px+1)*4)
c1# = (c1# + bc1# + bc11#) / 3
c2# = (c2# + bc2# + bc22#) / 3
c3# = (c3# + bc3# + bc33#) / 3
endif
`we have the correct spot on the texture, and returning the color to be draw on the screen
`we also adjust the color by the positioning of the face
c = rgb(c1#*fc#,c2#*fc#,c3#*fc#) `color r g b is stored in reverse b g r
EndFunction c