-
-
Save whoisryosuke/4de1891af955e295210d20dca2034782 to your computer and use it in GitHub Desktop.
Subpixel accurate triangle rasterizer prototype for Pico 8
This file contains 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 | |
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