Last active
October 6, 2021 07:42
-
-
Save Enichan/01b3ab4832a66824d3c26325217dc3ef to your computer and use it in GitHub Desktop.
Subpixel accurate triangle rasterizer prototype for Pico 8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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