Code archives/Graphics/Texture Filled Triangle Function

This code has been declared by its author to be Public Domain code.

Download source code

Texture Filled Triangle Function by Andy_A2011
Fill any triangle with any texture.

The textures in this demo code are just something I whipped up in a couple of minutes. The good news is that you can use any texture you have available.

The code is very redundant and should be optimized for better results.

[update]
Code redundancy removed.
;     Title: Textured Triangle Fill
;Programmer: Andy Amaya
;      Date: 2011.06.12

AppTitle "Texture Filled Triangle Function"

Global sw%, sh%
sw = 640 : sh = 480
Graphics sw, sh, 32, 2
SeedRnd MilliSecs()

ClsColor 32, 192, 255

; these are procedurally generated textures but,
; you can use any texture you have on your hard drive
img1% = makeTexture1()
img2% = makeTexture2()
img3% = makeTexture3()
img4% = makeTexture4()

;to display the textures being used change to 1
showTextures = 0

While MouseHit(1) = 0
	Cls
	If showTextures = 1 Then
		DrawBlock img1, 10,10
		DrawBlock img2, 40,10
		DrawBlock img3, 70,10
		DrawBlock img4, 100,10
		Color 0,0,0
		Text 144,16,"<=== These are the textures used"
	End If
    st = MilliSecs()
    For i = 1 To 4
        x1 = Rand(50,sw-50) : y1 = Rand(50,sh-50)
        x2 = Rand(50,sw-50) : y2 = Rand(50,sh-50)
        x3 = Rand(50,sw-50) : y3 = Rand(50,sh-50)
        Select i
            Case 1
            	textureFill(x1,y1,x2,y2,x3,y3,img1)
            Case 2
            	textureFill(x1,y1,x2,y2,x3,y3,img2)
            Case 3
            	textureFill(x1,y1,x2,y2,x3,y3,img3)
            Case 4
            	textureFill(x1,y1,x2,y2,x3,y3,img4)
        End Select
    Next
    et = MilliSecs()-st
	Color 0,0,0
    Text   5, sh-20,"et: "+et
    Text sw/2, sh-20,"R-click to repeat          L-click to exit",True
	Flip
    WaitMouse() ;L-click to exit ..... R-click to repeat
Wend


FreeImage img1
FreeImage img2
FreeImage img3
FreeImage img4
End


