複数メッシュを可能に

守矢諏訪子 <suwako@076.moe>、2026-06-27 21:49
コミット ab170ac879140f0611a00f0230374105bd0924c4 ・親 41e54a7 ・ファイルを見る

7個のファイル、+146 -65

@@ -38,6 +38,8 @@
3838
3939 #include <util/types.hh>
4040 #include <util/structs.hh>
41+#include <util/vector.hh>
42+#include <shader/buffers.hh>
4143 #define SOL_LUAJIT 1
4244 #define SOL_ALL_SAFETIES_ON 1
4345 #include <sol.hpp>
@@ -67,14 +69,21 @@
6769 }
6870 };
6971
72+ struct MeshObject {
73+ LuaMesh mesh;
74+ Vector3 position;
75+ Vector3 rotation;
76+ Vector3 scale;
77+ };
78+
7079 class LuaEngine {
7180 public:
7281 LuaEngine(const string &code, Program *prog, Info *info);
7382 ~LuaEngine();
7483
7584 public:
76- LuaMesh &GetMesh() { return m_Mesh; };
77- const LuaMesh &GetMesh() const { return m_Mesh; };
85+ vector<MeshObject> &GetObjects() { return m_Objects; }
86+ const vector<MeshObject> &GetObjects() const { return m_Objects; }
7887
7988 public:
8089 void Reload(const string &code);
@@ -101,7 +110,7 @@
101110 void Execute(sol::state &lua);
102111
103112 private:
104- LuaMesh m_Mesh;
113+ vector<MeshObject> m_Objects;
105114 sol::state m_Lua;
106115 string m_Code;
107116 bool m_IsInitialized = false;
@@ -39,6 +39,7 @@
3939 #include <util/glfwpp.hh>
4040 #include <util/types.hh>
4141 #include <util/vector.hh>
42+#include <util/matrix.hh>
4243 #include <util/sqlitepp.hh>
4344 #include <util/structs.hh>
4445 #include <util/random.hh>
@@ -64,6 +64,7 @@
6464 bool isNewShader = false;
6565
6666 bool showNewShaderPopup = false;
67+ bool pendingCompile = false;
6768
6869 std::string version = version::full;
6970 uint32_t shaderId = 0;
変更 main.cc
@@ -155,22 +155,27 @@
155155
156156 // 頂点データはLuaから受け取る
157157 lua::LuaEngine luaEngine(info.LUA.code, &shaderProgram, &info);
158- auto &mesh = luaEngine.GetMesh();
158+ info.pendingCompile = true;
159+ auto &objects = luaEngine.GetObjects();
159160
160161 VertexArrays VAO(1);
161162 Buffers VBO(Buffer, 1);
162163 Buffers EBO(ArrayBuffer, 1);
163164
164- VAO.BindVertexArray();
165- VBO.BindBuffer();
166- VBO.BufferData(mesh.vertices.data(), mesh.vertices.size() * sizeof(f32));
167- EBO.BindBuffer();
168- EBO.BufferData(mesh.indices.data(), mesh.indices.size() * sizeof(GLuint));
165+ for (auto &obj : objects) {
166+ VAO.BindVertexArray();
169167
170- // 頂点属性
171- for (const auto &a : mesh.attr) {
172- glVertexAttribPointer(a.location, a.size, GL_FLOAT, GL_FALSE, a.stride, (void *)(uintptr_t)a.offset);
173- glEnableVertexAttribArray(a.location);
168+ VBO.BindBuffer();
169+ VBO.BufferData(obj.mesh.vertices.data(), obj.mesh.vertices.size() * sizeof(f32));
170+
171+ EBO.BindBuffer();
172+ EBO.BufferData(obj.mesh.indices.data(), obj.mesh.indices.size() * sizeof(GLuint));
173+
174+ // 頂点属性
175+ for (const auto &a : obj.mesh.attr) {
176+ glVertexAttribPointer(a.location, a.size, GL_FLOAT, GL_FALSE, a.stride, (void *)(uintptr_t)a.offset);
177+ glEnableVertexAttribArray(a.location);
178+ }
174179 }
175180
176181 bool isHold = false;
@@ -181,6 +186,8 @@
181186 while (!window.ShouldClose() && info.isRunning) {
182187 #pragma region Lambda
183188 info.compile = [&]() {
189+ if (!info.pendingCompile) return;
190+ info.pendingCompile = false;
184191 if (luaEngine.GetInitializationState()) luaEngine.SetInitializationState(false);
185192 info.VERT.code = vertEditor.Get().GetText();
186193 info.FRAG.code = fragEditor.Get().GetText();
@@ -213,38 +220,40 @@
213220 luaEngine.SetProgram(&shaderProgram);
214221 luaEngine.Reload(info.LUA.code);
215222 {
216- lua::LuaMesh newMesh = luaEngine.GetMesh();
217- if (newMesh.vertices.empty() || newMesh.indices.empty()) {
218- string msg;
219- if (info.i18n->GetCurrentLanguage().code == "ja_JP") msg = "メッシュデータが空です。";
220- else "Mesh data is empty.";
221- throw std::runtime_error(msg);
222- }
223+ auto &newObj = luaEngine.GetObjects();
224+ for (auto &obj : newObj) {
225+ if (obj.mesh.vertices.empty() || obj.mesh.indices.empty()) {
226+ string msg;
227+ if (info.i18n->GetCurrentLanguage().code == "ja_JP") msg = "メッシュデータが空です。";
228+ else msg = "Mesh data is empty.";
229+ throw std::runtime_error(msg);
230+ }
223231
224- VAO.BindVertexArray();
232+ VAO.BindVertexArray();
225233
226- VBO.BindBuffer();
227- VBO.BufferData(
228- newMesh.vertices.data(),
229- newMesh.vertices.size() * sizeof(f32)
230- );
234+ VBO.BindBuffer();
235+ VBO.BufferData(
236+ obj.mesh.vertices.data(),
237+ obj.mesh.vertices.size() * sizeof(f32)
238+ );
231239
232- EBO.BindBuffer();
233- EBO.BufferData(
234- newMesh.indices.data(),
235- newMesh.indices.size() * sizeof(u32)
236- );
237-
238- for (const auto &a : newMesh.attr) {
239- glVertexAttribPointer(
240- a.location,
241- a.size,
242- GL_FLOAT,
243- GL_FALSE,
244- a.stride,
245- (any)(uintptr_t)a.offset
240+ EBO.BindBuffer();
241+ EBO.BufferData(
242+ obj.mesh.indices.data(),
243+ obj.mesh.indices.size() * sizeof(u32)
246244 );
247- glEnableVertexAttribArray(a.location);
245+
246+ for (const auto &a : obj.mesh.attr) {
247+ glVertexAttribPointer(
248+ a.location,
249+ a.size,
250+ GL_FLOAT,
251+ GL_FALSE,
252+ a.stride,
253+ (any)(uintptr_t)a.offset
254+ );
255+ glEnableVertexAttribArray(a.location);
256+ }
248257 }
249258 }
250259
@@ -346,7 +355,7 @@
346355 nTit = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")";
347356 luaEditor.SetTitle(nTit + "###LuaEditor");
348357
349- info.compile();
358+ info.pendingCompile = true;
350359
351360 gui::LogEntry entry;
352361 entry.type = gui::LogType::Info;
@@ -378,7 +387,7 @@
378387 nTit = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")";
379388 luaEditor.SetTitle(nTit + "###LuaEditor");
380389
381- info.compile();
390+ info.pendingCompile = true;
382391
383392 gui::LogEntry entry;
384393 entry.type = gui::LogType::Info;
@@ -419,7 +428,7 @@
419428
420429 if (!isHold) {
421430 if (isCompileKey) {
422- info.compile();
431+ info.pendingCompile = true;
423432 }
424433
425434 if (isNewKey) {
@@ -481,6 +490,7 @@
481490 }
482491
483492 info.create();
493+ info.compile();
484494
485495 #ifndef PRODUCTION_BUILD
486496 if (showDemo) ImGui::ShowDemoWindow(&showDemo);
@@ -509,9 +519,43 @@
509519 luaEngine.Init();
510520 luaEngine.Update();
511521
512- // クアッドを描画
513- VAO.BindVertexArray();
514- glDrawElements(GL_TRIANGLES, mesh.GetIndexCount(), GL_UNSIGNED_INT, nullptr);
522+ auto &objects = luaEngine.GetObjects();
523+ for (auto &obj : objects) {
524+ if (obj.mesh.vertices.empty()) continue;
525+ if (obj.mesh.indices.empty()) continue;
526+
527+ // モデルマトリックスの作成
528+ Matrix4 T = mat4Translate(
529+ obj.position.pos.x,
530+ obj.position.pos.y,
531+ obj.position.pos.z
532+ );
533+
534+ Matrix4 R = mat4Rotate(
535+ obj.rotation.pos.x,
536+ obj.rotation.pos.y,
537+ obj.rotation.pos.z
538+ );
539+
540+ Matrix4 S = mat4Scale(
541+ obj.scale.pos.x,
542+ obj.scale.pos.y,
543+ obj.scale.pos.z
544+ );
545+
546+ Matrix4 model = mat4Mul(T, mat4Mul(R, S));
547+
548+ glUniformMatrix4fv(shaderProgram.GetUniformLocation("uModel"), 1, GL_FALSE, model.m);
549+
550+ // 描画
551+ VAO.BindVertexArray();
552+ VBO.BindBuffer();
553+ VBO.BufferData(obj.mesh.vertices.data(), obj.mesh.vertices.size() * sizeof(f32));
554+ EBO.BindBuffer();
555+ EBO.BufferData(obj.mesh.indices.data(), obj.mesh.indices.size() * sizeof(GLuint));
556+
557+ glDrawElements(GL_TRIANGLES, obj.mesh.GetIndexCount(), GL_UNSIGNED_INT, nullptr);
558+ }
515559 glBindFramebuffer(GL_FRAMEBUFFER, 0);
516560
517561 // バッファをスワップし、イベントを処理
@@ -132,9 +132,10 @@
132132 } -- uv
133133 }
134134 }
135-
136-le.gfx.set_mesh(mesh)
137135
136+le.gfx.add_mesh(mesh)
137+le.gfx.set_position(0, 0, 0, 0)
138+
138139 function init()
139140 end
140141
@@ -211,22 +212,26 @@
211212 }
212213 }
213214
214-le.gfx.set_mesh(mesh)
215+le.gfx.add_mesh(mesh)
216+le.gfx.set_position(0, 0, 0, 1)
217+le.gfx.add_mesh(mesh)
218+le.gfx.set_position(1, -8, -2, -11)
219+le.gfx.add_mesh(mesh)
220+le.gfx.set_position(2, 8, -2, -11)
215221
216222 function init()
217223 end
218224
219225 function update()
220226 local t = le.sys.get_time()
227+
228+ le.gfx.set_rotation(0, t*0.7, t*1.0, t*0.4)
229+ le.gfx.set_rotation(1, t*0.2, t*0.8, t*1.4)
230+ le.gfx.set_rotation(2, t*0.2, t*0.8, t*1.4)
231+
221232 local reso = le.sys.get_resolution()
222233 local aspect = reso.x / reso.y
223234
224- local model = le.math.rotate(
225- t * 0.7,
226- t * 1.0,
227- t * 0.4
228- )
229-
230235 local view = le.math.look_at(
231236 0, 0, 4, -- eye
232237 0, 0, 0, -- target
@@ -240,7 +245,6 @@
240245 100.0
241246 )
242247
243- le.gfx.set_uniform_mat4("uModel", model)
244248 le.gfx.set_uniform_mat4("uView", view)
245249 le.gfx.set_uniform_mat4("uProjection", projection)
246250 end)";
@@ -59,6 +59,7 @@
5959
6060 void LuaEngine::Reload(const string &code) {
6161 m_Code = code;
62+ m_Objects.clear();
6263 m_Lua = MakeAPI();
6364 Execute(m_Lua);
6465 }
@@ -612,16 +613,19 @@
612613 void LuaEngine::BindGraphics(sol::state &lua) {
613614 lua["le"]["gfx"] = lua.create_table();
614615
615- lua["le"]["gfx"]["set_mesh"] = [&](sol::table t) {
616- m_Mesh.vertices.clear();
617- m_Mesh.indices.clear();
618- m_Mesh.attr.clear();
616+ lua["le"]["gfx"]["add_mesh"] = [&](sol::table t) {
617+ MeshObject obj{};
618+ obj.scale = { 1.f, 1.f, 1.f };
619619
620+ obj.mesh.vertices.clear();
621+ obj.mesh.indices.clear();
622+ obj.mesh.attr.clear();
623+
620624 sol::table verts = t["vertices"];
621- for (auto &v : verts) m_Mesh.vertices.push_back(v.second.as<f32>());
625+ for (auto &v : verts) obj.mesh.vertices.push_back(v.second.as<f32>());
622626
623627 sol::table inds = t["indices"];
624- for (auto &i : inds) m_Mesh.indices.push_back(i.second.as<u32>());
628+ for (auto &i : inds) obj.mesh.indices.push_back(i.second.as<u32>());
625629
626630 sol::table attrs = t["attributes"];
627631 for (auto &k : attrs) {
@@ -636,13 +640,30 @@
636640 throw std::runtime_error("メッシュアトリビュートが不正です。");
637641 }
638642
639- m_Mesh.attr.push_back({
643+ obj.mesh.attr.push_back({
640644 a["location"],
641645 a["size"],
642646 a["stride"],
643647 a["offset"],
644648 });
645649 }
650+
651+ m_Objects.push_back(obj);
652+ };
653+
654+ lua["le"]["gfx"]["set_position"] = [&](i32 index, f32 x, f32 y, f32 z) {
655+ if (index < 0 || index >= m_Objects.size()) return;
656+ m_Objects[index].position = { x, y, z };
657+ };
658+
659+ lua["le"]["gfx"]["set_rotation"] = [&](i32 index, f32 x, f32 y, f32 z) {
660+ if (index < 0 || index >= m_Objects.size()) return;
661+ m_Objects[index].rotation = { x, y, z };
662+ };
663+
664+ lua["le"]["gfx"]["set_scale"] = [&](i32 index, f32 x, f32 y, f32 z) {
665+ if (index < 0 || index >= m_Objects.size()) return;
666+ m_Objects[index].scale = { x, y, z };
646667 };
647668
648669 lua["le"]["gfx"]["set_uniform1"] = [&](const string &name, f32 x) {
@@ -152,7 +152,8 @@
152152 }
153153 }
154154
155-le.gfx.set_mesh(mesh)
155+le.gfx.add_mesh(mesh)
156+le.gfx.set_position(0, 0, 0, 0)
156157
157158 function init()
158159 le.log("screen res: ", le.sys.get_resolution())