Skip to content

Instantly share code, notes, and snippets.

@Enichan
Last active October 6, 2021 07:42
Show Gist options
  • Save Enichan/01b3ab4832a66824d3c26325217dc3ef to your computer and use it in GitHub Desktop.
Save Enichan/01b3ab4832a66824d3c26325217dc3ef to your computer and use it in GitHub Desktop.
Subpixel accurate triangle rasterizer prototype for Pico 8
pico-8 cartridge // http://www.pico-8.com
version 18
__lua__
--[[function spline(x0,y0,x1,y1,c)
local dx = x1 - x0
local dy = y1 - y0
local step = dx/dy
local x = x0 - (y0 % 1) * step
local y = flr(y0)
local ymax = flr(y1)
pset(x0, y0, 8)
while y < ymax do
pset(x, y, c)
y += 1
x += step
end
end]]
function getline(x0,y0,x1,y1)
local dx = x1 - x0
local dy = y1 - y0
local step = dx/dy
local x = x0 - (y0 % 1) * step
--local y = flr(y0)
--local ymax = flr(y1)
return {
x = x,
--y = y,
--ymax = ymax,
step = step
}
end
function drawpx(x,y,c)
pset(x, y,
bxor(pget(x, y), c))
end
function drawtri(tri,c)
local dy = tri[2].y - tri[1].y
local left, right
if dy == 0 then
left = getline(
tri[1].x, tri[1].y,
tri[3].x, tri[3].y)
right = getline(
tri[2].x, tri[2].y,
tri[3].x, tri[3].y)
else
left = getline(
tri[1].x, tri[1].y,
tri[2].x, tri[2].y)
right = getline(
tri[1].x, tri[1].y,
tri[3].x, tri[3].y)
end
local y = flr(tri[1].y)
local ymax = flr(tri[3].y)
y+=1
left.x += left.step
right.x += right.step
while y <= ymax do
local x=flr(left.x)
local maxx=flr(right.x)
while x < maxx do
-- using pset here for debugging, use rectfill
-- in the real world for performance!!
drawpx(x,y,c)
x += 1
end
y += 1
left.x += left.step
right.x += right.step
end
end
function maketri(x0,y0,x1,y1,x2,y2)
local top, middle, bottom, tmp
local tris={}
top = { x=x0, y=y0 }
middle = { x=x1, y=y1 }
bottom = { x=x2, y=y2 }
if top.y > middle.y then
tmp = top
top = middle
middle = tmp
end
if top.y > bottom.y then
tmp = top
top = bottom
bottom = tmp
end
if middle.y > bottom.y then
tmp = middle
middle = bottom
bottom = tmp
end
if top.y == middle.y then
if top.x < middle.x then
add(tris,{top,middle,bottom})
else
add(tris,{middle,top,bottom})
end
elseif bottom.y == middle.y then
if middle.x < bottom.x then
add(tris,{top,middle,bottom})
else
add(tris,{top,bottom,middle})
end
else
local step =
(bottom.x - top.x) /
(bottom.y - top.y)
local dist = middle.y - top.y
local mid2 = {
x = top.x + step * dist,
y = middle.y
}
if middle.x < mid2.x then
add(tris,{top,middle,mid2})
add(tris,{middle,mid2,bottom})
else
add(tris,{top,mid2,middle})
add(tris,{mid2,middle,bottom})
end
end
return tris
end
xadd=0
yadd=0
function _draw()
cls()
local tris = {}
add(tris,maketri(
60 + xadd, 32 + yadd,
31 + xadd, 97 + yadd,
93 + xadd, 81 + yadd))
add(tris,maketri(
60 + xadd, 32 + yadd,
93 + xadd, 81 + yadd,
100 + xadd, 28 + yadd))
add(tris,maketri(
31 + xadd, 97 + yadd,
93 + xadd, 81 + yadd,
105 + xadd, 108 + yadd))
add(tris,maketri(
93 + xadd, 81 + yadd,
105 + xadd, 108 + yadd,
100 + xadd, 28 + yadd))
local c=1
for i=1,#tris do
for j=1,#tris[i] do
local tri=tris[i][j]
drawtri(tri,c)
end
c *= 2
end
--xadd += 0.1
--yadd += 0.1
xadd = sin(t() / 12) * 10
yadd = cos(t() / 12) * 10
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment