クリアカラーの設定可能に
守矢諏訪子 <suwako@076.moe>、2026-06-28 21:37
コミット 0133274dc0d14c24e1d43d72420c165bac265624
・親 c35ce33
・ファイルを見る
8個のファイル、+148 -20
| @@ -37,6 +37,7 @@ | ||
| 37 | 37 | #pragma once |
| 38 | 38 | |
| 39 | 39 | #include <util/types.hh> |
| 40 | +#include <util/vector.hh> | |
| 40 | 41 | #include <database/setup.hh> |
| 41 | 42 | |
| 42 | 43 | namespace sqlitepp { |
| @@ -58,11 +59,13 @@ | ||
| 58 | 59 | CodeData vertexShader = {}; |
| 59 | 60 | CodeData fragmentShader = {}; |
| 60 | 61 | CodeData luaCode = {}; |
| 62 | + Vector4 clearColor = {}; | |
| 61 | 63 | }; |
| 62 | 64 | |
| 63 | 65 | vector<ShaderData> GetAllShaders(sqlitepp::Instance &db); |
| 64 | 66 | ShaderData GetShader(sqlitepp::Instance &db, u32 id); |
| 65 | 67 | void SaveNewShader(sqlitepp::Instance &db, const ShaderData &data); |
| 68 | + void SaveSkybox(sqlitepp::Instance &db, const ShaderData &data); | |
| 66 | 69 | void SaveCode(sqlitepp::Instance &db, const CodeData &data); |
| 67 | 70 | u32 GetLastShaderID(sqlitepp::Instance &db); |
| 68 | 71 | } // namespace db |
| @@ -37,6 +37,7 @@ | ||
| 37 | 37 | #pragma once |
| 38 | 38 | |
| 39 | 39 | #include <util/glfwpp.hh> |
| 40 | +#include <util/vector.hh> | |
| 40 | 41 | #include <version.hh> |
| 41 | 42 | #include <functional> |
| 42 | 43 | #include <string> |
| @@ -75,6 +76,7 @@ | ||
| 75 | 76 | db::CodeData FRAG = {}; |
| 76 | 77 | db::CodeData LUA = {}; |
| 77 | 78 | std::string currentFile = ""; |
| 79 | + Vector4 sceneClearColor = {}; | |
| 78 | 80 | |
| 79 | 81 | gui::ConsoleLog *cmd; |
| 80 | 82 | db::Locale *i18n; |
変更
main.cc
| @@ -183,12 +183,15 @@ | ||
| 183 | 183 | gui::Manual manual; |
| 184 | 184 | |
| 185 | 185 | // データベースからシェーダーと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; | |
| 186 | + { | |
| 187 | + db::ShaderData shaderData = db::GetShader(db, 1); | |
| 188 | + info.shaderId = shaderData.id; | |
| 189 | + info.shaderName = shaderData.name; | |
| 190 | + info.sceneClearColor = shaderData.clearColor; | |
| 191 | + info.VERT = shaderData.vertexShader; | |
| 192 | + info.FRAG = shaderData.fragmentShader; | |
| 193 | + info.LUA = shaderData.luaCode; | |
| 194 | + } | |
| 192 | 195 | |
| 193 | 196 | string title = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")"; |
| 194 | 197 | gui::Editor vertEditor((title + "###VertexEditor").c_str(), "VertexEditor", info.VERT.code, gui::Glsl, ge.GetCjkFont(), ge.GetMonoFont()); |
| @@ -365,7 +368,13 @@ | ||
| 365 | 368 | return; |
| 366 | 369 | } |
| 367 | 370 | |
| 371 | + db::ShaderData shdr; | |
| 372 | + shdr.id = info.shaderId; | |
| 373 | + shdr.clearColor = info.sceneClearColor; | |
| 374 | + | |
| 375 | + db::SaveSkybox(db, shdr); | |
| 368 | 376 | db::SaveCode(db, info.VERT); |
| 377 | + db::SaveCode(db, info.VERT); | |
| 369 | 378 | db::SaveCode(db, info.FRAG); |
| 370 | 379 | db::SaveCode(db, info.LUA); |
| 371 | 380 | |
| @@ -392,7 +401,7 @@ | ||
| 392 | 401 | if (ImGui::BeginPopupModal(info.i18n->GetWord("fileopenshader").c_str(), nullptr)) { |
| 393 | 402 | if (ImGui::IsKeyPressed(ImGuiKey_Escape)) ImGui::CloseCurrentPopup(); |
| 394 | 403 | |
| 395 | - vector <db::ShaderData > shdrs = db::GetAllShaders(db); | |
| 404 | + vector <db::ShaderData> shdrs = db::GetAllShaders(db); | |
| 396 | 405 | ImGui::BeginChild("ShaderList", ImVec2(0, 300), true); |
| 397 | 406 | |
| 398 | 407 | for (const auto &s : shdrs) { |
| @@ -417,6 +426,7 @@ | ||
| 417 | 426 | db::ShaderData shaderData = db::GetShader(db, selectedId); |
| 418 | 427 | info.shaderId = shaderData.id; |
| 419 | 428 | info.shaderName = shaderData.name; |
| 429 | + info.sceneClearColor = shaderData.clearColor; | |
| 420 | 430 | info.VERT = shaderData.vertexShader; |
| 421 | 431 | info.FRAG = shaderData.fragmentShader; |
| 422 | 432 | info.LUA = shaderData.luaCode; |
| @@ -470,6 +480,7 @@ | ||
| 470 | 480 | db::ShaderData shdr = db::GetShader(db, db::GetLastShaderID(db)); |
| 471 | 481 | info.shaderId = shdr.id; |
| 472 | 482 | info.shaderName = shdr.name; |
| 483 | + info.sceneClearColor = shdr.clearColor; | |
| 473 | 484 | info.VERT = shdr.vertexShader; |
| 474 | 485 | info.FRAG = shdr.fragmentShader; |
| 475 | 486 | info.LUA = shdr.luaCode; |
| @@ -499,6 +510,7 @@ | ||
| 499 | 510 | auto shdr = newShader.Make(gui::ShaderType::Simple2D); |
| 500 | 511 | info.shaderId = shdr.id; |
| 501 | 512 | info.shaderName = shdr.name; |
| 513 | + info.sceneClearColor = shdr.clearColor; | |
| 502 | 514 | info.VERT = shdr.vertexShader; |
| 503 | 515 | info.FRAG = shdr.fragmentShader; |
| 504 | 516 | info.LUA = shdr.luaCode; |
| @@ -531,6 +543,7 @@ | ||
| 531 | 543 | auto shdr = newShader.Make(gui::ShaderType::Simple3D); |
| 532 | 544 | info.shaderId = shdr.id; |
| 533 | 545 | info.shaderName = shdr.name; |
| 546 | + info.sceneClearColor = shdr.clearColor; | |
| 534 | 547 | info.VERT = shdr.vertexShader; |
| 535 | 548 | info.FRAG = shdr.fragmentShader; |
| 536 | 549 | info.LUA = shdr.luaCode; |
| @@ -563,6 +576,7 @@ | ||
| 563 | 576 | auto shdr = newShader.Make(gui::ShaderType::Scene); |
| 564 | 577 | info.shaderId = shdr.id; |
| 565 | 578 | info.shaderName = shdr.name; |
| 579 | + info.sceneClearColor = shdr.clearColor; | |
| 566 | 580 | info.VERT = shdr.vertexShader; |
| 567 | 581 | info.FRAG = shdr.fragmentShader; |
| 568 | 582 | info.LUA = shdr.luaCode; |
| @@ -790,8 +804,11 @@ | ||
| 790 | 804 | // 画面をクリア |
| 791 | 805 | glBindFramebuffer(GL_FRAMEBUFFER, viewport.GetFBO()); |
| 792 | 806 | glViewport(0, 0, viewport.GetWidth(), viewport.GetHeight()); |
| 793 | - shaderProgram.ClearColor(0.f, 0.f, 0.f, 1.f); | |
| 794 | - shaderProgram.Clear(); | |
| 807 | + { | |
| 808 | + auto cc = info.sceneClearColor.rgba; | |
| 809 | + shaderProgram.ClearColor(cc.r, cc.g, cc.b, cc.a); | |
| 810 | + shaderProgram.Clear(); | |
| 811 | + } | |
| 795 | 812 | |
| 796 | 813 | // シェーダープログラムを使用 |
| 797 | 814 | shaderProgram.Use(); |
| @@ -81,8 +81,8 @@ | ||
| 81 | 81 | CREATE TRIGGER IF NOT EXISTS version_updated_at |
| 82 | 82 | AFTER UPDATE ON version |
| 83 | 83 | BEGIN |
| 84 | - UPDATE version | |
| 85 | - SET updated_at = CURRENT_TIMESTAMP | |
| 84 | + UPDATE version | |
| 85 | + SET updated_at = CURRENT_TIMESTAMP | |
| 86 | 86 | WHERE id = NEW.id; |
| 87 | 87 | END; |
| 88 | 88 | |
| @@ -100,13 +100,34 @@ | ||
| 100 | 100 | AFTER UPDATE ON scenes |
| 101 | 101 | BEGIN |
| 102 | 102 | UPDATE scenes |
| 103 | - SET updated_at = CURRENT_TIMESTAMP | |
| 103 | + SET updated_at = CURRENT_TIMESTAMP | |
| 104 | 104 | WHERE id = NEW.id; |
| 105 | 105 | END; |
| 106 | 106 | |
| 107 | +CREATE TABLE IF NOT EXISTS scene_skybox ( | |
| 108 | + id INTEGER PRIMARY KEY, | |
| 109 | + scene_id INTEGER NOT NULL, | |
| 110 | + clear_r REAL NOT NULL, | |
| 111 | + clear_g REAL NOT NULL, | |
| 112 | + clear_b REAL NOT NULL, | |
| 113 | + clear_a REAL NOT NULL, | |
| 114 | + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, | |
| 115 | + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, | |
| 116 | + | |
| 117 | + FOREIGN KEY (scene_id) REFERENCES scenes(id) ON DELETE CASCADE | |
| 118 | +); | |
| 119 | + | |
| 120 | +CREATE TRIGGER IF NOT EXISTS scene_skybox_updated_at | |
| 121 | +AFTER UPDATE ON scene_skybox | |
| 122 | +BEGIN | |
| 123 | + UPDATE scene_skybox | |
| 124 | + SET updated_at = CURRENT_TIMESTAMP | |
| 125 | + WHERE id = NEW.id; | |
| 126 | +END; | |
| 127 | + | |
| 107 | 128 | CREATE TABLE IF NOT EXISTS scene_code ( |
| 108 | 129 | id INTEGER PRIMARY KEY, |
| 109 | - scene_id INTEGER NOT NULL, | |
| 130 | + scene_id INTEGER NOT NULL, | |
| 110 | 131 | code_type INTEGER NOT NULL, |
| 111 | 132 | code TEXT NOT NULL, |
| 112 | 133 | filename TEXT, |
| @@ -120,7 +141,7 @@ | ||
| 120 | 141 | AFTER UPDATE ON scene_code |
| 121 | 142 | BEGIN |
| 122 | 143 | UPDATE scene_code |
| 123 | - SET updated_at = CURRENT_TIMESTAMP | |
| 144 | + SET updated_at = CURRENT_TIMESTAMP | |
| 124 | 145 | WHERE id = NEW.id; |
| 125 | 146 | END; |
| 126 | 147 | |
| @@ -266,6 +287,8 @@ | ||
| 266 | 287 | createWord(db, 2, "consoleloginfolangchangeok", "Language has been changed."); |
| 267 | 288 | createWord(db, 1, "consoleloginfocreateok", "新しいシェーダーを作成しました。保存するには、「CTRL + S」を押して下さい。"); |
| 268 | 289 | createWord(db, 2, "consoleloginfocreateok", "New shader has been created. In order to save, press \"CTRL + S\"."); |
| 290 | + createWord(db, 1, "clearcolor", "クリアカラー"); | |
| 291 | + createWord(db, 2, "clearcolor", "Clear color"); | |
| 269 | 292 | } |
| 270 | 293 | |
| 271 | 294 | i64 shaderId = 0; |
| @@ -277,6 +300,18 @@ | ||
| 277 | 300 | stmt.BindText(2, ""); |
| 278 | 301 | assert(stmt.Step() == SQLITE_DONE && "最初のシェーダーを入れ込みに失敗。\n"); |
| 279 | 302 | shaderId = db.GetLastInsertId(); |
| 303 | + } | |
| 304 | + | |
| 305 | + { | |
| 306 | + sqlitepp::Stmt stmt(db.GetDB()); | |
| 307 | + stmt.Prepare("INSERT INTO scene_skybox (scene_id, clear_r, clear_g, clear_b, clear_a) VALUES (?, ?, ?, ?, ?);"); | |
| 308 | + stmt.BindInt(1, shaderId); | |
| 309 | + stmt.BindDouble(2, 0.f); | |
| 310 | + stmt.BindDouble(3, 0.f); | |
| 311 | + stmt.BindDouble(4, 0.f); | |
| 312 | + stmt.BindDouble(5, 1.f); | |
| 313 | + | |
| 314 | + assert(stmt.Step() == SQLITE_DONE && "最初のシェーダーを入れ込みに失敗。\n"); | |
| 280 | 315 | } |
| 281 | 316 | |
| 282 | 317 | { |
| @@ -73,6 +73,21 @@ | ||
| 73 | 73 | } |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | + void getShaderSkybox(sqlitepp::Instance &db, ShaderData &data) { | |
| 77 | + sqlitepp::Stmt stmt(db.GetDB()); | |
| 78 | + stmt.Prepare("SELECT clear_r, clear_g, clear_b, clear_a FROM scene_skybox WHERE scene_id = ?;"); | |
| 79 | + stmt.BindInt(1, data.id); | |
| 80 | + | |
| 81 | + while (stmt.Step() == SQLITE_ROW) { | |
| 82 | + f32 r = stmt.ColumnDouble(0); | |
| 83 | + f32 g = stmt.ColumnDouble(1); | |
| 84 | + f32 b = stmt.ColumnDouble(2); | |
| 85 | + f32 a = stmt.ColumnDouble(3); | |
| 86 | + | |
| 87 | + data.clearColor = { r, g, b, a }; | |
| 88 | + } | |
| 89 | + } | |
| 90 | + | |
| 76 | 91 | vector<ShaderData> GetAllShaders(sqlitepp::Instance &db) { |
| 77 | 92 | vector<ShaderData> out; |
| 78 | 93 | |
| @@ -85,6 +100,7 @@ | ||
| 85 | 100 | data.name = stmt.ColumnText(1); |
| 86 | 101 | data.description = stmt.ColumnText(2); |
| 87 | 102 | getShaderCode(db, data); |
| 103 | + getShaderSkybox(db, data); | |
| 88 | 104 | |
| 89 | 105 | out.push_back(std::move(data)); |
| 90 | 106 | } |
| @@ -103,21 +119,35 @@ | ||
| 103 | 119 | data.name = stmt.ColumnText(1); |
| 104 | 120 | data.description = stmt.ColumnText(2); |
| 105 | 121 | getShaderCode(db, data); |
| 122 | + getShaderSkybox(db, data); | |
| 106 | 123 | } |
| 107 | 124 | |
| 108 | 125 | return data; |
| 109 | 126 | } |
| 110 | 127 | |
| 111 | - void insertShaderCode(sqlitepp::Instance &db, const CodeData &data, u32 id) { | |
| 128 | + void insertSceneCode(sqlitepp::Instance &db, const CodeData &data, u32 id) { | |
| 112 | 129 | sqlitepp::Stmt stmt(db.GetDB()); |
| 113 | 130 | stmt.Prepare("INSERT INTO scene_code (scene_id, code_type, code, filename) VALUES (?, ?, ?, ?);"); |
| 114 | 131 | stmt.BindInt(1, id); |
| 115 | 132 | stmt.BindInt(2, static_cast<u32>(data.type)); |
| 116 | 133 | stmt.BindText(3, data.code); |
| 117 | 134 | stmt.BindText(4, data.filename); |
| 118 | - assert(stmt.Step() == SQLITE_DONE && "シェーダーコードの保存に失敗。\n"); | |
| 135 | + assert(stmt.Step() == SQLITE_DONE && "シーンコードの保存に失敗。\n"); | |
| 119 | 136 | } |
| 120 | 137 | |
| 138 | + void insertSceneSkybox(sqlitepp::Instance &db, const ShaderData &data, u32 id) { | |
| 139 | + sqlitepp::Stmt stmt(db.GetDB()); | |
| 140 | + stmt.Prepare("INSERT INTO scene_skybox (scene_id, clear_r, clear_g, clear_b, clear_a) VALUES (?, ?, ?, ?, ?);"); | |
| 141 | + auto col = data.clearColor.rgba; | |
| 142 | + | |
| 143 | + stmt.BindInt(1, id); | |
| 144 | + stmt.BindDouble(2, col.r); | |
| 145 | + stmt.BindDouble(3, col.g); | |
| 146 | + stmt.BindDouble(4, col.b); | |
| 147 | + stmt.BindDouble(5, col.a); | |
| 148 | + assert(stmt.Step() == SQLITE_DONE && "シーンスカイボックスの保存に失敗。\n"); | |
| 149 | + } | |
| 150 | + | |
| 121 | 151 | void SaveNewShader(sqlitepp::Instance &db, const ShaderData &data) { |
| 122 | 152 | sqlitepp::Stmt stmt(db.GetDB()); |
| 123 | 153 | stmt.Prepare("INSERT INTO scenes (name, description) VALUES (?, ?);"); |
| @@ -125,11 +155,26 @@ | ||
| 125 | 155 | stmt.BindText(1, data.name); |
| 126 | 156 | stmt.BindText(2, data.description); |
| 127 | 157 | |
| 128 | - assert(stmt.Step() == SQLITE_DONE && "シェーダーの保存に失敗。\n"); | |
| 158 | + assert(stmt.Step() == SQLITE_DONE && "シーンの保存に失敗。\n"); | |
| 129 | 159 | u32 id = GetLastShaderID(db); |
| 130 | - insertShaderCode(db, data.vertexShader, id); | |
| 131 | - insertShaderCode(db, data.fragmentShader, id); | |
| 132 | - insertShaderCode(db, data.luaCode, id); | |
| 160 | + insertSceneSkybox(db, data, id); | |
| 161 | + insertSceneCode(db, data.vertexShader, id); | |
| 162 | + insertSceneCode(db, data.fragmentShader, id); | |
| 163 | + insertSceneCode(db, data.luaCode, id); | |
| 164 | + } | |
| 165 | + | |
| 166 | + void SaveSkybox(sqlitepp::Instance &db, const ShaderData &data) { | |
| 167 | + sqlitepp::Stmt stmt(db.GetDB()); | |
| 168 | + stmt.Prepare("UPDATE scene_skybox SET clear_r = ?, clear_g = ?, clear_b = ?, clear_a = ? WHERE scene_id = ?;"); | |
| 169 | + auto col = data.clearColor.rgba; | |
| 170 | + | |
| 171 | + stmt.BindDouble(1, col.r); | |
| 172 | + stmt.BindDouble(2, col.g); | |
| 173 | + stmt.BindDouble(3, col.b); | |
| 174 | + stmt.BindDouble(4, col.a); | |
| 175 | + stmt.BindDouble(5, data.id); | |
| 176 | + | |
| 177 | + assert(stmt.Step() == SQLITE_DONE && "スカイボックスの保存に失敗。\n"); | |
| 133 | 178 | } |
| 134 | 179 | |
| 135 | 180 | void SaveCode(sqlitepp::Instance &db, const CodeData &data) { |
| @@ -36,6 +36,7 @@ | ||
| 36 | 36 | */ |
| 37 | 37 | #include <gui/newshader.hh> |
| 38 | 38 | #include <database/locale.hh> |
| 39 | +#include <util/vector.hh> | |
| 39 | 40 | #include <imgui.h> |
| 40 | 41 | |
| 41 | 42 | namespace gui { |
| @@ -45,6 +46,7 @@ | ||
| 45 | 46 | newShader.id = 0; |
| 46 | 47 | if (curLang == "ja_JP") newShader.name = "(名無し)"; |
| 47 | 48 | else newShader.name = "(Unnamed)"; |
| 49 | + newShader.clearColor.rgba = { 0.f, 0.f, 0.f, 1.f }; | |
| 48 | 50 | newShader.description = ""; |
| 49 | 51 | |
| 50 | 52 | newShader.vertexShader.id = 0; |
| @@ -46,6 +46,7 @@ | ||
| 46 | 46 | db::ShaderData saveShader = {}; |
| 47 | 47 | saveShader.name = m_Info->shaderName; |
| 48 | 48 | saveShader.description = ""; |
| 49 | + saveShader.clearColor = m_Info->sceneClearColor; | |
| 49 | 50 | saveShader.vertexShader.filename = m_Info->shaderName + ".vert"; |
| 50 | 51 | saveShader.vertexShader.type = db::ShaderCodeType::GlslVertex; |
| 51 | 52 | saveShader.vertexShader.code = m_Info->VERT.code; |
| @@ -125,6 +125,29 @@ | ||
| 125 | 125 | } |
| 126 | 126 | |
| 127 | 127 | ImGui::Image((ImTextureID)(intptr_t)m_Texture, avail, ImVec2(0, 1), ImVec2(1, 0)); |
| 128 | + | |
| 129 | + if (ImGui::BeginPopupContextItem("scene props")) { | |
| 130 | + Vector4 col = info.sceneClearColor; | |
| 131 | + ImVec4 bytecol( | |
| 132 | + col.rgba.r, | |
| 133 | + col.rgba.g, | |
| 134 | + col.rgba.b, | |
| 135 | + col.rgba.a | |
| 136 | + ); | |
| 137 | + | |
| 138 | + ImGui::Text("%s", info.i18n->GetWord("clearcolor").c_str()); | |
| 139 | + ImGui::SameLine(); | |
| 140 | + ImGui::ColorEdit4("##clearcolor", (f32 *)&bytecol); | |
| 141 | + | |
| 142 | + col.rgba.a = bytecol.w; | |
| 143 | + col.rgba.r = bytecol.x; | |
| 144 | + col.rgba.g = bytecol.y; | |
| 145 | + col.rgba.b = bytecol.z; | |
| 146 | + info.sceneClearColor = col; | |
| 147 | + | |
| 148 | + ImGui::EndPopup(); | |
| 149 | + } | |
| 150 | + | |
| 128 | 151 | ImGui::End(); |
| 129 | 152 | } |
| 130 | 153 | } // namespace gui |