Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
MenuBar.cpp
Go to the documentation of this file.
1
2
3#include "Headers/MenuBar.h"
5
11
13
15
28
29#include "GUI/Headers/GUI.h"
30
33
36
41
42#include <imgui_internal.h>
44#include <IconsForkAwesome.h>
45#include <ECS/SystemManager.h>
46
47namespace Divide
48{
49 namespace
50 {
52 SceneGraphNodeDescriptor g_nodeDescriptor;
53
54 const string s_messages[] = {
55 "Please wait while saving current scene! App may appear frozen or stuttery for up to 30 seconds ...",
56 "Saved scene succesfully",
57 "Failed to save the current scene"
58 };
59
61 {
62 SceneEntry _targetScene = {};
63 string _saveMessage = "";
64 U32 _saveElementCount = 0u;
65 U32 _saveProgress = 0u;
66 bool _closePopup = false;
67 } g_saveSceneParams;
68
69 const char* EdgeMethodName( const PreRenderBatch::EdgeDetectionMethod method ) noexcept
70 {
71 switch ( method )
72 {
77 }
78 return "Unknown";
79 }
80 }
81
82
83 MenuBar::MenuBar( PlatformContext& context, const bool mainMenu )
84 : PlatformContextComponent( context )
85 , _isMainMenu( mainMenu )
86 , _sceneOpenDialog( true, true )
87 , _sceneSaveDialog( true )
88 {
89 }
90
92 {
94
96 const bool modifierPressed = imguiContext.IO.KeyShift;
97
98 if ( ImGui::BeginMainMenuBar() )
99 {
100 drawFileMenu( modifierPressed );
101 drawEditMenu( modifierPressed );
102 drawProjectMenu( modifierPressed );
103 drawObjectMenu( modifierPressed );
104 drawToolsMenu( modifierPressed );
105 //drawWindowsMenu(modifierPressed);
106 drawPostFXMenu( modifierPressed );
107 drawDebugMenu( modifierPressed );
108 drawHelpMenu( modifierPressed );
109
110 ImGui::EndMainMenuBar();
111
112 for ( vector<Handle<Texture>>::iterator it = std::begin( _previewTextures ); it != std::end( _previewTextures ); )
113 {
114 if ( Attorney::EditorGeneralWidget::modalTextureView( _context.editor(), Util::StringFormat( "Image Preview: {}", Get(*it)->resourceName().c_str() ).c_str(), *it, vec2<F32>( 512, 512 ), true, false ) )
115 {
116 it = _previewTextures.erase( it );
117 }
118 else
119 {
120 ++it;
121 }
122 }
123
124 if ( _closePopup )
125 {
126 Util::OpenCenteredPopup( "Confirm Close" );
127
128 if ( ImGui::BeginPopupModal( "Confirm Close", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) )
129 {
130 ImGui::Text( "Are you sure you want to close the editor? You have unsaved items!" );
131 ImGui::Separator();
132
133 if ( ImGui::Button( "Cancel", ImVec2( 120, 0 ) ) )
134 {
135 ImGui::CloseCurrentPopup();
136 _closePopup = false;
137 }
138 ImGui::SetItemDefaultFocus();
139 ImGui::SameLine();
140 if ( ImGui::Button( "Yes", ImVec2( 120, 0 ) ) )
141 {
142
143 ImGui::CloseCurrentPopup();
144 _closePopup = false;
145 _context.editor().toggle( false );
146 }
147 ImGui::EndPopup();
148 }
149 }
150
151 if ( !_errorMsg.empty() )
152 {
153 Util::OpenCenteredPopup( "Error!" );
154 if ( ImGui::BeginPopupModal( "Error!", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) )
155 {
156 ImGui::Text( _errorMsg.c_str() );
157 if ( ImGui::Button( "Ok" ) )
158 {
159 ImGui::CloseCurrentPopup();
160 _errorMsg.clear();
161 }
162 ImGui::EndPopup();
163 }
164 }
165
166 if ( _newScenePopup )
167 {
168 Util::OpenCenteredPopup( "Create New Scene" );
169 if ( ImGui::BeginPopupModal( "Create New Scene", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) )
170 {
171 static char buf[256];
172 ImGui::Text( "This will automatically load the newly created scene!\nWARNING: All unsaved changes will be lost!" );
173 ImGui::Text( "New Scene Name:" ); ImGui::SameLine();
174 if ( ImGui::InputText( "##New Scene Name:", &buf[0], 254 ) )
175 {
176
177 }
178 ImGui::Separator();
179 if ( ImGui::Button( "Cancel", ImVec2( 120, 0 ) ) )
180 {
181 ImGui::CloseCurrentPopup();
182 _newScenePopup = false;
183 }
184 ImGui::SetItemDefaultFocus();
185 ImGui::SameLine();
186 if ( ImGui::Button( "Create", ImVec2( 120, 0 ) ) )
187 {
188 ImGui::CloseCurrentPopup();
189 _newScenePopup = false;
190 SceneEntry newScene;
191 newScene._name = buf;
192
193 if ( newScene._name.empty() )
194 {
195 _errorMsg.append( "Scenes must be named!. \n" );
196 }
197 else if ( !Util::CompareIgnoreCase( newScene._name.c_str(), Config::DEFAULT_SCENE_NAME ) )
198 {
200 {
202 }
203 }
204 else
205 {
206 _errorMsg.append( "Tried to use a reserved name for a new scene! Try a different name. \n" );
207 }
208 }
209 ImGui::EndPopup();
210 }
211 }
212
213 if ( _saveSceneAsPopup )
214 {
215 Util::OpenCenteredPopup( "Save Scene As ..." );
216 if ( ImGui::BeginPopupModal( "Save Scene As ...", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) )
217 {
218 static char buf[256];
219 ImGui::Text( "Target Name:" ); ImGui::SameLine();
220 if ( ImGui::InputText( "##Target Name:", &buf[0], 254 ) )
221 {
222
223 }
224 ImGui::Separator();
225 if ( ImGui::Button( "Cancel", ImVec2( 120, 0 ) ) )
226 {
227 ImGui::CloseCurrentPopup();
228 _saveSceneAsPopup = false;
229 }
230 ImGui::SetItemDefaultFocus();
231 ImGui::SameLine();
232 if ( ImGui::Button( "Save", ImVec2( 120, 0 ) ) )
233 {
234 ImGui::CloseCurrentPopup();
235 _saveSceneAsPopup = false;
236
237 SceneEntry newScene;
238 newScene._name = buf;
239
240 if ( newScene._name.empty() )
241 {
242 _errorMsg.append( "Scenes must be named!. \n" );
243 }
244 else if ( !Util::CompareIgnoreCase( newScene._name.c_str(), Config::DEFAULT_SCENE_NAME ) )
245 {
246 _errorMsg.append( "Can't overwrite the default scene!. \n" );
247 }
248
249 saveAndDrawModalPopup( newScene );
250 }
251
252 ImGui::EndPopup();
253 }
254 }
255
256 if ( _quitPopup )
257 {
258 Util::OpenCenteredPopup( "Confirm Quit" );
259 if ( ImGui::BeginPopupModal( "Confirm Quit", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) )
260 {
261 ImGui::Text( "Are you sure you want to quit?" );
262 ImGui::NewLine();
263 static bool clearCache = false;
264 ImGui::Checkbox( "Clear All Cache Items", &clearCache );
265 ImGui::NewLine();
266 ImGui::Separator();
267
268 if ( ImGui::Button( "Cancel", ImVec2( 120, 0 ) ) )
269 {
270 ImGui::CloseCurrentPopup();
271 _quitPopup = false;
272 }
273 ImGui::SetItemDefaultFocus();
274 ImGui::SameLine();
275 if ( ImGui::Button( "Yes", ImVec2( 120, 0 ) ) )
276 {
277 ImGui::CloseCurrentPopup();
278 _quitPopup = false;
279 context().app().RequestShutdown( clearCache );
280 }
281 ImGui::EndPopup();
282 }
283 }
284 if ( _restartPopup )
285 {
286 Util::OpenCenteredPopup( "Confirm Restart" );
287 if ( ImGui::BeginPopupModal( "Confirm Restart", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) )
288 {
289 ImGui::Text( "Are you sure you want to restart the application?" );
290 ImGui::NewLine();
291 static bool clearCache = false;
292 ImGui::Checkbox("Clear All Cache Items", &clearCache);
293 ImGui::NewLine();
294 ImGui::Separator();
295
296 if ( ImGui::Button( "Cancel", ImVec2( 120, 0 ) ) )
297 {
298 ImGui::CloseCurrentPopup();
299 _restartPopup = false;
300 }
301 ImGui::SetItemDefaultFocus();
302 ImGui::SameLine();
303 if ( ImGui::Button( "Yes", ImVec2( 120, 0 ) ) )
304 {
305 ImGui::CloseCurrentPopup();
306 _restartPopup = false;
307 context().app().RequestRestart(clearCache);
308 }
309 ImGui::EndPopup();
310 }
311 }
312 if ( _savePopup )
313 {
314 Util::OpenCenteredPopup( "Saving Scene" );
315 if ( ImGui::BeginPopupModal( "Saving Scene", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) )
316 {
317 constexpr U32 maxSize = 40u;
318 const U32 ident = MAP( g_saveSceneParams._saveProgress, 0u, g_saveSceneParams._saveElementCount, 0u, maxSize - 5u /*overestimate a bit*/ );
319
320 ImGui::Text( "Saving Scene!\n\n%s", g_saveSceneParams._saveMessage.c_str() );
321 ImGui::Separator();
322
323 string progress;
324 for ( U32 i = 0u; i < maxSize; ++i )
325 {
326 progress.append( i < ident ? "~" : " " );
327 }
328 ImGui::Text( "[%s]", progress.c_str() );
329 ImGui::Separator();
330
331 if ( g_saveSceneParams._closePopup )
332 {
333 _savePopup = false;
334 ImGui::CloseCurrentPopup();
335 }
336 ImGui::EndPopup();
337 }
338 }
339
340 static F32 sphereRadius = 1.f;
341 static U32 resolution = 16u;
342 static vec3<F32> sides{ 1.f, 1.f, 1.f };
343 static bool doubleSided = true;
344
345 const auto createPrimitive = [&]()
346 {
347 Scene* activeScene = _context.kernel().projectManager()->activeProject()->getActiveScene();
348
349 g_nodeDescriptor._componentMask = to_U32( ComponentType::TRANSFORM ) |
356
357 if ( g_nodeDescriptor._name.empty() )
358 {
359 Util::StringFormat( g_nodeDescriptor._name, "Primitive_{}", DefaultObjectIndex++ );
360 }
361
362 SceneNodeHandle handle{};
363 Handle<Material> materialHandle = INVALID_HANDLE<Material>;
364
365 switch ( _newPrimitiveType )
366 {
368 {
369 ResourceDescriptor<Sphere3D> nodeDescriptor( (g_nodeDescriptor._name + "_n").c_str() );
370 nodeDescriptor.ID( resolution );
371 nodeDescriptor.enumValue( Util::FLOAT_TO_UINT( sphereRadius ) );
372
373 Handle<Sphere3D> handleTmp = CreateResource( nodeDescriptor );
374 materialHandle = Get( handleTmp )->getMaterialTpl();
375 handle = FromHandle(handleTmp);
376 } break;
378 {
379 ResourceDescriptor<Box3D> nodeDescriptor( (g_nodeDescriptor._name + "_n").c_str() );
380 nodeDescriptor.data(
381 {
382 Util::FLOAT_TO_UINT( sides.x ),
383 Util::FLOAT_TO_UINT( sides.y ),
384 Util::FLOAT_TO_UINT( sides.z )
385 }
386 );
387
388 const Handle<Box3D> handleTmp = CreateResource( nodeDescriptor );
389 materialHandle = Get( handleTmp )->getMaterialTpl();
390 handle = FromHandle(handleTmp);
391 } break;
393 {
394 ResourceDescriptor<Quad3D> nodeDescriptor( (g_nodeDescriptor._name + "_n").c_str() );
395
396 P32 quadMask;
397 quadMask.i = 0;
398 quadMask.b[0] = doubleSided ? 0 : 1;
399 nodeDescriptor.mask( quadMask );
400 const vec3<F32> halfSides = sides * 0.5f;
401 const Handle<Quad3D> handleTmp = CreateResource( nodeDescriptor );
402 materialHandle = Get( handleTmp )->getMaterialTpl();
403 handle = FromHandle( handleTmp );
404
405 ResourcePtr<Quad3D> node = Get( handleTmp );
406 node->setCorner( Quad3D::CornerLocation::TOP_LEFT, vec3<F32>( -halfSides.x, halfSides.y, 0 ) );
407 node->setCorner( Quad3D::CornerLocation::TOP_RIGHT, vec3<F32>( halfSides.x, halfSides.y, 0 ) );
408 node->setCorner( Quad3D::CornerLocation::BOTTOM_LEFT, vec3<F32>( -halfSides.x, -halfSides.y, 0 ) );
409 node->setCorner( Quad3D::CornerLocation::BOTTOM_RIGHT, vec3<F32>( halfSides.x, -halfSides.y, 0 ) );
410 } break;
411
412 default:
414 break;
415 }
416
417 ResourcePtr<Material> mat = Get( materialHandle );
418 mat->properties().shadingMode( ShadingMode::PBR_MR );
419 mat->properties().baseColour( FColour4( 0.4f, 0.4f, 0.4f, 1.0f ) );
420 mat->properties().roughness( 0.5f );
421 mat->properties().metallic( 0.5f );
422 g_nodeDescriptor._nodeHandle = handle;
423
424 activeScene->sceneGraph()->getRoot()->addChildNode( g_nodeDescriptor );
426
428 };
429
431 {
432 if ( modifierPressed )
433 {
434 createPrimitive();
435 }
436 else
437 {
438 Util::OpenCenteredPopup( "Create Primitive" );
439 if ( ImGui::BeginPopupModal( "Create Primitive", nullptr, ImGuiWindowFlags_AlwaysAutoResize ) )
440 {
441 ImGui::Text( "Create a new [ %s ]?", Names::sceneNodeType[to_base( _newPrimitiveType )] );
442 ImGui::Separator();
443
444 static char buf[64];
445 ImGui::Text( "Name:" ); ImGui::SameLine();
446 if ( ImGui::InputText( "##Name:", &buf[0], 61 ) )
447 {
448 g_nodeDescriptor._name = buf;
449 }
450
451 switch ( _newPrimitiveType )
452 {
454 ImGui::InputFloat( "Radius", &sphereRadius );
455 ImGui::InputScalar( "Resolution", ImGuiDataType_U32, &resolution );
456 break;
458 Util::DrawVec<F32, 3, false>( ImGuiDataType_Float, "Side length", Util::FieldLabels, sides._v, false, false, 0.1f, 0.001f, 10000.f );
459 break;
461 Util::DrawVec<F32, 2, false>( ImGuiDataType_Float, "Side length", Util::FieldLabels, sides._v, false, false, 0.1f, 0.001f, 10000.f );
462 ImGui::Checkbox( "Double Sided", &doubleSided );
463 break;
464 default: break;
465 }
466 if ( ImGui::Button( "Cancel", ImVec2( 120, 0 ) ) )
467 {
468 ImGui::CloseCurrentPopup();
470 }
471 ImGui::SetItemDefaultFocus();
472 ImGui::SameLine();
473 if ( g_nodeDescriptor._name.empty() )
474 {
475 PushReadOnly();
476 }
477 if ( ImGui::Button( "Create", ImVec2( 120, 0 ) ) )
478 {
479 createPrimitive();
480 ImGui::CloseCurrentPopup();
482 }
483 if ( g_nodeDescriptor._name.empty() )
484 {
485 PopReadOnly();
486 }
487
488 std::memset( buf, 0, 64 * sizeof( char ) );
489 ImGui::EndPopup();
490 }
491 }
492 }
493
495 {
496 spawnDebugObject( _debugObject, modifierPressed );
498 }
499 }
500 }
501
503 {
504 _savePopup = true;
505
506 g_saveSceneParams._targetScene = targetScene;
507 g_saveSceneParams._closePopup = false;
508 g_saveSceneParams._saveProgress = 0u;
509 g_saveSceneParams._saveElementCount = Attorney::EditorGeneralWidget::saveItemCount( _context.editor() );
510
511 const auto messageCbk = []( const std::string_view msg )
512 {
513 g_saveSceneParams._saveMessage = msg;
514 ++g_saveSceneParams._saveProgress;
515 };
516
517 const auto closeDialog = [this]( const bool success )
518 {
519 Attorney::EditorGeneralWidget::showStatusMessage( _context.editor(), s_messages[success ? 1 : 2], Time::SecondsToMilliseconds<F32>( 6 ), !success );
520 g_saveSceneParams._closePopup = true;
521 };
522
523 Attorney::EditorGeneralWidget::showStatusMessage( _context.editor(), s_messages[0], Time::SecondsToMilliseconds<F32>( 6 ), false );
524 if ( !Attorney::EditorGeneralWidget::saveSceneChanges( _context.editor(), messageCbk, closeDialog ) )
525 {
526 _errorMsg.append( "Error occurred while saving the current scene!\n Try again or check the logs for errors!\n" );
527 }
528 }
529
530 void MenuBar::drawFileMenu( [[maybe_unused]] const bool modifierPressed )
531 {
532 if ( ImGui::BeginMenu( "File" ) )
533 {
534 const bool hasUnsavedElements = Attorney::EditorGeneralWidget::hasUnsavedSceneChanges( _context.editor() );
535 const bool isDefaultScene = Attorney::EditorGeneralWidget::isDefaultScene( _context.editor() );
536
537
538 const auto& projectList = Attorney::EditorMenuBar::getProjectList( _context.editor() );
539 if ( ImGui::BeginMenu( "Open Project", !projectList.empty() ) )
540 {
541 bool success = true;
542 for ( size_t i = 0u; i < projectList.size(); ++i )
543 {
544 if ( ImGui::MenuItem( projectList[i]._name.c_str() ) )
545 {
546 if (!Attorney::EditorMenuBar::openProject( _context.editor(), projectList[i] ))
547 {
548 success = false;
549 _errorMsg.append( Util::StringFormat( "Error occurred while trying to open project [ {} ]\n Try again or check the logs for errors!\n", projectList[i]._name.c_str()) );
550
551 for (const auto& backup : projectList)
552 {
553 if (backup._name == Config::DEFAULT_PROJECT_NAME)
554 {
555 if (Attorney::EditorMenuBar::openProject( _context.editor(), projectList.front() ))
556 {
557 success = true;
558 }
559 break;
560 }
561 }
562 }
563 if (!success)
564 {
565 DIVIDE_UNEXPECTED_CALL_MSG(Util::StringFormat(LOCALE_STR("ERROR_PROJECT_LOAD"), projectList[i]._name).c_str());
566 }
567 }
568 }
569 ImGui::EndMenu();
570 }
571
572 if ( ImGui::MenuItem( "New Scene", "Ctrl+N", false, true ) )
573 {
574 if ( hasUnsavedElements && !isDefaultScene )
575 {
576 saveAndDrawModalPopup( _context.kernel().projectManager()->activeProject()->getActiveScene()->entry() );
577 }
578 _newScenePopup = true;
579 }
580
582 if ( ImGui::BeginMenu("Open Scene", !sceneList.empty()) )
583 {
584 for ( size_t i = 0u; i < sceneList.size(); ++i )
585 {
586 if ( ImGui::MenuItem( sceneList[i]._name.c_str() ) )
587 {
589 }
590 }
591
592 ImGui::EndMenu();
593 }
594
595 const auto& recentSceneList = Attorney::EditorMenuBar::getRecentSceneList( _context.editor() );
596 if ( ImGui::BeginMenu( "Open Recent", !recentSceneList.empty() ) )
597 {
598 for ( size_t i = 0u; i < recentSceneList.size(); ++i )
599 {
600 if ( ImGui::MenuItem( recentSceneList.get( i )._name.c_str() ) )
601 {
602 Attorney::EditorGeneralWidget::switchScene( _context.editor(), recentSceneList.get( i ), false );
603 }
604 }
605
606 ImGui::EndMenu();
607 }
608
609 if ( ImGui::MenuItem( modifierPressed ? (ICON_FK_FLOPPY_O" Save Scene (Forced)") : (ICON_FK_FLOPPY_O" Save Scene"), "", false, hasUnsavedElements || isDefaultScene || modifierPressed ) )
610 {
611 if ( isDefaultScene && !modifierPressed )
612 {
613 _saveSceneAsPopup = true;
614 }
615 else
616 {
617 saveAndDrawModalPopup( _context.kernel().projectManager()->activeProject()->getActiveScene()->entry() );
618 }
619 }
620 if ( modifierPressed )
621 {
623 }
624
625 if ( ImGui::MenuItem( ICON_FK_FLOPPY_O" Save Scene As", "", false, !isDefaultScene ) )
626 {
627 _saveSceneAsPopup = true;
628 }
629
630 ImGui::Separator();
631 if ( ImGui::BeginMenu( "Options" ) )
632 {
633 GFXDevice& gfx = _context.gfx();
634 const Configuration& config = _context.config();
635
636 if ( ImGui::BeginMenu( "MSAA" ) )
637 {
638 for ( U8 i = 0; 1 << i <= DisplayManager::MaxMSAASamples(); ++i )
639 {
640 const U8 sampleCount = i == 0u ? 0u : 1 << i;
641 if ( sampleCount % 2 == 0 )
642 {
643 bool msaaEntryEnabled = config.rendering.MSAASamples == sampleCount;
644 if ( ImGui::MenuItem( Util::StringFormat( "{}x", to_U32( sampleCount ) ).c_str(), "", &msaaEntryEnabled ) )
645 {
646 gfx.setScreenMSAASampleCount( sampleCount );
647 }
648 }
649 }
650 ImGui::EndMenu();
651 }
652
653 for ( U8 type = 0; type < to_U8( ShadowType::COUNT ); ++type )
654 {
655 const ShadowType sType = static_cast<ShadowType>(type);
656 if ( sType != ShadowType::CUBEMAP &&
657 ImGui::BeginMenu( Util::StringFormat( "{} ShadowMap MSAA", Names::shadowType[type] ).c_str() ) )
658 {
659 const U8 currentCount = sType == ShadowType::CSM
662
663 for ( U8 i = 0; 1 << i <= DisplayManager::MaxMSAASamples(); ++i )
664 {
665 const U8 sampleCount = i == 0u ? 0u : 1 << i;
666 if ( sampleCount % 2 == 0 )
667 {
668 bool msaaEntryEnabled = currentCount == sampleCount;
669 if ( ImGui::MenuItem( Util::StringFormat( "{}x", to_U32( sampleCount ) ).c_str(), "", &msaaEntryEnabled ) )
670 {
671 gfx.setShadowMSAASampleCount( sType, sampleCount );
672 }
673 }
674 }
675 ImGui::EndMenu();
676 }
677 }
678
679 ImGui::EndMenu();
680 }
681
683 ImGui::MenuItem( "Editor options", "", &options );
684
685 ImGui::Separator();
686 if ( ImGui::BeginMenu( "Export Game" ) )
687 {
688 for ( auto platform : Editor::g_supportedExportPlatforms )
689 {
690 PushReadOnly(true);
691 if ( ImGui::MenuItem( platform, "", false, true ) )
692 {
693 if ( hasUnsavedElements )
694 {
695 saveAndDrawModalPopup( _context.kernel().projectManager()->activeProject()->getActiveScene()->entry() );
696 }
697 Attorney::EditorGeneralWidget::showStatusMessage( _context.editor(), Util::StringFormat( "Exported game for [ {} ]!", platform ), Time::SecondsToMilliseconds<F32>( 3.0f ), false );
698 break;
699 }
700 PopReadOnly();
701 }
702
703 ImGui::EndMenu();
704 }
705 ImGui::Separator();
706 if ( ImGui::MenuItem( "Close Editor" ) )
707 {
708 if ( hasUnsavedElements )
709 {
710 _closePopup = true;
711 }
712 else
713 {
714 _context.editor().toggle( false );
715 }
716 }
717
718 if ( ImGui::MenuItem( "Restart" ) )
719 {
720 _restartPopup = true;
721 }
722
723 if ( ImGui::MenuItem( "Quit", "Alt+F4" ) )
724 {
725 _quitPopup = true;
726 }
727
728 ImGui::EndMenu();
729 }
730 }
731
732 void MenuBar::drawEditMenu( [[maybe_unused]] const bool modifierPressed ) const
733 {
734 if ( ImGui::BeginMenu( "Edit" ) )
735 {
736 if ( ImGui::MenuItem( "Undo", "CTRL+Z", false, _context.editor().UndoStackSize() > 0 ) )
737 {
738 if ( !_context.editor().Undo() )
739 {
740 Attorney::EditorGeneralWidget::showStatusMessage( _context.editor(), "ERROR: Undo failed!", Time::SecondsToMilliseconds<F32>( 3.0f ), true );
741 }
742 }
743
744 if ( ImGui::MenuItem( "Redo", "CTRL+Y", false, _context.editor().RedoStackSize() > 0 ) )
745 {
746 if ( !_context.editor().Redo() )
747 {
748 Attorney::EditorGeneralWidget::showStatusMessage( _context.editor(), "ERROR: Redo failed!", Time::SecondsToMilliseconds<F32>( 3.0f ), true );
749 }
750 }
751
752 ImGui::Separator();
753
754 if ( ImGui::MenuItem( "Cut", "CTRL+X", false, false ) )
755 {
756 }
757
758 if ( ImGui::MenuItem( "Copy", "CTRL+C", false, false ) )
759 {
760 }
761
762 if ( ImGui::MenuItem( "Paste", "CTRL+V", false, false ) )
763 {
764 }
765
766 ImGui::Separator();
767 ImGui::EndMenu();
768 }
769 }
770
771 void MenuBar::drawProjectMenu( [[maybe_unused]] const bool modifierPressed ) const
772 {
773 if ( ImGui::BeginMenu( "Project" ) )
774 {
775 if ( ImGui::MenuItem( "Configuration", "", false, false ) )
776 {
777 }
778
779 ImGui::EndMenu();
780 }
781 }
782 void MenuBar::drawObjectMenu( const bool modifierPressed )
783 {
784 if ( ImGui::BeginMenu( "Object" ) )
785 {
786 if ( ImGui::BeginMenu( "New Primitive" ) )
787 {
788 if ( ImGui::MenuItem( "Sphere" ) )
789 {
790 g_nodeDescriptor = {};
792 }
793 if ( modifierPressed )
794 {
796 }
797 if ( ImGui::MenuItem( "Box" ) )
798 {
799 g_nodeDescriptor = {};
801 }
802 if ( modifierPressed )
803 {
805 }
806 if ( ImGui::MenuItem( "Plane" ) )
807 {
808 g_nodeDescriptor = {};
810 }
811 if ( modifierPressed )
812 {
814 }
815 ImGui::EndMenu();
816 }
817 if ( ImGui::BeginMenu( "Debug Objects" ) )
818 {
819 if ( ImGui::MenuItem( "Sponza" ) )
820 {
821 g_nodeDescriptor = {};
823 }
824 if ( modifierPressed )
825 {
827 }
828 ImGui::EndMenu();
829 }
830
831 ImGui::EndMenu();
832 }
833
834 }
835 void MenuBar::drawToolsMenu( [[maybe_unused]] const bool modifierPressed )
836 {
837 if ( ImGui::BeginMenu( "Tools" ) )
838 {
839 const bool memEditorEnabled = Attorney::EditorMenuBar::memoryEditorEnabled( _context.editor() );
840 if ( ImGui::MenuItem( "Memory Editor", nullptr, memEditorEnabled ) )
841 {
843 if ( !_context.editor().saveToXML() )
844 {
845 Attorney::EditorGeneralWidget::showStatusMessage( _context.editor(), "ERROR: Save failed!", Time::SecondsToMilliseconds<F32>( 3.0f ), true );
846 }
847 }
848
849 if ( ImGui::BeginMenu( "Render Targets" ) )
850 {
851 const GFXRTPool& pool = _context.gfx().renderTargetPool();
852 for ( auto& rt : pool.getRenderTargets() )
853 {
854 if ( ImGui::BeginMenu( rt->name().c_str() ) )
855 {
856 for ( U8 j = 0u; j < 2u; ++j )
857 {
859 const U8 count = rt->getAttachmentCount( type );
860
861 for ( U8 k = 0; k < count; ++k )
862 {
863 RTAttachment* attachment = rt->getAttachment( type, static_cast<RTColourAttachmentSlot>(k) );
864 if ( attachment == nullptr )
865 {
866 continue;
867 }
868 const Handle<Texture> tex = attachment->texture();
869 if ( tex == INVALID_HANDLE<Texture> )
870 {
871 continue;
872 }
873
874 if ( ImGui::MenuItem( Get(tex)->resourceName().c_str() ) )
875 {
876 _previewTextures.push_back( tex );
877 }
878 }
879 }
880 ImGui::EndMenu();
881 }
882 }
883 ImGui::EndMenu();
884 }
885 ImGui::EndMenu();
886 }
887 }
888
889 void MenuBar::drawWindowsMenu( [[maybe_unused]] const bool modifierPressed ) const
890 {
891 if ( ImGui::BeginMenu( "Window" ) )
892 {
893 bool& sampleWindowEnabled = Attorney::EditorMenuBar::sampleWindowEnabled( _context.editor() );
894 if ( ImGui::MenuItem( "Sample Window", nullptr, &sampleWindowEnabled ) )
895 {
896
897 }
898 ImGui::EndMenu();
899 }
900 }
901
902 void MenuBar::drawPostFXMenu( [[maybe_unused]] const bool modifierPressed ) const
903 {
904 if ( ImGui::BeginMenu( "PostFX" ) )
905 {
906 PostFX& postFX = _context.gfx().getRenderer().postFX();
907 for ( U16 i = 0u; i < to_base( FilterType::FILTER_COUNT ); ++i )
908 {
909 const FilterType f = static_cast<FilterType>(i);
910
911 bool filterEnabled = postFX.getFilterState( f );
912 if ( ImGui::MenuItem( PostFX::FilterName( f ), nullptr, &filterEnabled ) )
913 {
914 if ( filterEnabled )
915 {
916 postFX.pushFilter( f, true );
917 }
918 else
919 {
920 postFX.popFilter( f, true );
921 }
922 }
923 }
924 ImGui::EndMenu();
925 }
926 }
927
928 void MenuBar::drawDebugMenu( [[maybe_unused]] const bool modifierPressed )
929 {
930 if ( ImGui::BeginMenu( "Debug" ) )
931 {
932 if ( ImGui::BeginMenu( "BRDF Settings" ) )
933 {
934 const MaterialDebugFlag debugFlag = _context.gfx().materialDebugFlag();
935 bool debug = false;
936 for ( U8 i = 0u; i < to_U8( MaterialDebugFlag::COUNT ); ++i )
937 {
938 const MaterialDebugFlag flag = static_cast<MaterialDebugFlag>(i);
939 debug = debugFlag == flag;
940 if ( ImGui::MenuItem( TypeUtil::MaterialDebugFlagToString( flag ), "", &debug ) )
941 {
942 _context.gfx().materialDebugFlag( debug ? flag : MaterialDebugFlag::COUNT );
943 }
944 }
945 ImGui::EndMenu();
946 }
947
950
951 if ( ImGui::BeginMenu( "Render Filters" ) )
952 {
954 bool configDirty = false;
955 if ( ImGui::MenuItem( "MESHES", "", &renderFilters.meshes ) )
956 {
957 configDirty = true;
958 }
959 if ( ImGui::MenuItem( "PARTICLES", "", &renderFilters.particles ) )
960 {
961 configDirty = true;
962 }
963 if ( ImGui::MenuItem( "PRIMITIVES", "", &renderFilters.primitives ) )
964 {
965 configDirty = true;
966 }
967 if ( ImGui::MenuItem( "SKY", "", &renderFilters.sky ) )
968 {
969 configDirty = true;
970 }
971 if ( ImGui::MenuItem( "TERRAIN", "", &renderFilters.terrain ) )
972 {
973 configDirty = true;
974 }
975 if ( ImGui::MenuItem( "VEGETATION", "", &renderFilters.vegetation ) )
976 {
977 configDirty = true;
978 }
979 if ( ImGui::MenuItem( "WATER", "", &renderFilters.water ) )
980 {
981 configDirty = true;
982 }
983 if ( ImGui::MenuItem( "DECALS", "", &renderFilters.decals ) )
984 {
985 configDirty = true;
986 }
987 if ( configDirty )
988 {
989 _context.config().changed( true );
990 }
991 ImGui::EndMenu();
992 }
993
994 if ( ImGui::BeginMenu( "Toggle Light Types" ) )
995 {
996 for ( U8 i = 0; i < to_U8( LightType::COUNT ); ++i )
997 {
998 const LightType type = static_cast<LightType>(i);
999
1000 bool state = pool.lightTypeEnabled( type );
1001 if ( ImGui::MenuItem( TypeUtil::LightTypeToString( type ), "", &state ) )
1002 {
1003 pool.toggleLightType( type, state );
1004 }
1005 }
1006 ImGui::EndMenu();
1007 }
1008
1009 if ( ImGui::BeginMenu( "Select Env Probe" ) )
1010 {
1011 constexpr U8 MaxProbesPerPage = 32;
1012 bool debuggingSkyLight = SceneEnvironmentProbePool::DebuggingSkyLight();
1013
1014 const auto PrintProbeEntry = [&envProbPool, debuggingSkyLight]( const EnvironmentProbeList& probes, const size_t j )
1015 {
1016 EnvironmentProbeComponent* crtProbe = probes[j];
1017 bool selected = !debuggingSkyLight &&
1018 envProbPool->debugProbe() == crtProbe;
1019 if ( ImGui::MenuItem( crtProbe->parentSGN()->name().c_str(), "", &selected ) )
1020 {
1021 envProbPool->debugProbe( selected ? crtProbe : nullptr );
1023 }
1024 };
1025
1026 if ( ImGui::MenuItem( "Sky Light", "", &debuggingSkyLight ) )
1027 {
1028 envProbPool->debugProbe( nullptr );
1030 }
1031
1032 envProbPool->lockProbeList();
1033 const EnvironmentProbeList& probes = envProbPool->getLocked();
1034 const size_t probeCount = probes.size();
1035 if ( probeCount > MaxProbesPerPage )
1036 {
1037 const size_t pageCount = probeCount > MaxProbesPerPage ? probeCount / MaxProbesPerPage : 1;
1038 const size_t remainder = probeCount > MaxProbesPerPage ? probeCount - pageCount * MaxProbesPerPage : 0;
1039 for ( U8 p = 0; p < pageCount + 1; ++p )
1040 {
1041 const size_t start = p * MaxProbesPerPage;
1042 const size_t end = start + (p < pageCount ? MaxProbesPerPage : remainder);
1043 if ( ImGui::BeginMenu( Util::StringFormat( "{} - {}", start, end ).c_str() ) )
1044 {
1045 for ( size_t j = start; j < end; ++j )
1046 {
1047 PrintProbeEntry( probes, j );
1048 }
1049 ImGui::EndMenu();
1050 }
1051 }
1052 }
1053 else
1054 {
1055 for ( size_t j = 0; j < probeCount; ++j )
1056 {
1057 PrintProbeEntry( probes, j );
1058 }
1059 }
1060 envProbPool->unlockProbeList();
1061 ImGui::EndMenu();
1062 }
1063
1064 if ( ImGui::BeginMenu( "Select Debug light" ) )
1065 {
1066 constexpr U8 MaxLightsPerPage = 32;
1067 const auto PrintLightEntry = [&pool]( const LightPool::LightList& lights, const size_t j )
1068 {
1069 Light* crtLight = lights[j];
1070 bool selected = pool.debugLight() == crtLight;
1071 if ( ImGui::MenuItem( crtLight->sgn()->name().c_str(), "", &selected ) )
1072 {
1073 pool.debugLight( crtLight );
1074 }
1075 };
1076
1077 for ( U8 i = 0; i < to_U8( LightType::COUNT ); ++i )
1078 {
1079 const LightType type = static_cast<LightType>(i);
1080 const LightPool::LightList& lights = pool.getLights( type );
1081 if ( !lights.empty() )
1082 {
1083 const size_t lightCount = lights.size();
1084
1085 if ( ImGui::BeginMenu( TypeUtil::LightTypeToString( type ) ) )
1086 {
1087 if ( lightCount > MaxLightsPerPage )
1088 {
1089 const size_t pageCount = lightCount > MaxLightsPerPage ? lightCount / MaxLightsPerPage : 1;
1090 const size_t remainder = lightCount > MaxLightsPerPage ? lightCount - pageCount * MaxLightsPerPage : 0;
1091 for ( U8 p = 0; p < pageCount + 1; ++p )
1092 {
1093 const size_t start = p * MaxLightsPerPage;
1094 const size_t end = start + (p < pageCount ? MaxLightsPerPage : remainder);
1095 if ( ImGui::BeginMenu( Util::StringFormat( "{} - {}", start, end ).c_str() ) )
1096 {
1097 for ( size_t j = start; j < end; ++j )
1098 {
1099 PrintLightEntry( lights, j );
1100 }
1101 ImGui::EndMenu();
1102 }
1103 }
1104 }
1105 else
1106 {
1107 for ( size_t j = 0; j < lightCount; ++j )
1108 {
1109 PrintLightEntry( lights, j );
1110 }
1111 }
1112
1113 ImGui::EndMenu();
1114 }
1115 }
1116 else
1117 {
1118 ImGui::Text( TypeUtil::LightTypeToString( type ) );
1119 }
1120 }
1121 if ( ImGui::BeginMenu( "Shadow enabled" ) )
1122 {
1123 for ( U8 i = 0; i < to_U8( LightType::COUNT ); ++i )
1124 {
1125 const LightType type = static_cast<LightType>(i);
1126 const LightPool::LightList& lights = pool.getLights( type );
1127 for ( Light* crtLight : lights )
1128 {
1129 if ( crtLight->castsShadows() )
1130 {
1131 bool selected = pool.debugLight() == crtLight;
1132 if ( ImGui::MenuItem( crtLight->sgn()->name().c_str(), "", &selected ) )
1133 {
1134 pool.debugLight( crtLight );
1135 }
1136 }
1137 }
1138 }
1139 ImGui::EndMenu();
1140 }
1141
1142 ImGui::EndMenu();
1143 }
1144
1145 bool lightImpostors = pool.lightImpostorsEnabled();
1146 if ( ImGui::MenuItem( "Draw Light Impostors", "", &lightImpostors ) )
1147 {
1148 pool.lightImpostorsEnabled( lightImpostors );
1149 }
1150
1151 const ECSManager& ecsManager = _context.kernel().projectManager()->activeProject()->getActiveScene()->sceneGraph()->GetECSManager();
1152 bool playAnimations = ecsManager.ecsEngine().GetSystemManager()->GetSystem<AnimationSystem>()->getAnimationState();
1153
1154 if ( ImGui::MenuItem( "Play animations", "", &playAnimations ) )
1155 {
1156 ecsManager.ecsEngine().GetSystemManager()->GetSystem<AnimationSystem>()->toggleAnimationState( playAnimations );
1157 }
1158
1159 if ( ImGui::BeginMenu( "Debug Gizmos" ) )
1160 {
1161 ProjectManager* projectManager = context().kernel().projectManager().get();
1162 SceneRenderState& renderState = projectManager->activeProject()->getActiveScene()->state()->renderState();
1163
1165 if ( ImGui::MenuItem( "Show AABBs", "", &temp ) )
1166 {
1167 Console::d_printfn( LOCALE_STR( "TOGGLE_SCENE_BOUNDING_BOXES" ), temp ? "On" : "Off" );
1169 }
1171 if ( ImGui::MenuItem( "Show OBBs", "", &temp ) )
1172 {
1173 Console::d_printfn( LOCALE_STR( "TOGGLE_SCENE_ORIENTED_BOUNDING_BOXES" ), temp ? "On" : "Off" );
1175 }
1177 if ( ImGui::MenuItem( "Show bounding spheres", "", &temp ) )
1178 {
1179 Console::d_printfn( LOCALE_STR( "TOGGLE_SCENE_BOUNDING_SPHERES" ), temp ? "On" : "Off" );
1181 }
1183 if ( ImGui::MenuItem( "Show skeletons", "", &temp ) )
1184 {
1185 Console::d_printfn( LOCALE_STR( "TOGGLE_SCENE_SKELETONS" ), temp ? "On" : "Off" );
1187 }
1189 if ( ImGui::MenuItem( "Show scene axis", "", &temp ) )
1190 {
1191 Console::d_printfn( LOCALE_STR( "TOGGLE_SCENE_AXIS_GIZMO" ) );
1193 }
1195 if ( ImGui::MenuItem( "Show selection axis", "", &temp ) )
1196 {
1198 }
1200 if ( ImGui::MenuItem( "Show all axis", "", &temp ) )
1201 {
1203 }
1205 if ( ImGui::MenuItem( "Render geometry", "", &temp ) )
1206 {
1208 }
1210 if ( ImGui::MenuItem( "Render wireframe", "", &temp ) )
1211 {
1213 }
1215 if ( ImGui::MenuItem( "Render custom gismos", "", &temp ) )
1216 {
1218 }
1219 ImGui::EndMenu();
1220 }
1221
1222 if ( ImGui::BeginMenu( "Edge Detection Method" ) )
1223 {
1224
1226 bool noneSelected = batch.edgeDetectionMethod() == PreRenderBatch::EdgeDetectionMethod::COUNT;
1227 if ( ImGui::MenuItem( "None", "", &noneSelected ) )
1228 {
1229 batch.edgeDetectionMethod( PreRenderBatch::EdgeDetectionMethod::COUNT );
1230 }
1231
1232 for ( U8 i = 0; i < to_U8( PreRenderBatch::EdgeDetectionMethod::COUNT ) + 1; ++i )
1233 {
1235
1236 bool selected = batch.edgeDetectionMethod() == method;
1237 if ( ImGui::MenuItem( EdgeMethodName( method ), "", &selected ) )
1238 {
1239 batch.edgeDetectionMethod( method );
1240 }
1241 }
1242
1243 ImGui::EndMenu();
1244 }
1245
1246 if ( ImGui::BeginMenu( "Debug Views" ) )
1247 {
1249 _context.gfx().getDebugViewNames( viewNames );
1250
1251 eastl::set<I16> groups = {};
1252 for ( auto [name, groupID, index, enabled] : viewNames )
1253 {
1254 if ( groupID != -1 )
1255 {
1256 groups.insert( groupID );
1257 }
1258
1259 const string label = groupID == -1 ? name : Util::StringFormat( "({}) {}", groupID, name.c_str() );
1260 if ( ImGui::MenuItem( label.c_str(), "", &enabled ) )
1261 {
1262 _context.gfx().toggleDebugView( index, enabled );
1263 }
1264 }
1265 if ( !groups.empty() )
1266 {
1267 ImGui::Separator();
1268 for ( const I16 group : groups )
1269 {
1270 bool groupEnabled = _context.gfx().getDebugGroupState( group );
1271 if ( ImGui::MenuItem( Util::StringFormat( "Enable Group [ {} ]", group ).c_str(), "", &groupEnabled ) )
1272 {
1273 _context.gfx().toggleDebugGroup( group, groupEnabled );
1274 }
1275 }
1276 }
1277 ImGui::EndMenu();
1278 }
1279
1280 bool state = context().gui().showDebugCursor();
1281 if ( ImGui::MenuItem( "Show CEGUI Debug Cursor", "", &state ) )
1282 {
1283 context().gui().showDebugCursor( state );
1284 }
1285
1286 ImGui::EndMenu();
1287 }
1288 }
1289
1290 void MenuBar::drawHelpMenu( [[maybe_unused]] const bool modifierPressed ) const
1291 {
1292 if ( ImGui::BeginMenu( "Help" ) )
1293 {
1294 bool& sampleWindowEnabled = Attorney::EditorMenuBar::sampleWindowEnabled( _context.editor() );
1295 if ( ImGui::MenuItem( "Sample Window", nullptr, &sampleWindowEnabled ) )
1296 {
1297
1298 }
1299 ImGui::Separator();
1300
1301 ImGui::Text( "Copyright(c) 2018 DIVIDE - Studio" );
1302 ImGui::Text( "Copyright(c) 2009 Ionut Cava" );
1303 ImGui::EndMenu();
1304 }
1305 }
1306
1307 void MenuBar::spawnDebugObject( const DebugObject object, const bool modifierPressed ) const
1308 {
1309 if ( object == DebugObject::SPONZA)
1310 {
1311 ResourceDescriptor<Mesh> model( "Debug_Sponza" );
1312 model.assetLocation( Paths::g_modelsLocation );
1313 model.assetName( "sponza.obj" );
1314 model.flag( true );
1315 //model.waitForReady(true);
1316
1317 Handle<Mesh> spawnMesh = CreateResource( model );
1318 if ( spawnMesh == INVALID_HANDLE<Mesh> )
1319 {
1320 Attorney::EditorGeneralWidget::showStatusMessage( _context.editor(), "ERROR: Couldn't load Sponza model!", Time::SecondsToMilliseconds<F32>( 3 ), true );
1321 }
1322
1323 if ( Attorney::EditorGeneralWidget::modalModelSpawn( _context.editor(), spawnMesh, modifierPressed, vec3<F32>{0.1f} ) )
1324 {
1325 }
1326 }
1327 else
1328 {
1329 Attorney::EditorGeneralWidget::showStatusMessage( _context.editor(), "ERROR: Only Sponza model supported for nowl!", Time::SecondsToMilliseconds<F32>( 3 ), true );
1330 }
1331 }
1332} //namespace Divide
#define LOCALE_STR(X)
Definition: Localization.h:91
#define DIVIDE_UNEXPECTED_CALL()
#define DIVIDE_UNEXPECTED_CALL_MSG(X)
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
void RequestRestart(bool clearCache) noexcept
Definition: Application.inl:61
void RequestShutdown(bool clearCache) noexcept
Definition: Application.inl:45
static bool modalTextureView(const Editor &editor, const std::string_view modalName, Handle< Texture > tex, const vec2< F32 > dimensions, const bool preserveAspect, const bool useModal)
Definition: Editor.h:676
static void showStatusMessage(const Editor &editor, const string &message, const F32 durationMS, const bool error)
Definition: Editor.h:711
static void setSceneGizmoEnabled(Editor &editor, const bool state) noexcept
Definition: Editor.h:631
static LightPool & getActiveLightPool(const Editor &editor)
Definition: Editor.h:611
static bool isDefaultScene(const Editor &editor) noexcept
Definition: Editor.h:651
static U32 saveItemCount(const Editor &editor) noexcept
Definition: Editor.h:641
static bool switchScene(Editor &editor, const SceneEntry &scene, bool createIfNotExists)
Definition: Editor.h:666
static SceneEnvironmentProbePool * getActiveEnvProbePool(const Editor &editor)
Definition: Editor.h:616
static bool saveSceneChanges(const Editor &editor, const DELEGATE< void, std::string_view > &msgCallback, const DELEGATE< void, bool > &finishCallback)
Definition: Editor.h:661
static bool modalModelSpawn(Editor &editor, Handle< Mesh > mesh, bool quick, const vec3< F32 > &scale=VECTOR3_UNIT, const vec3< F32 > &position=VECTOR3_ZERO)
Definition: Editor.h:681
static bool getSceneGizmoEnabled(const Editor &editor) noexcept
Definition: Editor.h:636
static ImGuiContext & getImGuiContext(Editor &editor, const Editor::ImGuiContextType type) noexcept
Definition: Editor.h:686
static void registerUnsavedSceneChanges(Editor &editor) noexcept
Definition: Editor.h:656
static bool hasUnsavedSceneChanges(const Editor &editor) noexcept
Definition: Editor.h:646
static bool & optionWindowEnabled(Editor &editor) noexcept
Definition: Editor.h:571
static bool openProject(Editor &editor, const ProjectID &projectID) noexcept
Definition: Editor.h:591
static const ProjectIDs & getProjectList(Editor &editor) noexcept
Definition: Editor.h:586
static bool & sampleWindowEnabled(Editor &editor) noexcept
Definition: Editor.h:566
static const SceneEntries & getSceneList(const Editor &editor) noexcept
Definition: Editor.h:581
static bool memoryEditorEnabled(const Editor &editor) noexcept
Definition: Editor.h:561
static void toggleMemoryEditor(Editor &editor, const bool state) noexcept
Definition: Editor.h:556
static const CircularBuffer< SceneEntry, 10 > & getRecentSceneList(const Editor &editor) noexcept
Definition: Editor.h:576
size_t UndoStackSize() const noexcept
Definition: Editor.inl:66
bool Redo() const
Definition: Editor.cpp:1685
bool saveToXML() const
Definition: Editor.cpp:2833
bool Undo() const
Definition: Editor.cpp:1670
void toggle(bool state)
Definition: Editor.cpp:883
static std::array< const char *, 3 > g_supportedExportPlatforms
Definition: Editor.h:157
size_t RedoStackSize() const noexcept
Definition: Editor.inl:70
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
Definition: GFXDevice.h:215
void setShadowMSAASampleCount(ShadowType type, U8 sampleCount)
Definition: GFXDevice.cpp:1744
void setScreenMSAASampleCount(U8 sampleCount)
Definition: GFXDevice.cpp:1739
GFXRTPool & renderTargetPool() noexcept
Definition: GFXDevice.inl:133
Renderer & getRenderer() const
Definition: GFXDevice.inl:117
void getDebugViewNames(vector< std::tuple< string, I16, I16, bool > > &namesOut)
Definition: GFXDevice.cpp:2821
void toggleDebugGroup(I16 groupID, bool state)
Definition: GFXDevice.cpp:2792
bool getDebugGroupState(I16 groupID) const
Definition: GFXDevice.cpp:2804
void toggleDebugView(I16 index, bool state)
Definition: GFXDevice.cpp:2779
const vector< RenderTarget_uptr > & getRenderTargets() const noexcept
Definition: GFXRTPool.h:50
void showDebugCursor(bool state)
Toggle debug cursor rendering on or off.
Definition: GUI.cpp:709
A light object placed in the scene at a certain position.
Definition: Light.h:58
void debugLight(Light *light)
nullptr = disabled
Definition: LightPool.cpp:355
LightList & getLights(const LightType type)
Definition: LightPool.h:136
void toggleLightType(const LightType type) noexcept
disable or enable a specific light type
Definition: LightPool.h:128
eastl::fixed_vector< Light *, 32u, true > LightList
Definition: LightPool.h:115
bool lightTypeEnabled(const LightType type) const noexcept
Definition: LightPool.h:131
MenuBar(PlatformContext &context, bool mainMenu)
Definition: MenuBar.cpp:83
void drawHelpMenu(bool modifierPressed) const
Definition: MenuBar.cpp:1290
void drawToolsMenu(bool modifierPressed)
Definition: MenuBar.cpp:835
void spawnDebugObject(DebugObject object, bool modifierPressed) const
Definition: MenuBar.cpp:1307
string _errorMsg
Definition: MenuBar.h:82
void drawObjectMenu(bool modifierPressed)
Definition: MenuBar.cpp:782
bool _savePopup
Definition: MenuBar.h:78
bool _quitPopup
Definition: MenuBar.h:73
void drawPostFXMenu(bool modifierPressed) const
Definition: MenuBar.cpp:902
void drawWindowsMenu(bool modifierPressed) const
Definition: MenuBar.cpp:889
void drawDebugMenu(bool modifierPressed)
Definition: MenuBar.cpp:928
SceneNodeType _newPrimitiveType
Definition: MenuBar.h:79
void drawEditMenu(bool modifierPressed) const
Definition: MenuBar.cpp:732
void saveAndDrawModalPopup(const SceneEntry &targetScene)
Definition: MenuBar.cpp:502
DebugObject _debugObject
Definition: MenuBar.h:80
bool _saveSceneAsPopup
Definition: MenuBar.h:76
bool _newScenePopup
Definition: MenuBar.h:75
bool _restartPopup
Definition: MenuBar.h:74
void drawProjectMenu(bool modifierPressed) const
Definition: MenuBar.cpp:771
bool _closePopup
Definition: MenuBar.h:77
vector< Handle< Texture > > _previewTextures
Definition: MenuBar.h:83
void drawFileMenu(bool modifierPressed)
Definition: MenuBar.cpp:530
PlatformContext & context() noexcept
Application & app() noexcept
Kernel & kernel() noexcept
Editor & editor() noexcept
GFXDevice & gfx() noexcept
Configuration & config() noexcept
Definition: PostFX.h:47
void popFilter(const FilterType filter, const bool overrideScene=false)
Definition: PostFX.h:94
bool getFilterState(const FilterType filter) const noexcept
Definition: PostFX.h:111
PreRenderBatch & getFilterBatch() noexcept
Definition: PostFX.h:119
void pushFilter(const FilterType filter, const bool overrideScene=false)
Definition: PostFX.h:77
static const char * FilterName(FilterType filter) noexcept
Definition: PostFX.cpp:27
Handle< Texture > texture() const
PostFX & postFX()
Definition: Renderer.h:61
const EnvironmentProbeList & getLocked() const noexcept
@ RENDER_WIREFRAME
Render wireframe for all scene geometry.
@ RENDER_OBB
Show/hide oriented bounding boxes.
@ RENDER_SKELETONS
Render skeletons for animated geometry.
@ RENDER_CUSTOM_PRIMITIVES
Show/hide custom IMPrimitive elements.
@ RENDER_AABB
Show/hide axis aligned bounding boxes.
@ RENDER_BSPHERES
Show/hide bounding spheres.
bool isEnabledOption(RenderOptions option) const noexcept
Definition: SceneState.cpp:74
void toggleOption(RenderOptions option) noexcept
Definition: SceneState.cpp:89
constexpr char DEFAULT_PROJECT_NAME[]
Definition: config.h:197
constexpr char DEFAULT_SCENE_NAME[]
Definition: config.h:198
const char * sceneNodeType[to_base(SceneNodeType::COUNT)+1u]
Definition: SceneNode.cpp:21
static const char * shadowType[]
Definition: ShadowMap.h:48
constexpr Optick::Category::Type GUI
Definition: Profiler.h:64
const char * LightTypeToString(LightType lightType) noexcept
Definition: Light.cpp:21
const char * MaterialDebugFlagToString(const MaterialDebugFlag unitType) noexcept
Definition: Material.cpp:28
Str StringFormat(const char *fmt, Args &&...args)
bool CompareIgnoreCase(const char *a, const char *b) noexcept
void OpenCenteredPopup(const char *name, ImGui::ImGuiPopupFlags popup_flags=0)
void AddUnderLine()
Definition: Utils.cpp:229
U32 FLOAT_TO_UINT(F32 src)
Definition: MathHelper.cpp:345
constexpr const char * FieldLabels[]
Definition: Utils.h:69
const char * EdgeMethodName(const PreRenderBatch::EdgeDetectionMethod method) noexcept
Definition: MenuBar.cpp:69
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
constexpr U32 to_U32(const T value)
vector< SceneEntry > SceneEntries
Definition: Scene.h:116
vec4< F32 > FColour4
Definition: MathHelper.h:73
void PushReadOnly(const bool fade)
Definition: Editor.cpp:2961
MaterialDebugFlag
Definition: MaterialEnums.h:37
T * ResourcePtr
Definition: Resource.h:112
uint8_t U8
int16_t I16
RTAttachmentType
This enum is used when creating render targets to define the channel that the texture will attach to.
Definition: RTAttachment.h:47
eastl::vector< Type > vector
Definition: Vector.h:42
void PopReadOnly()
Definition: Editor.cpp:2971
uint16_t U16
FORCE_INLINE Handle< T > CreateResource(const ResourceDescriptor< T > &descriptor, bool &wasInCache, std::atomic_uint &taskCounter)
::value constexpr T MAP(T input, T in_min, T in_max, T out_min, T out_max, D64 &slopeOut) noexcept
Definition: MathHelper.inl:141
LightType
The different types of lights supported.
RTColourAttachmentSlot
constexpr U8 to_U8(const T value)
ShadowType
Definition: ShadowMap.h:40
SceneNodeHandle FromHandle(const Handle< T > handle)
vector< EnvironmentProbeComponent * > EnvironmentProbeList
int64_t I64
FORCE_INLINE T * Get(const Handle< T > handle)
uint32_t U32
constexpr auto to_base(const Type value) -> Type
struct Divide::Configuration::Debug::RenderFilter renderFilter
Divide::Configuration::Rendering::ShadowMapping::CSMSettings csm
struct Divide::Configuration::Rendering::ShadowMapping shadowMapping
struct Divide::Configuration::Rendering rendering
struct Divide::Configuration::Debug debug
static NO_INLINE void d_printfn(const char *format, T &&... args)
static U8 MaxMSAASamples() noexcept
Definition: Scene.h:112
Str< 256 > _name
Definition: Scene.h:113