1 module app; 2 3 import bindbc.sdl; 4 5 import cimgui.cimgui; 6 7 import game_core.basic; 8 import game_core.job_updater; 9 10 import bubel.ecs.core; 11 import bubel.ecs.manager; 12 import bubel.ecs.std; 13 14 import ecs_utils.gfx.renderer; 15 import ecs_utils.imgui_bind; 16 import ecs_utils.imgui_styles; 17 import ecs_utils.math.vector; 18 import ecs_utils.utils; 19 20 import glad.gl.gl; 21 import glad.gl.gles2; 22 import glad.gl.loader; 23 24 import gui.manager; 25 import gui.tool_circle; 26 27 extern (C) : 28 29 enum Tool 30 { 31 entity_spawner, 32 component_manipulator, 33 selector 34 } 35 36 __gshared const (char)*[3] tool_strings = ["Entity spawner", "Component manipulator", "Selector"]; 37 38 struct Mouse 39 { 40 vec2 position; 41 bool left, right, middle; 42 } 43 44 struct DemoCallbacks 45 { 46 void function() register; 47 void function() initialize; 48 void function() deinitialize; 49 bool function() loop; 50 void function(SDL_Event*) event; 51 const (char)* tips; 52 } 53 54 struct Launcher 55 { 56 ECSJobUpdater* job_updater; 57 GUIManager* gui_manager; 58 ImGuiContext* context; 59 SDL_Window* window; 60 SDL_GLContext gl_context; 61 /*bool function() loop; 62 void function() end; 63 void function(SDL_Event*) event;*/ 64 //void function(vec2, Tool, int, bool) tool; 65 float scalling; 66 ivec2 window_size = ivec2(1024,768); 67 Renderer renderer; 68 ubyte[] keys; 69 uint style = 3; 70 uint entities_count; 71 bool multithreading; 72 int threads = 1; 73 ulong timer_freq; 74 double delta_time; 75 uint fps; 76 vec2 render_position; 77 bool play = true; 78 79 Tool used_tool; 80 int tool_size = 100; 81 float tool_repeat = 0; 82 float repeat_time = 0; 83 bool tool_show = true; 84 bool override_ = true; 85 bool tool_mode = true; 86 ToolCircle* tool_circle; 87 bool show_filtered; 88 EntityID selected_entity; 89 90 bool swap_interval = true; 91 92 float windows_alpha = 0.75; 93 94 //const (char)* tips; 95 96 bool show_stat_wnd = true; 97 bool show_tips = true; 98 bool show_demo_wnd = true; 99 bool show_tools_wnd = true; 100 bool show_virtual_keys_wnd = false; 101 bool show_profile_wnd = true; 102 103 int plot_index; 104 PlotStruct[] plot_values; 105 106 Mouse mouse; 107 108 struct PlotStruct 109 { 110 float delta_time = 0; 111 float loop_time = 0; 112 float draw_time = 0; 113 } 114 115 double deltaTime() 116 { 117 return delta_time * play; 118 } 119 120 DemoCallbacks demo; 121 122 void switchDemo(DemoCallbacks callbacks)//void function() start, bool function() loop, void function() end, void function(SDL_Event*) event, const (char)* tips) 123 { 124 show_tips = true; 125 gui_manager.clear(); 126 //launcher.ent 127 128 gEntityManager.begin(); 129 gEntityManager.update("clean"); 130 gEntityManager.end(); 131 132 if(this.demo.deinitialize)this.demo.deinitialize(); 133 134 foreach(ref system; gEntityManager.systems) 135 { 136 if(system.id != becsID!CountSystem && system.id != becsID!CleanSystem)system.disable(); 137 } 138 139 /*gEntityManager.getSystem(becsID!CountSystem).enable(); 140 gEntityManager.getSystem(becsID!CleanSystem).enable();//*/ 141 142 if(callbacks.register)callbacks.register(); 143 if(callbacks.initialize)callbacks.initialize(); 144 demo = callbacks; 145 /*this.loop = loop; 146 this.end = end; 147 this.event = event; 148 this.tips = tips;*/ 149 //this.tool = tool; 150 } 151 152 bool filterEntity(ref const Entity entity) 153 { 154 EntityMeta meta = entity.getMeta(); 155 foreach(id;gui_manager.filter_list) 156 { 157 if(!meta.hasComponent(id))return false; 158 } 159 if(used_tool == Tool.component_manipulator) 160 { 161 if(!meta.hasComponent(gui_manager.getSelectedComponent().component_id))return false; 162 } 163 return true; 164 } 165 166 void processTool(vec2 position, bool mode) 167 { 168 static struct Iterator 169 { 170 float size2; 171 vec2 position; 172 ComponentRef[] add_comps; 173 ushort[] rem_comps; 174 ushort[] filter; 175 float distance = float.max; 176 177 bool filterEntity(ref const Entity entity) 178 { 179 EntityMeta meta = entity.getMeta(); 180 foreach(id;filter) 181 { 182 if(!meta.hasComponent(id))return false; 183 } 184 return true; 185 } 186 187 void removeEntity(IteratorSystem.EntitiesData data) 188 { 189 if(!filterEntity(data.entity[0]))return; 190 foreach(i;0..data.length) 191 { 192 vec2 rel_vec = data.location[i] - position; 193 float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; 194 if(length < size2)gEntityManager.removeEntity(data.entity[i].id); 195 } 196 } 197 198 void addComponent(IteratorSystem.EntitiesData data) 199 { 200 if(!filterEntity(data.entity[0]))return; 201 foreach(i;0..data.length) 202 { 203 vec2 rel_vec = data.location[i] - position; 204 float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; 205 if(length < size2)gEntityManager.addComponents(data.entity[i].id, add_comps); 206 } 207 } 208 209 void overrideComponent(IteratorSystem.EntitiesData data) 210 { 211 if(!filterEntity(data.entity[0]))return; 212 foreach(i;0..data.length) 213 { 214 vec2 rel_vec = data.location[i] - position; 215 float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; 216 if(length < size2) 217 { 218 gEntityManager.removeComponents(data.entity[i].id, rem_comps); 219 gEntityManager.addComponents(data.entity[i].id, add_comps); 220 } 221 } 222 } 223 224 void removeComponent(IteratorSystem.EntitiesData data) 225 { 226 if(!filterEntity(data.entity[0]))return; 227 foreach(i;0..data.length) 228 { 229 vec2 rel_vec = data.location[i] - position; 230 float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; 231 if(length < size2)gEntityManager.removeComponents(data.entity[i].id, rem_comps); 232 } 233 } 234 235 void selectEntity(IteratorSystem.EntitiesData data) 236 { 237 if(!filterEntity(data.entity[0]))return; 238 foreach(i;0..data.length) 239 { 240 vec2 rel_vec = data.location[i] - position; 241 float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; 242 if(length < distance) 243 { 244 distance = length; 245 launcher.selected_entity = data.entity[i].id; 246 } 247 } 248 } 249 } 250 251 float half_size = tool_size * 0.5; 252 float size2 = half_size * half_size; 253 Iterator iterator; 254 iterator.size2 = size2; 255 iterator.position = position; 256 iterator.filter = gui_manager.filter_list[]; 257 258 switch(used_tool) 259 { 260 case Tool.entity_spawner: 261 if(mode) 262 { 263 if(gui_manager.templates.length == 0)return; 264 EntityTemplate* tmpl = gui_manager.getSelectedTemplate(); 265 CLocation* location = tmpl.getComponent!CLocation; 266 if(location) 267 { 268 position += randomCircularSample() * half_size; 269 //if(position.y < 16)position.y = 16; 270 //else if(position.y > 299)position.y = 299; 271 *location = position; 272 } 273 gEntityManager.addEntity(tmpl); 274 } 275 else 276 { 277 gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.removeEntity); 278 } 279 break; 280 case Tool.component_manipulator: 281 { 282 if(gui_manager.components.length == 0)return; 283 if(mode) 284 { 285 ComponentRef[1] comps = [gui_manager.getSelectedComponent()]; 286 iterator.add_comps = comps; 287 if(launcher.override_) 288 { 289 ushort[1] rcomps = [gui_manager.getSelectedComponent().component_id]; 290 iterator.rem_comps = rcomps; 291 gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.overrideComponent); 292 } 293 else gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.addComponent); 294 } 295 else 296 { 297 ushort[1] comps = [gui_manager.getSelectedComponent().component_id]; 298 iterator.rem_comps = comps; 299 gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.removeComponent); 300 } 301 } 302 break; 303 case Tool.selector: 304 iterator.distance = size2; 305 gEntityManager.callEntitiesFunction!IteratorSystem(&iterator.selectEntity); 306 break; 307 default: 308 break; 309 } 310 } 311 312 bool getKeyState(SDL_Scancode key) 313 { 314 if(keys[key])return true; 315 else return false; 316 } 317 318 void setStyle(uint index) 319 { 320 style = index; 321 .setStyle(index); 322 } 323 324 double getTime() 325 { 326 ulong local_freq = timer_freq / 1000_000; 327 //return cast(double)(SDL_GetPerformanceCounter() & 0x00FFFFFF) / timer_freq; 328 if(local_freq == 0)return cast(double)(SDL_GetPerformanceCounter() / timer_freq * 1000); 329 else return cast(double)(SDL_GetPerformanceCounter() / local_freq) / 1000; 330 } 331 } 332 333 __gshared Launcher launcher; 334 335 struct CountSystem 336 { 337 mixin ECS.System!1; 338 339 struct EntitiesData 340 { 341 uint length; 342 const (Entity)[] entity; 343 } 344 345 bool onBegin() 346 { 347 launcher.entities_count = 0; 348 return true; 349 } 350 351 void onUpdate(EntitiesData data) 352 { 353 launcher.entities_count += data.length; 354 } 355 } 356 357 struct CleanSystem 358 { 359 mixin ECS.System!64; 360 361 struct EntitiesData 362 { 363 uint length; 364 Entity[] entities; 365 } 366 367 void onUpdate(EntitiesData data) 368 { 369 foreach(i; 0..data.length) 370 { 371 gEntityManager.removeEntity(data.entities[i].id); 372 } 373 } 374 } 375 376 struct IteratorSystem 377 { 378 mixin ECS.System!1; 379 380 struct EntitiesData 381 { 382 uint length; 383 const (Entity)[] entity; 384 CLocation[] location; 385 } 386 387 bool onBegin() 388 { 389 return false; 390 } 391 392 void onUpdate(EntitiesData) 393 { 394 395 } 396 } 397 398 void mainLoop(void* arg) 399 { 400 __gshared double time = 0; 401 launcher.delta_time = launcher.getTime() - time; 402 time = launcher.getTime(); 403 404 if(launcher.delta_time > 1000)launcher.delta_time = 1000; 405 406 __gshared uint temp_fps = 0; 407 __gshared double fps_time = 0; 408 temp_fps++; 409 fps_time += launcher.delta_time; 410 while(fps_time > 1000) 411 { 412 fps_time -= 1000; 413 launcher.fps = temp_fps; 414 temp_fps = 0; 415 } 416 417 SDL_Event event; 418 while (SDL_PollEvent(&event)) 419 { 420 ImGui_ImplSDL2_ProcessEvent(&event); 421 if(launcher.demo.event)launcher.demo.event(&event); 422 if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)) { 423 quit(); 424 *cast(bool*)arg = false; 425 return; 426 } 427 else if(event.type == SDL_KEYDOWN) 428 { 429 if(event.key.state) 430 { 431 if(SDL_GetModState() & KMOD_CTRL) 432 { 433 switch(event.key.keysym.scancode) 434 { 435 case SDL_SCANCODE_1:launcher.used_tool=Tool.entity_spawner;break; 436 case SDL_SCANCODE_2:launcher.used_tool=Tool.component_manipulator;break; 437 case SDL_SCANCODE_3:launcher.used_tool=Tool.selector;break; 438 default:break; 439 } 440 } 441 else 442 { 443 switch(event.key.keysym.scancode) 444 { 445 case SDL_SCANCODE_1:break; 446 case SDL_SCANCODE_2:break; 447 case SDL_SCANCODE_3:break; 448 case SDL_SCANCODE_4:break; 449 default:break; 450 } 451 } 452 } 453 } 454 else if(event.type == SDL_WINDOWEVENT) 455 { 456 switch(event.window.event) 457 { 458 case SDL_WINDOWEVENT_RESIZED: 459 //launcher.renderer.resize(ivec2(event.window.data1,event.window.data2)); 460 launcher.window_size = ivec2(event.window.data1,event.window.data2); 461 break; 462 case SDL_WINDOWEVENT_SIZE_CHANGED: 463 //launcher.renderer.resize(ivec2(event.window.data1,event.window.data2)); 464 launcher.window_size = ivec2(event.window.data1,event.window.data2); 465 break; 466 default:break; 467 } 468 } 469 else if(event.type == SDL_MOUSEBUTTONDOWN) 470 { 471 switch(event.button.button) 472 { 473 case SDL_BUTTON_LEFT:launcher.mouse.left = true;break; 474 case SDL_BUTTON_RIGHT:launcher.mouse.right = true;break; 475 case SDL_BUTTON_MIDDLE:launcher.mouse.middle = true;break; 476 default:break; 477 } 478 if(!igIsAnyItemHovered())igSetWindowFocus(); 479 if(!igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow)) 480 { 481 launcher.repeat_time = 0; 482 if(event.button.button == SDL_BUTTON_LEFT)launcher.processTool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position,launcher.tool_mode); 483 else if(event.button.button == SDL_BUTTON_RIGHT)launcher.processTool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position,!launcher.tool_mode); 484 } 485 } 486 else if(event.type == SDL_MOUSEBUTTONUP) 487 { 488 switch(event.button.button) 489 { 490 case SDL_BUTTON_LEFT:launcher.mouse.left = false;break; 491 case SDL_BUTTON_RIGHT:launcher.mouse.right = false;break; 492 case SDL_BUTTON_MIDDLE:launcher.mouse.middle = false;break; 493 default:break; 494 } 495 } 496 else if(event.type == SDL_MOUSEMOTION) 497 { 498 launcher.mouse.position = vec2(event.motion.x, launcher.window_size.y - event.motion.y); 499 }else if(event.type == SDL_MOUSEWHEEL) 500 { 501 if(!igIsAnyItemHovered() && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow)) 502 { 503 if(SDL_GetModState() & KMOD_CTRL) 504 { 505 float sign = 1; 506 if(event.wheel.y < 0)sign = -1; 507 float val = /*sign * event.wheel.y */ launcher.tool_repeat * 0.25; 508 if(val < 0.1)val = 0.1; 509 launcher.tool_repeat -= sign * val; 510 if(launcher.tool_repeat < 0)launcher.tool_repeat = 0; 511 else if(launcher.tool_repeat > 1000)launcher.tool_repeat = 1000; 512 } 513 else if(SDL_GetModState() & KMOD_SHIFT) 514 { 515 int sign = 1; 516 if(event.wheel.y < 0)sign = -1; 517 switch(launcher.used_tool) 518 { 519 case Tool.entity_spawner: 520 launcher.gui_manager.selectTemplate(launcher.gui_manager.selected_template-sign); 521 break; 522 case Tool.component_manipulator: 523 launcher.gui_manager.selectComponent(launcher.gui_manager.selected_component-sign); 524 break; 525 default:break; 526 } 527 } 528 else 529 { 530 int sign = 1; 531 if(event.wheel.y < 0)sign = -1; 532 int val = /*sign * event.wheel.y */ launcher.tool_size / 4; 533 if(val < 1)val = 1; 534 launcher.tool_size -= sign * val; 535 if(launcher.tool_size < 1)launcher.tool_size = 1; 536 else if(launcher.tool_size > 256)launcher.tool_size = 256; 537 } 538 } 539 } 540 } 541 542 if(launcher.tool_repeat != 0 && (launcher.mouse.left || launcher.mouse.right) && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow)) 543 { 544 bool mode = launcher.tool_mode; 545 if(launcher.mouse.right)mode = !mode; 546 float range = 500.0 / cast(float)launcher.tool_repeat; 547 launcher.repeat_time += launcher.delta_time; 548 if(launcher.used_tool != Tool.entity_spawner || !mode) 549 { 550 if(launcher.repeat_time > range)launcher.processTool((launcher.mouse.position*launcher.scalling)-launcher.render_position, mode); 551 while(launcher.repeat_time > range)launcher.repeat_time -= range; 552 } 553 else 554 { 555 while(launcher.repeat_time > range) 556 { 557 launcher.repeat_time -= range; 558 launcher.processTool((launcher.mouse.position*launcher.scalling)-launcher.render_position, mode); 559 } 560 } 561 } 562 563 version(WebAssembly) 564 { 565 ImGui_ImplOpenGL3_NewFrame(); 566 ImGui_ImplSDL2_NewFrame(launcher.window); 567 } 568 else 569 { 570 //ImGuiImplOpenGL2NewFrame(); 571 ImGui_ImplOpenGL3_NewFrame(); 572 ImGuiImplSDL2NewFrame(launcher.window); 573 } 574 575 igNewFrame(); 576 577 if(igBeginMainMenuBar()) 578 { 579 if(igBeginMenu("File",true)) 580 { 581 if(igMenuItemBool("Close","esc",false,true)) 582 { 583 quit(); 584 *cast(bool*)arg = false; 585 return; 586 } 587 igEndMenu(); 588 } 589 if(igBeginMenu("Demos",true)) 590 { 591 if(igMenuItemBool("Simpe",null,false,true)) 592 { 593 import demos.simple; 594 launcher.switchDemo(getSimpleDemo());//&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); 595 } 596 if(igMenuItemBool("Snake",null,false,true)) 597 { 598 import demos.snake; 599 launcher.switchDemo(getSnakeDemo());//&snakeStart,&snakeLoop,&snakeEnd,&snakeEvent,Snake.tips); 600 } 601 if(igMenuItemBool("Space Invaders",null,false,true)) 602 { 603 import demos.space_invaders; 604 launcher.switchDemo(getSpaceInvadersDemo());//&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); 605 } 606 if(igMenuItemBool("Particles",null,false,true)) 607 { 608 import demos.particles; 609 launcher.switchDemo(getParticlesDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); 610 } 611 if(igMenuItemBool("Brick Breaker",null,false,true)) 612 { 613 import demos.brick_breaker; 614 launcher.switchDemo(getBrickBreakerDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); 615 } 616 if(igMenuItemBool("Sandbox",null,false,true)) 617 { 618 import demos.sandbox; 619 launcher.switchDemo(getSanboxDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); 620 } 621 igEndMenu(); 622 } 623 if(igBeginMenu("Options",true)) 624 { 625 if(igMenuItemBool("VSync", null, launcher.swap_interval, true)) 626 { 627 launcher.swap_interval = !launcher.swap_interval; 628 SDL_GL_SetSwapInterval(launcher.swap_interval); 629 } 630 if(igMenuItemBool("Multithreading", null, launcher.multithreading, true)) 631 { 632 launcher.multithreading = !launcher.multithreading; 633 if(launcher.multithreading) 634 { 635 launcher.job_updater.pool.setThreadsNum(launcher.threads); 636 } 637 else 638 { 639 launcher.job_updater.pool.setThreadsNum(1); 640 } 641 } 642 igSetNextItemWidth(0); 643 igLabelText("Threads:",null); 644 igSameLine(0,4); 645 if(igSliderInt("##Threads",&launcher.threads, 1, 32, null))//"Multithreading", null, launcher.multithreading, true)) 646 { 647 launcher.job_updater.pool.setThreadsNum(launcher.threads); 648 //launcher.threads = !launcher.multithreading; 649 } 650 if(igBeginMenu("Show",true)) 651 { 652 igMenuItemBoolPtr("Statistics",null,&launcher.show_stat_wnd,true); 653 igMenuItemBoolPtr("Demo",null,&launcher.show_demo_wnd,true); 654 igMenuItemBoolPtr("Tips",null,&launcher.show_tips,true); 655 igMenuItemBoolPtr("Virual keys",null,&launcher.show_virtual_keys_wnd,true); 656 igMenuItemBoolPtr("Profile",null,&launcher.show_profile_wnd,true); 657 igEndMenu(); 658 } 659 if(igBeginMenu("Style",true)) 660 { 661 if(igMenuItemBool("Classic",null,launcher.style == 0,true)) 662 { 663 launcher.setStyle(0); 664 } 665 else if(igMenuItemBool("Dark",null,launcher.style == 1,true)) 666 { 667 launcher.setStyle(1); 668 } 669 else if(igMenuItemBool("Light",null,launcher.style == 2,true)) 670 { 671 launcher.setStyle(2); 672 } 673 else if(igMenuItemBool("Default",null,launcher.style == 3,true)) 674 { 675 launcher.setStyle(3); 676 } 677 igEndMenu(); 678 } 679 igEndMenu(); 680 } 681 igEndMainMenuBar(); 682 } 683 684 if(launcher.show_virtual_keys_wnd) 685 { 686 igSetNextWindowPos(ImVec2(launcher.window_size.x - 400, launcher.window_size.y - 200), ImGuiCond_Once, ImVec2(0,0)); 687 igSetNextWindowSize(ImVec2(64*4+128, 168), ImGuiCond_Once); 688 igSetNextWindowBgAlpha(launcher.windows_alpha); 689 ImGuiStyle * style = igGetStyle(); 690 style.Colors[ImGuiCol_Button].w = 0.8; 691 if(igBegin("Virtual keys",&launcher.show_virtual_keys_wnd, 0)) 692 { 693 igColumns(2,null,0); 694 igSetColumnWidth(0,64*3+16); 695 igIndent(64+4); 696 if(igButton("W",ImVec2(64,64)) || igIsItemDeactivated()) 697 { 698 launcher.keys[SDL_SCANCODE_W] = false; 699 } 700 else if(igIsItemActive()) 701 { 702 launcher.keys[SDL_SCANCODE_W] = true; 703 } 704 igUnindent(64+4); 705 if(igButton("A",ImVec2(64,64)) || igIsItemDeactivated()) 706 { 707 launcher.keys[SDL_SCANCODE_A] = false; 708 } 709 else if(igIsItemActive()) 710 { 711 launcher.keys[SDL_SCANCODE_A] = true; 712 } 713 igSameLine(0,4); 714 if(igButton("S",ImVec2(64,64)) || igIsItemDeactivated()) 715 { 716 launcher.keys[SDL_SCANCODE_S] = false; 717 } 718 else if(igIsItemActive()) 719 { 720 launcher.keys[SDL_SCANCODE_S] = true; 721 } 722 igSameLine(0,4); 723 if(igButton("D",ImVec2(64,64)) || igIsItemDeactivated()) 724 { 725 launcher.keys[SDL_SCANCODE_D] = false; 726 } 727 else if(igIsItemActive()) 728 { 729 launcher.keys[SDL_SCANCODE_D] = true; 730 } 731 igNextColumn(); 732 if(igButton("Space",ImVec2(-1,128)) || igIsItemDeactivated()) 733 { 734 launcher.keys[SDL_SCANCODE_SPACE] = false; 735 } 736 else if(igIsItemActive()) 737 { 738 launcher.keys[SDL_SCANCODE_SPACE] = true; 739 } 740 igColumns(1,null,0); 741 } 742 igEnd(); 743 style.Colors[ImGuiCol_Button].w = 1.0; 744 } 745 746 if(launcher.show_tips) 747 { 748 igSetNextWindowPos(ImVec2(launcher.window_size.x /2 -250, 100), ImGuiCond_Once, ImVec2(0,0)); 749 igSetNextWindowSize(ImVec2(500, -1), ImGuiCond_Once); 750 igSetNextWindowBgAlpha(0.95); 751 if(igBegin("Tips",&launcher.show_tips,ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) 752 { 753 // igBeginChild("",ImVec2(0,0),0,0); 754 igTextWrapped(launcher.demo.tips); 755 // igEndChild(); 756 } 757 igEnd(); 758 } 759 760 if(launcher.show_demo_wnd) 761 { 762 igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, 30), ImGuiCond_Once, ImVec2(0,0)); 763 igSetNextWindowSize(ImVec2(250, 300), ImGuiCond_Once); 764 if(igBegin("Demo",&launcher.show_demo_wnd,0)) 765 { 766 igCheckbox("Play",&launcher.play); 767 ImDrawList* draw_list = igGetWindowDrawList(); 768 igBeginGroup(); 769 launcher.gui_manager.gui(); 770 igEndGroup(); 771 ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 4, ImDrawCornerFlags_All, 1); 772 773 //ImDrawList_AddRect(draw_list, igGetItemRectMin(), igGetItemRectMax(), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), -1, 0, 1); 774 //igBeginChildFrame(1,ImVec2(0,-1),ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_ChildWindow); 775 //igBeginChild("Tool frame",ImVec2(-1,-1),true,0); 776 // igBeginGroup(); 777 // if(igCollapsingHeader("Tool##ToolHeader", ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen)) 778 // { 779 // igIndent(8); 780 /*if(igBeginCombo("Tool",tool_strings[launcher.used_tool],0)) 781 { 782 if(igSelectable("Entity spawner",false,0,ImVec2(0,0))) 783 { 784 launcher.used_tool = Tool.entity_spawner; 785 } 786 if(igSelectable("Component manipulator",false,0,ImVec2(0,0))) 787 { 788 launcher.used_tool = Tool.component_manipulator; 789 } 790 if(igSelectable("Selector",false,0,ImVec2(0,0))) 791 { 792 launcher.used_tool = Tool.selector; 793 } 794 igEndCombo(); 795 }*/ 796 /*if(igSelectable("Entity spawner",false,0,ImVec2(0,0))) 797 { 798 launcher.used_tool = Tool.entity_spawner; 799 } 800 if(igSelectable("Component manipulator",false,0,ImVec2(0,0))) 801 { 802 launcher.used_tool = Tool.component_manipulator; 803 } 804 if(igSelectable("Selector",false,0,ImVec2(0,0))) 805 { 806 launcher.used_tool = Tool.selector; 807 }*/ 808 /*if(igBeginTabBar("Tool",ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) 809 { 810 if(igIsItemHovered(0))igSetTooltip("Select tool (CTRL + 1,2,3)"); 811 bool a = 1; 812 //this is used as hack to make CTRL+1/2/3 tab selection possible 813 static Tool prev_tool = Tool.entity_spawner; 814 bool different = prev_tool != launcher.used_tool; 815 Tool tool; 816 if(igBeginTabItem("Entity spawner", &a, launcher.used_tool == Tool.entity_spawner && different ? ImGuiTabItemFlags_SetSelected : 0)) 817 { 818 tool = Tool.entity_spawner; 819 igEndTabItem(); 820 } 821 if(igBeginTabItem("Component manipulator", &a, launcher.used_tool == Tool.component_manipulator && different ? ImGuiTabItemFlags_SetSelected : 0)) 822 { 823 tool = Tool.component_manipulator; 824 igEndTabItem(); 825 } 826 if(igBeginTabItem("Selector", &a, launcher.used_tool == Tool.selector && different ? ImGuiTabItemFlags_SetSelected : 0)) 827 { 828 tool = Tool.selector; 829 igEndTabItem(); 830 } 831 launcher.used_tool = tool; 832 prev_tool = launcher.used_tool; 833 } 834 igEndTabBar(); 835 836 837 igCheckbox("Show Tool", &launcher.tool_show); 838 if(igIsItemHovered(0))igSetTooltip("Show/hide graphical tool representation"); 839 igSameLine(0,4); 840 igCheckbox("Show Filtered", &launcher.show_filtered); 841 if(igIsItemHovered(0))igSetTooltip("Show/hide filtered entities"); 842 if(launcher.used_tool == Tool.component_manipulator) 843 { 844 igCheckbox("Override", &launcher.override_); 845 } 846 847 //igSelectable("Selectabe",false,ImGuiSelectableFlags_None,ImVec2(0,0)); 848 if(launcher.used_tool != Tool.selector) 849 { 850 if(igRadioButtonBool("Add", launcher.tool_mode))launcher.tool_mode = true; 851 if(igIsItemHovered(0))igSetTooltip("Tool should adding (Entities or components)"); 852 igSameLine(0,4); 853 if(igRadioButtonBool("Remove", !launcher.tool_mode))launcher.tool_mode = false; 854 if(igIsItemHovered(0))igSetTooltip("Tool should removing (Entities or components)"); 855 } 856 857 igSliderInt("Tool size", &launcher.tool_size, 0, 256, null); 858 igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4); 859 launcher.gui_manager.toolGui();*/ 860 861 // igUnindent(8); 862 // } 863 // igEndGroup(); 864 ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 2, ImDrawCornerFlags_All, 1); 865 866 //igBeginGroup(); 867 if(igCollapsingHeader("Filter", ImGuiTreeNodeFlags_SpanAvailWidth)) 868 { 869 igIndent(8); 870 launcher.gui_manager.filterGUI(); 871 igUnindent(8); 872 } 873 //igEndGroup(); 874 //ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 2, ImDrawCornerFlags_All, 1); 875 876 //igEndChild(); 877 //igEndChildFrame(); 878 if(igButton("Clear",ImVec2(-1,0))) 879 { 880 gEntityManager.begin(); 881 gEntityManager.update("clean"); 882 gEntityManager.end(); 883 } 884 } 885 igEnd(); 886 } 887 888 if(launcher.show_tools_wnd) 889 { 890 891 igSetNextWindowPos(ImVec2(launcher.window_size.x - 300, 340), ImGuiCond_Once, ImVec2(0,0)); 892 igSetNextWindowSize(ImVec2(300, launcher.window_size.y - 370), ImGuiCond_Once); 893 if(igBegin("Tools", &launcher.show_tools_wnd, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) 894 { 895 if(igIsItemHovered(0))igSetTooltip("Select tool (CTRL + 1,2,3)"); 896 897 if(igBeginTabBar("Tool",ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) 898 { 899 bool a = 1; 900 //this is used as hack to make CTRL+1/2/3 tab selection possible 901 static Tool prev_tool = Tool.entity_spawner; 902 bool different = prev_tool != launcher.used_tool; 903 Tool tool; 904 if(igBeginTabItem("Entity spawner", &a, launcher.used_tool == Tool.entity_spawner && different ? ImGuiTabItemFlags_SetSelected : 0)) 905 { 906 tool = Tool.entity_spawner; 907 igEndTabItem(); 908 } 909 if(igBeginTabItem("Component manipulator", &a, launcher.used_tool == Tool.component_manipulator && different ? ImGuiTabItemFlags_SetSelected : 0)) 910 { 911 tool = Tool.component_manipulator; 912 igEndTabItem(); 913 } 914 if(igBeginTabItem("Selector", &a, launcher.used_tool == Tool.selector && different ? ImGuiTabItemFlags_SetSelected : 0)) 915 { 916 tool = Tool.selector; 917 igEndTabItem(); 918 } 919 launcher.used_tool = tool; 920 prev_tool = launcher.used_tool; 921 } 922 igEndTabBar(); 923 924 925 igCheckbox("Show Tool", &launcher.tool_show); 926 if(igIsItemHovered(0))igSetTooltip("Show/hide graphical tool representation"); 927 igSameLine(0,4); 928 igCheckbox("Show Filtered", &launcher.show_filtered); 929 if(igIsItemHovered(0))igSetTooltip("Show/hide filtered entities"); 930 if(launcher.used_tool == Tool.component_manipulator) 931 { 932 igCheckbox("Override", &launcher.override_); 933 } 934 935 //igSelectable("Selectabe",false,ImGuiSelectableFlags_None,ImVec2(0,0)); 936 if(launcher.used_tool != Tool.selector) 937 { 938 if(igRadioButtonBool("Add", launcher.tool_mode))launcher.tool_mode = true; 939 if(igIsItemHovered(0))igSetTooltip("Tool should adding (Entities or components)"); 940 igSameLine(0,4); 941 if(igRadioButtonBool("Remove", !launcher.tool_mode))launcher.tool_mode = false; 942 if(igIsItemHovered(0))igSetTooltip("Tool should removing (Entities or components)"); 943 } 944 945 igSliderInt("Tool size", &launcher.tool_size, 0, 256, null); 946 igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4); 947 948 if(igBeginChild("",ImVec2(0,0),1,0)) 949 { 950 launcher.gui_manager.toolGui(); 951 } 952 igEndChild(); 953 } 954 igEnd(); 955 } 956 957 if(launcher.show_profile_wnd) 958 { 959 //igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, launcher.window_size.y - 280), ImGuiCond_Once, ImVec2(0,0)); 960 igSetNextWindowPos(ImVec2(8, launcher.window_size.y - 258), ImGuiCond_Once, ImVec2(0,0)); 961 igSetNextWindowSize(ImVec2(250, 250), ImGuiCond_Once); 962 if(igBegin("Profile",&launcher.show_profile_wnd,0)) 963 { 964 if(igBeginTabBar("ProfileTabBar",ImGuiTabBarFlags_FittingPolicyScroll)) 965 { 966 967 if(igBeginTabItem("Plots", null, 0)) 968 { 969 if(igBeginChild("ProfileChild",ImVec2(-1,-1),0,0)) 970 { 971 igPlotLines("Delta time",&launcher.plot_values[0].delta_time,100,launcher.plot_index,"Delta time",0,float.max,ImVec2(0,64),Launcher.PlotStruct.sizeof); 972 igPlotLines("Loop time",&launcher.plot_values[0].loop_time,100,launcher.plot_index,"Loop time",0,float.max,ImVec2(0,64),Launcher.PlotStruct.sizeof); 973 igPlotLines("Draw time",&launcher.plot_values[0].draw_time,100,launcher.plot_index,"Draw time",0,float.max,ImVec2(0,64),Launcher.PlotStruct.sizeof); 974 } 975 igEndChild(); 976 igEndTabItem(); 977 } 978 if(igBeginTabItem("Multithreading graph", null, 0)) 979 { 980 if(igBeginChild("ProfileChild",ImVec2(-1,-1),0,0)) 981 { 982 igText("Work in proggress"); 983 } 984 igEndChild(); 985 igEndTabItem(); 986 } 987 988 igEndTabBar(); 989 } 990 } 991 igEnd(); 992 } 993 994 launcher.renderer.resize(launcher.window_size); 995 //launcher.renderer.view(vec2(0,0),vec2(launcher.window_size.x,launcher.window_size.y)); 996 //if(384, 768, 1152, 1536) 997 //576 960 1344 1728 998 //float scalling; 999 if(launcher.window_size.y < 360)launcher.scalling = 1; 1000 else launcher.scalling = 1.0 / ((launcher.window_size.y+120)/360); 1001 launcher.renderer.view(launcher.render_position,vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling); 1002 //launcher.renderer.view(vec2(0,0),vec2(1024*launcher.window_size.x/launcher.window_size.y,768)); 1003 //glClear(GL_COLOR_BUFFER_BIT); 1004 launcher.renderer.clear(); 1005 1006 double loop_time = launcher.getTime(); 1007 launcher.job_updater.pool.tryWaitCount = 10000; 1008 if(launcher.play) 1009 { 1010 if(launcher.demo.loop && !launcher.demo.loop()) 1011 { 1012 quit(); 1013 *cast(bool*)arg = false; 1014 } 1015 } 1016 else 1017 { 1018 gEntityManager.begin(); 1019 import game_core.rendering; 1020 DrawSystem* draw_system = gEntityManager.getSystem!DrawSystem; 1021 gEntityManager.callEntitiesFunction!DrawSystem(&draw_system.onUpdate); 1022 gEntityManager.end(); 1023 } 1024 launcher.job_updater.pool.tryWaitCount = 0; 1025 1026 loop_time = launcher.getTime() - loop_time; 1027 1028 double draw_time = launcher.getTime(); 1029 launcher.renderer.present(); 1030 draw_time = launcher.getTime() - draw_time; 1031 1032 if(launcher.tool_show)launcher.tool_circle.draw(&launcher.renderer, (launcher.mouse.position*launcher.scalling)-launcher.render_position, cast(float)launcher.tool_size, launcher.renderer.view_size.y*6*launcher.scalling); 1033 1034 __gshared float plot_time = 0; 1035 __gshared uint plot_samples = 0; 1036 plot_time += launcher.delta_time; 1037 plot_samples++; 1038 launcher.plot_values[100].delta_time += launcher.delta_time; 1039 launcher.plot_values[100].loop_time += loop_time; 1040 launcher.plot_values[100].draw_time += draw_time; 1041 if(plot_time > 100) 1042 { 1043 launcher.plot_values[launcher.plot_index].delta_time = launcher.plot_values[100].delta_time / cast(float)plot_samples; 1044 launcher.plot_values[launcher.plot_index].loop_time = launcher.plot_values[100].loop_time / cast(float)plot_samples; 1045 launcher.plot_values[launcher.plot_index].draw_time = launcher.plot_values[100].draw_time / cast(float)plot_samples; 1046 launcher.plot_values[100].delta_time = 0; 1047 launcher.plot_values[100].loop_time = 0; 1048 launcher.plot_values[100].draw_time = 0; 1049 1050 plot_samples = 0; 1051 plot_time -= 100; 1052 launcher.plot_index++; 1053 if(launcher.plot_index >= 100)launcher.plot_index = 0; 1054 } 1055 1056 if(launcher.show_stat_wnd) 1057 { 1058 igSetNextWindowPos(ImVec2(10, 30), ImGuiCond_Appearing, ImVec2(0,0)); 1059 igSetNextWindowContentSize(ImVec2(150, 0.0f)); 1060 igSetNextWindowBgAlpha(launcher.windows_alpha); 1061 if(igBegin("Statistics", &launcher.show_stat_wnd, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) 1062 { 1063 igColumns(2,null,0); 1064 igSetColumnWidth(0,100); 1065 igText("FPS: "); 1066 igText("Entities: "); 1067 igText("Loop time: "); 1068 igText("Draw time: "); 1069 igText("Delta time: "); 1070 igNextColumn(); 1071 igText("%u",launcher.fps); 1072 igText("%u",launcher.entities_count); 1073 igText("%2.2fms",loop_time); 1074 igText("%2.2fms",draw_time); 1075 igText("%2.2fms",launcher.delta_time); 1076 igColumns(1,null,0); 1077 } 1078 igEnd(); 1079 } 1080 1081 glUseProgram(0); 1082 import ecs_utils.gfx.buffer; 1083 Buffer.unbind(Buffer.BindTarget.array); 1084 Buffer.unbind(Buffer.BindTarget.element_array); 1085 1086 igRender(); 1087 version(WebAssembly)ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); 1088 else version(Android)ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); 1089 else ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); 1090 //ImGuiImplOpenGL2RenderDrawData(igGetDrawData()); 1091 1092 //launcher.renderer.clear(); 1093 //launcher.renderer.present(); 1094 1095 SDL_GL_SwapWindow(launcher.window); 1096 1097 } 1098 1099 void quit() 1100 { 1101 import game_core.rendering : TexCoordsManager; 1102 launcher.gui_manager.clear(); 1103 Mallocator.dispose(launcher.gui_manager); 1104 1105 if(launcher.demo.deinitialize)launcher.demo.deinitialize(); 1106 1107 gEntityManager.destroy(); 1108 gEntityManager = null; 1109 1110 TexCoordsManager.destroy(); 1111 1112 SDL_Quit(); 1113 1114 version(WebAssembly)emscripten_cancel_main_loop(); 1115 } 1116 1117 version(Android) 1118 { 1119 export extern (C) int SDL_main(int argc, char** args) 1120 { 1121 return app_main(argc,args); 1122 } 1123 1124 import ldc.attributes; 1125 1126 extern (C) __gshared 1127 { 1128 @section(".tdata") 1129 int _tlsstart = 0; 1130 @section(".tcommon") 1131 int _tlsend = 0; 1132 } 1133 1134 } 1135 else 1136 { 1137 extern (C) int main(int argc, char** argv) 1138 { 1139 return app_main(argc,argv); 1140 } 1141 } 1142 1143 int app_main(int argc, char** argv) 1144 //int main(int argc, char** argv) 1145 { 1146 1147 version(BindSDL_Static){} 1148 else 1149 { 1150 loadSDL(); 1151 loadSDLImage(); 1152 } 1153 1154 if (SDL_Init(SDL_INIT_VIDEO) < 0) 1155 { 1156 printf("SDL could not initialize! SDL_Error: %s", SDL_GetError()); 1157 return -1; 1158 } 1159 SDL_version sdl_version; 1160 SDL_GetVersion(&sdl_version); 1161 printf("SDL version: %u.%u.%u\n",cast(uint)sdl_version.major,cast(uint)sdl_version.minor,cast(uint)sdl_version.patch); 1162 1163 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); 1164 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); 1165 launcher.window = SDL_CreateWindow("Simple", SDL_WINDOWPOS_CENTERED, 1166 SDL_WINDOWPOS_CENTERED, launcher.window_size.x, launcher.window_size.y, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); 1167 SDL_MaximizeWindow(launcher.window); 1168 1169 launcher.gl_context = SDL_GL_CreateContext(launcher.window); 1170 launcher.context = igCreateContext(null); 1171 launcher.timer_freq = SDL_GetPerformanceFrequency(); 1172 1173 launcher.plot_values = Mallocator.makeArray!(Launcher.PlotStruct)(101); 1174 1175 SDL_GetWindowSize(launcher.window, &launcher.window_size.x, &launcher.window_size.y); 1176 1177 version(WebAssembly) 1178 { 1179 gladLoadGLES2(x => SDL_GL_GetProcAddress(x)); 1180 if(!ImGui_ImplSDL2_InitForOpenGL(launcher.window,launcher.gl_context)) 1181 { 1182 printf("ImGui initialization failed!"); 1183 return -2; 1184 } 1185 if(!ImGui_ImplOpenGL3_Init()) 1186 { 1187 printf("ImGui OpenGL initialization failed!"); 1188 return -3; 1189 } 1190 } 1191 else version(Android) 1192 { 1193 //gladLoadGL(); 1194 gladLoadGLES2(x => SDL_GL_GetProcAddress(x)); 1195 if(!ImGuiImplSDL2InitForOpenGL(launcher.window,launcher.gl_context)) 1196 { 1197 printf("ImGui initialization failed!"); 1198 return -2; 1199 } 1200 if(!ImGui_ImplOpenGL3_Init("#version 100")) 1201 { 1202 printf("ImGui OpenGL initialization failed!"); 1203 return -3; 1204 } 1205 } 1206 else 1207 { 1208 gladLoadGL(); 1209 if(!ImGuiImplSDL2InitForOpenGL(launcher.window,launcher.gl_context)) 1210 { 1211 printf("ImGui initialization failed!"); 1212 return -2; 1213 } 1214 //if(!ImGuiImplOpenGL2Init()) 1215 if(!ImGui_ImplOpenGL3_Init("#version 120")) 1216 { 1217 printf("ImGui OpenGL initialization failed!"); 1218 return -3; 1219 } 1220 } 1221 1222 //ImFontConfig* config = ImFontConfig_ImFontConfig(); 1223 ImGuiIO* io = igGetIO(); 1224 const ushort* font_ranges = ImFontAtlas_GetGlyphRangesDefault(io.Fonts); 1225 ImFontAtlas_AddFontFromFileTTF(io.Fonts,"assets/fonts/Ruda-Bold.ttf", 15.0f, null, font_ranges); 1226 //ImFontConfig_destroy(config); 1227 1228 setStyle(3); 1229 1230 launcher.job_updater = Mallocator.make!ECSJobUpdater(1); 1231 //launcher.job_updater.onCreate(); 1232 1233 EntityManager.initialize(32, 1<<16); 1234 //gEntityManager = gEntityManager; 1235 1236 //gEntityManager.m_thread_id_func = &launcher.job_updater.getThreadID; 1237 //gEntityManager.setJobDispachFunc(&launcher.job_updater.dispatch); 1238 gEntityManager.setMultithreadingCallbacks(&launcher.job_updater.dispatch, &launcher.job_updater.getThreadID); 1239 1240 gEntityManager.beginRegister(); 1241 1242 gEntityManager.registerPass("clean"); 1243 1244 gEntityManager.registerComponent!CLocation; 1245 1246 gEntityManager.registerSystem!CountSystem(10000); 1247 gEntityManager.registerSystem!CleanSystem(0,"clean"); 1248 gEntityManager.registerSystem!IteratorSystem(0,"clean"); 1249 1250 gEntityManager.endRegister(); 1251 1252 loadGFX(); 1253 1254 launcher.renderer.initialize(); 1255 import game_core.rendering : TexCoordsManager; 1256 TexCoordsManager.initialize(); 1257 1258 import mmutils.thread_pool : ThreadPool; 1259 launcher.threads = ThreadPool.getCPUCoresCount(); 1260 if(launcher.threads < 2)launcher.threads = 2; 1261 1262 launcher.gui_manager = Mallocator.make!GUIManager(); 1263 1264 { 1265 import demos.simple; 1266 import demos.space_invaders; 1267 import demos.particles; 1268 import demos.brick_breaker; 1269 // launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); 1270 // launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); 1271 // launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); 1272 // launcher.switchDemo(getParticlesDemo()); 1273 // launcher.switchDemo(getSimpleDemo()); 1274 launcher.switchDemo(getSimpleDemo()); 1275 } 1276 1277 int key_num; 1278 ubyte* keys = SDL_GetKeyboardState(&key_num); 1279 launcher.keys = keys[0..key_num]; 1280 1281 version(WebAssembly) 1282 { 1283 /*EmscriptenFullscreenStrategy strategy; 1284 strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH; 1285 strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF; 1286 strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST;*/ 1287 1288 //int result = emscripten_request_fullscreen_strategy(null, true, &strategy); 1289 //emscripten_enter_soft_fullscreen(null, &strategy); 1290 //printf("Fullscreen request: %s.\n", emscripten_result_to_string(result)); 1291 emscripten_set_main_loop_arg(&mainLoop, null, 0, 1); 1292 } 1293 else 1294 { 1295 bool arg = true; 1296 while(arg == true) 1297 { 1298 mainLoop(&arg); 1299 } 1300 } 1301 1302 return 0; 1303 } 1304 1305 void loadGFX() 1306 { 1307 import ecs_utils.gfx.texture; 1308 import ecs_utils.gfx.vertex; 1309 import ecs_utils.gfx.shader; 1310 import ecs_utils.gfx.material; 1311 import ecs_utils.gfx.config; 1312 import ecs_utils.gfx.mesh; 1313 1314 Texture.__loadBackend(); 1315 Renderer.__loadBackend(); 1316 1317 GfxConfig.materials = Mallocator.makeArray!Material(3); 1318 GfxConfig.meshes = Mallocator.makeArray!Mesh(1); 1319 1320 float[16] vertices = [-0.5,-0.5, 0,1, -0.5,0.5, 0,0, 0.5,-0.5, 1,1, 0.5,0.5, 1,0]; 1321 GfxConfig.meshes[0].vertices = Mallocator.makeArray(vertices); 1322 ushort[6] indices = [0,1,2,1,2,3]; 1323 GfxConfig.meshes[0].indices = Mallocator.makeArray(indices); 1324 GfxConfig.meshes[0].uploadData(); 1325 1326 Shader vsh; 1327 vsh.create(); 1328 vsh.load("assets/shaders/base.vp"); 1329 vsh.compile(); 1330 1331 Shader fsh; 1332 fsh.create(); 1333 fsh.load("assets/shaders/base.fp"); 1334 fsh.compile(); 1335 1336 GfxConfig.materials[0].create(); 1337 GfxConfig.materials[0].data.blend_mode = Material.BlendMode.opaque; 1338 GfxConfig.materials[0].data.mode = Material.TransformMode.position; 1339 Material.ShaderModule[1] modules = [Material.ShaderModule(vsh,fsh)]; 1340 GfxConfig.materials[0].attachModules(modules); 1341 //GfxConfig.materials[0]. 1342 //GfxConfig.materials[0].load(load_data.materials[i].str); 1343 GfxConfig.materials[0].compile(); 1344 GfxConfig.materials[0].bindAttribLocation("positions",0); 1345 GfxConfig.materials[0].bindAttribLocation("tex_coords",1); 1346 GfxConfig.materials[0].bindAttribLocation("depth",2); 1347 GfxConfig.materials[0].bindAttribLocation("vcolor",3); 1348 GfxConfig.materials[0].link(); 1349 1350 /* import std.stdio; 1351 writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions")); 1352 writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords")); 1353 writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth")); 1354 writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/ 1355 1356 GfxConfig.materials[0].data.uniforms = Mallocator.makeArray!(Material.Uniform)(3); 1357 GfxConfig.materials[0].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_1"), 0); 1358 GfxConfig.materials[0].data.uniforms[1] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_2"), 16); 1359 GfxConfig.materials[0].data.uniforms[2] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("uv_transform"), 32); 1360 GfxConfig.materials[0].data.bindings = Mallocator.makeArray!(int)(1); 1361 GfxConfig.materials[0].data.bindings[0] = GfxConfig.materials[0].getLocation("tex"); 1362 1363 1364 Shader vsh2; 1365 vsh2.create(); 1366 vsh2.load("assets/shaders/circle.vp"); 1367 vsh2.compile(); 1368 1369 Shader fsh2; 1370 fsh2.create(); 1371 fsh2.load("assets/shaders/circle.fp"); 1372 fsh2.compile(); 1373 1374 GfxConfig.materials[1].create(); 1375 GfxConfig.materials[1].data.blend_mode = Material.BlendMode.mixed; 1376 GfxConfig.materials[1].data.mode = Material.TransformMode.position; 1377 Material.ShaderModule[1] modules2 = [Material.ShaderModule(vsh2,fsh2)]; 1378 GfxConfig.materials[1].attachModules(modules2); 1379 //GfxConfig.materials[0]. 1380 //GfxConfig.materials[0].load(load_data.materials[i].str); 1381 GfxConfig.materials[1].compile(); 1382 GfxConfig.materials[1].bindAttribLocation("positions",0); 1383 //GfxConfig.materials[1].bindAttribLocation("tex_coords",1); 1384 //GfxConfig.materials[1].bindAttribLocation("depth",2); 1385 //GfxConfig.materials[1].bindAttribLocation("vcolor",3); 1386 GfxConfig.materials[1].link(); 1387 1388 /* import std.stdio; 1389 writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions")); 1390 writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords")); 1391 writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth")); 1392 writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/ 1393 1394 GfxConfig.materials[1].data.uniforms = Mallocator.makeArray!(Material.Uniform)(2); 1395 GfxConfig.materials[1].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[1].getLocation("matrix_1"), 0); 1396 GfxConfig.materials[1].data.uniforms[1] = Material.Uniform(Material.Type.float4, GfxConfig.materials[1].getLocation("matrix_2"), 16); 1397 //GfxConfig.materials[1].data.uniforms[2] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("uv_transform"), 32); 1398 //GfxConfig.materials[1].data.bindings = Mallocator.makeArray!(int)(1); 1399 //GfxConfig.materials[1].data.bindings[0] = GfxConfig.materials[0].getLocation("tex"); 1400 1401 1402 1403 1404 1405 Shader vsh3; 1406 vsh3.create(); 1407 vsh3.load("assets/shaders/additive_particles.vp"); 1408 vsh3.compile(); 1409 1410 Shader fsh3; 1411 fsh3.create(); 1412 fsh3.load("assets/shaders/additive_particles.fp"); 1413 fsh3.compile(); 1414 1415 GfxConfig.materials[2].create(); 1416 GfxConfig.materials[2].data.blend_mode = Material.BlendMode.opaque; 1417 GfxConfig.materials[2].data.mode = Material.TransformMode.position; 1418 Material.ShaderModule[1] modules3 = [Material.ShaderModule(vsh3,fsh3)]; 1419 GfxConfig.materials[2].attachModules(modules3); 1420 //GfxConfig.materials[0]. 1421 //GfxConfig.materials[0].load(load_data.materials[i].str); 1422 GfxConfig.materials[2].compile(); 1423 GfxConfig.materials[2].bindAttribLocation("positions",0); 1424 GfxConfig.materials[2].bindAttribLocation("tex_coords",1); 1425 GfxConfig.materials[2].bindAttribLocation("depth",2); 1426 GfxConfig.materials[2].bindAttribLocation("vcolor",3); 1427 GfxConfig.materials[2].link(); 1428 1429 /* import std.stdio; 1430 writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions")); 1431 writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords")); 1432 writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth")); 1433 writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/ 1434 1435 GfxConfig.materials[2].data.uniforms = Mallocator.makeArray!(Material.Uniform)(3); 1436 GfxConfig.materials[2].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_1"), 0); 1437 GfxConfig.materials[2].data.uniforms[1] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_2"), 16); 1438 GfxConfig.materials[2].data.uniforms[2] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("uv_transform"), 32); 1439 GfxConfig.materials[2].data.bindings = Mallocator.makeArray!(int)(1); 1440 GfxConfig.materials[2].data.bindings[0] = GfxConfig.materials[0].getLocation("tex"); 1441 GfxConfig.materials[2].data.blend_mode = Material.BlendMode.additive; 1442 1443 1444 1445 1446 1447 1448 /*glUseProgram(0); 1449 glBindBuffer(GL_ARRAY_BUFFER, 0); 1450 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);*/ 1451 1452 launcher.tool_circle = Mallocator.make!ToolCircle; 1453 }