クリアカラーの設定可能に

守矢諏訪子 <suwako@076.moe>、2026-06-28 21:37
コミット 0133274dc0d14c24e1d43d72420c165bac265624 ・親 c35ce33 ・ファイルを見る

8個のファイル、+148 -20

@@ -37,6 +37,7 @@
3737 #pragma once
3838
3939 #include <util/types.hh>
40+#include <util/vector.hh>
4041 #include <database/setup.hh>
4142
4243 namespace sqlitepp {
@@ -58,11 +59,13 @@
5859 CodeData vertexShader = {};
5960 CodeData fragmentShader = {};
6061 CodeData luaCode = {};
62+ Vector4 clearColor = {};
6163 };
6264
6365 vector<ShaderData> GetAllShaders(sqlitepp::Instance &db);
6466 ShaderData GetShader(sqlitepp::Instance &db, u32 id);
6567 void SaveNewShader(sqlitepp::Instance &db, const ShaderData &data);
68+ void SaveSkybox(sqlitepp::Instance &db, const ShaderData &data);
6669 void SaveCode(sqlitepp::Instance &db, const CodeData &data);
6770 u32 GetLastShaderID(sqlitepp::Instance &db);
6871 } // namespace db
@@ -37,6 +37,7 @@
3737 #pragma once
3838
3939 #include <util/glfwpp.hh>
40+#include <util/vector.hh>
4041 #include <version.hh>
4142 #include <functional>
4243 #include <string>
@@ -75,6 +76,7 @@
7576 db::CodeData FRAG = {};
7677 db::CodeData LUA = {};
7778 std::string currentFile = "";
79+ Vector4 sceneClearColor = {};
7880
7981 gui::ConsoleLog *cmd;
8082 db::Locale *i18n;
変更 main.cc
@@ -183,12 +183,15 @@
183183 gui::Manual manual;
184184
185185 // データベースからシェーダーと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+ }
192195
193196 string title = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")";
194197 gui::Editor vertEditor((title + "###VertexEditor").c_str(), "VertexEditor", info.VERT.code, gui::Glsl, ge.GetCjkFont(), ge.GetMonoFont());
@@ -365,7 +368,13 @@
365368 return;
366369 }
367370
371+ db::ShaderData shdr;
372+ shdr.id = info.shaderId;
373+ shdr.clearColor = info.sceneClearColor;
374+
375+ db::SaveSkybox(db, shdr);
368376 db::SaveCode(db, info.VERT);
377+ db::SaveCode(db, info.VERT);
369378 db::SaveCode(db, info.FRAG);
370379 db::SaveCode(db, info.LUA);
371380
@@ -392,7 +401,7 @@
392401 if (ImGui::BeginPopupModal(info.i18n->GetWord("fileopenshader").c_str(), nullptr)) {
393402 if (ImGui::IsKeyPressed(ImGuiKey_Escape)) ImGui::CloseCurrentPopup();
394403
395- vector <db::ShaderData > shdrs = db::GetAllShaders(db);
404+ vector <db::ShaderData> shdrs = db::GetAllShaders(db);
396405 ImGui::BeginChild("ShaderList", ImVec2(0, 300), true);
397406
398407 for (const auto &s : shdrs) {
@@ -417,6 +426,7 @@
417426 db::ShaderData shaderData = db::GetShader(db, selectedId);
418427 info.shaderId = shaderData.id;
419428 info.shaderName = shaderData.name;
429+ info.sceneClearColor = shaderData.clearColor;
420430 info.VERT = shaderData.vertexShader;
421431 info.FRAG = shaderData.fragmentShader;
422432 info.LUA = shaderData.luaCode;
@@ -470,6 +480,7 @@
470480 db::ShaderData shdr = db::GetShader(db, db::GetLastShaderID(db));
471481 info.shaderId = shdr.id;
472482 info.shaderName = shdr.name;
483+ info.sceneClearColor = shdr.clearColor;
473484 info.VERT = shdr.vertexShader;
474485 info.FRAG = shdr.fragmentShader;
475486 info.LUA = shdr.luaCode;
@@ -499,6 +510,7 @@
499510 auto shdr = newShader.Make(gui::ShaderType::Simple2D);
500511 info.shaderId = shdr.id;
501512 info.shaderName = shdr.name;
513+ info.sceneClearColor = shdr.clearColor;
502514 info.VERT = shdr.vertexShader;
503515 info.FRAG = shdr.fragmentShader;
504516 info.LUA = shdr.luaCode;
@@ -531,6 +543,7 @@
531543 auto shdr = newShader.Make(gui::ShaderType::Simple3D);
532544 info.shaderId = shdr.id;
533545 info.shaderName = shdr.name;
546+ info.sceneClearColor = shdr.clearColor;
534547 info.VERT = shdr.vertexShader;
535548 info.FRAG = shdr.fragmentShader;
536549 info.LUA = shdr.luaCode;
@@ -563,6 +576,7 @@
563576 auto shdr = newShader.Make(gui::ShaderType::Scene);
564577 info.shaderId = shdr.id;
565578 info.shaderName = shdr.name;
579+ info.sceneClearColor = shdr.clearColor;
566580 info.VERT = shdr.vertexShader;
567581 info.FRAG = shdr.fragmentShader;
568582 info.LUA = shdr.luaCode;
@@ -790,8 +804,11 @@
790804 // 画面をクリア
791805 glBindFramebuffer(GL_FRAMEBUFFER, viewport.GetFBO());
792806 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+ }
795812
796813 // シェーダープログラムを使用
797814 shaderProgram.Use();
@@ -81,8 +81,8 @@
8181 CREATE TRIGGER IF NOT EXISTS version_updated_at
8282 AFTER UPDATE ON version
8383 BEGIN
84- UPDATE version
85- SET updated_at = CURRENT_TIMESTAMP
84+ UPDATE version
85+ SET updated_at = CURRENT_TIMESTAMP
8686 WHERE id = NEW.id;
8787 END;
8888
@@ -100,13 +100,34 @@
100100 AFTER UPDATE ON scenes
101101 BEGIN
102102 UPDATE scenes
103- SET updated_at = CURRENT_TIMESTAMP
103+ SET updated_at = CURRENT_TIMESTAMP
104104 WHERE id = NEW.id;
105105 END;
106106
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+
107128 CREATE TABLE IF NOT EXISTS scene_code (
108129 id INTEGER PRIMARY KEY,
109- scene_id INTEGER NOT NULL,
130+ scene_id INTEGER NOT NULL,
110131 code_type INTEGER NOT NULL,
111132 code TEXT NOT NULL,
112133 filename TEXT,
@@ -120,7 +141,7 @@
120141 AFTER UPDATE ON scene_code
121142 BEGIN
122143 UPDATE scene_code
123- SET updated_at = CURRENT_TIMESTAMP
144+ SET updated_at = CURRENT_TIMESTAMP
124145 WHERE id = NEW.id;
125146 END;
126147
@@ -266,6 +287,8 @@
266287 createWord(db, 2, "consoleloginfolangchangeok", "Language has been changed.");
267288 createWord(db, 1, "consoleloginfocreateok", "新しいシェーダーを作成しました。保存するには、「CTRL + S」を押して下さい。");
268289 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");
269292 }
270293
271294 i64 shaderId = 0;
@@ -277,6 +300,18 @@
277300 stmt.BindText(2, "");
278301 assert(stmt.Step() == SQLITE_DONE && "最初のシェーダーを入れ込みに失敗。\n");
279302 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");
280315 }
281316
282317 {
@@ -73,6 +73,21 @@
7373 }
7474 }
7575
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+
7691 vector<ShaderData> GetAllShaders(sqlitepp::Instance &db) {
7792 vector<ShaderData> out;
7893
@@ -85,6 +100,7 @@
85100 data.name = stmt.ColumnText(1);
86101 data.description = stmt.ColumnText(2);
87102 getShaderCode(db, data);
103+ getShaderSkybox(db, data);
88104
89105 out.push_back(std::move(data));
90106 }
@@ -103,21 +119,35 @@
103119 data.name = stmt.ColumnText(1);
104120 data.description = stmt.ColumnText(2);
105121 getShaderCode(db, data);
122+ getShaderSkybox(db, data);
106123 }
107124
108125 return data;
109126 }
110127
111- void insertShaderCode(sqlitepp::Instance &db, const CodeData &data, u32 id) {
128+ void insertSceneCode(sqlitepp::Instance &db, const CodeData &data, u32 id) {
112129 sqlitepp::Stmt stmt(db.GetDB());
113130 stmt.Prepare("INSERT INTO scene_code (scene_id, code_type, code, filename) VALUES (?, ?, ?, ?);");
114131 stmt.BindInt(1, id);
115132 stmt.BindInt(2, static_cast<u32>(data.type));
116133 stmt.BindText(3, data.code);
117134 stmt.BindText(4, data.filename);
118- assert(stmt.Step() == SQLITE_DONE && "シェーダーコードの保存に失敗。\n");
135+ assert(stmt.Step() == SQLITE_DONE && "シーンコードの保存に失敗。\n");
119136 }
120137
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+
121151 void SaveNewShader(sqlitepp::Instance &db, const ShaderData &data) {
122152 sqlitepp::Stmt stmt(db.GetDB());
123153 stmt.Prepare("INSERT INTO scenes (name, description) VALUES (?, ?);");
@@ -125,11 +155,26 @@
125155 stmt.BindText(1, data.name);
126156 stmt.BindText(2, data.description);
127157
128- assert(stmt.Step() == SQLITE_DONE && "シェーダーの保存に失敗。\n");
158+ assert(stmt.Step() == SQLITE_DONE && "シーンの保存に失敗。\n");
129159 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");
133178 }
134179
135180 void SaveCode(sqlitepp::Instance &db, const CodeData &data) {
@@ -36,6 +36,7 @@
3636 */
3737 #include <gui/newshader.hh>
3838 #include <database/locale.hh>
39+#include <util/vector.hh>
3940 #include <imgui.h>
4041
4142 namespace gui {
@@ -45,6 +46,7 @@
4546 newShader.id = 0;
4647 if (curLang == "ja_JP") newShader.name = "(名無し)";
4748 else newShader.name = "(Unnamed)";
49+ newShader.clearColor.rgba = { 0.f, 0.f, 0.f, 1.f };
4850 newShader.description = "";
4951
5052 newShader.vertexShader.id = 0;
@@ -46,6 +46,7 @@
4646 db::ShaderData saveShader = {};
4747 saveShader.name = m_Info->shaderName;
4848 saveShader.description = "";
49+ saveShader.clearColor = m_Info->sceneClearColor;
4950 saveShader.vertexShader.filename = m_Info->shaderName + ".vert";
5051 saveShader.vertexShader.type = db::ShaderCodeType::GlslVertex;
5152 saveShader.vertexShader.code = m_Info->VERT.code;
@@ -125,6 +125,29 @@
125125 }
126126
127127 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+
128151 ImGui::End();
129152 }
130153 } // namespace gui