master
ブランチ master
ShaderPlayground / main.cc
28.1 KB、885行 生 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 <glad/glad.h>
38#include <util.hh>
39#include <shader.hh>
40#include <database.hh>
41#include <lua.hh>
42#include <gui.hh>
43#include <version.hh>
44#include <iostream>
45
46#include <imgui.h>
47#include <imgui_internal.h>
48#include <backends/imgui_impl_glfw.h>
49#include <backends/imgui_impl_opengl3.h>
50
51#include <sol.hpp>
52#include <chrono>
53
54constexpr int windowWidth = 1280;
55constexpr int windowHeight = 720;
56string sofname = "Shader Playground";
57
58int main(void) {
59 // GLFWを初期化
60 glfwpp::Instance glfw;
61 glfw.SetErrorCallback();
62 glfw.SetContextMajorVersion(4);
63 glfw.SetContextMinorVersion(6);
64 glfw.SetOpenGLProfile(glfwpp::Attributes::OpenGLCore);
65 glfw.SetForwardCompatibility(true);
66 glfw.SetMaximized(true);
67 glfw.CreateWindowHints();
68
69 u32 seed = static_cast<u32>(std::chrono::high_resolution_clock::now().time_since_epoch().count());
70 util::rand::Seed(seed);
71
72 // ウィンドウを作成
73 string winName = sofname + " " + version::full;
74 f32 mainScale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor());
75 glfwpp::Window window((windowWidth * mainScale), (windowHeight * mainScale), winName);
76 window.MakeContextCurrent();
77 glfw.SwapInterval(1);
78
79 Info info = { &glfw, &window, true, false, false, false };
80
81#ifndef PRODUCTION_BUILD
82 bool showDemo = true;
83#endif
84
85 // GLADを初期化
86 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
87 std::cerr << "GLADの初期化に失敗しました" << std::endl;
88 return -1;
89 }
90
91 // シャドーマッピング
92#pragma region shadowmap
93 constexpr u32 SHADOW_WIDTH = 1024;
94 constexpr u32 SHADOW_HEIGHT = 1024;
95
96 GLuint shadowFBO;
97 glGenFramebuffers(1, &shadowFBO);
98
99 GLuint shadowMap;
100 glGenTextures(1, &shadowMap);
101 glBindTexture(GL_TEXTURE_2D, shadowMap);
102
103 glTexImage2D(
104 GL_TEXTURE_2D,
105 0,
106 GL_DEPTH_COMPONENT,
107 SHADOW_WIDTH,
108 SHADOW_HEIGHT,
109 0,
110 GL_DEPTH_COMPONENT,
111 GL_FLOAT,
112 nullptr
113 );
114
115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
117 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
119
120 float borderColor[] = { 1.f, 1.f, 1.f, 1.f };
121 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
122
123 glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO);
124 glFramebufferTexture2D(
125 GL_FRAMEBUFFER,
126 GL_DEPTH_ATTACHMENT,
127 GL_TEXTURE_2D,
128 shadowMap,
129 0
130 );
131
132 glDrawBuffer(GL_NONE);
133 glReadBuffer(GL_NONE);
134
135 glBindFramebuffer(GL_FRAMEBUFFER, 0);
136
137 string depthVertSource = R"(#version 460 core
138layout(location = 0) in vec3 aPosition;
139
140uniform mat4 uLightSpace;
141uniform mat4 uModel;
142
143void main() {
144 gl_Position = uLightSpace * uModel * vec4(aPosition, 1.0);
145})";
146
147 string depthFragSource = R"(#version 460 core
148void main() { })";
149#pragma endregion
150
151 // 3Dを有効
152 glEnable(GL_DEPTH_TEST);
153 glDepthFunc(GL_LESS);
154 //glEnable(GL_CULL_FACE);
155
156 // ImGui設定
157 gui::GuiEngine ge(&window);
158
159 // フレームバッファーサイズ
160 window.SetFramebufferSizeCallback();
161
162 // データベースが未だ存在しなければ、初期設定
163 sqlitepp::Instance db;
164 try {
165 db::Initialize(db);
166 } catch (const std::exception &e) {
167 std::cerr << e.what() << std::endl;
168 return -1;
169 }
170
171 // 言語
172 db::Locale i18n(&db);
173 info.i18n = &i18n;
174
175 // コンソール
176 gui::ConsoleLog cmd;
177 info.cmd = &cmd;
178
179 // ビューポート
180 gui::ViewPort viewport;
181 viewport.Init();
182
183 // マニュアル
184 gui::Manual manual;
185
186 // データベースからシェーダーとLuaコードの受け取り
187 {
188 db::ShaderData shaderData = db::GetShader(db, 1);
189 info.shaderId = shaderData.id;
190 info.shaderName = shaderData.name;
191 info.sceneClearColor = shaderData.clearColor;
192 info.VERT = shaderData.vertexShader;
193 info.FRAG = shaderData.fragmentShader;
194 info.LUA = shaderData.luaCode;
195 }
196
197 string title = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")";
198 gui::Editor vertEditor(&info, (title + "###VertexEditor").c_str(), "VertexEditor", info.VERT.code, gui::Glsl, ge.GetCjkFont(), ge.GetMonoFont());
199 info.textEditors.emplace_back(&vertEditor.Get());
200
201 title = info.shaderName + "(" + info.i18n->GetWord("editorfragshader") + ")";
202 gui::Editor fragEditor(&info, (title + "###FragmentEditor").c_str(), "FragmentEditor", info.FRAG.code, gui::Glsl, ge.GetCjkFont(), ge.GetMonoFont());
203 info.textEditors.emplace_back(&fragEditor.Get());
204
205 title = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")";
206 gui::Editor luaEditor(&info, (title + "###LuaEditor").c_str(), "LuaEditor", info.LUA.code, gui::Lua, ge.GetCjkFont(), ge.GetMonoFont());
207 info.textEditors.emplace_back(&luaEditor.Get());
208
209 // シェーダーをコンパイル
210 Shader vertexShader(info.VERT.code, GL_VERTEX_SHADER);
211 Shader fragmentShader(info.FRAG.code, GL_FRAGMENT_SHADER);
212
213 // シェーダープログラムをリンク
214 Program shaderProgram(vertexShader, fragmentShader);
215
216 // 頂点データはLuaから受け取る
217 lua::LuaEngine luaEngine(info.LUA.code, &shaderProgram, &info);
218 info.pendingCompile = true;
219 auto &objects = luaEngine.GetObjects();
220
221 VertexArrays VAO(1);
222 Buffers VBO(Buffer, 1);
223 Buffers EBO(ArrayBuffer, 1);
224
225 for (auto &obj : objects) {
226 VAO.BindVertexArray();
227
228 VBO.BindBuffer();
229 VBO.BufferData(obj.mesh.vertices.data(), obj.mesh.vertices.size() * sizeof(f32));
230
231 EBO.BindBuffer();
232 EBO.BufferData(obj.mesh.indices.data(), obj.mesh.indices.size() * sizeof(GLuint));
233
234 // 頂点属性
235 for (const auto &a : obj.mesh.attr) {
236 glVertexAttribPointer(a.location, a.size, GL_FLOAT, GL_FALSE, a.stride, (void *)(uintptr_t)a.offset);
237 glEnableVertexAttribArray(a.location);
238 }
239 }
240
241 bool isHold = false;
242 gui::About about;
243 gui::Settings settings;
244
245#pragma region shadowmap
246 Shader depthVertex(depthVertSource, GL_VERTEX_SHADER);
247 Shader depthFragment(depthFragSource, GL_FRAGMENT_SHADER);
248 Program depthProgram(depthVertex, depthFragment);
249#pragma endregion
250
251 // メインレンダリングループ
252 while (!window.ShouldClose() && info.isRunning) {
253#pragma region Lambda
254 info.compile = [&]() {
255 if (!info.pendingCompile) return;
256 info.pendingCompile = false;
257 if (luaEngine.GetInitializationState()) luaEngine.SetInitializationState(false);
258 info.VERT.code = vertEditor.Get().GetText();
259 info.FRAG.code = fragEditor.Get().GetText();
260 info.LUA.code = luaEditor.Get().GetText();
261
262 try {
263 try {
264 if (!luaEngine.Validate(info.LUA.code)) {
265 gui::LogEntry entry;
266 entry.type = gui::LogType::Error;
267 entry.text = info.i18n->GetWord("consolelogerrorluainvalidcomp");
268 info.cmd->Add(entry);
269 std::cerr << entry.text << std::endl;
270 return;
271 }
272 } catch (const std::exception &e) {
273 gui::LogEntry entry;
274 entry.type = gui::LogType::Error;
275 entry.text = e.what();
276 info.cmd->Add(entry);
277 std::cerr << entry.text << std::endl;
278 entry.text = info.i18n->GetWord("consolelogerrorluainvalidcomp");
279 info.cmd->Add(entry);
280 std::cerr << entry.text << std::endl;
281 return;
282 }
283
284 shaderProgram.Reload(info.VERT.code, info.FRAG.code);
285 shaderProgram.Use();
286 luaEngine.SetProgram(&shaderProgram);
287 luaEngine.Reload(info.LUA.code);
288 {
289 auto &newObj = luaEngine.GetObjects();
290 for (auto &obj : newObj) {
291 if (obj.mesh.vertices.empty() || obj.mesh.indices.empty()) {
292 string msg;
293 if (info.i18n->GetCurrentLanguage().code == "ja_JP") msg = "メッシュデータが空です。";
294 else msg = "Mesh data is empty.";
295 throw std::runtime_error(msg);
296 }
297
298 VAO.BindVertexArray();
299
300 VBO.BindBuffer();
301 VBO.BufferData(
302 obj.mesh.vertices.data(),
303 obj.mesh.vertices.size() * sizeof(f32)
304 );
305
306 EBO.BindBuffer();
307 EBO.BufferData(
308 obj.mesh.indices.data(),
309 obj.mesh.indices.size() * sizeof(u32)
310 );
311
312 for (const auto &a : obj.mesh.attr) {
313 glVertexAttribPointer(
314 a.location,
315 a.size,
316 GL_FLOAT,
317 GL_FALSE,
318 a.stride,
319 (any)(uintptr_t)a.offset
320 );
321 glEnableVertexAttribArray(a.location);
322 }
323 }
324 }
325
326 gui::LogEntry entry;
327 entry.type = gui::LogType::Info;
328 entry.text = info.i18n->GetWord("consoleloginfocompileok");
329 info.cmd->Add(entry);
330 std::cout << entry.text << std::endl;
331 } catch (const std::exception &e) {
332 gui::LogEntry entry;
333 entry.type = gui::LogType::Error;
334 entry.text = e.what();
335 info.cmd->Add(entry);
336 std::cerr << entry.text << std::endl;
337 entry.text = info.i18n->GetWord("consolelogerrorluainvalidcomp");
338 info.cmd->Add(entry);
339 std::cerr << entry.text << std::endl;
340 }
341 };
342
343 info.save = [&]() {
344 if (info.shaderId == 0) {
345 info.showSaveAsShaderPopup = true;
346 return;
347 }
348
349 info.VERT.code = vertEditor.Get().GetText();
350 info.FRAG.code = fragEditor.Get().GetText();
351 info.LUA.code = luaEditor.Get().GetText();
352
353 try {
354 try {
355 if (!luaEngine.Validate(info.LUA.code)) {
356 gui::LogEntry entry;
357 entry.type = gui::LogType::Error;
358 entry.text = info.i18n->GetWord("consolelogerrorluainvalidsave");
359 info.cmd->Add(entry);
360 std::cout << entry.text << std::endl;
361 return;
362 }
363 } catch (const std::exception &e) {
364 gui::LogEntry entry;
365 entry.type = gui::LogType::Error;
366 entry.text = e.what();
367 info.cmd->Add(entry);
368 std::cout << entry.text << std::endl;
369 entry.text = info.i18n->GetWord("consolelogerrorluainvalidsave");
370 info.cmd->Add(entry);
371 std::cout << entry.text << std::endl;
372 return;
373 }
374
375 db::ShaderData shdr;
376 shdr.id = info.shaderId;
377 shdr.clearColor = info.sceneClearColor;
378
379 db::SaveSkybox(db, shdr);
380 db::SaveCode(db, info.VERT);
381 db::SaveCode(db, info.VERT);
382 db::SaveCode(db, info.FRAG);
383 db::SaveCode(db, info.LUA);
384
385 gui::LogEntry entry;
386 entry.type = gui::LogType::Info;
387 entry.text = info.i18n->GetWord("consoleloginfosaveok");
388 info.cmd->Add(entry);
389 std::cout << entry.text << std::endl;
390 } catch (const std::exception &e) {
391 gui::LogEntry entry;
392 entry.type = gui::LogType::Error;
393 entry.text = e.what();
394 info.cmd->Add(entry);
395 std::cout << entry.text << std::endl;
396 entry.text = info.i18n->GetWord("consolelogerrorluainvalidsave");
397 info.cmd->Add(entry);
398 std::cout << entry.text << std::endl;
399 }
400 };
401
402 info.open = [&]() {
403 static i32 selectedId = -1;
404 ImGui::SetNextWindowSize(ImVec2(500, 400), ImGuiCond_FirstUseEver);
405 if (ImGui::BeginPopupModal(info.i18n->GetWord("fileopenshader").c_str(), nullptr)) {
406 if (ImGui::IsKeyPressed(ImGuiKey_Escape)) ImGui::CloseCurrentPopup();
407
408 vector <db::ShaderData> shdrs = db::GetAllShaders(db);
409 ImGui::BeginChild("ShaderList", ImVec2(0, 300), true);
410
411 for (const auto &s : shdrs) {
412 bool sel = (selectedId == s.id);
413
414 if (ImGui::Selectable(s.name.c_str(), sel)) {
415 selectedId = s.id;
416 }
417 }
418
419 ImGui::EndChild();
420 ImGui::Separator();
421
422 if (ImGui::Button(info.i18n->GetWord("cancel").c_str())) {
423 ImGui::CloseCurrentPopup();
424 }
425
426 ImGui::SameLine();
427
428 if (ImGui::Button(info.i18n->GetWord("fileopen").c_str())) {
429 if (selectedId != -1) {
430 db::ShaderData shaderData = db::GetShader(db, selectedId);
431 info.shaderId = shaderData.id;
432 info.shaderName = shaderData.name;
433 info.sceneClearColor = shaderData.clearColor;
434 info.VERT = shaderData.vertexShader;
435 info.FRAG = shaderData.fragmentShader;
436 info.LUA = shaderData.luaCode;
437
438 vertEditor.SetCode(info.VERT.code);
439 string nTit = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")";
440 vertEditor.SetTitle(nTit + "###VertexEditor");
441
442 fragEditor.SetCode(info.FRAG.code);
443 nTit = info.shaderName + "(" + info.i18n->GetWord("editorfragshader") + ")";
444 fragEditor.SetTitle(nTit + "###FragmentEditor");
445
446 luaEditor.SetCode(info.LUA.code);
447 nTit = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")";
448 luaEditor.SetTitle(nTit + "###LuaEditor");
449
450 info.pendingCompile = true;
451 }
452 ImGui::CloseCurrentPopup();
453 }
454
455 ImGui::EndPopup();
456 }
457 };
458
459 info.saveAs = [&]() {
460 if (ImGui::BeginPopupModal(info.i18n->GetWord("filesaveasshader").c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
461 if (ImGui::IsKeyPressed(ImGuiKey_Escape)) ImGui::CloseCurrentPopup();
462
463 ImGui::Text(info.i18n->GetWord("fileshadername").c_str());
464 ImGui::SameLine();
465 static char str0[128] = "new";
466 ImGui::InputText("##SaveInput", str0, IM_COUNTOF(str0));
467
468 ImGui::Separator();
469
470 if (ImGui::Button(info.i18n->GetWord("cancel").c_str())) {
471 ImGui::CloseCurrentPopup();
472 }
473
474 ImGui::SameLine();
475
476 if (ImGui::Button(info.i18n->GetWord("filesave").c_str())) {
477 info.shaderName = string(str0);
478 info.VERT.code = vertEditor.Get().GetText();
479 info.FRAG.code = fragEditor.Get().GetText();
480 info.LUA.code = luaEditor.Get().GetText();
481
482 gui::SaveShader saveShader(&info);
483 saveShader.Save(db);
484 db::ShaderData shdr = db::GetShader(db, db::GetLastShaderID(db));
485 info.shaderId = shdr.id;
486 info.shaderName = shdr.name;
487 info.sceneClearColor = shdr.clearColor;
488 info.VERT = shdr.vertexShader;
489 info.FRAG = shdr.fragmentShader;
490 info.LUA = shdr.luaCode;
491
492 string nTit = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")";
493 vertEditor.SetTitle(nTit + "###VertexEditor");
494
495 nTit = info.shaderName + "(" + info.i18n->GetWord("editorfragshader") + ")";
496 fragEditor.SetTitle(nTit + "###FragmentEditor");
497
498 nTit = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")";
499 luaEditor.SetTitle(nTit + "###LuaEditor");
500
501 ImGui::CloseCurrentPopup();
502 }
503
504 ImGui::EndPopup();
505 }
506 };
507
508 info.create = [&]() {
509 if (ImGui::BeginPopupModal(info.i18n->GetWord("filenewcreateshader").c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
510 if (ImGui::IsKeyPressed(ImGuiKey_Escape)) ImGui::CloseCurrentPopup();
511
512 if (ImGui::Button(info.i18n->GetWord("filenew2dshader").c_str(), ImVec2(200, 0))) {
513 gui::NewShader newShader(&info);
514 auto shdr = newShader.Make(gui::ShaderType::Simple2D);
515 info.shaderId = shdr.id;
516 info.shaderName = shdr.name;
517 info.sceneClearColor = shdr.clearColor;
518 info.VERT = shdr.vertexShader;
519 info.FRAG = shdr.fragmentShader;
520 info.LUA = shdr.luaCode;
521
522 vertEditor.SetCode(info.VERT.code);
523 string nTit = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")";
524 vertEditor.SetTitle(nTit + "###VertexEditor");
525
526 fragEditor.SetCode(info.FRAG.code);
527 nTit = info.shaderName + "(" + info.i18n->GetWord("editorfragshader") + ")";
528 fragEditor.SetTitle(nTit + "###FragmentEditor");
529
530 luaEditor.SetCode(info.LUA.code);
531 nTit = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")";
532 luaEditor.SetTitle(nTit + "###LuaEditor");
533
534 info.pendingCompile = true;
535
536 gui::LogEntry entry;
537 entry.type = gui::LogType::Info;
538 entry.text = info.i18n->GetWord("consoleloginfocreateok");
539 info.cmd->Add(entry);
540 std::cout << entry.text << std::endl;
541
542 ImGui::CloseCurrentPopup();
543 }
544
545 if (ImGui::Button(info.i18n->GetWord("filenew3dshader").c_str(), ImVec2(200, 0))) {
546 gui::NewShader newShader(&info);
547 auto shdr = newShader.Make(gui::ShaderType::Simple3D);
548 info.shaderId = shdr.id;
549 info.shaderName = shdr.name;
550 info.sceneClearColor = shdr.clearColor;
551 info.VERT = shdr.vertexShader;
552 info.FRAG = shdr.fragmentShader;
553 info.LUA = shdr.luaCode;
554
555 vertEditor.SetCode(info.VERT.code);
556 string nTit = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")";
557 vertEditor.SetTitle(nTit + "###VertexEditor");
558
559 fragEditor.SetCode(info.FRAG.code);
560 nTit = info.shaderName + "(" + info.i18n->GetWord("editorfragshader") + ")";
561 fragEditor.SetTitle(nTit + "###FragmentEditor");
562
563 luaEditor.SetCode(info.LUA.code);
564 nTit = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")";
565 luaEditor.SetTitle(nTit + "###LuaEditor");
566
567 info.pendingCompile = true;
568
569 gui::LogEntry entry;
570 entry.type = gui::LogType::Info;
571 entry.text = info.i18n->GetWord("consoleloginfocreateok");
572 info.cmd->Add(entry);
573 std::cout << entry.text << std::endl;
574
575 ImGui::CloseCurrentPopup();
576 }
577
578 if (ImGui::Button(info.i18n->GetWord("filenewsceneshader").c_str(), ImVec2(200, 0))) {
579 gui::NewShader newShader(&info);
580 auto shdr = newShader.Make(gui::ShaderType::Scene);
581 info.shaderId = shdr.id;
582 info.shaderName = shdr.name;
583 info.sceneClearColor = shdr.clearColor;
584 info.VERT = shdr.vertexShader;
585 info.FRAG = shdr.fragmentShader;
586 info.LUA = shdr.luaCode;
587
588 vertEditor.SetCode(info.VERT.code);
589 string nTit = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")";
590 vertEditor.SetTitle(nTit + "###VertexEditor");
591
592 fragEditor.SetCode(info.FRAG.code);
593 nTit = info.shaderName + "(" + info.i18n->GetWord("editorfragshader") + ")";
594 fragEditor.SetTitle(nTit + "###FragmentEditor");
595
596 luaEditor.SetCode(info.LUA.code);
597 nTit = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")";
598 luaEditor.SetTitle(nTit + "###LuaEditor");
599
600 info.pendingCompile = true;
601
602 gui::LogEntry entry;
603 entry.type = gui::LogType::Info;
604 entry.text = info.i18n->GetWord("consoleloginfocreateok");
605 info.cmd->Add(entry);
606 std::cout << entry.text << std::endl;
607
608 ImGui::CloseCurrentPopup();
609 }
610
611 ImGui::Separator();
612
613 if (ImGui::Button(info.i18n->GetWord("cancel").c_str())) {
614 ImGui::CloseCurrentPopup();
615 }
616
617 ImGui::EndPopup();
618 }
619 };
620#pragma endregion
621
622 glfw.PollEvents();
623
624 bool isManualKey = window.GetKey(GLFW_KEY_F1);
625 bool isCompileKey = window.GetKey(GLFW_KEY_F5);
626
627 bool ctrlMod = (window.GetKey(GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || window.GetKey(GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS);
628 bool shiftMod = (window.GetKey(GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS || window.GetKey(GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS);
629 //bool altMod = (window.GetKey(GLFW_KEY_LEFT_ALT) == GLFW_PRESS || window.GetKey(GLFW_KEY_RIGHT_ALT) == GLFW_PRESS);
630 bool isTab = window.GetKey(GLFW_KEY_TAB) == GLFW_PRESS;
631
632 bool isNewKey = (window.GetKey(GLFW_KEY_N) == GLFW_PRESS && ctrlMod);
633 bool isOpenKey = (window.GetKey(GLFW_KEY_O) == GLFW_PRESS && ctrlMod);
634 bool isSaveAsKey = (window.GetKey(GLFW_KEY_S) == GLFW_PRESS && ctrlMod && shiftMod);
635 bool isSaveKey = (window.GetKey(GLFW_KEY_S) == GLFW_PRESS && ctrlMod);
636 bool isQuitKey = (window.GetKey(GLFW_KEY_Q) == GLFW_PRESS && ctrlMod);
637 bool isAboutKey = (window.GetKey(GLFW_KEY_H) == GLFW_PRESS && ctrlMod);
638 bool isSettingsKey = (window.GetKey(GLFW_KEY_COMMA) == GLFW_PRESS && ctrlMod);
639
640 if (!isHold) {
641 if (isCompileKey) {
642 info.pendingCompile = true;
643 }
644
645 if (isNewKey) {
646 info.showNewShaderPopup = true;
647 }
648
649 if (isOpenKey) {
650 info.showOpenShaderPopup = true;
651 }
652
653 if (isSaveAsKey) {
654 info.showSaveAsShaderPopup = true;
655 }
656
657 if (isSaveKey) {
658 if (info.shaderId == 0) info.showSaveAsShaderPopup = true;
659 else info.save();
660 }
661
662 if (isManualKey) {
663 info.isManual = true;
664 }
665
666 if (isSettingsKey) {
667 info.isSettings = true;
668 }
669
670 if (isAboutKey) {
671 info.isAbout = true;
672 }
673
674 if (isQuitKey) {
675 info.isRunning = false;
676 }
677 }
678
679 isHold = isSaveKey ||
680 isCompileKey ||
681 isAboutKey ||
682 isQuitKey ||
683 isManualKey ||
684 isSettingsKey ||
685 isNewKey ||
686 isOpenKey;
687
688 if (info.isLangChange) {
689 string nTit = info.shaderName + "(" + info.i18n->GetWord("editorvertshader") + ")";
690 vertEditor.SetTitle(nTit + "###VertexEditor");
691 nTit = info.shaderName + "(" + info.i18n->GetWord("editorfragshader") + ")";
692 fragEditor.SetTitle(nTit + "###FragmentEditor");
693 nTit = info.shaderName + "(" + info.i18n->GetWord("editorlua") + ")";
694 luaEditor.SetTitle(nTit + "###LuaEditor");
695 info.isLangChange = false;
696 }
697
698 if (window.GetAttrib(glfwpp::Attributes::Iconified) != 0) {
699 ImGui_ImplGlfw_Sleep(10);
700 continue;
701 }
702
703 gui::showTitleBar(info);
704
705 if (info.showSaveAsShaderPopup) {
706 ImGui::OpenPopup(info.i18n->GetWord("filesaveasshader").c_str());
707 info.showSaveAsShaderPopup = false;
708 }
709
710 if (info.showOpenShaderPopup) {
711 ImGui::OpenPopup(info.i18n->GetWord("fileopenshader").c_str());
712 info.showOpenShaderPopup = false;
713 }
714
715 if (info.showNewShaderPopup) {
716 ImGui::OpenPopup(info.i18n->GetWord("filenewcreateshader").c_str());
717 info.showNewShaderPopup = false;
718 }
719
720 info.create();
721 info.open();
722 info.saveAs();
723 info.compile();
724
725#ifndef PRODUCTION_BUILD
726 if (showDemo) ImGui::ShowDemoWindow(&showDemo);
727#endif
728
729 vertEditor.Render();
730 fragEditor.Render();
731 luaEditor.Render();
732 info.cmd->Draw(info, info.i18n->GetWord("editorconsole").c_str());
733 about.Draw(info);
734 settings.Draw(info);
735 manual.Draw(info);
736
737 viewport.Draw(info);
738
739 ImGui::Render();
740
741#pragma region shadowmap
742 Matrix4 lightProjection = mat4Ortho(
743 -20.f, 20.f,
744 -20.f, 20.f,
745 0.1f, 100.f
746 );
747
748 Matrix4 lightView = mat4LookAt(
749 { 10.f, 10.f, 10.f }, // 光の位置
750 { 0.f, 0.f, 0.f }, // ターゲット
751 { 0.f, 1.f, 0.f } // 上
752 );
753
754 Matrix4 lightSpace = mat4Mul(lightProjection, lightView);
755
756 glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
757 glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO);
758 glClear(GL_DEPTH_BUFFER_BIT);
759
760 depthProgram.Use();
761 depthProgram.SetUniformMat4("uLightSpace", lightSpace);
762
763 for (auto &obj : objects) {
764 if (obj.mesh.vertices.empty()) continue;
765 if (obj.mesh.indices.empty()) continue;
766
767 Matrix4 T = mat4Translate(
768 obj.position.pos.x,
769 obj.position.pos.y,
770 obj.position.pos.z
771 );
772
773 Matrix4 R = mat4Rotate(
774 obj.rotation.pos.x,
775 obj.rotation.pos.y,
776 obj.rotation.pos.z
777 );
778
779 Matrix4 S = mat4Scale(
780 obj.scale.pos.x,
781 obj.scale.pos.y,
782 obj.scale.pos.z
783 );
784
785 Matrix4 model = mat4Mul(T, mat4Mul(R, S));
786
787 depthProgram.SetUniformMat4("uModel", model);
788
789 VAO.BindVertexArray();
790 VBO.BindBuffer();
791 VBO.BufferData(obj.mesh.vertices.data(),
792 obj.mesh.vertices.size() * sizeof(f32));
793
794 EBO.BindBuffer();
795 EBO.BufferData(obj.mesh.indices.data(),
796 obj.mesh.indices.size() * sizeof(GLuint));
797
798 glDrawElements(
799 GL_TRIANGLES,
800 obj.mesh.GetIndexCount(),
801 GL_UNSIGNED_INT,
802 nullptr
803 );
804 }
805
806 glBindFramebuffer(GL_FRAMEBUFFER, 0);
807#pragma endregion
808
809 // 画面をクリア
810 glBindFramebuffer(GL_FRAMEBUFFER, viewport.GetFBO());
811 glViewport(0, 0, viewport.GetWidth(), viewport.GetHeight());
812 {
813 auto cc = info.sceneClearColor.rgba;
814 shaderProgram.ClearColor(cc.r, cc.g, cc.b, cc.a);
815 shaderProgram.Clear();
816 }
817
818 // シェーダープログラムを使用
819 shaderProgram.Use();
820
821#pragma region shadowmap
822 shaderProgram.SetUniformMat4("uLightSpace", lightSpace);
823
824 glActiveTexture(GL_TEXTURE0);
825 glBindTexture(GL_TEXTURE_2D, shadowMap);
826 shaderProgram.SetUniformInt("uShadowMap", 0);
827#pragma endregion
828
829 luaEngine.Init();
830 luaEngine.Update();
831
832 auto &objects = luaEngine.GetObjects();
833 for (auto &obj : objects) {
834 if (obj.mesh.vertices.empty()) continue;
835 if (obj.mesh.indices.empty()) continue;
836
837 // モデルマトリックスの作成
838 Matrix4 T = mat4Translate(
839 obj.position.pos.x,
840 obj.position.pos.y,
841 obj.position.pos.z
842 );
843
844 Matrix4 R = mat4Rotate(
845 obj.rotation.pos.x,
846 obj.rotation.pos.y,
847 obj.rotation.pos.z
848 );
849
850 Matrix4 S = mat4Scale(
851 obj.scale.pos.x,
852 obj.scale.pos.y,
853 obj.scale.pos.z
854 );
855
856 Matrix4 model = mat4Mul(T, mat4Mul(R, S));
857 glUniformMatrix4fv(shaderProgram.GetUniformLocation("uModel"), 1, GL_FALSE, model.m);
858
859 // 描画
860 VAO.BindVertexArray();
861 VBO.BindBuffer();
862 VBO.BufferData(obj.mesh.vertices.data(), obj.mesh.vertices.size() * sizeof(f32));
863 EBO.BindBuffer();
864 EBO.BufferData(obj.mesh.indices.data(), obj.mesh.indices.size() * sizeof(GLuint));
865
866 glDrawElements(GL_TRIANGLES, obj.mesh.GetIndexCount(), GL_UNSIGNED_INT, nullptr);
867 }
868 glBindFramebuffer(GL_FRAMEBUFFER, 0);
869
870 // バッファをスワップし、イベントを処理
871 ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
872 if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
873 GLFWwindow *backup_current_context = glfwGetCurrentContext();
874
875 ImGui::UpdatePlatformWindows();
876 ImGui::RenderPlatformWindowsDefault();
877
878 glfwMakeContextCurrent(backup_current_context);
879 }
880
881 window.SwapBuffers();
882 }
883
884 return 0;
885}