| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 | |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | |
| 32 | |
| 33 | |
| 34 | |
| 35 | |
| 36 | |
| 37 | #include <database/shaderdata.hh> |
| 38 | #include <util/sqlitepp.hh> |
| 39 | #include <sqlite3.h> |
| 40 | #include <iostream> |
| 41 | #include <cassert> |
| 42 | #include <stdexcept> |
| 43 | |
| 44 | namespace db { |
| 45 | void getShaderCode(sqlitepp::Instance &db, ShaderData &data) { |
| 46 | sqlitepp::Stmt stmt(db.GetDB()); |
| 47 | stmt.Prepare("SELECT id, code_type, code, filename FROM scene_code WHERE scene_id = ?;"); |
| 48 | stmt.BindInt(1, data.id); |
| 49 | |
| 50 | while (stmt.Step() == SQLITE_ROW) { |
| 51 | u32 id = stmt.ColumnInt(0); |
| 52 | ShaderCodeType type = static_cast<ShaderCodeType>(stmt.ColumnInt(1)); |
| 53 | string code = stmt.ColumnText(2); |
| 54 | string filename = stmt.ColumnText(3); |
| 55 | |
| 56 | if (type == ShaderCodeType::GlslVertex) { |
| 57 | data.vertexShader.id = id; |
| 58 | data.vertexShader.type = type; |
| 59 | data.vertexShader.code = code; |
| 60 | data.vertexShader.filename = filename; |
| 61 | } else if (type == ShaderCodeType::GlslFragment) { |
| 62 | data.fragmentShader.id = id; |
| 63 | data.fragmentShader.type = type; |
| 64 | data.fragmentShader.code = code; |
| 65 | data.fragmentShader.filename = filename; |
| 66 | } else if (type == ShaderCodeType::Lua) { |
| 67 | data.luaCode.id = id; |
| 68 | data.luaCode.type = type; |
| 69 | data.luaCode.code = code; |
| 70 | data.luaCode.filename = filename; |
| 71 | } else { |
| 72 | throw std::runtime_error("未対応コード類。"); |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | void getShaderSkybox(sqlitepp::Instance &db, ShaderData &data) { |
| 78 | sqlitepp::Stmt stmt(db.GetDB()); |
| 79 | stmt.Prepare("SELECT clear_r, clear_g, clear_b, clear_a FROM scene_skybox WHERE scene_id = ?;"); |
| 80 | stmt.BindInt(1, data.id); |
| 81 | |
| 82 | while (stmt.Step() == SQLITE_ROW) { |
| 83 | f32 r = stmt.ColumnDouble(0); |
| 84 | f32 g = stmt.ColumnDouble(1); |
| 85 | f32 b = stmt.ColumnDouble(2); |
| 86 | f32 a = stmt.ColumnDouble(3); |
| 87 | |
| 88 | data.clearColor = { r, g, b, a }; |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | vector<ShaderData> GetAllShaders(sqlitepp::Instance &db) { |
| 93 | vector<ShaderData> out; |
| 94 | |
| 95 | sqlitepp::Stmt stmt(db.GetDB()); |
| 96 | stmt.Prepare("SELECT id, name, description FROM scenes ORDER BY updated_at DESC;"); |
| 97 | |
| 98 | while (stmt.Step() == SQLITE_ROW) { |
| 99 | ShaderData data; |
| 100 | data.id = stmt.ColumnInt(0); |
| 101 | data.name = stmt.ColumnText(1); |
| 102 | data.description = stmt.ColumnText(2); |
| 103 | getShaderCode(db, data); |
| 104 | getShaderSkybox(db, data); |
| 105 | |
| 106 | out.push_back(std::move(data)); |
| 107 | } |
| 108 | |
| 109 | return out; |
| 110 | } |
| 111 | |
| 112 | ShaderData GetShader(sqlitepp::Instance &db, u32 id) { |
| 113 | ShaderData data = {}; |
| 114 | sqlitepp::Stmt stmt(db.GetDB()); |
| 115 | stmt.Prepare("SELECT id, name, description FROM scenes WHERE id = ?;"); |
| 116 | stmt.BindInt(1, id); |
| 117 | |
| 118 | while (stmt.Step() == SQLITE_ROW) { |
| 119 | data.id = stmt.ColumnInt(0); |
| 120 | data.name = stmt.ColumnText(1); |
| 121 | data.description = stmt.ColumnText(2); |
| 122 | getShaderCode(db, data); |
| 123 | getShaderSkybox(db, data); |
| 124 | } |
| 125 | |
| 126 | return data; |
| 127 | } |
| 128 | |
| 129 | void insertSceneCode(sqlitepp::Instance &db, const CodeData &data, u32 id) { |
| 130 | sqlitepp::Stmt stmt(db.GetDB()); |
| 131 | stmt.Prepare("INSERT INTO scene_code (scene_id, code_type, code, filename) VALUES (?, ?, ?, ?);"); |
| 132 | stmt.BindInt(1, id); |
| 133 | stmt.BindInt(2, static_cast<u32>(data.type)); |
| 134 | stmt.BindText(3, data.code); |
| 135 | stmt.BindText(4, data.filename); |
| 136 | assert(stmt.Step() == SQLITE_DONE && "シーンコードの保存に失敗。\n"); |
| 137 | } |
| 138 | |
| 139 | void insertSceneSkybox(sqlitepp::Instance &db, const ShaderData &data, u32 id) { |
| 140 | sqlitepp::Stmt stmt(db.GetDB()); |
| 141 | stmt.Prepare("INSERT INTO scene_skybox (scene_id, clear_r, clear_g, clear_b, clear_a) VALUES (?, ?, ?, ?, ?);"); |
| 142 | auto col = data.clearColor.rgba; |
| 143 | |
| 144 | stmt.BindInt(1, id); |
| 145 | stmt.BindDouble(2, col.r); |
| 146 | stmt.BindDouble(3, col.g); |
| 147 | stmt.BindDouble(4, col.b); |
| 148 | stmt.BindDouble(5, col.a); |
| 149 | assert(stmt.Step() == SQLITE_DONE && "シーンスカイボックスの保存に失敗。\n"); |
| 150 | } |
| 151 | |
| 152 | void SaveNewShader(sqlitepp::Instance &db, const ShaderData &data) { |
| 153 | sqlitepp::Stmt stmt(db.GetDB()); |
| 154 | stmt.Prepare("INSERT INTO scenes (name, description) VALUES (?, ?);"); |
| 155 | |
| 156 | stmt.BindText(1, data.name); |
| 157 | stmt.BindText(2, data.description); |
| 158 | |
| 159 | assert(stmt.Step() == SQLITE_DONE && "シーンの保存に失敗。\n"); |
| 160 | u32 id = GetLastShaderID(db); |
| 161 | insertSceneSkybox(db, data, id); |
| 162 | insertSceneCode(db, data.vertexShader, id); |
| 163 | insertSceneCode(db, data.fragmentShader, id); |
| 164 | insertSceneCode(db, data.luaCode, id); |
| 165 | } |
| 166 | |
| 167 | void SaveSkybox(sqlitepp::Instance &db, const ShaderData &data) { |
| 168 | sqlitepp::Stmt stmt(db.GetDB()); |
| 169 | stmt.Prepare("UPDATE scene_skybox SET clear_r = ?, clear_g = ?, clear_b = ?, clear_a = ? WHERE scene_id = ?;"); |
| 170 | auto col = data.clearColor.rgba; |
| 171 | |
| 172 | stmt.BindDouble(1, col.r); |
| 173 | stmt.BindDouble(2, col.g); |
| 174 | stmt.BindDouble(3, col.b); |
| 175 | stmt.BindDouble(4, col.a); |
| 176 | stmt.BindDouble(5, data.id); |
| 177 | |
| 178 | assert(stmt.Step() == SQLITE_DONE && "スカイボックスの保存に失敗。\n"); |
| 179 | } |
| 180 | |
| 181 | void SaveCode(sqlitepp::Instance &db, const CodeData &data) { |
| 182 | sqlitepp::Stmt stmt(db.GetDB()); |
| 183 | stmt.Prepare("UPDATE scene_code SET code = ?, filename = ? WHERE id = ?;"); |
| 184 | |
| 185 | stmt.BindText(1, data.code); |
| 186 | stmt.BindText(2, data.filename); |
| 187 | stmt.BindInt(3, data.id); |
| 188 | |
| 189 | assert(stmt.Step() == SQLITE_DONE && "コードの保存に失敗。\n"); |
| 190 | } |
| 191 | |
| 192 | u32 GetLastShaderID(sqlitepp::Instance &db) { |
| 193 | sqlitepp::Stmt stmt(db.GetDB()); |
| 194 | stmt.Prepare("SELECT MAX(id) FROM scenes;"); |
| 195 | return (stmt.Step() == SQLITE_ROW) ? stmt.ColumnInt(0) : 0; |
| 196 | } |
| 197 | } |