-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathextlua.lua
More file actions
130 lines (109 loc) · 2.66 KB
/
extlua.lua
File metadata and controls
130 lines (109 loc) · 2.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
-- bin/soluna.exe test/extlua.game
local soluna = require "soluna"
local foobar = require "ext.foobar"
local matpq = require "ext.material.perspective_quad"
print(foobar.hello())
soluna.set_window_title "extlua perspective quad"
local args = ...
local batch = args.batch
local callback = {}
local CARD_W <const> = 160
local CARD_H <const> = 196
local HALF_W <const> = CARD_W * 0.5
local HALF_H <const> = CARD_H * 0.5
local WHITE <const> = 0xffffffff
local function rgba(color)
local a = color >> 24 & 0xff
local r = color >> 16 & 0xff
local g = color >> 8 & 0xff
local b = color & 0xff
return string.pack("BBBB", r, g, b, a)
end
local function create_canvas(width, height)
local pixels = {}
local clear = rgba(0)
for i = 1, width * height do
pixels[i] = clear
end
local canvas = {}
function canvas.set_pixel(x, y, color)
if x < 0 or x >= width or y < 0 or y >= height then
return
end
pixels[y * width + x + 1] = rgba(color)
end
function canvas.to_content()
return table.concat(pixels)
end
return canvas
end
local function make_card_sprite()
local canvas = create_canvas(CARD_W, CARD_H)
for y = 0, CARD_H - 1 do
for x = 0, CARD_W - 1 do
local r = 40 + x * 120 // (CARD_W - 1)
local g = 56 + y * 140 // (CARD_H - 1)
local b = 224 - y * 72 // (CARD_H - 1)
canvas.set_pixel(x, y, 0xff000000 | r << 16 | g << 8 | b)
end
end
for y = 0, CARD_H - 1 do
for x = 0, CARD_W - 1 do
if x < 3 or x >= CARD_W - 3 or y < 3 or y >= CARD_H - 3 then
canvas.set_pixel(x, y, 0xffffffff)
elseif x % 32 == 0 or y % 32 == 0 then
canvas.set_pixel(x, y, 0x80ffffff)
end
end
end
soluna.preload {
filename = "@extlua_perspective_card",
content = canvas.to_content(),
w = CARD_W,
h = CARD_H,
}
return soluna.load_sprites {
{
name = "card",
filename = "@extlua_perspective_card",
},
}
end
local sprites = make_card_sprite()
local card = assert(sprites.card)
local function card_quad(theta)
local dist = 460.0
local focal = 460.0
local c = math.cos(theta)
local s = math.sin(theta)
local corners = {
{ -HALF_W, -HALF_H },
{ HALF_W, -HALF_H },
{ -HALF_W, HALF_H },
{ HALF_W, HALF_H },
}
local quad = {}
local q = {}
for i = 1, 4 do
local x = corners[i][1]
local y = corners[i][2]
local rx = x * c
local rz = -x * s
local w = dist + rz
local scale = focal / w
quad[#quad + 1] = rx * scale
quad[#quad + 1] = y * scale
q[i] = 1.0 / w
end
return quad, q
end
function callback.frame(count)
local theta = math.sin(count * 0.021) * 1.15
local quad, q = card_quad(theta)
batch:add(matpq.sprite(card, {
quad = quad,
q = q,
color = WHITE,
}), args.width * 0.5, args.height * 0.5)
end
return callback