コンソールログの修正、ベクターの修正、GLFW++の修正、Lua EngineにAPIの追加

守矢諏訪子 <suwako@076.moe>、2026-06-26 01:58
コミット 8bb473d7b5db2b22c8c0d586b4ebee33ff62a2e0 ・親 287da7d ・ファイルを見る

11個のファイル、+773 -48

@@ -14,7 +14,7 @@
1414
1515 if(MSVC)
1616 set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
17- add_compile_options(/utf-8)
17+ add_compile_options(/utf-8 /bigobj)
1818 endif()
1919
2020 set(DB_NAME "shaderplayground.db" CACHE STRING "データベースのパス" FORCE)
@@ -1,3 +1,37 @@
1+/*
2+Copyright (c) テクニカル諏訪子
3+
4+Permission is hereby granted to any person obtaining a copy of the software
5+Shader Playground (the "Software") to use, modify, merge, copy, publish, distribute,
6+sublicense, and/or sell copies of the Software, subject to the following conditions:
7+
8+ 1. **Origin Attribution**:
9+ - You must not misrepresent the origin of the Software; you must not claim
10+ you created the original Software.
11+ - If the Software is used in a product, you must either:
12+ a. Provide clear attribution in the product's documentation, user interface,
13+ or other visible areas, **OR**
14+ b. Pay the original developers a fee they specify in writing.
15+ 2. **Usage Restriction**:
16+ - The Software, or any derivative works, dependencies, or libraries
17+ incorporating it, must not be used for censorship or to suppress freedom of
18+ speech, expression, or creativity. Prohibited uses include, but are not
19+ limited to:
20+ - Censorship of so-called "hate speech", visuals, non-mainstream opinions,
21+ ideas, or objective reality.
22+ - Tools or systems designed to restrict access to information or
23+ artistic works.
24+ 3. **Notice Preservation**:
25+ - This license and the above copyright notice must remain intact in all copies
26+ of the source code.
27+
28+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
29+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
30+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
31+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
32+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
33+OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34+*/
135 #pragma once
236
337 #include <util/types.hh>
@@ -19,8 +53,6 @@
1953 public:
2054 void Add(LogEntry entry);
2155 void Draw(cstr title = "コンソール");
22-
23- private:
2456 void Clear();
2557
2658 private:
@@ -35,6 +35,7 @@
3535 #pragma once
3636
3737 #include <util/types.hh>
38+#include <util/structs.hh>
3839 #define SOL_LUAJIT 1
3940 #define SOL_ALL_SAFETIES_ON 1
4041 #include <sol.hpp>
@@ -62,7 +63,7 @@
6263
6364 class LuaEngine {
6465 public:
65- LuaEngine(const string &code, Program *prog, gui::ConsoleLog *cmd = nullptr);
66+ LuaEngine(const string &code, Program *prog, GlfwInfo *glfwInfo, gui::ConsoleLog *cmd = nullptr);
6667 ~LuaEngine();
6768
6869 public:
@@ -85,6 +86,7 @@
8586 sol::state MakeAPI();
8687 void BindEngine(sol::state &lua);
8788 void BindSystem(sol::state &lua);
89+ void BindIO(sol::state &lua);
8890 void BindGraphics(sol::state &lua);
8991 void Execute(sol::state &lua);
9092
@@ -94,6 +96,8 @@
9496 string m_Code;
9597 Program *m_Program = nullptr;
9698 gui::ConsoleLog *m_Console = nullptr;
99+ GlfwInfo *m_GlfwInfo = {};
97100 string m_ApiVersion = "1.0.0";
101+ f32 m_LastTime = 0.f;
98102 };
99103 } // namespace lua
@@ -188,6 +188,7 @@
188188 bool ShouldClose() const;
189189 void SwapBuffers();
190190
191+ void GetSize(int *w, int *h);
191192 void SetClipboardString(string str);
192193 string GetClipboardString();
193194 void MakeContextCurrent();
@@ -0,0 +1,44 @@
1+/*
2+Copyright (c) テクニカル諏訪子
3+
4+Permission is hereby granted to any person obtaining a copy of the software
5+Shader Playground (the "Software") to use, modify, merge, copy, publish, distribute,
6+sublicense, and/or sell copies of the Software, subject to the following conditions:
7+
8+ 1. **Origin Attribution**:
9+ - You must not misrepresent the origin of the Software; you must not claim
10+ you created the original Software.
11+ - If the Software is used in a product, you must either:
12+ a. Provide clear attribution in the product's documentation, user interface,
13+ or other visible areas, **OR**
14+ b. Pay the original developers a fee they specify in writing.
15+ 2. **Usage Restriction**:
16+ - The Software, or any derivative works, dependencies, or libraries
17+ incorporating it, must not be used for censorship or to suppress freedom of
18+ speech, expression, or creativity. Prohibited uses include, but are not
19+ limited to:
20+ - Censorship of so-called "hate speech", visuals, non-mainstream opinions,
21+ ideas, or objective reality.
22+ - Tools or systems designed to restrict access to information or
23+ artistic works.
24+ 3. **Notice Preservation**:
25+ - This license and the above copyright notice must remain intact in all copies
26+ of the source code.
27+
28+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
29+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
30+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
31+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
32+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
33+OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34+*/
35+#ifndef RANDOM_HH
36+#define RANDOM_HH
37+
38+#include <util/types.hh>
39+
40+namespace util::rand {
41+ i32 GetRandom(i32 min, i32 max);
42+} // namespace util::rand
43+
44+#endif // RANDOM_HH
@@ -0,0 +1,42 @@
1+/*
2+Copyright (c) テクニカル諏訪子
3+
4+Permission is hereby granted to any person obtaining a copy of the software
5+Shader Playground (the "Software") to use, modify, merge, copy, publish, distribute,
6+sublicense, and/or sell copies of the Software, subject to the following conditions:
7+
8+ 1. **Origin Attribution**:
9+ - You must not misrepresent the origin of the Software; you must not claim
10+ you created the original Software.
11+ - If the Software is used in a product, you must either:
12+ a. Provide clear attribution in the product's documentation, user interface,
13+ or other visible areas, **OR**
14+ b. Pay the original developers a fee they specify in writing.
15+ 2. **Usage Restriction**:
16+ - The Software, or any derivative works, dependencies, or libraries
17+ incorporating it, must not be used for censorship or to suppress freedom of
18+ speech, expression, or creativity. Prohibited uses include, but are not
19+ limited to:
20+ - Censorship of so-called "hate speech", visuals, non-mainstream opinions,
21+ ideas, or objective reality.
22+ - Tools or systems designed to restrict access to information or
23+ artistic works.
24+ 3. **Notice Preservation**:
25+ - This license and the above copyright notice must remain intact in all copies
26+ of the source code.
27+
28+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
29+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
30+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
31+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
32+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
33+OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34+*/
35+#pragma once
36+
37+#include <util/glfwpp.hh>
38+
39+struct GlfwInfo {
40+ glfwpp::Instance *instance;
41+ glfwpp::Window *window;
42+};
@@ -37,121 +37,244 @@
3737
3838 #include "types.hh"
3939
40-typedef union {
41- struct {
40+union Vector2 {
41+ struct Position {
4242 f32 x;
4343 f32 y;
4444 };
45- struct {
45+ struct UV {
4646 f32 u;
4747 f32 v;
4848 };
49-} Vector2;
5049
51-typedef union {
52- struct {
50+ Position pos;
51+ UV uv;
52+};
53+
54+union Vector2f {
55+ struct Position {
56+ f32 x;
57+ f32 y;
58+ };
59+ struct UV {
60+ f32 u;
61+ f32 v;
62+ };
63+
64+ Position pos;
65+ UV uv;
66+};
67+
68+union Vector2d {
69+ struct Position {
70+ f64 x;
71+ f64 y;
72+ };
73+ struct UV {
74+ f64 u;
75+ f64 v;
76+ };
77+
78+ Position pos;
79+ UV uv;
80+};
81+
82+union Vector2i {
83+ struct Position {
5384 i32 x;
5485 i32 y;
5586 };
56- struct {
87+ struct UV {
5788 i32 u;
5889 i32 v;
5990 };
60-} Vector2i;
6191
62-typedef union {
63- struct {
92+ Position pos;
93+ UV uv;
94+};
95+
96+union Vector2u {
97+ struct Position {
6498 u32 x;
6599 u32 y;
66100 };
67- struct {
101+ struct UV {
68102 u32 u;
69103 u32 v;
70104 };
71-} Vector2u;
72105
73-typedef union {
74- struct {
106+ Position pos;
107+ UV uv;
108+};
109+
110+union Vector3 {
111+ struct Position {
75112 f32 x;
76113 f32 y;
77114 f32 z;
78115 };
79- struct {
116+ struct RGB {
80117 f32 r;
81118 f32 g;
82119 f32 b;
83120 };
84-} Vector3;
85121
86-typedef union {
87- struct {
122+ Position pos;
123+ RGB rgb;
124+};
125+
126+union Vector3f {
127+ struct Position {
128+ f32 x;
129+ f32 y;
130+ f32 z;
131+ };
132+ struct RGB {
133+ f32 r;
134+ f32 g;
135+ f32 b;
136+ };
137+
138+ Position pos;
139+ RGB rgb;
140+};
141+
142+union Vector3d {
143+ struct Position {
144+ f64 x;
145+ f64 y;
146+ f64 z;
147+ };
148+ struct RGB {
149+ f64 r;
150+ f64 g;
151+ f64 b;
152+ };
153+
154+ Position pos;
155+ RGB rgb;
156+};
157+
158+union Vector3i {
159+ struct Position {
88160 i32 x;
89161 i32 y;
90162 i32 z;
91163 };
92- struct {
164+ struct RGB {
93165 i32 r;
94166 i32 g;
95167 i32 b;
96168 };
97-} Vector3i;
98169
99-typedef union {
100- struct {
170+ Position pos;
171+ RGB rgb;
172+};
173+
174+union Vector3u {
175+ struct Position {
101176 u32 x;
102177 u32 y;
103178 u32 z;
104179 };
105- struct {
180+ struct RGB {
106181 u32 r;
107182 u32 g;
108183 u32 b;
109184 };
110-} Vector3u;
111185
112-typedef union {
113- struct {
186+ Position pos;
187+ RGB rgb;
188+};
189+
190+union Vector4 {
191+ struct Position {
114192 f32 x;
115193 f32 y;
116194 f32 z;
117195 f32 w;
118196 };
119- struct {
197+ struct RGBA {
120198 f32 r;
121199 f32 g;
122200 f32 b;
123201 f32 a;
124202 };
125-} Vector4;
126203
127-typedef union {
128- struct {
204+ Position pos;
205+ RGBA rgba;
206+};
207+
208+union Vector4f {
209+ struct Position {
210+ f32 x;
211+ f32 y;
212+ f32 z;
213+ f32 w;
214+ };
215+ struct RGBA {
216+ f32 r;
217+ f32 g;
218+ f32 b;
219+ f32 a;
220+ };
221+
222+ Position pos;
223+ RGBA rgba;
224+};
225+
226+union Vector4d {
227+ struct Position {
228+ f64 x;
229+ f64 y;
230+ f64 z;
231+ f64 w;
232+ };
233+ struct RGBA {
234+ f64 r;
235+ f64 g;
236+ f64 b;
237+ f64 a;
238+ };
239+
240+ Position pos;
241+ RGBA rgba;
242+};
243+
244+union Vector4i {
245+ struct Position {
129246 i32 x;
130247 i32 y;
131248 i32 z;
132249 i32 w;
133250 };
134- struct {
251+ struct RGBA {
135252 i32 r;
136253 i32 g;
137254 i32 b;
138255 i32 a;
139256 };
140-} Vector4i;
141257
142-typedef union {
143- struct {
258+ Position pos;
259+ RGBA rgba;
260+};
261+
262+union Vector4u {
263+ struct Position {
144264 u32 x;
145265 u32 y;
146266 u32 z;
147267 u32 w;
148268 };
149- struct {
269+ struct RGBA {
150270 u32 r;
151271 u32 g;
152272 u32 b;
153273 u32 a;
154274 };
155-} Vector4u;
275+
276+ Position pos;
277+ RGBA rgba;
278+};
156279
157280 #endif
変更 main.cc
@@ -39,6 +39,7 @@
3939 #include <util/types.hh>
4040 #include <util/vector.hh>
4141 #include <util/sqlite.hh>
42+#include <util/structs.hh>
4243 #include <shader/shader.hh>
4344 #include <shader/buffers.hh>
4445 #include <database/setup.hh>
@@ -76,6 +77,8 @@
7677 window.MakeContextCurrent();
7778 glfw.SwapInterval(1);
7879
80+ GlfwInfo glfwInfo = { &glfw, &window };
81+
7982 #ifndef PRODUCTION_BUILD
8083 bool showDemo = true;
8184 #endif
@@ -132,7 +135,7 @@
132135 Program shaderProgram(vertexShader, fragmentShader);
133136
134137 // 頂点データはLuaから受け取る
135- lua::LuaEngine luaEngine(LUA.code, &shaderProgram, &cmd);
138+ lua::LuaEngine luaEngine(LUA.code, &shaderProgram, &glfwInfo, &cmd);
136139 auto &mesh = luaEngine.GetMesh();
137140
138141 VertexArrays VAO(1);
@@ -195,7 +198,7 @@
195198 EBO.BindBuffer();
196199 EBO.BufferData(
197200 newMesh.indices.data(),
198- newMesh.indices.size() * sizeof(f32)
201+ newMesh.indices.size() * sizeof(u32)
199202 );
200203
201204 for (const auto &a : newMesh.attr) {
@@ -32,25 +32,31 @@
3232 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
3333 OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3434 */
35-#include <lua/luaengine.hh>
3635 #include <glad/glad.h>
36+#include <lua/luaengine.hh>
3737 #include <shader/shader.hh>
3838 #include <glfw/glfw3.h>
39+#include <util/glfwpp.hh>
3940 #include <gui/consolelog.hh>
41+#include <util/vector.hh>
42+#include <util/random.hh>
4043
4144 namespace lua {
42- LuaEngine::LuaEngine(const string &code, Program *prog, gui::ConsoleLog *cmd)
45+ LuaEngine::LuaEngine(const string &code, Program *prog, GlfwInfo *glfwInfo, gui::ConsoleLog *cmd)
4346 : m_Code(code)
4447 , m_Program(prog)
48+ , m_GlfwInfo(glfwInfo)
4549 , m_Console(cmd)
4650 {
4751 m_Lua = MakeAPI();
52+ Execute(m_Lua);
4853 }
4954
5055 LuaEngine::~LuaEngine() {}
5156
5257 void LuaEngine::Reload(const string &code) {
5358 m_Code = code;
59+ m_Lua = MakeAPI();
5460 Execute(m_Lua);
5561 }
5662
@@ -76,7 +82,8 @@
7682 }
7783
7884 sol::state testApi = MakeAPI();
79- sol::protected_function_result resApi = testApi.safe_script(code);
85+ sol::load_result resApi = m_Lua.load(code);
86+ //sol::protected_function_result resApi = testApi.safe_script(code);
8087 if (!resApi.valid()) {
8188 sol::error err = resApi;
8289 LogError(err);
@@ -118,11 +125,203 @@
118125 sol::lib::string
119126 );
120127
128+ out.new_usertype<Vector2i>(
129+ "Vector2i",
130+ "x", sol::property(
131+ [](Vector2i &v) { return v.pos.x; },
132+ [](Vector2i &v, i32 val) { v.pos.x = val; }
133+ ),
134+ "y", sol::property(
135+ [](Vector2i &v) { return v.pos.y; },
136+ [](Vector2i &v, i32 val) { v.pos.y = val; }
137+ )
138+ );
139+
140+ out.new_usertype<Vector2u>(
141+ "Vector2u",
142+ "x", sol::property(
143+ [](Vector2u &v) { return v.pos.x; },
144+ [](Vector2u &v, u32 val) { v.pos.x = val; }
145+ ),
146+ "y", sol::property(
147+ [](Vector2u &v) { return v.pos.y; },
148+ [](Vector2u &v, u32 val) { v.pos.y = val; }
149+ )
150+ );
151+
152+ out.new_usertype<Vector2f>(
153+ "Vector2f",
154+ "x", sol::property(
155+ [](Vector2f &v) { return v.pos.x; },
156+ [](Vector2f &v, f32 val) { v.pos.x = val; }
157+ ),
158+ "y", sol::property(
159+ [](Vector2f &v) { return v.pos.y; },
160+ [](Vector2f &v, f32 val) { v.pos.y = val; }
161+ )
162+ );
163+
164+ out.new_usertype<Vector2d>(
165+ "Vector2d",
166+ "x", sol::property(
167+ [](Vector2d &v) { return v.pos.x; },
168+ [](Vector2d &v, i32 val) { v.pos.x = val; }
169+ ),
170+ "y", sol::property(
171+ [](Vector2d &v) { return v.pos.y; },
172+ [](Vector2d &v, f64 val) { v.pos.y = val; }
173+ )
174+ );
175+
176+ out.new_usertype<Vector3i>(
177+ "Vector3i",
178+ "x", sol::property(
179+ [](Vector3i &v) { return v.pos.x; },
180+ [](Vector3i &v, i32 val) { v.pos.x = val; }
181+ ),
182+ "y", sol::property(
183+ [](Vector3i &v) { return v.pos.y; },
184+ [](Vector3i &v, i32 val) { v.pos.y = val; }
185+ ),
186+ "z", sol::property(
187+ [](Vector3i &v) { return v.pos.z; },
188+ [](Vector3i &v, i32 val) { v.pos.z = val; }
189+ )
190+ );
191+
192+ out.new_usertype<Vector3u>(
193+ "Vector3u",
194+ "x", sol::property(
195+ [](Vector3u &v) { return v.pos.x; },
196+ [](Vector3u &v, u32 val) { v.pos.x = val; }
197+ ),
198+ "y", sol::property(
199+ [](Vector3u &v) { return v.pos.y; },
200+ [](Vector3u &v, u32 val) { v.pos.y = val; }
201+ ),
202+ "z", sol::property(
203+ [](Vector3u &v) { return v.pos.z; },
204+ [](Vector3u &v, u32 val) { v.pos.z = val; }
205+ )
206+ );
207+
208+ out.new_usertype<Vector3f>(
209+ "Vector3f",
210+ "x", sol::property(
211+ [](Vector3f &v) { return v.pos.x; },
212+ [](Vector3f &v, f32 val) { v.pos.x = val; }
213+ ),
214+ "y", sol::property(
215+ [](Vector3f &v) { return v.pos.y; },
216+ [](Vector3f &v, f32 val) { v.pos.y = val; }
217+ ),
218+ "z", sol::property(
219+ [](Vector3f &v) { return v.pos.z; },
220+ [](Vector3f &v, f32 val) { v.pos.z = val; }
221+ )
222+ );
223+
224+ out.new_usertype<Vector3d>(
225+ "Vector3d",
226+ "x", sol::property(
227+ [](Vector3d &v) { return v.pos.x; },
228+ [](Vector3d &v, i32 val) { v.pos.x = val; }
229+ ),
230+ "y", sol::property(
231+ [](Vector3d &v) { return v.pos.y; },
232+ [](Vector3d &v, f64 val) { v.pos.y = val; }
233+ ),
234+ "z", sol::property(
235+ [](Vector3d &v) { return v.pos.z; },
236+ [](Vector3d &v, f64 val) { v.pos.z = val; }
237+ )
238+ );
239+
240+ out.new_usertype<Vector4i>(
241+ "Vector4i",
242+ "x", sol::property(
243+ [](Vector4i &v) { return v.pos.x; },
244+ [](Vector4i &v, i32 val) { v.pos.x = val; }
245+ ),
246+ "y", sol::property(
247+ [](Vector4i &v) { return v.pos.y; },
248+ [](Vector4i &v, i32 val) { v.pos.y = val; }
249+ ),
250+ "z", sol::property(
251+ [](Vector4i &v) { return v.pos.z; },
252+ [](Vector4i &v, i32 val) { v.pos.z = val; }
253+ ),
254+ "w", sol::property(
255+ [](Vector4i &v) { return v.pos.w; },
256+ [](Vector4i &v, i32 val) { v.pos.w = val; }
257+ )
258+ );
259+
260+ out.new_usertype<Vector4u>(
261+ "Vector4u",
262+ "x", sol::property(
263+ [](Vector4u &v) { return v.pos.x; },
264+ [](Vector4u &v, u32 val) { v.pos.x = val; }
265+ ),
266+ "y", sol::property(
267+ [](Vector4u &v) { return v.pos.y; },
268+ [](Vector4u &v, u32 val) { v.pos.y = val; }
269+ ),
270+ "z", sol::property(
271+ [](Vector4u &v) { return v.pos.z; },
272+ [](Vector4u &v, u32 val) { v.pos.z = val; }
273+ ),
274+ "w", sol::property(
275+ [](Vector4u &v) { return v.pos.w; },
276+ [](Vector4u &v, u32 val) { v.pos.w = val; }
277+ )
278+ );
279+
280+ out.new_usertype<Vector4f>(
281+ "Vector4f",
282+ "x", sol::property(
283+ [](Vector4f &v) { return v.pos.x; },
284+ [](Vector4f &v, f32 val) { v.pos.x = val; }
285+ ),
286+ "y", sol::property(
287+ [](Vector4f &v) { return v.pos.y; },
288+ [](Vector4f &v, f32 val) { v.pos.y = val; }
289+ ),
290+ "z", sol::property(
291+ [](Vector4f &v) { return v.pos.z; },
292+ [](Vector4f &v, f32 val) { v.pos.z = val; }
293+ ),
294+ "w", sol::property(
295+ [](Vector4f &v) { return v.pos.w; },
296+ [](Vector4f &v, f32 val) { v.pos.w = val; }
297+ )
298+ );
299+
300+ out.new_usertype<Vector4d>(
301+ "Vector4d",
302+ "x", sol::property(
303+ [](Vector4d &v) { return v.pos.x; },
304+ [](Vector4d &v, i32 val) { v.pos.x = val; }
305+ ),
306+ "y", sol::property(
307+ [](Vector4d &v) { return v.pos.y; },
308+ [](Vector4d &v, f64 val) { v.pos.y = val; }
309+ ),
310+ "z", sol::property(
311+ [](Vector4d &v) { return v.pos.z; },
312+ [](Vector4d &v, f64 val) { v.pos.z = val; }
313+ ),
314+ "w", sol::property(
315+ [](Vector4d &v) { return v.pos.w; },
316+ [](Vector4d &v, f64 val) { v.pos.w = val; }
317+ )
318+ );
319+
121320 try {
122321 BindEngine(out);
123322 BindSystem(out);
323+ BindIO(out);
124324 BindGraphics(out);
125- Execute(out);
126325 } catch (const std::exception &e) {
127326 LogError(e);
128327 return {};
@@ -134,16 +333,122 @@
134333 void LuaEngine::BindEngine(sol::state &lua) {
135334 lua["le"] = lua.create_table();
136335 lua["le"]["api_version"] = m_ApiVersion;
336+
337+ lua["le"]["log"] = [&](sol::variadic_args va) {
338+ string out;
339+
340+ for (auto v : va) {
341+ if (v.is<string>())
342+ out += v.as<string>();
343+ else if (v.is<i32>())
344+ out += std::to_string(v.as<i32>());
345+ else if (v.is<f64>())
346+ out += std::to_string(v.as<f64>());
347+ else if (v.is<bool>())
348+ out += v.as<bool>() ? "true" : "false";
349+ else if (v.is<Vector2i>())
350+ out += "{" + std::to_string(v.as<Vector2i>().pos.x) + ", " + std::to_string(v.as<Vector2i>().pos.y) + "}";
351+ else if (v.is<Vector2u>())
352+ out += "{" + std::to_string(v.as<Vector2u>().pos.x) + ", " + std::to_string(v.as<Vector2u>().pos.y) + "}";
353+ else if (v.is<Vector2f>())
354+ out += "{" + std::to_string(v.as<Vector2f>().pos.x) + ", " + std::to_string(v.as<Vector2f>().pos.y) + "}";
355+ else if (v.is<Vector2d>())
356+ out += "{" + std::to_string(v.as<Vector2d>().pos.x) + ", " + std::to_string(v.as<Vector2d>().pos.y) + "}";
357+ else if (v.is<Vector3i>())
358+ out += "{" + std::to_string(v.as<Vector3i>().pos.x) + ", " + std::to_string(v.as<Vector3i>().pos.y) + ", " + std::to_string(v.as<Vector3i>().pos.z) + "}";
359+ else if (v.is<Vector3u>())
360+ out += "{" + std::to_string(v.as<Vector3u>().pos.x) + ", " + std::to_string(v.as<Vector3u>().pos.y) + ", " + std::to_string(v.as<Vector3u>().pos.z) + "}";
361+ else if (v.is<Vector3f>())
362+ out += "{" + std::to_string(v.as<Vector3f>().pos.x) + ", " + std::to_string(v.as<Vector3f>().pos.y) + ", " + std::to_string(v.as<Vector3f>().pos.z) + "}";
363+ else if (v.is<Vector3d>())
364+ out += "{" + std::to_string(v.as<Vector3d>().pos.x) + ", " + std::to_string(v.as<Vector3d>().pos.y) + ", " + std::to_string(v.as<Vector3d>().pos.z) + "}";
365+ else if (v.is<Vector4i>())
366+ out += "{" + std::to_string(v.as<Vector4i>().pos.x) + ", " + std::to_string(v.as<Vector4i>().pos.y) + ", " + std::to_string(v.as<Vector4i>().pos.z) + ", " + std::to_string(v.as<Vector4i>().pos.w) + "}";
367+ else if (v.is<Vector4u>())
368+ out += "{" + std::to_string(v.as<Vector4u>().pos.x) + ", " + std::to_string(v.as<Vector4u>().pos.y) + ", " + std::to_string(v.as<Vector4u>().pos.z) + ", " + std::to_string(v.as<Vector4u>().pos.w) + "}";
369+ else if (v.is<Vector4f>())
370+ out += "{" + std::to_string(v.as<Vector4f>().pos.x) + ", " + std::to_string(v.as<Vector4f>().pos.y) + ", " + std::to_string(v.as<Vector4f>().pos.z) + ", " + std::to_string(v.as<Vector4f>().pos.w) + "}";
371+ else if (v.is<Vector4d>())
372+ out += "{" + std::to_string(v.as<Vector4d>().pos.x) + ", " + std::to_string(v.as<Vector4d>().pos.y) + ", " + std::to_string(v.as<Vector4d>().pos.z) + ", " + std::to_string(v.as<Vector4d>().pos.w) + "}";
373+ else if (v.get_type() == sol::type::table) {
374+ sol::table t = v.as<sol::table>();
375+ out += "{";
376+
377+ bool first = true;
378+ for (auto &kv : t) {
379+ if (!first) out += ", ";
380+ first = false;
381+
382+ if (kv.second.is<i32>())
383+ out += std::to_string(kv.second.as<i32>());
384+ else if (kv.second.is<f64>())
385+ out += std::to_string(kv.second.as<f64>());
386+ else if (kv.second.is<string>())
387+ out += kv.second.as<string>();
388+ else
389+ out += "undefined";
390+ }
391+
392+ out += "}";
393+ }
394+ else
395+ out += "undefined";
396+
397+ out += " ";
398+ }
399+
400+ gui::LogEntry entry = {};
401+ entry.type = gui::LogType::Normal;
402+ entry.text = out;
403+ if (m_Console) m_Console->Add(entry);
404+ else std::cerr << entry.text << std::endl;
405+ };
137406 }
138407
139408 void LuaEngine::BindSystem(sol::state &lua) {
140409 lua["le"]["sys"] = lua.create_table();
141410
142411 lua["le"]["sys"]["get_time"] = [&]() -> f32 {
143- return (f32)glfwGetTime();
412+ return (f32)m_GlfwInfo->instance->GetTime();
144413 };
414+
415+ lua["le"]["sys"]["get_delta_time"] = [&]() -> f32 {
416+ f32 now = (f32)m_GlfwInfo->instance->GetTime();
417+ f32 delta = now - m_LastTime;
418+ m_LastTime = now;
419+ if (delta > 1.f / 5) delta = 1.f / 5;
420+ return delta;
421+ };
422+
423+ lua["le"]["sys"]["get_timer_frequency"] = [&]() -> u64 {
424+ return m_GlfwInfo->instance->GetTimerFrequency();
425+ };
426+
427+ lua["le"]["sys"]["get_resolution"] = [&]() -> Vector2i {
428+ Vector2i size = {};
429+ m_GlfwInfo->window->GetSize(&size.pos.x, &size.pos.y);
430+ return size;
431+ };
432+
433+ lua["le"]["sys"]["random"] = [&](i32 min, i32 max) -> i32 {
434+ return util::rand::GetRandom(min, max);
435+ };
145436 }
146437
438+ void LuaEngine::BindIO(sol::state &lua) {
439+ lua["le"]["io"] = lua.create_table();
440+
441+ lua["le"]["io"]["get_mouse"] = [&]() -> Vector2d {
442+ Vector2d cursor{};
443+ m_GlfwInfo->window->GetCursorPos(&cursor.pos.x, &cursor.pos.y);
444+ return cursor;
445+ };
446+
447+ lua["le"]["io"]["is_key_down"] = [&](int key) -> bool {
448+ return m_GlfwInfo->window->GetKey(key) == GLFW_PRESS;
449+ };
450+ }
451+
147452 void LuaEngine::BindGraphics(sol::state &lua) {
148453 lua["le"]["gfx"] = lua.create_table();
149454
@@ -180,9 +485,104 @@
180485 }
181486 };
182487
488+ lua["le"]["gfx"]["set_uniform1"] = [&](const string &name, f32 x) {
489+ if (!m_Program) return;
490+ glUniform1f(m_Program->GetUniformLocation(name), x);
491+ };
492+
493+ lua["le"]["gfx"]["set_uniform2"] = [&](const string &name, f32 x, f32 y) {
494+ if (!m_Program) return;
495+ glUniform2f(m_Program->GetUniformLocation(name), x, y);
496+ };
497+
183498 lua["le"]["gfx"]["set_uniform3"] = [&](const string &name, f32 x, f32 y, f32 z) {
184499 if (!m_Program) return;
185500 glUniform3f(m_Program->GetUniformLocation(name), x, y, z);
501+ };
502+
503+ lua["le"]["gfx"]["set_uniform4"] = [&](const string &name, f32 x, f32 y, f32 z, f32 w) {
504+ if (!m_Program) return;
505+ glUniform4f(m_Program->GetUniformLocation(name), x, y, z, w);
506+ };
507+
508+ lua["le"]["gfx"]["set_uniform_float1"] = [&](const string &name, f32 x) {
509+ if (!m_Program) return;
510+ glUniform1f(m_Program->GetUniformLocation(name), x);
511+ };
512+
513+ lua["le"]["gfx"]["set_uniform_float2"] = [&](const string &name, f32 x, f32 y) {
514+ if (!m_Program) return;
515+ glUniform2f(m_Program->GetUniformLocation(name), x, y);
516+ };
517+
518+ lua["le"]["gfx"]["set_uniform_float3"] = [&](const string &name, f32 x, f32 y, f32 z) {
519+ if (!m_Program) return;
520+ glUniform3f(m_Program->GetUniformLocation(name), x, y, z);
521+ };
522+
523+ lua["le"]["gfx"]["set_uniform_float4"] = [&](const string &name, f32 x, f32 y, f32 z, f32 w) {
524+ if (!m_Program) return;
525+ glUniform4f(m_Program->GetUniformLocation(name), x, y, z, w);
526+ };
527+
528+ lua["le"]["gfx"]["set_uniform_double1"] = [&](const string &name, f64 x) {
529+ if (!m_Program) return;
530+ glUniform1d(m_Program->GetUniformLocation(name), x);
531+ };
532+
533+ lua["le"]["gfx"]["set_uniform_double2"] = [&](const string &name, f64 x, f64 y) {
534+ if (!m_Program) return;
535+ glUniform2d(m_Program->GetUniformLocation(name), x, y);
536+ };
537+
538+ lua["le"]["gfx"]["set_uniform_double3"] = [&](const string &name, f64 x, f64 y, f64 z) {
539+ if (!m_Program) return;
540+ glUniform3d(m_Program->GetUniformLocation(name), x, y, z);
541+ };
542+
543+ lua["le"]["gfx"]["set_uniform_double4"] = [&](const string &name, f64 x, f64 y, f64 z, f64 w) {
544+ if (!m_Program) return;
545+ glUniform4d(m_Program->GetUniformLocation(name), x, y, z, w);
546+ };
547+
548+ lua["le"]["gfx"]["set_uniform_int1"] = [&](const string &name, i32 x) {
549+ if (!m_Program) return;
550+ glUniform1i(m_Program->GetUniformLocation(name), x);
551+ };
552+
553+ lua["le"]["gfx"]["set_uniform_int2"] = [&](const string &name, i32 x, i32 y) {
554+ if (!m_Program) return;
555+ glUniform2i(m_Program->GetUniformLocation(name), x, y);
556+ };
557+
558+ lua["le"]["gfx"]["set_uniform_int3"] = [&](const string &name, i32 x, i32 y, i32 z) {
559+ if (!m_Program) return;
560+ glUniform3i(m_Program->GetUniformLocation(name), x, y, z);
561+ };
562+
563+ lua["le"]["gfx"]["set_uniform_int4"] = [&](const string &name, i32 x, i32 y, i32 z, i32 w) {
564+ if (!m_Program) return;
565+ glUniform4i(m_Program->GetUniformLocation(name), x, y, z, w);
566+ };
567+
568+ lua["le"]["gfx"]["set_uniform_uint1"] = [&](const string &name, u32 x) {
569+ if (!m_Program) return;
570+ glUniform1ui(m_Program->GetUniformLocation(name), x);
571+ };
572+
573+ lua["le"]["gfx"]["set_uniform_uint2"] = [&](const string &name, u32 x, u32 y) {
574+ if (!m_Program) return;
575+ glUniform2ui(m_Program->GetUniformLocation(name), x, y);
576+ };
577+
578+ lua["le"]["gfx"]["set_uniform_uint3"] = [&](const string &name, u32 x, u32 y, u32 z) {
579+ if (!m_Program) return;
580+ glUniform3ui(m_Program->GetUniformLocation(name), x, y, z);
581+ };
582+
583+ lua["le"]["gfx"]["set_uniform_uint4"] = [&](const string &name, u32 x, u32 y, u32 z, u32 w) {
584+ if (!m_Program) return;
585+ glUniform4ui(m_Program->GetUniformLocation(name), x, y, z, w);
186586 };
187587 }
188588
@@ -157,6 +157,10 @@
157157 glfwSwapBuffers(m_Window);
158158 }
159159
160+ void Window::GetSize(int *w, int *h) {
161+ glfwGetWindowSize(m_Window, w, h);
162+ }
163+
160164 void Window::SetClipboardString(string str) {
161165 glfwSetClipboardString(m_Window, str.c_str());
162166 }
@@ -182,7 +186,7 @@
182186 }
183187
184188 int Window::RawMouseMotionSupported() {
185- return RawMouseMotionSupported();
189+ return glfwRawMouseMotionSupported();
186190 }
187191
188192 cstr Window::GetKeyName(int key, int scancode) {
@@ -0,0 +1,72 @@
1+/*
2+Copyright (c) テクニカル諏訪子
3+
4+Permission is hereby granted to any person obtaining a copy of the software
5+Shader Playground (the "Software") to use, modify, merge, copy, publish, distribute,
6+sublicense, and/or sell copies of the Software, subject to the following conditions:
7+
8+ 1. **Origin Attribution**:
9+ - You must not misrepresent the origin of the Software; you must not claim
10+ you created the original Software.
11+ - If the Software is used in a product, you must either:
12+ a. Provide clear attribution in the product's documentation, user interface,
13+ or other visible areas, **OR**
14+ b. Pay the original developers a fee they specify in writing.
15+ 2. **Usage Restriction**:
16+ - The Software, or any derivative works, dependencies, or libraries
17+ incorporating it, must not be used for censorship or to suppress freedom of
18+ speech, expression, or creativity. Prohibited uses include, but are not
19+ limited to:
20+ - Censorship of so-called "hate speech", visuals, non-mainstream opinions,
21+ ideas, or objective reality.
22+ - Tools or systems designed to restrict access to information or
23+ artistic works.
24+ 3. **Notice Preservation**:
25+ - This license and the above copyright notice must remain intact in all copies
26+ of the source code.
27+
28+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
29+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
30+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
31+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
32+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
33+OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34+*/
35+#include <util/random.hh>
36+#include <cmath>
37+
38+namespace util::rand {
39+ u32 randState[4];
40+ static inline u32 randLeftRot(const u32 x, i32 k) {
41+ return (x << k) | (x >> (32 - k));
42+ }
43+
44+ u32 randXoshiro128() {
45+ const u32 res = randLeftRot(randState[1] * 5, 7) * 9;
46+ const u32 t = randState[1] << 9;
47+
48+ randState[2] ^= randState[0];
49+ randState[3] ^= randState[1];
50+ randState[1] ^= randState[2];
51+ randState[0] ^= randState[3];
52+
53+ randState[2] ^= t;
54+ randState[3] = randLeftRot(randState[3], 11);
55+
56+ return res;
57+ }
58+
59+ i32 randGetValue(i32 min, i32 max) {
60+ return randXoshiro128() % (abs(max - min) + 1) + min;
61+ }
62+
63+ i32 GetRandom(i32 min, i32 max) {
64+ if (min > max) {
65+ i32 tmp = max;
66+ max = min;
67+ min = tmp;
68+ }
69+
70+ return randGetValue(min, max);
71+ }
72+} // namespace util::rand