master
ブランチ master
ShaderPlayground / src / database / shaderdata.cc
7.1 KB、197行 生 Blame 履歴
1/*
2# 076 License
3
4Copyright (c) 076 Studio LLC
5
6Permission is hereby granted to any person obtaining a copy of the software
7Shader Playground (the "Software") to use, modify, merge, copy, publish, distribute,
8sublicense, 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
30THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
31INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
32PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
33HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
34CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
35OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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
44namespace 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} // namespace db