Luaコードからプログラミング可能に
守矢諏訪子 <suwako@076.moe>、2026-06-25 03:33
コミット e2e8dd050684e1be1d15feb8c92771d009212ef3
・親 f8b12a7
・ファイルを見る
4個のファイル、+72 -43
| @@ -39,6 +39,8 @@ | ||
| 39 | 39 | #define SOL_ALL_SAFETIES_ON 1 |
| 40 | 40 | #include <sol.hpp> |
| 41 | 41 | |
| 42 | +struct Program; | |
| 43 | + | |
| 42 | 44 | namespace lua { |
| 43 | 45 | struct LuaMesh { |
| 44 | 46 | vector<f32> vertices; |
| @@ -56,19 +58,23 @@ | ||
| 56 | 58 | |
| 57 | 59 | class LuaEngine { |
| 58 | 60 | public: |
| 59 | - LuaEngine(const string &code); | |
| 61 | + LuaEngine(const string &code, Program *prog); | |
| 60 | 62 | ~LuaEngine(); |
| 61 | 63 | |
| 62 | 64 | LuaMesh &GetMesh() { return m_Mesh; }; |
| 63 | 65 | const LuaMesh &GetMesh() const { return m_Mesh; }; |
| 64 | 66 | void Reload(const string &code); |
| 67 | + void Update(); | |
| 68 | + void SetProgram(Program *prog); | |
| 65 | 69 | |
| 66 | 70 | private: |
| 67 | 71 | void BindGraphics(); |
| 68 | 72 | void Execute(); |
| 69 | 73 | |
| 74 | + private: | |
| 70 | 75 | LuaMesh m_Mesh; |
| 71 | 76 | sol::state m_Lua; |
| 72 | 77 | string m_Code; |
| 78 | + Program *m_Program = nullptr; | |
| 73 | 79 | }; |
| 74 | 80 | } // namespace lua |
変更
main.cc
| @@ -128,7 +128,7 @@ | ||
| 128 | 128 | Program shaderProgram(vertexShader, fragmentShader); |
| 129 | 129 | |
| 130 | 130 | // 頂点データはLuaから受け取る |
| 131 | - lua::LuaEngine luaEngine(LUA); | |
| 131 | + lua::LuaEngine luaEngine(LUA, &shaderProgram); | |
| 132 | 132 | auto &mesh = luaEngine.GetMesh(); |
| 133 | 133 | |
| 134 | 134 | VertexArrays VAO(1); |
| @@ -178,6 +178,7 @@ | ||
| 178 | 178 | |
| 179 | 179 | try { |
| 180 | 180 | shaderProgram.Reload(VERT, FRAG); |
| 181 | + luaEngine.SetProgram(&shaderProgram); | |
| 181 | 182 | luaEngine.Reload(LUA); |
| 182 | 183 | { |
| 183 | 184 | lua::LuaMesh newMesh = luaEngine.GetMesh(); |
| @@ -237,34 +238,7 @@ | ||
| 237 | 238 | |
| 238 | 239 | // シェーダープログラムを使用 |
| 239 | 240 | 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(); | |
| 268 | 242 | |
| 269 | 243 | // クアッドを描画 |
| 270 | 244 | VAO.BindVertexArray(); |
| @@ -33,10 +33,14 @@ | ||
| 33 | 33 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 34 | 34 | */ |
| 35 | 35 | #include <lua/luaengine.hh> |
| 36 | -//#include <utility> | |
| 36 | +#include <glad/glad.h> | |
| 37 | +#include <shader/shader.hh> | |
| 38 | +#include <glfw/glfw3.h> | |
| 37 | 39 | |
| 38 | 40 | 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) { | |
| 40 | 44 | m_Lua.open_libraries( |
| 41 | 45 | sol::lib::base, |
| 42 | 46 | sol::lib::math, |
| @@ -57,6 +61,21 @@ | ||
| 57 | 61 | Execute(); |
| 58 | 62 | } |
| 59 | 63 | |
| 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 | + | |
| 60 | 79 | void LuaEngine::BindGraphics() { |
| 61 | 80 | m_Lua["graphics"] = m_Lua.create_table(); |
| 62 | 81 | |
| @@ -82,6 +101,15 @@ | ||
| 82 | 101 | a["offset"], |
| 83 | 102 | }); |
| 84 | 103 | } |
| 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); | |
| 85 | 113 | }; |
| 86 | 114 | } |
| 87 | 115 |
| @@ -102,8 +102,7 @@ | ||
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | string GetDefaultVertexShader() { |
| 105 | - return R"( | |
| 106 | -#version 460 core | |
| 105 | + return R"(#version 460 core | |
| 107 | 106 | |
| 108 | 107 | layout(location = 0) in vec2 aPosition; |
| 109 | 108 | layout(location = 1) in vec2 aUv; |
| @@ -112,13 +111,11 @@ | ||
| 112 | 111 | void main() { |
| 113 | 112 | vUv = aUv; |
| 114 | 113 | gl_Position = vec4(aPosition, 0.0, 1.0); |
| 114 | +})"; | |
| 115 | 115 | } |
| 116 | -)"; | |
| 117 | -} | |
| 118 | 116 | |
| 119 | 117 | string GetDefaultFragmentShader() { |
| 120 | - return R"( | |
| 121 | -#version 460 core | |
| 118 | + return R"(#version 460 core | |
| 122 | 119 | |
| 123 | 120 | in vec2 vUv; |
| 124 | 121 | out vec4 out_color; |
| @@ -131,13 +128,11 @@ | ||
| 131 | 128 | vec3 temp = mix(uColorA, uColorB, vUv.x); |
| 132 | 129 | vec3 blendedColor = mix(temp, uColorC, vUv.y * 0.95); |
| 133 | 130 | out_color = vec4(blendedColor, 1.0); |
| 131 | +})"; | |
| 134 | 132 | } |
| 135 | -)"; | |
| 136 | -} | |
| 137 | 133 | |
| 138 | 134 | string GetDefaultLuaCode() { |
| 139 | - return R"( | |
| 140 | -local mesh = { | |
| 135 | + return R"(local mesh = { | |
| 141 | 136 | vertices = { |
| 142 | 137 | -1, -1, 0, 0, |
| 143 | 138 | 1, -1, 1, 0, |
| @@ -156,5 +151,31 @@ | ||
| 156 | 151 | } |
| 157 | 152 | |
| 158 | 153 | 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)"; | |
| 160 | 181 | } |