Function textureFill(x1#, y1#, x2#, y2#, x3#, y3#, imageHandle%)
	Local slope1#, slope2#, slope3#, x#, y#
	Local imgW%, imgH%, tx%, sy%, ey%, ix%, iy%, vLen%, tLen%
	
	imgW = ImageWidth(imageHandle)
	imgH = ImageHeight(imageHandle)
	
    ;triangle coordinates must be ordered: where x1 < x2 < x3
    If x2 < x1 Then x  = x2 : y  = y2 : x2 = x1 : y2 = y1 : x1 = x  : y1 = y
    ;swap x1, y1, with x3, y3
    If x3 < x1 Then x  = x3 : y  = y3 : x3 = x1 : y3 = y1 : x1 = x  : y1 = y
    ;swap x2, y2 with x3, y3
    If x3 < x2 Then x  = x3 : y  = y3 : x3 = x2 : y3 = y2 : x2 = x  : y2 = y
    If x1 <> x3 Then slope1 = (y3-y1)/(x3-x1)
    ;draw the first half of the triangle
    length = x2 - x1
    If length <> 0 Then
        slope2 = (y2-y1)/(x2-x1)
        For x = 0 To length
            ;add x to coord x1
            tx = x+x1
            ;find modulus of x coord on texture
            ix = tx Mod imgW
            ;calc the starting y pos
            sy = Int(x*slope1+y1)
            ;calc the ending y pos
            ey = Int(x*slope2+y1)
            ;make sure starting y pos is less than ending y pos
            If ey < sy Then tmp=sy: sy = ey: ey = tmp
            ;vLen (vertical length) is delta of starting y pos and ending y pos
            vLen = ey-sy
            ;while vertical length is non-zero add slices of texture (vLen = zero at vertex)
            While vLen > 0
                ;find the modulus of starting y pos to grab a slice of texture image at correct position
                iy = sy Mod imgH
                ;tLen represents length of texture slice to grab
                tLen = imgH - iy
                ;if starting y pos plus texture length >= ending y pos of triangle then truncate tLen
				If (sy + tLen) >= ey Then tLen = ey-sy
				;grab a 1 by tLen slice of the texture at ix, iy
				CopyRect ix, iy,1,tLen, tx, sy, ImageBuffer(imageHandle),BackBuffer()
                If tLen > 0 Then
                    ;increment the starting y pos by adding texture slice length
                    sy = sy + tLen
                    ;subtract texture slice length from vertical length triangle section
                    ;(this is how we eventually exit the While-Wend loop)
                    vLen = vLen - tLen
                End If
            Wend
        Next
    End If
    ;draw the second half of the triangle
    y = length*slope1+y1 : length = x3-x2
    If length <> 0 Then
        slope3 = (y3-y2)/(x3-x2)
        For x = 0 To length
            ;add x to coord x2
            tx = x+x2
            ;find modulus of x coord on texture
            ix = tx Mod imgW
            ;calc the starting y pos
            sy = Int(x*slope1+y)
            ;calc the ending y pos
            ey = Int(x*slope3+y2)
            ;make sure start y pos is less than ending y pos
            If ey < sy Then tmp=sy: sy = ey: ey = tmp
            ;vLen (vertical length) is delta of starting y pos and ending y pos
            vLen = ey-sy
            ;while vertical length is non-zero add slices of texture (vLen = zero at vertex)
            While vLen > 0
                ;find the modulus of starting y pos to grab a slice of texture image at correct position
                iy = sy Mod imgH
                ;tLen represents length of texture slice to grab
                tLen = imgH - iy
                ;if starting y pos plus texture length >= ending y pos of triangle then truncate tLen
				If (sy + tLen) >= ey Then tLen = ey-sy
				;grab a 1 by tLen slice of the texture at ix, iy
				CopyRect ix, iy,1,tLen, tx, sy, ImageBuffer(imageHandle),BackBuffer()
                If tLen > 0 Then
                    ;increment the starting y pos by adding texture slice length
                    sy = sy + tLen
                    ;subtract texture slice length from vertical length triangle section
                    ;(this is how we eventually exit the While-Wend loop)
                    vLen = vLen - tLen
                End If
            Wend
        Next
    End If
End Function

Function makeTexture1()
	Local dh#, diam%, j#, i%
	
	texture% = CreateImage(24,24)
	SetBuffer(ImageBuffer(texture))
	Color 0, 0, 128
	Rect 0, 0, 24, 24, True
	dh = 256./23.
	diam = 24
	j = 91.0
	offset = 0
	While j <= 224.0
		i = Floor(j)
		Color i,i,i
		Oval 0+offset, 0+offset, diam, diam, True
		diam = diam - 2
		offset = offset + 1
		If diam < 1 Then diam = 1: offset = diam/2
		j = j + dh
	Wend
	SetBuffer(BackBuffer())
	Return texture
End Function

Function makeTexture2()
	texture% = CreateImage(21,21)
	SetBuffer(ImageBuffer(texture))
	Color 128, 0, 0
	Rect 0, 0, 21, 3, True
	Color 255,160,0
	Rect 0, 3, 21, 3, True
	Color 255,255,0
	Rect 0, 6, 21, 3, True
	Color 0,255,0
	Rect 0, 9, 21, 3, True
	Color 0,0,255
	Rect 0,12, 21, 3, True
	Color 128,0,255
	Rect 0,15, 21, 3, True
	Color 0,0,128
	Rect 0,18, 21, 3, True
	SetBuffer(BackBuffer())
	Return texture
End Function

Function makeTexture3()
	Local dh#, diam%, j#, i%
	
	texture% = CreateImage(24,24)
	SetBuffer(ImageBuffer(texture))
	Color 128, 0, 0
	Rect 0, 0, 24, 24, True
	dh = 256./23.
	diam = 24
	j = 91.0
	offset = 0
	While j <= 224.0
		i = Floor(j)
		Color i,i,0
		Oval 0+offset, 0+offset, diam, diam, True
		diam = diam - 2
		offset = offset + 1
		If diam < 1 Then diam = 1: offset = diam/2
		j = j + dh
	Wend
	SetBuffer(BackBuffer())
	Return texture
End Function

Function makeTexture4()
	texture% = CreateImage(42,24)
	SetBuffer(ImageBuffer(texture))
	Color 0,80,112
	Rect 0,0,42,28,True
	Color 255,255,32
	Text 21, 0,"Blitz",True
	Text 21,11,"Plus",True
	SetBuffer(BackBuffer())
	Return texture
End Function

Comments

None.

Code Archives Forum