523 lines
13 KiB
Lua
523 lines
13 KiB
Lua
local fps = 0
|
|
|
|
local function ClearBuffers(meta, colorbuffer, depthbuffer, color, depth)
|
|
local i
|
|
for i = 0, meta[3] - 1 do
|
|
colorbuffer[1 + i * 3] = color[1]
|
|
colorbuffer[1 + i * 3 + 1] = color[2]
|
|
colorbuffer[1 + i * 3 + 2] = color[3]
|
|
|
|
depthbuffer[1 + i] = depth
|
|
end
|
|
end
|
|
|
|
local function DegToRad(deg)
|
|
local rad
|
|
rad = deg * 0.0174532925
|
|
return rad
|
|
end
|
|
|
|
local function Min(a, b)
|
|
local r
|
|
if a < b then
|
|
r = a
|
|
else
|
|
r = b
|
|
end
|
|
return r
|
|
end
|
|
|
|
local function Min3(a, b, c)
|
|
local r
|
|
r = Min(Min(a, b), c)
|
|
return r
|
|
end
|
|
|
|
local function Max(a, b)
|
|
local r
|
|
if a > b then
|
|
r = a
|
|
else
|
|
r = b
|
|
end
|
|
return r
|
|
end
|
|
|
|
local function Max3(a, b, c)
|
|
local r
|
|
r = Max(Max(a, b), c)
|
|
return r
|
|
end
|
|
|
|
local function IsOnRight(a, b, c)
|
|
local r
|
|
if (b[1] - a[1]) * (c[2] - a[2]) - (b[2] - a[2]) * (c[1] - a[1]) <= 0 then
|
|
r = true
|
|
else
|
|
r = false
|
|
end
|
|
return r
|
|
end
|
|
|
|
local function Distance2(a, b)
|
|
local x, y, d
|
|
x = b[1] - a[1]
|
|
y = b[2] - a[2]
|
|
d = math.sqrt(x * x + y * y)
|
|
return d
|
|
end
|
|
|
|
local function Normalize(a)
|
|
local l
|
|
l = math.sqrt(a[1] * a[1] + a[2] * a[2] + a[3] * a[3])
|
|
a[1] = a[1] / l
|
|
a[2] = a[2] / l
|
|
a[3] = a[3] / l
|
|
end
|
|
|
|
local function MapToRes(meta, a)
|
|
a[1] = a[1] / a[4]
|
|
a[2] = a[2] / a[4]
|
|
a[3] = a[3] / a[4]
|
|
|
|
a[1] = (a[1] + 1.0) * 0.5 * (meta[1] - 1)
|
|
a[2] = (1.0 - a[2]) * 0.5 * (meta[2] - 1)
|
|
end
|
|
|
|
local function Cross(result, a, b)
|
|
result[1] = a[2] * b[3] - a[3] * b[2]
|
|
result[2] = a[3] * b[1] - a[1] * b[3]
|
|
result[3] = a[1] * b[2] - a[2] * b[1]
|
|
end
|
|
|
|
local function Dot(a, b)
|
|
local result
|
|
result = a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
|
|
return result
|
|
end
|
|
|
|
local function Dot2(a, b)
|
|
local result
|
|
result = a[1] * b[1] + a[2] * b[2]
|
|
return result
|
|
end
|
|
|
|
local function VecCopy3(result, a)
|
|
result[1] = a[1]
|
|
result[2] = a[2]
|
|
result[3] = a[3]
|
|
end
|
|
|
|
local function VecSubVec3(result, a, b)
|
|
result[1] = a[1] - b[1]
|
|
result[2] = a[2] - b[2]
|
|
result[3] = a[3] - b[3]
|
|
end
|
|
|
|
local function MatMultMat(result, a, b)
|
|
result[1] = a[1] * b[1] + a[2] * b[5] + a[3] * b[9] + a[4] * b[13]
|
|
result[2] = a[1] * b[2] + a[2] * b[6] + a[3] * b[10] + a[4] * b[14]
|
|
result[3] = a[1] * b[3] + a[2] * b[7] + a[3] * b[11] + a[4] * b[15]
|
|
result[4] = a[1] * b[4] + a[2] * b[8] + a[3] * b[12] + a[4] * b[16]
|
|
result[5] = a[5] * b[1] + a[6] * b[5] + a[7] * b[9] + a[8] * b[13]
|
|
result[6] = a[5] * b[2] + a[6] * b[6] + a[7] * b[10] + a[8] * b[14]
|
|
result[7] = a[5] * b[3] + a[6] * b[7] + a[7] * b[11] + a[8] * b[15]
|
|
result[8] = a[5] * b[4] + a[6] * b[8] + a[7] * b[12] + a[8] * b[16]
|
|
result[9] = a[9] * b[1] + a[10] * b[5] + a[11] * b[9] + a[12] * b[13]
|
|
result[10] = a[9] * b[2] + a[10] * b[6] + a[11] * b[10] + a[12] * b[14]
|
|
result[11] = a[9] * b[3] + a[10] * b[7] + a[11] * b[11] + a[12] * b[15]
|
|
result[12] = a[9] * b[4] + a[10] * b[8] + a[11] * b[12] + a[12] * b[16]
|
|
result[13] = a[13] * b[1] + a[14] * b[5] + a[15] * b[9] + a[16] * b[13]
|
|
result[14] = a[13] * b[2] + a[14] * b[6] + a[15] * b[10] + a[16] * b[14]
|
|
result[15] = a[13] * b[3] + a[14] * b[7] + a[15] * b[11] + a[16] * b[15]
|
|
result[16] = a[13] * b[4] + a[14] * b[8] + a[15] * b[12] + a[16] * b[16]
|
|
end
|
|
|
|
local function MatMultVec(result, a, v)
|
|
result[1] = a[1] * v[1] + a[2] * v[2] + a[3] * v[3] + a[4] * v[4]
|
|
result[2] = a[5] * v[1] + a[6] * v[2] + a[7] * v[3] + a[8] * v[4]
|
|
result[3] = a[9] * v[1] + a[10] * v[2] + a[11] * v[3] + a[12] * v[4]
|
|
result[4] = a[13] * v[1] + a[14] * v[2] + a[15] * v[3] + a[16] * v[4]
|
|
end
|
|
|
|
local function MatMultVec3(result, a, v)
|
|
result[1] = a[1] * v[1] + a[2] * v[2] + a[3] * v[3] + a[4]
|
|
result[2] = a[5] * v[1] + a[6] * v[2] + a[7] * v[3] + a[8]
|
|
result[3] = a[9] * v[1] + a[10] * v[2] + a[11] * v[3] + a[12]
|
|
result[4] = a[13] * v[1] + a[14] * v[2] + a[15] * v[3] + a[16]
|
|
end
|
|
|
|
local function LookAt(mat, campos, targetpos, upvec)
|
|
local forward = {}
|
|
local right = {}
|
|
local up = {}
|
|
|
|
VecSubVec3(forward, targetpos, campos)
|
|
Normalize(forward)
|
|
|
|
Cross(right, forward, upvec)
|
|
Normalize(right)
|
|
|
|
Cross(up, right, forward)
|
|
|
|
mat[1] = right[1]
|
|
mat[2] = right[2]
|
|
mat[3] = right[3]
|
|
mat[4] = -Dot(right, campos)
|
|
mat[5] = up[1]
|
|
mat[6] = up[2]
|
|
mat[7] = up[3]
|
|
mat[8] = -Dot(up, campos)
|
|
mat[9] = -forward[1]
|
|
mat[10] = -forward[2]
|
|
mat[11] = -forward[3]
|
|
mat[12] = Dot(forward, campos)
|
|
mat[13] = 0.0
|
|
mat[14] = 0.0
|
|
mat[15] = 0.0
|
|
mat[16] = 1.0
|
|
end
|
|
|
|
local function Perspective(mat, fov, aspectratio, near, far)
|
|
local tanhalffovy
|
|
tanhalffovy = math.tan(fov * 0.5)
|
|
|
|
mat[1] = 1 / (aspectratio * tanhalffovy)
|
|
mat[2] = 0.0
|
|
mat[3] = 0.0
|
|
mat[4] = 0.0
|
|
mat[5] = 0.0
|
|
mat[6] = 1 / tanhalffovy
|
|
mat[7] = 0.0
|
|
mat[8] = 0.0
|
|
mat[9] = 0.0
|
|
mat[10] = 0.0
|
|
mat[11] = -(far + near) / (far - near)
|
|
mat[12] = -(2 * far * near) / (far - near)
|
|
mat[13] = 0.0
|
|
mat[14] = 0.0
|
|
mat[15] = -1.0
|
|
mat[16] = 0.0
|
|
end
|
|
|
|
local function DrawTriangle(meta, colorbuffer, depthbuffer, wp0, wp1, wp2, texture, c0, c1, c2, mvp, lightdir, n0, n1, n2)
|
|
local p0 = {}
|
|
local p1 = {}
|
|
local p2 = {}
|
|
|
|
MatMultVec3(p0, mvp, wp0)
|
|
MatMultVec3(p1, mvp, wp1)
|
|
MatMultVec3(p2, mvp, wp2)
|
|
|
|
if p0[4] ~= 0.0 and p1[4] ~= 0.0 and p2[4] ~= 0.0 then
|
|
MapToRes(meta, p0)
|
|
MapToRes(meta, p1)
|
|
MapToRes(meta, p2)
|
|
|
|
local aabbmin = {}
|
|
local aabbmax = {}
|
|
|
|
aabbmin[1] = Max(Min3(p0[1], p1[1], p2[1]), 0)
|
|
aabbmin[2] = Max(Min3(p0[2], p1[2], p2[2]), 0)
|
|
aabbmax[1] = Min(Max3(p0[1], p1[1], p2[1]), meta[1] - 1)
|
|
aabbmax[2] = Min(Max3(p0[2], p1[2], p2[2]), meta[2] - 1)
|
|
|
|
local idx, tx, ty, ti
|
|
local p = {}
|
|
local depth
|
|
local w0, w1, w2, dot00, dot01, dot11, dot20, dot21, denom, d0, d1, d2
|
|
|
|
local v0 = {}
|
|
local v1 = {}
|
|
local v2 = {}
|
|
|
|
local texcoord = {}
|
|
|
|
local normal = {}
|
|
local diff
|
|
|
|
for x = math.floor(aabbmin[1]), math.floor(aabbmax[1]) do
|
|
for y = math.floor(aabbmin[2]), math.floor(aabbmax[2]) do
|
|
p[1] = x
|
|
p[2] = y
|
|
|
|
if IsOnRight(p0, p1, p) and IsOnRight(p1, p2, p) and IsOnRight(p2, p0, p) then
|
|
v0[1] = p1[1] - p0[1]
|
|
v0[2] = p1[2] - p0[2]
|
|
v1[1] = p2[1] - p0[1]
|
|
v1[2] = p2[2] - p0[2]
|
|
v2[1] = p[1] - p0[1]
|
|
v2[2] = p[2] - p0[2]
|
|
|
|
dot00 = Dot2(v0, v0)
|
|
dot01 = Dot2(v0, v1)
|
|
dot11 = Dot2(v1, v1)
|
|
dot20 = Dot2(v2, v0)
|
|
dot21 = Dot2(v2, v1)
|
|
|
|
denom = dot00 * dot11 - dot01 * dot01
|
|
w1 = (dot11 * dot20 - dot01 * dot21) / denom
|
|
w2 = (dot00 * dot21 - dot01 * dot20) / denom
|
|
w0 = 1.0 - w1 - w2
|
|
|
|
depth = p0[3] * w0 + p1[3] * w1 + p2[3] * w2
|
|
|
|
idx = math.floor(x) + meta[1] * math.floor(y)
|
|
|
|
if depth > 0.0 and depthbuffer[1 + idx] > depth then
|
|
depthbuffer[1 + idx] = depth
|
|
idx = idx * 3
|
|
|
|
texcoord[1] = w0 * c0[1] + w1 * c1[1] + w2 * c2[1]
|
|
texcoord[2] = w0 * c0[2] + w1 * c1[2] + w2 * c2[2]
|
|
|
|
normal[1] = w0 * n0[1] + w1 * n1[1] + w2 * n2[1]
|
|
normal[2] = w0 * n0[2] + w1 * n1[2] + w2 * n2[2]
|
|
normal[3] = w0 * n0[3] + w1 * n1[3] + w2 * n2[3]
|
|
|
|
Normalize(normal)
|
|
diff = Max(0.5, Dot(normal, lightdir))
|
|
|
|
tx = math.floor(texcoord[1] * meta[4])
|
|
ty = math.floor((1 - texcoord[2]) * meta[5])
|
|
ti = (tx + ty * meta[4]) * 3
|
|
|
|
|
|
-- uz ne kokote
|
|
|
|
|
|
|
|
colorbuffer[1 + idx] = texture[1 + ti] / 255 * diff
|
|
colorbuffer[1 + idx + 1] = texture[1 + ti + 1] / 255 * diff
|
|
colorbuffer[1 + idx + 2] = texture[1 + ti + 2] / 255 * diff
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function OutputVT100(meta, colorbuffer)
|
|
print("\x1b[1;1H")
|
|
|
|
local r1, g1, b1, r2, b2, g2, width, height, idx, rowoffset
|
|
width = meta[1]
|
|
height = meta[2]
|
|
|
|
local out = {}
|
|
|
|
local pr1, pg1, pb1, pr2, pg2, pb2 = 0, 0, 0, 0, 0, 0
|
|
|
|
for y = 0, height - 2, 2 do
|
|
table.insert(out, "\n")
|
|
for x = 0, width - 1 do
|
|
idx = (x + y * width) * 3
|
|
rowoffset = width * 3
|
|
|
|
r1 = math.floor(colorbuffer[1 + idx] * 255)
|
|
g1 = math.floor(colorbuffer[1 + idx + 1] * 255)
|
|
b1 = math.floor(colorbuffer[1 + idx + 2] * 255)
|
|
|
|
r2 = math.floor(colorbuffer[1 + idx + rowoffset] * 255)
|
|
g2 = math.floor(colorbuffer[1 + idx + 1 + rowoffset] * 255)
|
|
b2 = math.floor(colorbuffer[1 + idx + 2 + rowoffset] * 255)
|
|
|
|
if r1 == pr1 and g1 == pg1 and b1 == pb1 and r2 == pr2 and g2 == pg2 and b2 == pb2 then
|
|
table.insert(out, "\xDF")
|
|
else
|
|
pr1, pg1, pb1, pr2, pg2, pb2 = r1, g1, b1, r2, g2, b2
|
|
table.insert(out, string.format("\x1b[38;2;%d;%d;%dm\x1b[48;2;%d;%d;%dm\xDF", r1, g1, b1, r2, g2, b2))
|
|
end
|
|
|
|
|
|
-- io.write("\x1b[38;2;" ..
|
|
-- r1 .. ";" .. g1 .. ";" .. b1 .. "m" .. "\x1b[48;2;" .. r2 .. ";" .. g2 .. ";" .. b2 .. "m" .. "\xDF")
|
|
end
|
|
end
|
|
|
|
io.write(table.concat(out))
|
|
|
|
io.write(string.format("\n\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m%d FPS", fps))
|
|
end
|
|
|
|
local file = io.open("data.txt", "r")
|
|
|
|
local function Input()
|
|
return file:read("*n")
|
|
end
|
|
|
|
-- file:close() -- Close the file
|
|
|
|
-- return number
|
|
|
|
local function Main()
|
|
os.execute(" ")
|
|
|
|
local meta = {}
|
|
|
|
meta[1] = 175
|
|
meta[2] = 120
|
|
|
|
|
|
meta[3] = meta[1] * meta[2]
|
|
|
|
local depthbuffer = {}
|
|
local colorbuffer = {}
|
|
|
|
local background = {}
|
|
background[1] = 0.3
|
|
background[2] = 0.3
|
|
background[3] = 0.3
|
|
|
|
ClearBuffers(meta, colorbuffer, depthbuffer, background, 100.0)
|
|
|
|
local lightdir = {}
|
|
lightdir[1] = .3
|
|
lightdir[2] = 1
|
|
lightdir[3] = .4
|
|
Normalize(lightdir)
|
|
|
|
local view = {}
|
|
local proj = {}
|
|
local mvp = {}
|
|
|
|
local campos = {}
|
|
local targetpos = {}
|
|
local upvector = {}
|
|
|
|
targetpos[1] = 0
|
|
targetpos[2] = 0
|
|
targetpos[3] = 0
|
|
|
|
upvector[1] = 0
|
|
upvector[2] = 1
|
|
upvector[3] = 0
|
|
local aspectratio
|
|
aspectratio = 1.46
|
|
|
|
|
|
Perspective(proj, DegToRad(90.0) / aspectratio, aspectratio, 0.1, 50.0)
|
|
|
|
local p0 = {}
|
|
local p1 = {}
|
|
local p2 = {}
|
|
|
|
local c0 = {}
|
|
local c1 = {}
|
|
local c2 = {}
|
|
|
|
local n0 = {}
|
|
local n1 = {}
|
|
local n2 = {}
|
|
|
|
local datasize, i, vertices
|
|
datasize = Input()
|
|
vertices = Input()
|
|
|
|
local data = {}
|
|
for i = 1, datasize do
|
|
data[i] = Input()
|
|
end
|
|
|
|
print("model rdy")
|
|
|
|
meta[4] = Input()
|
|
meta[5] = Input()
|
|
|
|
local tp
|
|
tp = meta[4] * meta[5] * 3
|
|
|
|
local texture = {}
|
|
|
|
for i = 0, tp - 1 do
|
|
texture[1 + i] = Input()
|
|
end
|
|
|
|
print("textura rdy")
|
|
|
|
local temp
|
|
|
|
local i0, i1, i2
|
|
|
|
local camangle
|
|
camangle = 0
|
|
|
|
local frames = 0
|
|
local lastframereset = 0
|
|
|
|
while true do
|
|
frames = frames + 1
|
|
|
|
local time = os.clock() * 1000
|
|
|
|
if time > lastframereset + 1000 then
|
|
fps = frames
|
|
frames = 0
|
|
lastframereset = time
|
|
end
|
|
|
|
|
|
ClearBuffers(meta, colorbuffer, depthbuffer, background, 100.0)
|
|
|
|
local camdis
|
|
camdis = 7.0
|
|
|
|
campos[1] = math.sin(camangle) * camdis
|
|
campos[2] = 0.8 * camdis
|
|
campos[3] = math.cos(camangle) * camdis
|
|
|
|
|
|
camangle = camangle + math.pi / 50
|
|
|
|
LookAt(view, campos, targetpos, upvector)
|
|
MatMultMat(mvp, proj, view)
|
|
|
|
for i = 0, vertices - 3, 3 do
|
|
i0 = i * 8
|
|
i1 = (i + 1) * 8
|
|
i2 = (i + 2) * 8
|
|
|
|
p0[1] = data[1 + i0]
|
|
p0[2] = data[1 + i0 + 1]
|
|
p0[3] = data[1 + i0 + 2]
|
|
|
|
p1[1] = data[1 + i1]
|
|
p1[2] = data[1 + i1 + 1]
|
|
p1[3] = data[1 + i1 + 2]
|
|
|
|
p2[1] = data[1 + i2]
|
|
p2[2] = data[1 + i2 + 1]
|
|
p2[3] = data[1 + i2 + 2]
|
|
|
|
|
|
c0[1] = data[1 + i0 + 3]
|
|
c0[2] = data[1 + i0 + 4]
|
|
|
|
c1[1] = data[1 + i1 + 3]
|
|
c1[2] = data[1 + i1 + 4]
|
|
|
|
c2[1] = data[1 + i2 + 3]
|
|
c2[2] = data[1 + i2 + 4]
|
|
|
|
n0[1] = data[1 + i0 + 5]
|
|
n0[2] = data[1 + i0 + 6]
|
|
n0[3] = data[1 + i0 + 7]
|
|
|
|
n1[1] = data[1 + i1 + 5]
|
|
n1[2] = data[1 + i1 + 6]
|
|
n1[3] = data[1 + i1 + 7]
|
|
|
|
n2[1] = data[1 + i2 + 5]
|
|
n2[2] = data[1 + i2 + 6]
|
|
n2[3] = data[1 + i2 + 7]
|
|
|
|
DrawTriangle(meta, colorbuffer, depthbuffer, p0, p1, p2, texture, c0, c1, c2, mvp, lightdir, n0, n1, n2)
|
|
end
|
|
|
|
|
|
OutputVT100(meta, colorbuffer)
|
|
end
|
|
end
|
|
|
|
Main()
|