Luaエンジンに算数ライブラリの追加、マトリックスライブラリ、そして3Dシェーダー
守矢諏訪子 <suwako@076.moe>、2026-06-27 06:30
コミット 41e54a766d031765ef525d2e4766a6d6d7fe9478
・親 d49c308
・ファイルを見る
10個のファイル、+728 -65
| @@ -45,12 +45,17 @@ | ||
| 45 | 45 | NewShader(Info *info); |
| 46 | 46 | ~NewShader(); |
| 47 | 47 | |
| 48 | - db::ShaderData Make(); | |
| 48 | + void DrawPopup(); | |
| 49 | + db::ShaderData Make(bool is3D = false); | |
| 49 | 50 | |
| 50 | 51 | private: |
| 51 | - string getDefaultVert(); | |
| 52 | - string getDefaultFrag(); | |
| 53 | - string getDefaultLua(); | |
| 52 | + string getDefaultVert2D(); | |
| 53 | + string getDefaultFrag2D(); | |
| 54 | + string getDefaultLua2D(); | |
| 55 | + | |
| 56 | + string getDefaultVert3D(); | |
| 57 | + string getDefaultFrag3D(); | |
| 58 | + string getDefaultLua3D(); | |
| 54 | 59 | |
| 55 | 60 | private: |
| 56 | 61 | Info *m_Info; |
| @@ -61,6 +61,10 @@ | ||
| 61 | 61 | }; |
| 62 | 62 | |
| 63 | 63 | std::vector<Attribute> attr; |
| 64 | + | |
| 65 | + GLsizei GetIndexCount() const { | |
| 66 | + return static_cast<GLsizei>(indices.size()); | |
| 67 | + } | |
| 64 | 68 | }; |
| 65 | 69 | |
| 66 | 70 | class LuaEngine { |
| @@ -87,10 +91,12 @@ | ||
| 87 | 91 | private: |
| 88 | 92 | void LogError(sol::error err); |
| 89 | 93 | void LogError(const std::exception &err); |
| 94 | + void LogError(const string &err); | |
| 90 | 95 | sol::state MakeAPI(); |
| 91 | 96 | void BindEngine(sol::state &lua); |
| 92 | 97 | void BindSystem(sol::state &lua); |
| 93 | 98 | void BindIO(sol::state &lua); |
| 99 | + void BindMath(sol::state &lua); | |
| 94 | 100 | void BindGraphics(sol::state &lua); |
| 95 | 101 | void Execute(sol::state &lua); |
| 96 | 102 |
| @@ -0,0 +1,212 @@ | ||
| 1 | +/* | |
| 2 | +# 076 Free License | |
| 3 | + | |
| 4 | +Copyright (c) テクニカル諏訪子 | |
| 5 | + | |
| 6 | +Permission is hereby granted to any person obtaining a copy of the software | |
| 7 | +C++ Utils (the "Software") to use, modify, merge, copy, publish, distribute, | |
| 8 | +sublicense, and/or sell copies of the Software, subject to the following conditions: | |
| 9 | + | |
| 10 | + 1. **Origin Attribution**: | |
| 11 | + - You must not misrepresent the origin of the Software; you must not claim | |
| 12 | + you created the original Software. | |
| 13 | + 2. **Notice Preservation**: | |
| 14 | + - This license and the above copyright notice must remain intact in all copies | |
| 15 | + of the source code. | |
| 16 | + | |
| 17 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |
| 18 | +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |
| 19 | +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
| 20 | +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
| 21 | +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |
| 22 | +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 23 | +*/ | |
| 24 | +#ifndef MATRIX_HH | |
| 25 | +#define MATRIX_HH | |
| 26 | + | |
| 27 | +#include <util/types.hh> | |
| 28 | +#include <util/vector.hh> | |
| 29 | + | |
| 30 | +typedef struct { | |
| 31 | + f32 m[16]; | |
| 32 | +} Matrix4; | |
| 33 | + | |
| 34 | +typedef struct { | |
| 35 | + f32 m[16]; | |
| 36 | +} Matrix4x4; | |
| 37 | + | |
| 38 | +typedef struct { | |
| 39 | + f32 m[12]; | |
| 40 | +} Matrix4x3; | |
| 41 | + | |
| 42 | +inline Matrix4 operator*(const Matrix4 &a, const Matrix4 &b) { | |
| 43 | + Matrix4 out = {}; | |
| 44 | + | |
| 45 | + for (int i = 0; i < 4; ++i) { | |
| 46 | + for (int j = 0; j < 4; ++j) { | |
| 47 | + float sum = 0.0f; | |
| 48 | + for (int k = 0; k < 4; ++k) { | |
| 49 | + sum += a.m[i + k * 4] * b.m[k + j * 4]; | |
| 50 | + } | |
| 51 | + out.m[i + j * 4] = sum; | |
| 52 | + } | |
| 53 | + } | |
| 54 | + return out; | |
| 55 | +} | |
| 56 | + | |
| 57 | +inline Matrix4 &operator*=(Matrix4 &a, const Matrix4 &b) { | |
| 58 | + a = a * b; | |
| 59 | + return a; | |
| 60 | +} | |
| 61 | + | |
| 62 | +inline Matrix4 mat4Identity() { | |
| 63 | + Matrix4 out{}; | |
| 64 | + | |
| 65 | + out.m[0] = 1.f; | |
| 66 | + out.m[5] = 1.f; | |
| 67 | + out.m[10] = 1.f; | |
| 68 | + out.m[15] = 1.f; | |
| 69 | + | |
| 70 | + return out; | |
| 71 | +} | |
| 72 | + | |
| 73 | +inline Matrix4x4 mat4x4Identity() { | |
| 74 | + Matrix4x4 out{}; | |
| 75 | + | |
| 76 | + out.m[0] = 1.f; | |
| 77 | + out.m[5] = 1.f; | |
| 78 | + out.m[10] = 1.f; | |
| 79 | + out.m[15] = 1.f; | |
| 80 | + | |
| 81 | + return out; | |
| 82 | +} | |
| 83 | + | |
| 84 | +inline Matrix4 mat4Mul(const Matrix4 &a, const Matrix4 &b) { | |
| 85 | + Matrix4 out{}; | |
| 86 | + | |
| 87 | + for (int row = 0; row < 4; ++row) { | |
| 88 | + for (int col = 0; col < 4; ++col) { | |
| 89 | + out.m[col * 4 + row] = | |
| 90 | + a.m[0 * 4 + row] * b.m[col * 4 + 0] + | |
| 91 | + a.m[1 * 4 + row] * b.m[col * 4 + 1] + | |
| 92 | + a.m[2 * 4 + row] * b.m[col * 4 + 2] + | |
| 93 | + a.m[3 * 4 + row] * b.m[col * 4 + 3]; | |
| 94 | + } | |
| 95 | + } | |
| 96 | + | |
| 97 | + return out; | |
| 98 | +} | |
| 99 | + | |
| 100 | +inline Matrix4 mat4Translate(f32 x, f32 y, f32 z) { | |
| 101 | + Matrix4 out = mat4Identity(); | |
| 102 | + | |
| 103 | + out.m[12] = x; | |
| 104 | + out.m[13] = y; | |
| 105 | + out.m[14] = z; | |
| 106 | + | |
| 107 | + return out; | |
| 108 | +} | |
| 109 | + | |
| 110 | +inline Matrix4 mat4Scale(f32 x, f32 y, f32 z) { | |
| 111 | + Matrix4 out = {}; | |
| 112 | + | |
| 113 | + out.m[0] = x; | |
| 114 | + out.m[5] = y; | |
| 115 | + out.m[10] = z; | |
| 116 | + out.m[15] = 1.f; | |
| 117 | + | |
| 118 | + return out; | |
| 119 | +} | |
| 120 | + | |
| 121 | +inline Matrix4 mat4RotateX(f32 angle) { | |
| 122 | + Matrix4 out = mat4Identity(); | |
| 123 | + | |
| 124 | + f32 c = cosf(angle); | |
| 125 | + f32 s = sinf(angle); | |
| 126 | + | |
| 127 | + out.m[5] = c; // m[1][1] | |
| 128 | + out.m[6] = s; // m[1][2] | |
| 129 | + out.m[9] = -s; // m[2][1] | |
| 130 | + out.m[10] = c; // m[2][2] | |
| 131 | + | |
| 132 | + return out; | |
| 133 | +} | |
| 134 | + | |
| 135 | +inline Matrix4 mat4RotateY(f32 angle) { | |
| 136 | + Matrix4 out = mat4Identity(); | |
| 137 | + | |
| 138 | + f32 c = cosf(angle); | |
| 139 | + f32 s = sinf(angle); | |
| 140 | + | |
| 141 | + out.m[0] = c; // m[0][0] | |
| 142 | + out.m[2] = -s; // m[0][2] | |
| 143 | + out.m[8] = s; // m[2][0] | |
| 144 | + out.m[10] = c; // m[2][2] | |
| 145 | + | |
| 146 | + return out; | |
| 147 | +} | |
| 148 | + | |
| 149 | +inline Matrix4 mat4RotateZ(f32 angle) { | |
| 150 | + Matrix4 out = mat4Identity(); | |
| 151 | + | |
| 152 | + f32 c = cosf(angle); | |
| 153 | + f32 s = sinf(angle); | |
| 154 | + | |
| 155 | + out.m[0] = c; // m[0][0] | |
| 156 | + out.m[1] = s; // m[0][1] | |
| 157 | + out.m[4] = -s; // m[1][0] | |
| 158 | + out.m[5] = c; // m[1][1] | |
| 159 | + | |
| 160 | + return out; | |
| 161 | +} | |
| 162 | + | |
| 163 | +inline Matrix4 mat4Rotate(f32 pitch, f32 yaw, f32 roll) { | |
| 164 | + return mat4RotateZ(roll) * mat4RotateY(yaw) * mat4RotateX(pitch); | |
| 165 | +} | |
| 166 | + | |
| 167 | +inline Matrix4 mat4Perspective(f32 fov, f32 aspect, f32 near, f32 far) { | |
| 168 | + Matrix4 out = {}; | |
| 169 | + fov *= (3.14159265f / 180.f); | |
| 170 | + | |
| 171 | + f32 tanHalf = tanf(fov * 0.5f); | |
| 172 | + | |
| 173 | + out.m[0] = 1.f / (aspect * tanHalf); | |
| 174 | + out.m[5] = 1.f / tanHalf; | |
| 175 | + out.m[10] = -(far + near) / (far - near); | |
| 176 | + out.m[11] = -1.f; | |
| 177 | + out.m[14] = -(2.f * far * near) / (far - near); | |
| 178 | + | |
| 179 | + return out; | |
| 180 | +} | |
| 181 | + | |
| 182 | +inline Matrix4 mat4LookAt(Vector3 eye, Vector3 target, Vector3 up) { | |
| 183 | + Vector3 f = vec3Normalize(vec3Sub(target, eye)); | |
| 184 | + Vector3 r = vec3Normalize(vec3Cross(f, up)); | |
| 185 | + Vector3 u = vec3Cross(r, f); | |
| 186 | + | |
| 187 | + Matrix4 out = {}; | |
| 188 | + | |
| 189 | + out.m[0] = r.pos.x; | |
| 190 | + out.m[1] = u.pos.x; | |
| 191 | + out.m[2] = -f.pos.x; | |
| 192 | + out.m[3] = 0.f; | |
| 193 | + | |
| 194 | + out.m[4] = r.pos.y; | |
| 195 | + out.m[5] = u.pos.y; | |
| 196 | + out.m[6] = -f.pos.y; | |
| 197 | + out.m[7] = 0.f; | |
| 198 | + | |
| 199 | + out.m[8] = r.pos.z; | |
| 200 | + out.m[9] = u.pos.z; | |
| 201 | + out.m[10] = -f.pos.z; | |
| 202 | + out.m[11] = 0.f; | |
| 203 | + | |
| 204 | + out.m[12] = -vec3Dot(r, eye); | |
| 205 | + out.m[13] = -vec3Dot(u, eye); | |
| 206 | + out.m[14] = vec3Dot(f, eye); | |
| 207 | + out.m[15] = 1.f; | |
| 208 | + | |
| 209 | + return out; | |
| 210 | +} | |
| 211 | + | |
| 212 | +#endif // MATRIX_HH |
| @@ -63,6 +63,8 @@ | ||
| 63 | 63 | bool isLangChange = false; |
| 64 | 64 | bool isNewShader = false; |
| 65 | 65 | |
| 66 | + bool showNewShaderPopup = false; | |
| 67 | + | |
| 66 | 68 | std::string version = version::full; |
| 67 | 69 | uint32_t shaderId = 0; |
| 68 | 70 | std::string shaderName = ""; |
| @@ -24,7 +24,7 @@ | ||
| 24 | 24 | #ifndef VECTOR_HH |
| 25 | 25 | #define VECTOR_HH |
| 26 | 26 | |
| 27 | -#include "types.hh" | |
| 27 | +#include <util/types.hh> | |
| 28 | 28 | |
| 29 | 29 | union Vector2 { |
| 30 | 30 | struct Position { |
| @@ -265,5 +265,27 @@ | ||
| 265 | 265 | Position pos; |
| 266 | 266 | RGBA rgba; |
| 267 | 267 | }; |
| 268 | + | |
| 269 | +inline Vector3 vec3Sub(Vector3 a, Vector3 b) { | |
| 270 | + return { a.pos.x - b.pos.x, a.pos.y - b.pos.y, a.pos.z - b.pos.z }; | |
| 271 | +} | |
| 272 | + | |
| 273 | +inline f32 vec3Dot(Vector3 a, Vector3 b) { | |
| 274 | + return a.pos.x * b.pos.x + a.pos.y * b.pos.y + a.pos.z * b.pos.z; | |
| 275 | +} | |
| 276 | + | |
| 277 | +inline Vector3 vec3Cross(Vector3 a, Vector3 b) { | |
| 278 | + return { | |
| 279 | + a.pos.y * b.pos.z - a.pos.z * b.pos.y, | |
| 280 | + a.pos.z * b.pos.x - a.pos.x * b.pos.z, | |
| 281 | + a.pos.x * b.pos.y - a.pos.y * b.pos.x, | |
| 282 | + }; | |
| 283 | +} | |
| 284 | + | |
| 285 | +inline Vector3 vec3Normalize(Vector3 v) { | |
| 286 | + f32 len = sqrtf(v.pos.x * v.pos.x + v.pos.y * v.pos.y + v.pos.z * v.pos.z); | |
| 287 | + if (len == 0.f) return { 0, 0, 0 }; | |
| 288 | + return { v.pos.x / len, v.pos.y / len, v.pos.z / len }; | |
| 289 | +} | |
| 268 | 290 | |
| 269 | 291 | #endif // VECTOR_HH |
変更
main.cc
| @@ -87,6 +87,10 @@ | ||
| 87 | 87 | return -1; |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | + // 3Dを有効 | |
| 91 | + glEnable(GL_DEPTH_TEST); | |
| 92 | + //glEnable(GL_CULL_FACE); | |
| 93 | + | |
| 90 | 94 | // ImGui設定 |
| 91 | 95 | gui::GuiEngine ge(&window); |
| 92 | 96 | |
| @@ -205,10 +209,17 @@ | ||
| 205 | 209 | } |
| 206 | 210 | |
| 207 | 211 | shaderProgram.Reload(info.VERT.code, info.FRAG.code); |
| 212 | + shaderProgram.Use(); | |
| 208 | 213 | luaEngine.SetProgram(&shaderProgram); |
| 209 | 214 | luaEngine.Reload(info.LUA.code); |
| 210 | 215 | { |
| 211 | 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 | + } | |
| 212 | 223 | |
| 213 | 224 | VAO.BindVertexArray(); |
| 214 | 225 | |
| @@ -313,34 +324,79 @@ | ||
| 313 | 324 | }; |
| 314 | 325 | |
| 315 | 326 | info.create = [&]() { |
| 316 | - gui::NewShader newShader(&info); | |
| 317 | - auto shdr = newShader.Make(); | |
| 327 | + if (ImGui::BeginPopupModal(info.i18n->GetWord("filenewcreateshader").c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { | |
| 328 | + if (ImGui::Button(info.i18n->GetWord("filenew2dshader").c_str(), ImVec2(200, 0))) { | |
| 329 | + gui::NewShader newShader(&info); | |
| 330 | + auto shdr = newShader.Make(false); | |
| 331 | + info.shaderId = shdr.id; | |
| 332 | + info.shaderName = shdr.name; | |
| 333 | + info.VERT = shdr.vertexShader; | |
| 334 | + info.FRAG = shdr.fragmentShader; | |
| 335 | + info.LUA = shdr.luaCode; | |
| 318 | 336 | |
| 319 | - info.shaderId = shdr.id; | |
| 320 | - info.shaderName = shdr.name; | |
| 321 | - info.VERT = shdr.vertexShader; | |
| 322 | - info.FRAG = shdr.fragmentShader; | |
| 323 | - info.LUA = shdr.luaCode; | |
| 337 | + vertEditor.SetCode(info.VERT.code); | |
| 338 | + string nTit = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")"; | |
| 339 | + vertEditor.SetTitle(nTit + "###VertexEditor"); | |
| 324 | 340 | |
| 325 | - vertEditor.SetCode(info.VERT.code); | |
| 326 | - string nTit = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")"; | |
| 327 | - vertEditor.SetTitle(nTit + "###VertexEditor"); | |
| 341 | + fragEditor.SetCode(info.FRAG.code); | |
| 342 | + nTit = info.shaderName + "(" + info.i18n->GetWord("editorfragshader") + ")"; | |
| 343 | + fragEditor.SetTitle(nTit + "###FragmentEditor"); | |
| 328 | 344 | |
| 329 | - fragEditor.SetCode(info.FRAG.code); | |
| 330 | - nTit = info.shaderName + "(" + info.i18n->GetWord("editorfragshader") + ")"; | |
| 331 | - fragEditor.SetTitle(nTit + "###FragmentEditor"); | |
| 345 | + luaEditor.SetCode(info.LUA.code); | |
| 346 | + nTit = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")"; | |
| 347 | + luaEditor.SetTitle(nTit + "###LuaEditor"); | |
| 332 | 348 | |
| 333 | - luaEditor.SetCode(info.LUA.code); | |
| 334 | - nTit = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")"; | |
| 335 | - luaEditor.SetTitle(nTit + "###LuaEditor"); | |
| 349 | + info.compile(); | |
| 336 | 350 | |
| 337 | - info.compile(); | |
| 351 | + gui::LogEntry entry; | |
| 352 | + entry.type = gui::LogType::Info; | |
| 353 | + entry.text = info.i18n->GetWord("consoleloginfocreateok"); | |
| 354 | + info.cmd->Add(entry); | |
| 355 | + std::cout << entry.text << std::endl; | |
| 338 | 356 | |
| 339 | - gui::LogEntry entry; | |
| 340 | - entry.type = gui::LogType::Info; | |
| 341 | - entry.text = info.i18n->GetWord("consoleloginfocreateok"); | |
| 342 | - info.cmd->Add(entry); | |
| 343 | - std::cout << entry.text << std::endl; | |
| 357 | + ImGui::CloseCurrentPopup(); | |
| 358 | + } | |
| 359 | + | |
| 360 | + if (ImGui::Button(info.i18n->GetWord("filenew3dshader").c_str(), ImVec2(200, 0))) { | |
| 361 | + gui::NewShader newShader(&info); | |
| 362 | + auto shdr = newShader.Make(true); | |
| 363 | + info.shaderId = shdr.id; | |
| 364 | + info.shaderName = shdr.name; | |
| 365 | + info.VERT = shdr.vertexShader; | |
| 366 | + info.FRAG = shdr.fragmentShader; | |
| 367 | + info.LUA = shdr.luaCode; | |
| 368 | + | |
| 369 | + vertEditor.SetCode(info.VERT.code); | |
| 370 | + string nTit = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")"; | |
| 371 | + vertEditor.SetTitle(nTit + "###VertexEditor"); | |
| 372 | + | |
| 373 | + fragEditor.SetCode(info.FRAG.code); | |
| 374 | + nTit = info.shaderName + "(" + info.i18n->GetWord("editorfragshader") + ")"; | |
| 375 | + fragEditor.SetTitle(nTit + "###FragmentEditor"); | |
| 376 | + | |
| 377 | + luaEditor.SetCode(info.LUA.code); | |
| 378 | + nTit = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")"; | |
| 379 | + luaEditor.SetTitle(nTit + "###LuaEditor"); | |
| 380 | + | |
| 381 | + info.compile(); | |
| 382 | + | |
| 383 | + gui::LogEntry entry; | |
| 384 | + entry.type = gui::LogType::Info; | |
| 385 | + entry.text = info.i18n->GetWord("consoleloginfocreateok"); | |
| 386 | + info.cmd->Add(entry); | |
| 387 | + std::cout << entry.text << std::endl; | |
| 388 | + | |
| 389 | + ImGui::CloseCurrentPopup(); | |
| 390 | + } | |
| 391 | + | |
| 392 | + ImGui::Separator(); | |
| 393 | + | |
| 394 | + if (ImGui::Button(info.i18n->GetWord("cancel").c_str())) { | |
| 395 | + ImGui::CloseCurrentPopup(); | |
| 396 | + } | |
| 397 | + | |
| 398 | + ImGui::EndPopup(); | |
| 399 | + } | |
| 344 | 400 | }; |
| 345 | 401 | #pragma endregion |
| 346 | 402 | |
| @@ -367,7 +423,7 @@ | ||
| 367 | 423 | } |
| 368 | 424 | |
| 369 | 425 | if (isNewKey) { |
| 370 | - info.create(); | |
| 426 | + info.showNewShaderPopup = true; | |
| 371 | 427 | } |
| 372 | 428 | |
| 373 | 429 | if (isOpenKey) {} |
| @@ -419,6 +475,13 @@ | ||
| 419 | 475 | |
| 420 | 476 | gui::showTitleBar(info); |
| 421 | 477 | |
| 478 | + if (info.showNewShaderPopup) { | |
| 479 | + ImGui::OpenPopup(info.i18n->GetWord("filenewcreateshader").c_str()); | |
| 480 | + info.showNewShaderPopup = false; | |
| 481 | + } | |
| 482 | + | |
| 483 | + info.create(); | |
| 484 | + | |
| 422 | 485 | #ifndef PRODUCTION_BUILD |
| 423 | 486 | if (showDemo) ImGui::ShowDemoWindow(&showDemo); |
| 424 | 487 | #endif |
| @@ -448,7 +511,7 @@ | ||
| 448 | 511 | |
| 449 | 512 | // クアッドを描画 |
| 450 | 513 | VAO.BindVertexArray(); |
| 451 | - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); | |
| 514 | + glDrawElements(GL_TRIANGLES, mesh.GetIndexCount(), GL_UNSIGNED_INT, nullptr); | |
| 452 | 515 | glBindFramebuffer(GL_FRAMEBUFFER, 0); |
| 453 | 516 | |
| 454 | 517 | // バッファをスワップし、イベントを処理 |
| @@ -180,12 +180,22 @@ | ||
| 180 | 180 | createWord(db, 2, "file", "File"); |
| 181 | 181 | createWord(db, 1, "filenew", "新しいファイル"); |
| 182 | 182 | createWord(db, 2, "filenew", "New File"); |
| 183 | + createWord(db, 1, "filenewcreateshader", "新しいシェーダーを作成"); | |
| 184 | + createWord(db, 2, "filenewcreateshader", "New Shader Creation"); | |
| 185 | + createWord(db, 1, "filenew2dshader", "2D シェーダー"); | |
| 186 | + createWord(db, 2, "filenew2dshader", "2D Shader"); | |
| 187 | + createWord(db, 1, "filenew3dshader", "3D シェーダー"); | |
| 188 | + createWord(db, 2, "filenew3dshader", "3D Shader"); | |
| 183 | 189 | createWord(db, 1, "fileopen", "開く"); |
| 184 | 190 | createWord(db, 2, "fileopen", "Open"); |
| 185 | 191 | createWord(db, 1, "filesave", "保存"); |
| 186 | 192 | createWord(db, 2, "filesave", "Save"); |
| 187 | 193 | createWord(db, 1, "quit", "終了"); |
| 188 | 194 | createWord(db, 2, "quit", "Quit"); |
| 195 | + createWord(db, 1, "cancel", "キャンセル"); | |
| 196 | + createWord(db, 2, "cancel", "Cancel"); | |
| 197 | + createWord(db, 1, "ok", "OK"); | |
| 198 | + createWord(db, 2, "ok", "OK"); | |
| 189 | 199 | createWord(db, 1, "editorvertshader", "頂点シェーダー"); |
| 190 | 200 | createWord(db, 2, "editorvertshader", "Vertex Shader"); |
| 191 | 201 | createWord(db, 1, "editorfragshader", "フラグメントシェーダー"); |
| @@ -36,12 +36,25 @@ | ||
| 36 | 36 | */ |
| 37 | 37 | #include <gui/newshader.hh> |
| 38 | 38 | #include <database/locale.hh> |
| 39 | +#include <imgui.h> | |
| 39 | 40 | |
| 40 | 41 | namespace gui { |
| 41 | 42 | NewShader::NewShader(Info *info) : m_Info(info) {} |
| 42 | 43 | NewShader::~NewShader() {} |
| 43 | 44 | |
| 44 | - db::ShaderData NewShader::Make() { | |
| 45 | + void NewShader::DrawPopup() { | |
| 46 | + if (ImGui::BeginPopupModal("NewShaderPopup", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { | |
| 47 | + ImGui::Text(m_Info->i18n->GetWord("filenewcreateshader").c_str()); | |
| 48 | + ImGui::Separator(); | |
| 49 | + | |
| 50 | + if (ImGui::Button("2D Shader", ImVec2(200, 0))) { | |
| 51 | + Make(false); | |
| 52 | + m_Info->create(); | |
| 53 | + } | |
| 54 | + } | |
| 55 | + } | |
| 56 | + | |
| 57 | + db::ShaderData NewShader::Make(bool is3D) { | |
| 45 | 58 | db::ShaderData newShader = {}; |
| 46 | 59 | auto curLang = m_Info->i18n->GetCurrentLanguage().code; |
| 47 | 60 | newShader.id = 0; |
| @@ -51,17 +64,17 @@ | ||
| 51 | 64 | |
| 52 | 65 | newShader.vertexShader.id = 0; |
| 53 | 66 | newShader.vertexShader.type = db::ShaderCodeType::GlslVertex; |
| 54 | - newShader.vertexShader.code = getDefaultVert(); | |
| 67 | + newShader.vertexShader.code = is3D ? getDefaultVert3D() : getDefaultVert2D(); | |
| 55 | 68 | newShader.vertexShader.filename = ""; |
| 56 | 69 | |
| 57 | 70 | newShader.fragmentShader.id = 0; |
| 58 | 71 | newShader.fragmentShader.type = db::ShaderCodeType::GlslFragment; |
| 59 | - newShader.fragmentShader.code = getDefaultFrag(); | |
| 72 | + newShader.fragmentShader.code = is3D ? getDefaultFrag3D() : getDefaultFrag2D(); | |
| 60 | 73 | newShader.fragmentShader.filename = ""; |
| 61 | 74 | |
| 62 | 75 | newShader.luaCode.id = 0; |
| 63 | 76 | newShader.luaCode.type = db::ShaderCodeType::Lua; |
| 64 | - newShader.luaCode.code = getDefaultLua(); | |
| 77 | + newShader.luaCode.code = is3D ? getDefaultLua3D() : getDefaultLua2D(); | |
| 65 | 78 | newShader.luaCode.filename = ""; |
| 66 | 79 | |
| 67 | 80 | return newShader; |
| @@ -69,7 +82,7 @@ | ||
| 69 | 82 | |
| 70 | 83 | /////////////////////////// |
| 71 | 84 | |
| 72 | - string NewShader::getDefaultVert() { | |
| 85 | + string NewShader::getDefaultVert2D() { | |
| 73 | 86 | return R"(#version 460 core |
| 74 | 87 | |
| 75 | 88 | layout(location = 0) in vec2 aPosition; |
| @@ -82,7 +95,7 @@ | ||
| 82 | 95 | })"; |
| 83 | 96 | } |
| 84 | 97 | |
| 85 | - string NewShader::getDefaultFrag() { | |
| 98 | + string NewShader::getDefaultFrag2D() { | |
| 86 | 99 | return R"(#version 460 core |
| 87 | 100 | |
| 88 | 101 | in vec3 vColor; |
| @@ -93,7 +106,7 @@ | ||
| 93 | 106 | })"; |
| 94 | 107 | } |
| 95 | 108 | |
| 96 | - string NewShader::getDefaultLua() { | |
| 109 | + string NewShader::getDefaultLua2D() { | |
| 97 | 110 | return R"(local stride = le.sizeof("vec2") + le.sizeof("vec3") |
| 98 | 111 | |
| 99 | 112 | local mesh = { |
| @@ -126,6 +139,110 @@ | ||
| 126 | 139 | end |
| 127 | 140 | |
| 128 | 141 | function update() |
| 142 | +end)"; | |
| 143 | + } | |
| 144 | + | |
| 145 | + string NewShader::getDefaultVert3D() { | |
| 146 | + return R"(#version 460 core | |
| 147 | + | |
| 148 | +layout(location = 0) in vec3 aPosition; | |
| 149 | +layout(location = 1) in vec3 aColor; | |
| 150 | + | |
| 151 | +out vec3 vColor; | |
| 152 | + | |
| 153 | +uniform mat4 uModel; | |
| 154 | +uniform mat4 uView; | |
| 155 | +uniform mat4 uProjection; | |
| 156 | + | |
| 157 | +void main() { | |
| 158 | + vColor = aColor; | |
| 159 | + gl_Position = uProjection * uView * uModel * vec4(aPosition, 1.0); | |
| 160 | +})"; | |
| 161 | + } | |
| 162 | + | |
| 163 | + string NewShader::getDefaultFrag3D() { | |
| 164 | + return R"(#version 460 core | |
| 165 | + | |
| 166 | +in vec3 vColor; | |
| 167 | +out vec4 out_color; | |
| 168 | + | |
| 169 | +void main() { | |
| 170 | + out_color = vec4(vColor, 1.0); | |
| 171 | +})"; | |
| 172 | + } | |
| 173 | + | |
| 174 | + string NewShader::getDefaultLua3D() { | |
| 175 | + return R"(local offset = le.sizeof("vec3") | |
| 176 | +local stride = offset * 2 | |
| 177 | + | |
| 178 | +local mesh = { | |
| 179 | + vertices = { | |
| 180 | + -- position -- uv | |
| 181 | + -- mae | |
| 182 | + -0.5, -0.5, -0.5, 1,0,0, | |
| 183 | + 0.5, -0.5, -0.5, 0,1,0, | |
| 184 | + 0.5, 0.5, -0.5, 0,0,1, | |
| 185 | + -0.5, 0.5, -0.5, 1,1,0, | |
| 186 | + -- usiro | |
| 187 | + -0.5, -0.5, 0.5, 1,0,1, | |
| 188 | + 0.5, -0.5, 0.5, 0,1,1, | |
| 189 | + 0.5, 0.5, 0.5, 1,1,1, | |
| 190 | + -0.5, 0.5, 0.5, 1,0,1, | |
| 191 | + }, | |
| 192 | + | |
| 193 | + indices = { | |
| 194 | + -- mae | |
| 195 | + 0,1,2, 2,3,0, | |
| 196 | + -- migi | |
| 197 | + 1,5,6, 6,2,1, | |
| 198 | + -- usiro | |
| 199 | + 5,4,7, 7,6,5, | |
| 200 | + -- hidari | |
| 201 | + 4,0,3, 3,7,4, | |
| 202 | + -- ue | |
| 203 | + 3,2,6, 6,7,3, | |
| 204 | + -- sita | |
| 205 | + 4,5,1, 1,0,4 | |
| 206 | + }, | |
| 207 | + | |
| 208 | + attributes = { | |
| 209 | + { location = 0, size = 3, stride = stride, offset = 0 }, | |
| 210 | + { location = 1, size = 3, stride = stride, offset = offset } | |
| 211 | + } | |
| 212 | +} | |
| 213 | + | |
| 214 | +le.gfx.set_mesh(mesh) | |
| 215 | + | |
| 216 | +function init() | |
| 217 | +end | |
| 218 | + | |
| 219 | +function update() | |
| 220 | + local t = le.sys.get_time() | |
| 221 | + local reso = le.sys.get_resolution() | |
| 222 | + local aspect = reso.x / reso.y | |
| 223 | + | |
| 224 | + local model = le.math.rotate( | |
| 225 | + t * 0.7, | |
| 226 | + t * 1.0, | |
| 227 | + t * 0.4 | |
| 228 | + ) | |
| 229 | + | |
| 230 | + local view = le.math.look_at( | |
| 231 | + 0, 0, 4, -- eye | |
| 232 | + 0, 0, 0, -- target | |
| 233 | + 0, 1, 0 -- up | |
| 234 | + ) | |
| 235 | + | |
| 236 | + local projection = le.math.perspective( | |
| 237 | + 45.0, | |
| 238 | + aspect, | |
| 239 | + 0.1, | |
| 240 | + 100.0 | |
| 241 | + ) | |
| 242 | + | |
| 243 | + le.gfx.set_uniform_mat4("uModel", model) | |
| 244 | + le.gfx.set_uniform_mat4("uView", view) | |
| 245 | + le.gfx.set_uniform_mat4("uProjection", projection) | |
| 129 | 246 | end)"; |
| 130 | 247 | } |
| 131 | 248 | } // namespace gui |
| @@ -40,6 +40,7 @@ | ||
| 40 | 40 | #include <glfw/glfw3.h> |
| 41 | 41 | #include <util/glfwpp.hh> |
| 42 | 42 | #include <util/vector.hh> |
| 43 | +#include <util/matrix.hh> | |
| 43 | 44 | #include <util/random.hh> |
| 44 | 45 | #include <database/locale.hh> |
| 45 | 46 | #include <gui/consolelog.hh> |
| @@ -102,7 +103,7 @@ | ||
| 102 | 103 | } |
| 103 | 104 | |
| 104 | 105 | sol::state testApi = MakeAPI(); |
| 105 | - sol::load_result resApi = m_Lua.load(code); | |
| 106 | + sol::load_result resApi = testApi.load(code); | |
| 106 | 107 | //sol::protected_function_result resApi = testApi.safe_script(code); |
| 107 | 108 | if (!resApi.valid()) { |
| 108 | 109 | sol::error err = resApi; |
| @@ -124,7 +125,7 @@ | ||
| 124 | 125 | entry.type = gui::LogType::Error; |
| 125 | 126 | entry.text = err.what(); |
| 126 | 127 | m_Info->cmd->Add(entry); |
| 127 | - std::cerr << err.what() << std::endl; | |
| 128 | + std::cerr << entry.text << std::endl; | |
| 128 | 129 | } |
| 129 | 130 | |
| 130 | 131 | void LuaEngine::LogError(const std::exception &err) { |
| @@ -132,9 +133,17 @@ | ||
| 132 | 133 | entry.type = gui::LogType::Error; |
| 133 | 134 | entry.text = err.what(); |
| 134 | 135 | m_Info->cmd->Add(entry); |
| 135 | - std::cerr << err.what() << std::endl; | |
| 136 | + std::cerr << entry.text << std::endl; | |
| 136 | 137 | } |
| 137 | 138 | |
| 139 | + void LuaEngine::LogError(const string &err) { | |
| 140 | + gui::LogEntry entry = {}; | |
| 141 | + entry.type = gui::LogType::Error; | |
| 142 | + entry.text = err; | |
| 143 | + m_Info->cmd->Add(entry); | |
| 144 | + std::cerr << entry.text << std::endl; | |
| 145 | + } | |
| 146 | + | |
| 138 | 147 | sol::state LuaEngine::MakeAPI() { |
| 139 | 148 | sol::state out; |
| 140 | 149 | |
| @@ -341,6 +350,7 @@ | ||
| 341 | 350 | BindEngine(out); |
| 342 | 351 | BindSystem(out); |
| 343 | 352 | BindIO(out); |
| 353 | + BindMath(out); | |
| 344 | 354 | BindGraphics(out); |
| 345 | 355 | } catch (const std::exception &e) { |
| 346 | 356 | LogError(e); |
| @@ -446,11 +456,7 @@ | ||
| 446 | 456 | |
| 447 | 457 | auto it = sizes.find(type); |
| 448 | 458 | if (it == sizes.end()) { |
| 449 | - gui::LogEntry entry = {}; | |
| 450 | - entry.type = gui::LogType::Error; | |
| 451 | - entry.text = "不正な値類: " + type; | |
| 452 | - m_Info->cmd->Add(entry); | |
| 453 | - std::cerr << entry.text << std::endl; | |
| 459 | + LogError("不正な値類: " + type); | |
| 454 | 460 | return 0; |
| 455 | 461 | } |
| 456 | 462 | |
| @@ -502,6 +508,107 @@ | ||
| 502 | 508 | }; |
| 503 | 509 | } |
| 504 | 510 | |
| 511 | + void LuaEngine::BindMath(sol::state &lua) { | |
| 512 | + lua["le"]["math"] = lua.create_table(); | |
| 513 | + | |
| 514 | + lua["le"]["math"]["identity"] = [](sol::this_state ts) -> sol::table { | |
| 515 | + sol::state_view lua(ts); | |
| 516 | + Matrix4 m = mat4Identity(); | |
| 517 | + sol::table t = lua.create_table(); | |
| 518 | + for (i32 i = 0; i < 16; ++i) t[i + 1] = m.m[i]; | |
| 519 | + return t; | |
| 520 | + }; | |
| 521 | + | |
| 522 | + lua["le"]["math"]["translate"] = [](sol::this_state ts, f32 x, f32 y, f32 z) -> sol::table { | |
| 523 | + sol::state_view lua(ts); | |
| 524 | + Matrix4 m = mat4Translate(x, y, z); | |
| 525 | + sol::table t = lua.create_table(); | |
| 526 | + for (i32 i = 0; i < 16; ++i) t[i + 1] = m.m[i]; | |
| 527 | + return t; | |
| 528 | + }; | |
| 529 | + | |
| 530 | + lua["le"]["math"]["scale"] = [](sol::this_state ts, f32 x, f32 y, f32 z) -> sol::table { | |
| 531 | + sol::state_view lua(ts); | |
| 532 | + Matrix4 m = mat4Scale(x, y, z); | |
| 533 | + sol::table t = lua.create_table(); | |
| 534 | + for (i32 i = 0; i < 16; ++i) t[i + 1] = m.m[i]; | |
| 535 | + return t; | |
| 536 | + }; | |
| 537 | + | |
| 538 | + lua["le"]["math"]["rotate_x"] = [](sol::this_state ts, f32 angle) -> sol::table { | |
| 539 | + sol::state_view lua(ts); | |
| 540 | + Matrix4 m = mat4RotateX(angle); | |
| 541 | + sol::table t = lua.create_table(); | |
| 542 | + for (i32 i = 0; i < 16; ++i) t[i + 1] = m.m[i]; | |
| 543 | + return t; | |
| 544 | + }; | |
| 545 | + | |
| 546 | + lua["le"]["math"]["rotate_y"] = [](sol::this_state ts, f32 angle) -> sol::table { | |
| 547 | + sol::state_view lua(ts); | |
| 548 | + Matrix4 m = mat4RotateY(angle); | |
| 549 | + sol::table t = lua.create_table(); | |
| 550 | + for (i32 i = 0; i < 16; ++i) t[i + 1] = m.m[i]; | |
| 551 | + return t; | |
| 552 | + }; | |
| 553 | + | |
| 554 | + lua["le"]["math"]["rotate_z"] = [](sol::this_state ts, f32 angle) -> sol::table { | |
| 555 | + sol::state_view lua(ts); | |
| 556 | + Matrix4 m = mat4RotateZ(angle); | |
| 557 | + sol::table t = lua.create_table(); | |
| 558 | + for (i32 i = 0; i < 16; ++i) t[i + 1] = m.m[i]; | |
| 559 | + return t; | |
| 560 | + }; | |
| 561 | + | |
| 562 | + lua["le"]["math"]["rotate"] = [](sol::this_state ts, f32 pitch, f32 yaw, f32 roll) -> sol::table { | |
| 563 | + sol::state_view lua(ts); | |
| 564 | + Matrix4 m = mat4Rotate(pitch, yaw, roll); | |
| 565 | + sol::table t = lua.create_table(); | |
| 566 | + for (i32 i = 0; i < 16; ++i) t[i + 1] = m.m[i]; | |
| 567 | + return t; | |
| 568 | + }; | |
| 569 | + | |
| 570 | + lua["le"]["math"]["perspective"] = [](sol::this_state ts, f32 fov, f32 aspect, f32 near, f32 far) -> sol::table { | |
| 571 | + sol::state_view lua(ts); | |
| 572 | + Matrix4 m = mat4Perspective(fov, aspect, near, far); | |
| 573 | + sol::table t = lua.create_table(); | |
| 574 | + for (i32 i = 0; i < 16; ++i) t[i + 1] = m.m[i]; | |
| 575 | + return t; | |
| 576 | + }; | |
| 577 | + | |
| 578 | + lua["le"]["math"]["mul"] = [](sol::this_state ts, sol::table a, sol::table b) -> sol::table { | |
| 579 | + sol::state_view lua(ts); | |
| 580 | + Matrix4 ma{}, mb{}; | |
| 581 | + | |
| 582 | + for (i32 i = 0; i < 16; ++i) { | |
| 583 | + ma.m[i] = a[i + 1]; | |
| 584 | + mb.m[i] = b[i + 1]; | |
| 585 | + } | |
| 586 | + | |
| 587 | + Matrix4 out = mat4Mul(ma, mb); | |
| 588 | + sol::table t = lua.create_table(); | |
| 589 | + for (i32 i = 0; i < 16; ++i) t[i + 1] = out.m[i]; | |
| 590 | + | |
| 591 | + return t; | |
| 592 | + }; | |
| 593 | + | |
| 594 | + lua["le"]["math"]["look_at"] = [](sol::this_state ts, | |
| 595 | + f32 ex, f32 ey, f32 ez, | |
| 596 | + f32 tx, f32 ty, f32 tz, | |
| 597 | + f32 ux, f32 uy, f32 uz) -> sol::table { | |
| 598 | + sol::state_view lua(ts); | |
| 599 | + Matrix4 m = mat4LookAt( | |
| 600 | + { ex, ey, ez }, | |
| 601 | + { tx, ty, tz }, | |
| 602 | + { ux, uy, uz } | |
| 603 | + ); | |
| 604 | + | |
| 605 | + sol::table t = lua.create_table(); | |
| 606 | + for (i32 i = 0; i < 16; ++i) t[i + 1] = m.m[i]; | |
| 607 | + | |
| 608 | + return t; | |
| 609 | + }; | |
| 610 | + } | |
| 611 | + | |
| 505 | 612 | void LuaEngine::BindGraphics(sol::state &lua) { |
| 506 | 613 | lua["le"]["gfx"] = lua.create_table(); |
| 507 | 614 | |
| @@ -540,102 +647,221 @@ | ||
| 540 | 647 | |
| 541 | 648 | lua["le"]["gfx"]["set_uniform1"] = [&](const string &name, f32 x) { |
| 542 | 649 | if (!m_Program) return; |
| 543 | - glUniform1f(m_Program->GetUniformLocation(name), x); | |
| 650 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 651 | + if (loc == -1) { | |
| 652 | + LogError("ユニフォーム見つけられません: " + name); | |
| 653 | + return; | |
| 654 | + } | |
| 655 | + glUniform1f(loc, x); | |
| 544 | 656 | }; |
| 545 | 657 | |
| 546 | 658 | lua["le"]["gfx"]["set_uniform2"] = [&](const string &name, f32 x, f32 y) { |
| 547 | 659 | if (!m_Program) return; |
| 548 | - glUniform2f(m_Program->GetUniformLocation(name), x, y); | |
| 660 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 661 | + if (loc == -1) { | |
| 662 | + LogError("ユニフォーム見つけられません: " + name); | |
| 663 | + return; | |
| 664 | + } | |
| 665 | + glUniform2f(loc, x, y); | |
| 549 | 666 | }; |
| 550 | 667 | |
| 551 | 668 | lua["le"]["gfx"]["set_uniform3"] = [&](const string &name, f32 x, f32 y, f32 z) { |
| 552 | 669 | if (!m_Program) return; |
| 553 | - glUniform3f(m_Program->GetUniformLocation(name), x, y, z); | |
| 670 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 671 | + if (loc == -1) { | |
| 672 | + LogError("ユニフォーム見つけられません: " + name); | |
| 673 | + return; | |
| 674 | + } | |
| 675 | + glUniform3f(loc, x, y, z); | |
| 554 | 676 | }; |
| 555 | 677 | |
| 556 | 678 | lua["le"]["gfx"]["set_uniform4"] = [&](const string &name, f32 x, f32 y, f32 z, f32 w) { |
| 557 | 679 | if (!m_Program) return; |
| 558 | - glUniform4f(m_Program->GetUniformLocation(name), x, y, z, w); | |
| 680 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 681 | + if (loc == -1) { | |
| 682 | + LogError("ユニフォーム見つけられません: " + name); | |
| 683 | + return; | |
| 684 | + } | |
| 685 | + glUniform4f(loc, x, y, z, w); | |
| 559 | 686 | }; |
| 560 | 687 | |
| 561 | 688 | lua["le"]["gfx"]["set_uniform_float1"] = [&](const string &name, f32 x) { |
| 562 | 689 | if (!m_Program) return; |
| 563 | - glUniform1f(m_Program->GetUniformLocation(name), x); | |
| 690 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 691 | + if (loc == -1) { | |
| 692 | + LogError("ユニフォーム見つけられません: " + name); | |
| 693 | + return; | |
| 694 | + } | |
| 695 | + glUniform1f(loc, x); | |
| 564 | 696 | }; |
| 565 | 697 | |
| 566 | 698 | lua["le"]["gfx"]["set_uniform_float2"] = [&](const string &name, f32 x, f32 y) { |
| 567 | 699 | if (!m_Program) return; |
| 568 | - glUniform2f(m_Program->GetUniformLocation(name), x, y); | |
| 700 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 701 | + if (loc == -1) { | |
| 702 | + LogError("ユニフォーム見つけられません: " + name); | |
| 703 | + return; | |
| 704 | + } | |
| 705 | + glUniform2f(loc, x, y); | |
| 569 | 706 | }; |
| 570 | 707 | |
| 571 | 708 | lua["le"]["gfx"]["set_uniform_float3"] = [&](const string &name, f32 x, f32 y, f32 z) { |
| 572 | 709 | if (!m_Program) return; |
| 573 | - glUniform3f(m_Program->GetUniformLocation(name), x, y, z); | |
| 710 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 711 | + if (loc == -1) { | |
| 712 | + LogError("ユニフォーム見つけられません: " + name); | |
| 713 | + return; | |
| 714 | + } | |
| 715 | + glUniform3f(loc, x, y, z); | |
| 574 | 716 | }; |
| 575 | 717 | |
| 576 | 718 | lua["le"]["gfx"]["set_uniform_float4"] = [&](const string &name, f32 x, f32 y, f32 z, f32 w) { |
| 577 | 719 | if (!m_Program) return; |
| 578 | - glUniform4f(m_Program->GetUniformLocation(name), x, y, z, w); | |
| 720 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 721 | + if (loc == -1) { | |
| 722 | + LogError("ユニフォーム見つけられません: " + name); | |
| 723 | + return; | |
| 724 | + } | |
| 725 | + glUniform4f(loc, x, y, z, w); | |
| 579 | 726 | }; |
| 580 | 727 | |
| 581 | 728 | lua["le"]["gfx"]["set_uniform_double1"] = [&](const string &name, f64 x) { |
| 582 | 729 | if (!m_Program) return; |
| 583 | - glUniform1d(m_Program->GetUniformLocation(name), x); | |
| 730 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 731 | + if (loc == -1) { | |
| 732 | + LogError("ユニフォーム見つけられません: " + name); | |
| 733 | + return; | |
| 734 | + } | |
| 735 | + glUniform1d(loc, x); | |
| 584 | 736 | }; |
| 585 | 737 | |
| 586 | 738 | lua["le"]["gfx"]["set_uniform_double2"] = [&](const string &name, f64 x, f64 y) { |
| 587 | 739 | if (!m_Program) return; |
| 588 | - glUniform2d(m_Program->GetUniformLocation(name), x, y); | |
| 740 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 741 | + if (loc == -1) { | |
| 742 | + LogError("ユニフォーム見つけられません: " + name); | |
| 743 | + return; | |
| 744 | + } | |
| 745 | + glUniform2d(loc, x, y); | |
| 589 | 746 | }; |
| 590 | 747 | |
| 591 | 748 | lua["le"]["gfx"]["set_uniform_double3"] = [&](const string &name, f64 x, f64 y, f64 z) { |
| 592 | 749 | if (!m_Program) return; |
| 593 | - glUniform3d(m_Program->GetUniformLocation(name), x, y, z); | |
| 750 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 751 | + if (loc == -1) { | |
| 752 | + LogError("ユニフォーム見つけられません: " + name); | |
| 753 | + return; | |
| 754 | + } | |
| 755 | + glUniform3d(loc, x, y, z); | |
| 594 | 756 | }; |
| 595 | 757 | |
| 596 | 758 | lua["le"]["gfx"]["set_uniform_double4"] = [&](const string &name, f64 x, f64 y, f64 z, f64 w) { |
| 597 | 759 | if (!m_Program) return; |
| 598 | - glUniform4d(m_Program->GetUniformLocation(name), x, y, z, w); | |
| 760 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 761 | + if (loc == -1) { | |
| 762 | + LogError("ユニフォーム見つけられません: " + name); | |
| 763 | + return; | |
| 764 | + } | |
| 765 | + glUniform4d(loc, x, y, z, w); | |
| 599 | 766 | }; |
| 600 | 767 | |
| 601 | 768 | lua["le"]["gfx"]["set_uniform_int1"] = [&](const string &name, i32 x) { |
| 602 | 769 | if (!m_Program) return; |
| 603 | - glUniform1i(m_Program->GetUniformLocation(name), x); | |
| 770 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 771 | + if (loc == -1) { | |
| 772 | + LogError("ユニフォーム見つけられません: " + name); | |
| 773 | + return; | |
| 774 | + } | |
| 775 | + glUniform1i(loc, x); | |
| 604 | 776 | }; |
| 605 | 777 | |
| 606 | 778 | lua["le"]["gfx"]["set_uniform_int2"] = [&](const string &name, i32 x, i32 y) { |
| 607 | 779 | if (!m_Program) return; |
| 608 | - glUniform2i(m_Program->GetUniformLocation(name), x, y); | |
| 780 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 781 | + if (loc == -1) { | |
| 782 | + LogError("ユニフォーム見つけられません: " + name); | |
| 783 | + return; | |
| 784 | + } | |
| 785 | + glUniform2i(loc, x, y); | |
| 609 | 786 | }; |
| 610 | 787 | |
| 611 | 788 | lua["le"]["gfx"]["set_uniform_int3"] = [&](const string &name, i32 x, i32 y, i32 z) { |
| 612 | 789 | if (!m_Program) return; |
| 613 | - glUniform3i(m_Program->GetUniformLocation(name), x, y, z); | |
| 790 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 791 | + if (loc == -1) { | |
| 792 | + LogError("ユニフォーム見つけられません: " + name); | |
| 793 | + return; | |
| 794 | + } | |
| 795 | + glUniform3i(loc, x, y, z); | |
| 614 | 796 | }; |
| 615 | 797 | |
| 616 | 798 | lua["le"]["gfx"]["set_uniform_int4"] = [&](const string &name, i32 x, i32 y, i32 z, i32 w) { |
| 617 | 799 | if (!m_Program) return; |
| 618 | - glUniform4i(m_Program->GetUniformLocation(name), x, y, z, w); | |
| 800 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 801 | + if (loc == -1) { | |
| 802 | + LogError("ユニフォーム見つけられません: " + name); | |
| 803 | + return; | |
| 804 | + } | |
| 805 | + glUniform4i(loc, x, y, z, w); | |
| 619 | 806 | }; |
| 620 | 807 | |
| 621 | 808 | lua["le"]["gfx"]["set_uniform_uint1"] = [&](const string &name, u32 x) { |
| 622 | 809 | if (!m_Program) return; |
| 623 | - glUniform1ui(m_Program->GetUniformLocation(name), x); | |
| 810 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 811 | + if (loc == -1) { | |
| 812 | + LogError("ユニフォーム見つけられません: " + name); | |
| 813 | + return; | |
| 814 | + } | |
| 815 | + glUniform1ui(loc, x); | |
| 624 | 816 | }; |
| 625 | 817 | |
| 626 | 818 | lua["le"]["gfx"]["set_uniform_uint2"] = [&](const string &name, u32 x, u32 y) { |
| 627 | 819 | if (!m_Program) return; |
| 628 | - glUniform2ui(m_Program->GetUniformLocation(name), x, y); | |
| 820 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 821 | + if (loc == -1) { | |
| 822 | + LogError("ユニフォーム見つけられません: " + name); | |
| 823 | + return; | |
| 824 | + } | |
| 825 | + glUniform2ui(loc, x, y); | |
| 629 | 826 | }; |
| 630 | 827 | |
| 631 | 828 | lua["le"]["gfx"]["set_uniform_uint3"] = [&](const string &name, u32 x, u32 y, u32 z) { |
| 632 | 829 | if (!m_Program) return; |
| 633 | - glUniform3ui(m_Program->GetUniformLocation(name), x, y, z); | |
| 830 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 831 | + if (loc == -1) { | |
| 832 | + LogError("ユニフォーム見つけられません: " + name); | |
| 833 | + return; | |
| 834 | + } | |
| 835 | + glUniform3ui(loc, x, y, z); | |
| 634 | 836 | }; |
| 635 | 837 | |
| 636 | 838 | lua["le"]["gfx"]["set_uniform_uint4"] = [&](const string &name, u32 x, u32 y, u32 z, u32 w) { |
| 637 | 839 | if (!m_Program) return; |
| 638 | - glUniform4ui(m_Program->GetUniformLocation(name), x, y, z, w); | |
| 840 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 841 | + if (loc == -1) { | |
| 842 | + LogError("ユニフォーム見つけられません: " + name); | |
| 843 | + return; | |
| 844 | + } | |
| 845 | + glUniform4ui(loc, x, y, z, w); | |
| 846 | + }; | |
| 847 | + | |
| 848 | + lua["le"]["gfx"]["set_uniform_mat4"] = [&](const string &name, sol::table t) { | |
| 849 | + if (!m_Program) return; | |
| 850 | + if (t.size() != 16) { | |
| 851 | + if (m_Info->i18n->GetCurrentLanguage().code == "ja_JP") LogError("mat4は16個の値が必要です。"); | |
| 852 | + else LogError("mat4 must have 16 values."); | |
| 853 | + return; | |
| 854 | + } | |
| 855 | + | |
| 856 | + Matrix4 mat{}; | |
| 857 | + for (i32 i = 0; i < 16; ++i) mat.m[i] = t[i + 1]; | |
| 858 | + | |
| 859 | + GLint loc = m_Program->GetUniformLocation(name); | |
| 860 | + if (loc == -1) { | |
| 861 | + LogError("ユニフォーム見つけられません: " + name); | |
| 862 | + return; | |
| 863 | + } | |
| 864 | + glUniformMatrix4fv(loc, 1, GL_FALSE, mat.m); | |
| 639 | 865 | }; |
| 640 | 866 | } |
| 641 | 867 |
| @@ -96,7 +96,7 @@ | ||
| 96 | 96 | } |
| 97 | 97 | |
| 98 | 98 | void Program::Clear(GLbitfield mask) { |
| 99 | - glClear(GL_COLOR_BUFFER_BIT); | |
| 99 | + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | GLint Program::GetUniformLocation(string var) { |