新しいシェーダーを保存出来る様に
守矢諏訪子 <suwako@076.moe>、2026-06-28 04:18
コミット 5bb9aad045053c677baad8862841aa67a0f3c24f
・親 da3b0b6
・ファイルを見る
10個のファイル、+290 -93
| @@ -61,5 +61,8 @@ | ||
| 61 | 61 | }; |
| 62 | 62 | |
| 63 | 63 | vector<ShaderData> GetAllShaders(sqlitepp::Instance &db); |
| 64 | + ShaderData GetShader(sqlitepp::Instance &db, u32 id); | |
| 65 | + void SaveNewShader(sqlitepp::Instance &db, const ShaderData &data); | |
| 64 | 66 | void SaveCode(sqlitepp::Instance &db, const CodeData &data); |
| 67 | + u32 GetLastShaderID(sqlitepp::Instance &db); | |
| 65 | 68 | } // namespace db |
| @@ -46,4 +46,4 @@ | ||
| 46 | 46 | #include <gui/settings.hh> |
| 47 | 47 | #include <gui/newshader.hh> |
| 48 | 48 | //#include <gui/openshader.hh> |
| 49 | -//#include <gui/saveasshader.hh> | |
| 49 | +#include <gui/saveshader.hh> |
| @@ -48,10 +48,9 @@ | ||
| 48 | 48 | |
| 49 | 49 | class NewShader { |
| 50 | 50 | public: |
| 51 | - NewShader(Info *info); | |
| 52 | - ~NewShader(); | |
| 51 | + NewShader(Info *info) : m_Info(info) {} | |
| 52 | + ~NewShader() {} | |
| 53 | 53 | |
| 54 | - void DrawPopup(); | |
| 55 | 54 | db::ShaderData Make(ShaderType type = ShaderType::Simple2D); |
| 56 | 55 | |
| 57 | 56 | private: |
| @@ -0,0 +1,53 @@ | ||
| 1 | +/* | |
| 2 | +# 076 License | |
| 3 | + | |
| 4 | +Copyright (c) テクニカル諏訪子 | |
| 5 | + | |
| 6 | +Permission is hereby granted to any person obtaining a copy of the software | |
| 7 | +Shader Playground (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 | + - If the Software is used in a product, you must either: | |
| 14 | + a. Provide clear attribution in the product's documentation, user interface, | |
| 15 | + or other visible areas, **OR** | |
| 16 | + b. Pay the original developers a fee they specify in writing. | |
| 17 | + 2. **Usage Restriction**: | |
| 18 | + - The Software, or any derivative works, dependencies, or libraries | |
| 19 | + incorporating it, must not be used for censorship or to suppress freedom of | |
| 20 | + speech, expression, or creativity. Prohibited uses include, but are not | |
| 21 | + limited to: | |
| 22 | + - Censorship of so-called "hate speech", visuals, non-mainstream opinions, | |
| 23 | + ideas, or objective reality. | |
| 24 | + - Tools or systems designed to restrict access to information or | |
| 25 | + artistic works. | |
| 26 | + 3. **Notice Preservation**: | |
| 27 | + - This license and the above copyright notice must remain intact in all copies | |
| 28 | + of the source code. | |
| 29 | + | |
| 30 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |
| 31 | +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |
| 32 | +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
| 33 | +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
| 34 | +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |
| 35 | +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 36 | +*/ | |
| 37 | +#pragma once | |
| 38 | + | |
| 39 | +#include <util/types.hh> | |
| 40 | +#include <util/structs.hh> | |
| 41 | + | |
| 42 | +namespace gui { | |
| 43 | + class SaveShader { | |
| 44 | + public: | |
| 45 | + SaveShader(Info *info) : m_Info(info) {} | |
| 46 | + ~SaveShader() {} | |
| 47 | + | |
| 48 | + void Save(sqlitepp::Instance &db); | |
| 49 | + | |
| 50 | + private: | |
| 51 | + Info *m_Info; | |
| 52 | + }; // class SaveShader | |
| 53 | +} // namespace gui |
| @@ -61,9 +61,9 @@ | ||
| 61 | 61 | bool isManual = false; |
| 62 | 62 | bool isSettings = false; |
| 63 | 63 | bool isLangChange = false; |
| 64 | - bool isNewShader = false; | |
| 65 | 64 | |
| 66 | 65 | bool showNewShaderPopup = false; |
| 66 | + bool showSaveAsShaderPopup = false; | |
| 67 | 67 | bool viewportFocused = false; |
| 68 | 68 | bool pendingCompile = false; |
| 69 | 69 | |
| @@ -81,4 +81,5 @@ | ||
| 81 | 81 | std::function<void()> compile; |
| 82 | 82 | std::function<void()> save; |
| 83 | 83 | std::function<void()> create; |
| 84 | + std::function<void()> saveAs; | |
| 84 | 85 | }; |
変更
main.cc
| @@ -183,21 +183,13 @@ | ||
| 183 | 183 | gui::Manual manual; |
| 184 | 184 | |
| 185 | 185 | // データベースからシェーダーとLuaコードの受け取り |
| 186 | - vector<db::ShaderData> codeMap = db::GetAllShaders(db); | |
| 187 | - info.shaderId; | |
| 188 | - info.shaderName; | |
| 189 | - info.VERT = {}; | |
| 190 | - info.FRAG = {}; | |
| 191 | - info.LUA = {}; | |
| 186 | + db::ShaderData shaderData = db::GetShader(db, 1); | |
| 187 | + info.shaderId = shaderData.id; | |
| 188 | + info.shaderName = shaderData.name; | |
| 189 | + info.VERT = shaderData.vertexShader; | |
| 190 | + info.FRAG = shaderData.fragmentShader; | |
| 191 | + info.LUA = shaderData.luaCode; | |
| 192 | 192 | |
| 193 | - for (const auto &c : codeMap) { | |
| 194 | - info.shaderId = c.id; | |
| 195 | - info.shaderName = c.name; | |
| 196 | - info.VERT = c.vertexShader; | |
| 197 | - info.FRAG = c.fragmentShader; | |
| 198 | - info.LUA = c.luaCode; | |
| 199 | - } | |
| 200 | - | |
| 201 | 193 | string title = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")"; |
| 202 | 194 | gui::Editor vertEditor((title + "###VertexEditor").c_str(), "VertexEditor", info.VERT.code, gui::Glsl, ge.GetCjkFont(), ge.GetMonoFont()); |
| 203 | 195 | |
| @@ -399,6 +391,40 @@ | ||
| 399 | 391 | } |
| 400 | 392 | }; |
| 401 | 393 | |
| 394 | + info.saveAs = [&]() { | |
| 395 | + if (ImGui::BeginPopupModal(info.i18n->GetWord("filesaveasshader").c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { | |
| 396 | + ImGui::Text(info.i18n->GetWord("fileshadername").c_str()); | |
| 397 | + ImGui::SameLine(); | |
| 398 | + static char str0[128] = "new"; | |
| 399 | + ImGui::InputText("input text", str0, IM_COUNTOF(str0)); | |
| 400 | + | |
| 401 | + ImGui::Separator(); | |
| 402 | + | |
| 403 | + if (ImGui::Button(info.i18n->GetWord("cancel").c_str())) { | |
| 404 | + ImGui::CloseCurrentPopup(); | |
| 405 | + } | |
| 406 | + | |
| 407 | + if (ImGui::Button(info.i18n->GetWord("filesave").c_str())) { | |
| 408 | + info.shaderName = string(str0); | |
| 409 | + info.VERT.code = vertEditor.Get().GetText(); | |
| 410 | + info.FRAG.code = fragEditor.Get().GetText(); | |
| 411 | + info.LUA.code = luaEditor.Get().GetText(); | |
| 412 | + | |
| 413 | + gui::SaveShader saveShader(&info); | |
| 414 | + saveShader.Save(db); | |
| 415 | + db::ShaderData shdr = db::GetShader(db, db::GetLastShaderID(db)); | |
| 416 | + info.shaderId = shdr.id; | |
| 417 | + info.shaderName = shdr.name; | |
| 418 | + info.VERT = shdr.vertexShader; | |
| 419 | + info.FRAG = shdr.fragmentShader; | |
| 420 | + info.LUA = shdr.luaCode; | |
| 421 | + ImGui::CloseCurrentPopup(); | |
| 422 | + } | |
| 423 | + | |
| 424 | + ImGui::EndPopup(); | |
| 425 | + } | |
| 426 | + }; | |
| 427 | + | |
| 402 | 428 | info.create = [&]() { |
| 403 | 429 | if (ImGui::BeginPopupModal(info.i18n->GetWord("filenewcreateshader").c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { |
| 404 | 430 | if (ImGui::Button(info.i18n->GetWord("filenew2dshader").c_str(), ImVec2(200, 0))) { |
| @@ -519,8 +545,8 @@ | ||
| 519 | 545 | |
| 520 | 546 | bool isNewKey = (window.GetKey(GLFW_KEY_N) == GLFW_PRESS && ctrlMod); |
| 521 | 547 | bool isOpenKey = (window.GetKey(GLFW_KEY_O) == GLFW_PRESS && ctrlMod); |
| 522 | - bool isSaveKey = (window.GetKey(GLFW_KEY_S) == GLFW_PRESS && ctrlMod); | |
| 523 | 548 | bool isSaveAsKey = (window.GetKey(GLFW_KEY_S) == GLFW_PRESS && ctrlMod && shiftMod); |
| 549 | + bool isSaveKey = (window.GetKey(GLFW_KEY_S) == GLFW_PRESS && ctrlMod); | |
| 524 | 550 | bool isQuitKey = (window.GetKey(GLFW_KEY_Q) == GLFW_PRESS && ctrlMod); |
| 525 | 551 | bool isAboutKey = (window.GetKey(GLFW_KEY_H) == GLFW_PRESS && ctrlMod); |
| 526 | 552 | bool isSettingsKey = (window.GetKey(GLFW_KEY_COMMA) == GLFW_PRESS && ctrlMod); |
| @@ -536,6 +562,15 @@ | ||
| 536 | 562 | |
| 537 | 563 | if (isOpenKey) {} |
| 538 | 564 | |
| 565 | + if (isSaveAsKey) { | |
| 566 | + info.showSaveAsShaderPopup = true; | |
| 567 | + } | |
| 568 | + | |
| 569 | + if (isSaveKey) { | |
| 570 | + if (info.shaderId == 0) info.showSaveAsShaderPopup = true; | |
| 571 | + else info.save(); | |
| 572 | + } | |
| 573 | + | |
| 539 | 574 | if (isManualKey) { |
| 540 | 575 | info.isManual = true; |
| 541 | 576 | } |
| @@ -548,10 +583,6 @@ | ||
| 548 | 583 | info.isAbout = true; |
| 549 | 584 | } |
| 550 | 585 | |
| 551 | - if (isSaveKey) { | |
| 552 | - info.save(); | |
| 553 | - } | |
| 554 | - | |
| 555 | 586 | if (isQuitKey) { |
| 556 | 587 | info.isRunning = false; |
| 557 | 588 | } |
| @@ -583,12 +614,18 @@ | ||
| 583 | 614 | |
| 584 | 615 | gui::showTitleBar(info); |
| 585 | 616 | |
| 617 | + if (info.showSaveAsShaderPopup) { | |
| 618 | + ImGui::OpenPopup(info.i18n->GetWord("filesaveasshader").c_str()); | |
| 619 | + info.showSaveAsShaderPopup = false; | |
| 620 | + } | |
| 621 | + | |
| 586 | 622 | if (info.showNewShaderPopup) { |
| 587 | 623 | ImGui::OpenPopup(info.i18n->GetWord("filenewcreateshader").c_str()); |
| 588 | 624 | info.showNewShaderPopup = false; |
| 589 | 625 | } |
| 590 | 626 | |
| 591 | 627 | info.create(); |
| 628 | + info.saveAs(); | |
| 592 | 629 | info.compile(); |
| 593 | 630 | |
| 594 | 631 | #ifndef PRODUCTION_BUILD |
| @@ -176,10 +176,10 @@ | ||
| 176 | 176 | } |
| 177 | 177 | |
| 178 | 178 | { |
| 179 | - createWord(db, 1, "file", "ファイル"); | |
| 179 | + createWord(db, 1, "file", "ファイル(F)"); | |
| 180 | 180 | createWord(db, 2, "file", "File"); |
| 181 | - createWord(db, 1, "filenew", "新しいファイル"); | |
| 182 | - createWord(db, 2, "filenew", "New File"); | |
| 181 | + createWord(db, 1, "filenew", "新しいファイル(N)..."); | |
| 182 | + createWord(db, 2, "filenew", "New File..."); | |
| 183 | 183 | createWord(db, 1, "filenewcreateshader", "新しいシェーダーを作成"); |
| 184 | 184 | createWord(db, 2, "filenewcreateshader", "New Shader Creation"); |
| 185 | 185 | createWord(db, 1, "filenew2dshader", "2D シェーダー"); |
| @@ -188,15 +188,21 @@ | ||
| 188 | 188 | createWord(db, 2, "filenew3dshader", "3D Shader"); |
| 189 | 189 | createWord(db, 1, "filenewsceneshader", "シーン シェーダー"); |
| 190 | 190 | createWord(db, 2, "filenewsceneshader", "Scene Shader"); |
| 191 | - createWord(db, 1, "fileopen", "開く"); | |
| 192 | - createWord(db, 2, "fileopen", "Open"); | |
| 193 | - createWord(db, 1, "filesave", "保存"); | |
| 191 | + createWord(db, 1, "fileopen", "開く(O)..."); | |
| 192 | + createWord(db, 2, "fileopen", "Open..."); | |
| 193 | + createWord(db, 1, "filesave", "保存(S)"); | |
| 194 | 194 | createWord(db, 2, "filesave", "Save"); |
| 195 | - createWord(db, 1, "quit", "終了"); | |
| 195 | + createWord(db, 1, "filesaveas", "名前を付けて保存(A)..."); | |
| 196 | + createWord(db, 2, "filesaveas", "Save as..."); | |
| 197 | + createWord(db, 1, "filesaveasshader", "シェーダーの保存"); | |
| 198 | + createWord(db, 2, "filesaveasshader", "Save Shader"); | |
| 199 | + createWord(db, 1, "fileshadername", "シェーダー名"); | |
| 200 | + createWord(db, 2, "fileshadername", "Shader Name"); | |
| 201 | + createWord(db, 1, "quit", "終了(X)"); | |
| 196 | 202 | createWord(db, 2, "quit", "Quit"); |
| 197 | - createWord(db, 1, "cancel", "キャンセル"); | |
| 203 | + createWord(db, 1, "cancel", "キャンセル(C)"); | |
| 198 | 204 | createWord(db, 2, "cancel", "Cancel"); |
| 199 | - createWord(db, 1, "ok", "OK"); | |
| 205 | + createWord(db, 1, "ok", "OK(O)"); | |
| 200 | 206 | createWord(db, 2, "ok", "OK"); |
| 201 | 207 | createWord(db, 1, "editorvertshader", "頂点シェーダー"); |
| 202 | 208 | createWord(db, 2, "editorvertshader", "Vertex Shader"); |
| @@ -208,31 +214,31 @@ | ||
| 208 | 214 | createWord(db, 2, "editorviewport", "Viewport"); |
| 209 | 215 | createWord(db, 1, "editorconsole", "コンソール"); |
| 210 | 216 | createWord(db, 2, "editorconsole", "Console"); |
| 211 | - createWord(db, 1, "editorconsoleclear", "消す"); | |
| 217 | + createWord(db, 1, "editorconsoleclear", "消す(X)"); | |
| 212 | 218 | createWord(db, 2, "editorconsoleclear", "Clear"); |
| 213 | - createWord(db, 1, "edit", "編集"); | |
| 219 | + createWord(db, 1, "edit", "編集(E)"); | |
| 214 | 220 | createWord(db, 2, "edit", "Edit"); |
| 215 | - createWord(db, 1, "editundo", "元に戻す"); | |
| 221 | + createWord(db, 1, "editundo", "元に戻す(U)"); | |
| 216 | 222 | createWord(db, 2, "editundo", "Undo"); |
| 217 | - createWord(db, 1, "editredo", "やり直し"); | |
| 223 | + createWord(db, 1, "editredo", "やり直し(R)"); | |
| 218 | 224 | createWord(db, 2, "editredo", "Redo"); |
| 219 | - createWord(db, 1, "editcut", "切り取り"); | |
| 225 | + createWord(db, 1, "editcut", "切り取り(C)"); | |
| 220 | 226 | createWord(db, 2, "editcut", "Cut"); |
| 221 | - createWord(db, 1, "editcopy", "コピー"); | |
| 227 | + createWord(db, 1, "editcopy", "コピー(Y)"); | |
| 222 | 228 | createWord(db, 2, "editcopy", "Copy"); |
| 223 | - createWord(db, 1, "editpaste", "貼り付け"); | |
| 229 | + createWord(db, 1, "editpaste", "貼り付け(P)"); | |
| 224 | 230 | createWord(db, 2, "editpaste", "Paste"); |
| 225 | - createWord(db, 1, "editduplicate", "行を複製"); | |
| 231 | + createWord(db, 1, "editduplicate", "行を複製(D)"); | |
| 226 | 232 | createWord(db, 2, "editduplicate", "Duplicate"); |
| 227 | - createWord(db, 1, "settings", "設定"); | |
| 233 | + createWord(db, 1, "settings", "設定(S)"); | |
| 228 | 234 | createWord(db, 2, "settings", "Settings"); |
| 229 | - createWord(db, 1, "build", "ビルド"); | |
| 235 | + createWord(db, 1, "build", "ビルド(B)"); | |
| 230 | 236 | createWord(db, 2, "build", "Build"); |
| 231 | - createWord(db, 1, "buildcompile", "コンパイル"); | |
| 237 | + createWord(db, 1, "buildcompile", "コンパイル(C)"); | |
| 232 | 238 | createWord(db, 2, "buildcompile", "Compile"); |
| 233 | - createWord(db, 1, "help", "ヘルプ"); | |
| 239 | + createWord(db, 1, "help", "ヘルプ(H)"); | |
| 234 | 240 | createWord(db, 2, "help", "Help"); |
| 235 | - createWord(db, 1, "helpmanual", "マニュアル"); | |
| 241 | + createWord(db, 1, "helpmanual", "マニュアル(M)"); | |
| 236 | 242 | createWord(db, 2, "helpmanual", "Manual"); |
| 237 | 243 | createWord(db, 1, "helpmanualoverview", "概要"); |
| 238 | 244 | createWord(db, 2, "helpmanualoverview", "Overview"); |
| @@ -242,7 +248,7 @@ | ||
| 242 | 248 | createWord(db, 2, "helpmanuallua", "Lua Engine"); |
| 243 | 249 | createWord(db, 1, "helpmanualhotkey", "ホットキー"); |
| 244 | 250 | createWord(db, 2, "helpmanualhotkey", "Hotkeys"); |
| 245 | - createWord(db, 1, "helpabout", "Shader Playgroundについて"); | |
| 251 | + createWord(db, 1, "helpabout", "Shader Playgroundについて(A)"); | |
| 246 | 252 | createWord(db, 2, "helpabout", "About Shader Playground"); |
| 247 | 253 | createWord(db, 1, "currentfps", "現在フレームレート"); |
| 248 | 254 | createWord(db, 2, "currentfps", "Current Frame Rate"); |
| @@ -41,6 +41,38 @@ | ||
| 41 | 41 | #include <cassert> |
| 42 | 42 | |
| 43 | 43 | namespace db { |
| 44 | + void getShaderCode(sqlitepp::Instance &db, ShaderData &data) { | |
| 45 | + sqlitepp::Stmt stmt(db.GetDB()); | |
| 46 | + stmt.Prepare("SELECT id, code_type, code, filename FROM shader_code WHERE shader_id = ?;"); | |
| 47 | + stmt.BindInt(1, data.id); | |
| 48 | + | |
| 49 | + while (stmt.Step() == SQLITE_ROW) { | |
| 50 | + u32 id = stmt.ColumnInt(0); | |
| 51 | + ShaderCodeType type = static_cast<ShaderCodeType>(stmt.ColumnInt(1)); | |
| 52 | + string code = stmt.ColumnText(2); | |
| 53 | + string filename = stmt.ColumnText(3); | |
| 54 | + | |
| 55 | + if (type == ShaderCodeType::GlslVertex) { | |
| 56 | + data.vertexShader.id = id; | |
| 57 | + data.vertexShader.type = type; | |
| 58 | + data.vertexShader.code = code; | |
| 59 | + data.vertexShader.filename = filename; | |
| 60 | + } else if (type == ShaderCodeType::GlslFragment) { | |
| 61 | + data.fragmentShader.id = id; | |
| 62 | + data.fragmentShader.type = type; | |
| 63 | + data.fragmentShader.code = code; | |
| 64 | + data.fragmentShader.filename = filename; | |
| 65 | + } else if (type == ShaderCodeType::Lua) { | |
| 66 | + data.luaCode.id = id; | |
| 67 | + data.luaCode.type = type; | |
| 68 | + data.luaCode.code = code; | |
| 69 | + data.luaCode.filename = filename; | |
| 70 | + } else { | |
| 71 | + throw std::exception("未対応コード類。"); | |
| 72 | + } | |
| 73 | + } | |
| 74 | + } | |
| 75 | + | |
| 44 | 76 | vector<ShaderData> GetAllShaders(sqlitepp::Instance &db) { |
| 45 | 77 | vector<ShaderData> out; |
| 46 | 78 | |
| @@ -52,45 +84,54 @@ | ||
| 52 | 84 | data.id = stmt.ColumnInt(0); |
| 53 | 85 | data.name = stmt.ColumnText(1); |
| 54 | 86 | data.description = stmt.ColumnText(2); |
| 87 | + getShaderCode(db, data); | |
| 55 | 88 | |
| 56 | - { | |
| 57 | - sqlitepp::Stmt codeStmt(db.GetDB()); | |
| 58 | - codeStmt.Prepare("SELECT id, code_type, code, filename FROM shader_code WHERE shader_id = ?;"); | |
| 59 | - codeStmt.BindInt(1, data.id); | |
| 89 | + out.push_back(std::move(data)); | |
| 90 | + } | |
| 60 | 91 | |
| 61 | - while (codeStmt.Step() == SQLITE_ROW) { | |
| 62 | - u32 id = codeStmt.ColumnInt(0); | |
| 63 | - ShaderCodeType type = static_cast<ShaderCodeType>(codeStmt.ColumnInt(1)); | |
| 64 | - string code = codeStmt.ColumnText(2); | |
| 65 | - string filename = codeStmt.ColumnText(3); | |
| 92 | + return out; | |
| 93 | + } | |
| 66 | 94 | |
| 67 | - if (type == ShaderCodeType::GlslVertex) { | |
| 68 | - data.vertexShader.id = id; | |
| 69 | - data.vertexShader.type = type; | |
| 70 | - data.vertexShader.code = code; | |
| 71 | - data.vertexShader.filename = filename; | |
| 72 | - } else if (type == ShaderCodeType::GlslFragment) { | |
| 73 | - data.fragmentShader.id = id; | |
| 74 | - data.fragmentShader.type = type; | |
| 75 | - data.fragmentShader.code = code; | |
| 76 | - data.fragmentShader.filename = filename; | |
| 77 | - } else if (type == ShaderCodeType::Lua) { | |
| 78 | - data.luaCode.id = id; | |
| 79 | - data.luaCode.type = type; | |
| 80 | - data.luaCode.code = code; | |
| 81 | - data.luaCode.filename = filename; | |
| 82 | - } else { | |
| 83 | - throw std::exception("未対応コード類。"); | |
| 84 | - } | |
| 85 | - } | |
| 86 | - } | |
| 95 | + ShaderData GetShader(sqlitepp::Instance &db, u32 id) { | |
| 96 | + ShaderData data = {}; | |
| 97 | + sqlitepp::Stmt stmt(db.GetDB()); | |
| 98 | + stmt.Prepare("SELECT id, name, description FROM shaders WHERE id = ?;"); | |
| 99 | + stmt.BindInt(1, id); | |
| 87 | 100 | |
| 88 | - out.push_back(std::move(data)); | |
| 101 | + while (stmt.Step() == SQLITE_ROW) { | |
| 102 | + data.id = stmt.ColumnInt(0); | |
| 103 | + data.name = stmt.ColumnText(1); | |
| 104 | + data.description = stmt.ColumnText(2); | |
| 105 | + getShaderCode(db, data); | |
| 89 | 106 | } |
| 90 | 107 | |
| 91 | - return out; | |
| 108 | + return data; | |
| 92 | 109 | } |
| 93 | 110 | |
| 111 | + void insertShaderCode(sqlitepp::Instance &db, const CodeData &data, u32 id) { | |
| 112 | + sqlitepp::Stmt stmt(db.GetDB()); | |
| 113 | + stmt.Prepare("INSERT INTO shader_code (shader_id, code_type, code, filename) VALUES (?, ?, ?, ?);"); | |
| 114 | + stmt.BindInt(1, id); | |
| 115 | + stmt.BindInt(2, static_cast<u32>(data.type)); | |
| 116 | + stmt.BindText(3, data.code); | |
| 117 | + stmt.BindText(4, data.filename); | |
| 118 | + assert(stmt.Step() == SQLITE_DONE && "シェーダーコードの保存に失敗。\n"); | |
| 119 | + } | |
| 120 | + | |
| 121 | + void SaveNewShader(sqlitepp::Instance &db, const ShaderData &data) { | |
| 122 | + sqlitepp::Stmt stmt(db.GetDB()); | |
| 123 | + stmt.Prepare("INSERT INTO shaders (name, description) VALUES (?, ?);"); | |
| 124 | + | |
| 125 | + stmt.BindText(1, data.name); | |
| 126 | + stmt.BindText(2, data.description); | |
| 127 | + | |
| 128 | + assert(stmt.Step() == SQLITE_DONE && "シェーダーの保存に失敗。\n"); | |
| 129 | + u32 id = GetLastShaderID(db); | |
| 130 | + insertShaderCode(db, data.vertexShader, id); | |
| 131 | + insertShaderCode(db, data.fragmentShader, id); | |
| 132 | + insertShaderCode(db, data.luaCode, id); | |
| 133 | + } | |
| 134 | + | |
| 94 | 135 | void SaveCode(sqlitepp::Instance &db, const CodeData &data) { |
| 95 | 136 | sqlitepp::Stmt stmt(db.GetDB()); |
| 96 | 137 | stmt.Prepare("UPDATE shader_code SET code = ?, filename = ? WHERE id = ?;"); |
| @@ -100,5 +141,11 @@ | ||
| 100 | 141 | stmt.BindInt(3, data.id); |
| 101 | 142 | |
| 102 | 143 | assert(stmt.Step() == SQLITE_DONE && "コードの保存に失敗。\n"); |
| 144 | + } | |
| 145 | + | |
| 146 | + u32 GetLastShaderID(sqlitepp::Instance &db) { | |
| 147 | + sqlitepp::Stmt stmt(db.GetDB()); | |
| 148 | + stmt.Prepare("SELECT MAX(id) FROM shaders;"); | |
| 149 | + return (stmt.Step() == SQLITE_ROW) ? stmt.ColumnInt(0) : 0; | |
| 103 | 150 | } |
| 104 | 151 | } // namespace db |
| @@ -39,21 +39,6 @@ | ||
| 39 | 39 | #include <imgui.h> |
| 40 | 40 | |
| 41 | 41 | namespace gui { |
| 42 | - NewShader::NewShader(Info *info) : m_Info(info) {} | |
| 43 | - NewShader::~NewShader() {} | |
| 44 | - | |
| 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(gui::ShaderType::Simple2D); | |
| 52 | - m_Info->create(); | |
| 53 | - } | |
| 54 | - } | |
| 55 | - } | |
| 56 | - | |
| 57 | 42 | db::ShaderData NewShader::Make(ShaderType type) { |
| 58 | 43 | db::ShaderData newShader = {}; |
| 59 | 44 | auto curLang = m_Info->i18n->GetCurrentLanguage().code; |
| @@ -0,0 +1,66 @@ | ||
| 1 | +/* | |
| 2 | +# 076 License | |
| 3 | + | |
| 4 | +Copyright (c) テクニカル諏訪子 | |
| 5 | + | |
| 6 | +Permission is hereby granted to any person obtaining a copy of the software | |
| 7 | +Shader Playground (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 | + - If the Software is used in a product, you must either: | |
| 14 | + a. Provide clear attribution in the product's documentation, user interface, | |
| 15 | + or other visible areas, **OR** | |
| 16 | + b. Pay the original developers a fee they specify in writing. | |
| 17 | + 2. **Usage Restriction**: | |
| 18 | + - The Software, or any derivative works, dependencies, or libraries | |
| 19 | + incorporating it, must not be used for censorship or to suppress freedom of | |
| 20 | + speech, expression, or creativity. Prohibited uses include, but are not | |
| 21 | + limited to: | |
| 22 | + - Censorship of so-called "hate speech", visuals, non-mainstream opinions, | |
| 23 | + ideas, or objective reality. | |
| 24 | + - Tools or systems designed to restrict access to information or | |
| 25 | + artistic works. | |
| 26 | + 3. **Notice Preservation**: | |
| 27 | + - This license and the above copyright notice must remain intact in all copies | |
| 28 | + of the source code. | |
| 29 | + | |
| 30 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |
| 31 | +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |
| 32 | +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
| 33 | +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
| 34 | +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |
| 35 | +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 36 | +*/ | |
| 37 | +#include <gui/saveshader.hh> | |
| 38 | +#include <gui/consolelog.hh> | |
| 39 | +#include <database/locale.hh> | |
| 40 | +#include <database/shaderdata.hh> | |
| 41 | +#include <imgui.h> | |
| 42 | +#include <iostream> | |
| 43 | + | |
| 44 | +namespace gui { | |
| 45 | + void SaveShader::Save(sqlitepp::Instance &db) { | |
| 46 | + db::ShaderData saveShader = {}; | |
| 47 | + saveShader.name = m_Info->shaderName; | |
| 48 | + saveShader.description = ""; | |
| 49 | + saveShader.vertexShader.filename = m_Info->shaderName + ".vert"; | |
| 50 | + saveShader.vertexShader.type = db::ShaderCodeType::GlslVertex; | |
| 51 | + saveShader.vertexShader.code = m_Info->VERT.code; | |
| 52 | + saveShader.fragmentShader.filename = m_Info->shaderName + ".frag"; | |
| 53 | + saveShader.fragmentShader.type = db::ShaderCodeType::GlslFragment; | |
| 54 | + saveShader.fragmentShader.code = m_Info->FRAG.code; | |
| 55 | + saveShader.luaCode.filename = m_Info->shaderName + ".lua"; | |
| 56 | + saveShader.luaCode.type = db::ShaderCodeType::Lua; | |
| 57 | + saveShader.luaCode.code = m_Info->LUA.code; | |
| 58 | + | |
| 59 | + db::SaveNewShader(db, saveShader); | |
| 60 | + | |
| 61 | + LogEntry entry; | |
| 62 | + entry.text = saveShader.name; | |
| 63 | + entry.type = LogType::Normal; | |
| 64 | + m_Info->cmd->Add(entry); | |
| 65 | + } | |
| 66 | +} // namespace gui |