Luaコードからプログラミング可能に

守矢諏訪子 <suwako@076.moe>、2026-06-25 03:33
コミット e2e8dd050684e1be1d15feb8c92771d009212ef3 ・親 f8b12a7 ・ファイルを見る

4個のファイル、+72 -43

@@ -39,6 +39,8 @@
3939 #define SOL_ALL_SAFETIES_ON 1
4040 #include <sol.hpp>
4141
42+struct Program;
43+
4244 namespace lua {
4345 struct LuaMesh {
4446 vector<f32> vertices;
@@ -56,19 +58,23 @@
5658
5759 class LuaEngine {
5860 public:
59- LuaEngine(const string &code);
61+ LuaEngine(const string &code, Program *prog);
6062 ~LuaEngine();
6163
6264 LuaMesh &GetMesh() { return m_Mesh; };
6365 const LuaMesh &GetMesh() const { return m_Mesh; };
6466 void Reload(const string &code);
67+ void Update();
68+ void SetProgram(Program *prog);
6569
6670 private:
6771 void BindGraphics();
6872 void Execute();
6973
74+ private:
7075 LuaMesh m_Mesh;
7176 sol::state m_Lua;
7277 string m_Code;
78+ Program *m_Program = nullptr;
7379 };
7480 } // namespace lua
変更 main.cc
@@ -128,7 +128,7 @@
128128 Program shaderProgram(vertexShader, fragmentShader);
129129
130130 // 頂点データはLuaから受け取る
131- lua::LuaEngine luaEngine(LUA);
131+ lua::LuaEngine luaEngine(LUA, &shaderProgram);
132132 auto &mesh = luaEngine.GetMesh();
133133
134134 VertexArrays VAO(1);
@@ -178,6 +178,7 @@
178178
179179 try {
180180 shaderProgram.Reload(VERT, FRAG);
181+ luaEngine.SetProgram(&shaderProgram);
181182 luaEngine.Reload(LUA);
182183 {
183184 lua::LuaMesh newMesh = luaEngine.GetMesh();
@@ -237,34 +238,7 @@
237238
238239 // シェーダープログラムを使用
239240 shaderProgram.Use();
240-
241- // 時間に基づいて色をアニメーション
242- f32 time = (f32)glfw.GetTime();
243- f32 speed = 1.0f; // アニメーションの速度
244- f32 phase = 2.0f * 3.14159f / 3.0f; // // 120度の位相差(3色用)
245-
246- // uColorA: 赤 -> 緑 -> 青
247- Vector3 colorA;
248- colorA.r = sin(time * speed + 0.0f) * 0.5f + 0.5f; // 0.0 to 1.0
249- colorA.g = sin(time * speed + phase) * 0.5f + 0.5f;
250- colorA.b = sin(time * speed + 2.0f * phase) * 0.5f + 0.5f;
251-
252- // uColorB: 緑 -> 青 -> 赤
253- Vector3 colorB;
254- colorB.r = sin(time * speed + 2.0f * phase) * 0.5f + 0.5f;
255- colorB.g = sin(time * speed + 0.0f) * 0.5f + 0.5f;
256- colorB.b = sin(time * speed + phase) * 0.5f + 0.5f;
257-
258- // uColorC: 青 -> 赤 -> 緑
259- Vector3 colorC;
260- colorC.r = sin(time * speed + phase) * 0.5f + 0.5f;
261- colorC.g = sin(time * speed + 2.0f * phase) * 0.5f + 0.5f;
262- colorC.b = sin(time * speed + 0.0f) * 0.5f + 0.5f;
263-
264- // ユニフォームを設定
265- glUniform3f(shaderProgram.GetUniformLocation("uColorA"), colorA.r, colorA.g, colorA.b); // 赤
266- glUniform3f(shaderProgram.GetUniformLocation("uColorB"), colorB.r, colorB.g, colorB.b); // 緑
267- glUniform3f(shaderProgram.GetUniformLocation("uColorC"), colorC.r, colorC.g, colorC.b); // 青
241+ luaEngine.Update();
268242
269243 // クアッドを描画
270244 VAO.BindVertexArray();
@@ -33,10 +33,14 @@
3333 OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3434 */
3535 #include <lua/luaengine.hh>
36-//#include <utility>
36+#include <glad/glad.h>
37+#include <shader/shader.hh>
38+#include <glfw/glfw3.h>
3739
3840 namespace lua {
39- LuaEngine::LuaEngine(const string &code) : m_Code(code) {
41+ LuaEngine::LuaEngine(const string &code, Program *prog)
42+ : m_Code(code)
43+ , m_Program(prog) {
4044 m_Lua.open_libraries(
4145 sol::lib::base,
4246 sol::lib::math,
@@ -57,6 +61,21 @@
5761 Execute();
5862 }
5963
64+ void LuaEngine::Update() {
65+ sol::function update = m_Lua["update"];
66+ if (update.valid()) {
67+ sol::protected_function_result res = update();
68+
69+ if (!res.valid()) {
70+ sol::error err = res;
71+ std::cerr << err.what() << std::endl;
72+ }
73+ }
74+ }
75+
76+ void LuaEngine::SetProgram(Program *prog) {
77+ }
78+
6079 void LuaEngine::BindGraphics() {
6180 m_Lua["graphics"] = m_Lua.create_table();
6281
@@ -82,6 +101,15 @@
82101 a["offset"],
83102 });
84103 }
104+ };
105+
106+ m_Lua["graphics"]["get_time"] = [&]() -> f32 {
107+ return (f32)glfwGetTime();
108+ };
109+
110+ m_Lua["graphics"]["set_uniform3"] = [&](const string &name, f32 x, f32 y, f32 z) {
111+ if (!m_Program) return;
112+ glUniform3f(m_Program->GetUniformLocation(name), x, y, z);
85113 };
86114 }
87115
@@ -102,8 +102,7 @@
102102 }
103103
104104 string GetDefaultVertexShader() {
105- return R"(
106-#version 460 core
105+ return R"(#version 460 core
107106
108107 layout(location = 0) in vec2 aPosition;
109108 layout(location = 1) in vec2 aUv;
@@ -112,13 +111,11 @@
112111 void main() {
113112 vUv = aUv;
114113 gl_Position = vec4(aPosition, 0.0, 1.0);
114+})";
115115 }
116-)";
117-}
118116
119117 string GetDefaultFragmentShader() {
120- return R"(
121-#version 460 core
118+ return R"(#version 460 core
122119
123120 in vec2 vUv;
124121 out vec4 out_color;
@@ -131,13 +128,11 @@
131128 vec3 temp = mix(uColorA, uColorB, vUv.x);
132129 vec3 blendedColor = mix(temp, uColorC, vUv.y * 0.95);
133130 out_color = vec4(blendedColor, 1.0);
131+})";
134132 }
135-)";
136-}
137133
138134 string GetDefaultLuaCode() {
139- return R"(
140-local mesh = {
135+ return R"(local mesh = {
141136 vertices = {
142137 -1, -1, 0, 0,
143138 1, -1, 1, 0,
@@ -156,5 +151,31 @@
156151 }
157152
158153 graphics.set_mesh(mesh)
159-)";
154+
155+function update()
156+ local t = graphics.get_time() -- glfwGetTime()
157+ local speed = 1.0 -- animation speed
158+ local phase = math.pi * 2.0 / 3.0 -- 120 deg phase diff (3 color)
159+
160+ graphics.set_uniform3(
161+ "uColorA",
162+ math.sin(t * speed + 0.0) * 0.5 + 0.5,
163+ math.sin(t * speed + phase) * 0.5 + 0.5,
164+ math.sin(t * speed + phase * 2.0) * 0.5 + 0.5
165+ )
166+
167+ graphics.set_uniform3(
168+ "uColorB",
169+ math.sin(t * speed + phase * 2.0) * 0.5 + 0.5,
170+ math.sin(t * speed + 0.0) * 0.5 + 0.5,
171+ math.sin(t * speed + phase) * 0.5 + 0.5
172+ )
173+
174+ graphics.set_uniform3(
175+ "uColorC",
176+ math.sin(t * speed + phase) * 0.5 + 0.5,
177+ math.sin(t * speed + phase * 2.0) * 0.5 + 0.5,
178+ math.sin(t * speed + phase + 0.0) * 0.5 + 0.5
179+ )
180+end)";
160181 }