Leviathan  0.8.0.0
Leviathan game engine
Graphics.cpp
Go to the documentation of this file.
1 // ------------------------------------ //
2 #include "Graphics.h"
3 
8 #include "Engine.h"
9 #include "FileSystem.h"
10 #include "GUIOverlayRenderer.h"
11 #include "GeometryHelpers.h"
14 #include "Window.h"
15 
16 #include "BsApplication.h"
17 #include "Components/BsCCamera.h"
18 #include "CoreThread/BsCoreThread.h"
19 #include "Importer/BsImporter.h"
20 #include "Resources/BsEngineShaderIncludeHandler.h"
21 #include "Resources/BsResources.h"
22 #include "Scene/BsSceneObject.h"
23 #include "bsfCore/Animation/BsAnimationClip.h"
24 #include "bsfCore/Material/BsMaterial.h"
25 #include "bsfCore/Material/BsShaderManager.h"
26 #include "bsfCore/RenderAPI/BsRenderAPI.h"
27 #include "bsfCore/Resources/BsResourceManifest.h"
28 
29 #include <SDL.h>
30 #include <SDL_syswm.h>
31 
32 #include <future>
33 #include <regex>
34 
35 #ifdef __linux
36 #include "XLibInclude.h"
37 #endif
38 
39 #include <filesystem>
40 
41 using namespace Leviathan;
42 // ------------------------------------ //
44  const bs::String& message, bs::LogVerbosity verbosity, bs::UINT32 category)
45 {
46  // Forward to global logger if one exists
47  auto log = Logger::Get();
48 
49  if(log) {
50  bs::String categoryName;
51  bs::Log::getCategoryName(category, categoryName);
52  log->Write(("[BSF][" + categoryName + "][" + bs::toString(verbosity) + "] " + message)
53  .c_str());
54 
55  // Prevent BSF logging this as well
56  return true;
57  }
58 
59  // Allow default action
60  return false;
61 }
62 
63 class LeviathanBSFShaderIncludeHandler : public bs::EngineShaderIncludeHandler {
64 public:
65  virtual bs::HShaderInclude findInclude(const bs::String& name) const override
66  {
67  // If the file path is valid just pass it as is
68  const std::string converted(name.c_str(), name.size());
69  if(FileSystem::FileExists(converted))
70  return bs::EngineShaderIncludeHandler::findInclude(name);
71 
72  // We resolve the path and then give it to bsf
73  std::string searched = FileSystem::Get()->SearchForFile(FILEGROUP_SCRIPT,
74  StringOperations::RemoveExtension<std::string>(converted),
75  StringOperations::GetExtension<std::string>(converted), true);
76 
77  if(searched.empty()) {
78  if(name.find("$ENGINE$") == bs::String::npos) {
80  "LeviathanBSFShaderIncludeHandler: could not locate file anywhere: " +
81  converted);
82  }
83 
84  return bs::EngineShaderIncludeHandler::findInclude(name);
85  }
86 
87  return bs::EngineShaderIncludeHandler::findInclude(
88  bs::String(searched.c_str(), searched.size()));
89  }
90 };
91 
92 class LeviathanBSFApplication : public bs::Application {
93 public:
94  LeviathanBSFApplication(const bs::START_UP_DESC& desc) : bs::Application(desc) {}
95 
96  bs::SPtr<bs::IShaderIncludeHandler> getShaderIncludeHandler() const override
97  {
98  return bs::bs_shared_ptr_new<LeviathanBSFShaderIncludeHandler>();
99  }
100 
101  bs::SPtr<GUIOverlayRenderer> GUIRenderer;
102 };
103 
104 
106 
107  Private(const bs::START_UP_DESC& desc) : Description(desc) {}
108 
109 
110  template<class T>
111  auto LoadResource(const bs::String& path)
112  {
113  auto asset = bs::gResources().load<T>(path);
114 
115  if(!asset) {
116  LOG_ERROR(std::string("Graphics: loading asset failed: ") + path.c_str());
117  return decltype(asset)(nullptr);
118  }
119 
120  if(RegisteredAssets.find(path) != RegisteredAssets.end()) {
121  // Already registered, fine to just return
122  return asset;
123  }
124 
125  // Was not registered.
126 
127  bs::gResources().getResourceManifest("Default")->registerResource(
128  asset.getUUID(), path);
129 
130  RegisteredAssets.insert(path);
131  return asset;
132  }
133 
134  std::unordered_set<bs::String> RegisteredAssets;
135 
136  bs::START_UP_DESC Description;
138 };
139 
140 #ifdef __linux
141 bool HasX11Error = false;
142 
143 int LeviathanX11ErrorHandler(Display* display, XErrorEvent* event)
144 {
145  std::stringstream str;
146  str << "X error received: "
147  << "type " << event->type << ", "
148  << "serial " << event->serial << ", "
149  << "error_code " << static_cast<int>(event->error_code) << ", "
150  << "request_code " << static_cast<int>(event->request_code) << ", "
151  << "minor_code " << static_cast<int>(event->minor_code);
152 
153  LOG_ERROR(str.str());
154  HasX11Error = true;
155  return 0;
156 }
157 #endif
158 
160 
162 {
163  LEVIATHAN_ASSERT(!Initialized, "Graphics not released before destructor");
164 }
165 // ------------------------------------------- //
166 bool Graphics::Init(AppDef* appdef)
167 {
168  // StartUp SDL //
169  if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) != 0) {
170 
171  LOG_ERROR("Graphics: Init: SDL init failed, error: " + std::string(SDL_GetError()));
172  return false;
173  }
174 
175  SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
176 
177  int displays = SDL_GetNumVideoDisplays();
178 
179  LOG_INFO("SDL: display count: " + Convert::ToString(displays));
180 
181  // Get display positions
182  std::vector<SDL_Rect> displayBounds;
183 
184  for(int i = 0; i < displays; i++) {
185 
186  displayBounds.push_back(SDL_Rect());
187 
188  SDL_GetDisplayBounds(i, &displayBounds.back());
189 
190  const char* nameptr = SDL_GetDisplayName(i);
191 
192  const auto name = nameptr ? std::string(nameptr) : std::string("unnamed");
193 
194  // Video modes //
195  int videomodecount = SDL_GetNumDisplayModes(i);
196 
197  std::vector<std::string> videomodes;
198 
199  for(int a = 0; a < videomodecount; a++) {
200 
201 
202  SDL_DisplayMode mode = {SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0};
203 
204  if(SDL_GetDisplayMode(i, a, &mode) == 0) {
205 
206  videomodes.push_back(Convert::ToString(SDL_BITSPERPIXEL(mode.format)) +
207  " bpp " + Convert::ToString(mode.w) + "x" +
208  Convert::ToString(mode.h) + " at " +
209  Convert::ToString(mode.refresh_rate) + "Hz");
210  }
211  }
212 
213 
214  LOG_INFO("Display(" + Convert::ToString(i) + ", " + name + "): top left: (" +
215  Convert::ToString(displayBounds.back().x) + ", " +
216  Convert::ToString(displayBounds.back().y) +
217  ") size: " + Convert::ToString(displayBounds.back().w) + "x" +
218  Convert::ToString(displayBounds.back().h));
219 
220  // LOG_INFO("Supported modes(" + Convert::ToString(videomodes.size()) + "): ");
221  // for(const auto& mode : videomodes){
222 
223  // LOG_WRITE(" " + mode);
224  // }
225  }
226 
227 
228  if(!InitializeBSF(appdef)) {
229 
230  Logger::Get()->Error("Graphics: Init: failed to create bs::framework renderer");
231  return false;
232  }
233 
234 #ifdef __linux
235  // Set X11 error handler to not crash on non-fatal errors
236  XSetErrorHandler(LeviathanX11ErrorHandler);
237 #endif
238 
239  Initialized = true;
240  return true;
241 }
242 
244 {
245  if(Initialized) {
246 
247  ShutdownBSF();
248 
249  SDL_Quit();
250  }
251 
252  Initialized = false;
253  FirstWindowCreated = false;
254  Pimpl.reset();
255 }
256 // ------------------------------------------- //
257 bool Graphics::InitializeBSF(AppDef* appdef)
258 {
259  // Now with Ogre gone we print the CPU (and GPU) info here. However this seems to have some
260  // problems at least on my Linux computer printing the GPU info
261  std::stringstream sstream;
262 
263  sstream << "Start of graphics system information:\n"
264  << "// ------------------------------------ //\n";
265 
266  // This code is adapted from bs::Debug::saveTextLog
267 
268  sstream << "BSF version: " << BS_VERSION_MAJOR << "." << BS_VERSION_MINOR << "."
269  << BS_VERSION_PATCH << "\n";
270 
271  bs::SystemInfo systemInfo = bs::PlatformUtility::getSystemInfo();
272  sstream << "OS version: " << systemInfo.osName << " "
273  << (systemInfo.osIs64Bit ? "64-bit" : "32-bit") << "\n";
274  sstream << "CPU information:\n";
275  sstream << "CPU vendor: " << systemInfo.cpuManufacturer << "\n";
276  sstream << "CPU name: " << systemInfo.cpuModel << "\n";
277  sstream << "CPU clock speed: " << systemInfo.cpuClockSpeedMhz << "Mhz\n";
278  sstream << "CPU core count: " << systemInfo.cpuNumCores << "\n";
279 
280  sstream << "\n";
281  sstream << "GPU List:\n";
282 
283  // NOTE: this doesn't work on my Linux computer (returns an empty list)
284  if(systemInfo.gpuInfo.numGPUs == 1)
285  sstream << "GPU: " << systemInfo.gpuInfo.names[0] << "\n";
286  else {
287  for(bs::UINT32 i = 0; i < systemInfo.gpuInfo.numGPUs; i++)
288  sstream << "GPU #" << i << ": " << systemInfo.gpuInfo.names[i] << "\n";
289  }
290 
291  sstream << "// ------------------------------------ //";
292 
293  LOG_INFO(sstream.str());
294 
295  // Create render API settings
296  bs::START_UP_DESC desc;
297  desc.input = "bsfNullInput";
298  desc.audio = "bsfNullAudio";
299  desc.physics = "bsfNullPhysics";
300  desc.renderer = "bsfRenderBeast";
301  desc.physicsCooking = false;
302 
303  desc.importers.push_back("bsfFreeImgImporter");
304  desc.importers.push_back("bsfFBXImporter");
305  desc.importers.push_back("bsfFontImporter");
306  desc.importers.push_back("bsfSL");
307 
308 #ifdef _WIN32
309  const auto defaultRenderer = "DirectX";
310 #elif defined(__linux__)
311  const auto defaultRenderer = "OpenGL";
312 #else
313  const auto defaultRenderer = "Vulkan";
314 #endif
315 
316  std::string renderAPI;
317  ObjectFileProcessor::LoadValueFromNamedVars<std::string>(
318  appdef->GetValues(), "RenderAPI", renderAPI, defaultRenderer);
319 
320  LOG_INFO("Graphics: preferred rendering API: '" + renderAPI + "'");
321 
322  LOG_WRITE("TODO: add detection if vulkan is available or not");
323 
324  const std::regex vulkan(
325  "Vulkan", std::regex_constants::ECMAScript | std::regex_constants::icase);
326  const std::regex opengl(
327  "OpenGL", std::regex_constants::ECMAScript | std::regex_constants::icase);
328 
329 #ifdef _WIN32
330  const std::regex directx(
331  "DirectX\\s*(11)?", std::regex_constants::ECMAScript | std::regex_constants::icase);
332 #endif //_WIN32
333 
334  if(std::regex_match(renderAPI, vulkan)) {
335  desc.renderAPI = "bsfVulkanRenderAPI";
336  } else if(std::regex_match(renderAPI, opengl)) {
337  desc.renderAPI = "bsfGLRenderAPI";
338  }
339 #ifdef _WIN32
340  else if(std::regex_match(renderAPI, directx)) {
341  desc.renderAPI = "bsfD3D11RenderAPI";
342  }
343 #endif //_WIN32
344  else {
345  LOG_ERROR("Graphics: unknown render API selected: " + renderAPI);
346  return false;
347  }
348 
349  // Custom callbacks
350  desc.logCallback = &BSFLogForwarder;
351 
352  desc.crashHandling.disableCrashSignalHandler = CrashHandler::IsBreakpadRegistered();
353  desc.crashHandling.onBeforeReportCrash =
354  [](const bs::String& type, const bs::String& description, const bs::String& function,
355  const bs::String& file, bs::UINT32 line) {
357  return false;
358  };
359 
360  desc.crashHandling.onCrashPrintedToLog = []() {
361  if(auto logger = Logger::Get(); logger)
362  logger->Save();
364  };
365 
366 #ifdef _WIN32
367  desc.crashHandling.onBeforeWindowsSEHReportCrash = [](void* data) {
369  return false;
370  };
371 #endif //_WIN32
372 
373  Pimpl = std::make_unique<Private>(desc);
374 
375  return true;
376 }
377 
378 bs::SPtr<bs::RenderWindow> Graphics::RegisterCreatedWindow(Window& window)
379 {
380  if(FirstWindowCreated) {
381  // Register secondary window
382 
383  bs::RENDER_WINDOW_DESC windowDesc;
384 
385  windowDesc.depthBuffer = true;
386 
387  int multiSample;
388 
389  ObjectFileProcessor::LoadValueFromNamedVars<int>(
390  Engine::Get()->GetDefinition()->GetValues(), "WindowMultiSampleCount", multiSample,
391  1);
392 
393  windowDesc.multisampleCount = multiSample;
394  // windowDesc.multisampleHint = "";
395  // Not sure what all settings need to be copied
396  windowDesc.fullscreen = /* window.IsFullScreen() */ false;
397  windowDesc.vsync = false;
398 
399  int32_t width, height;
400  window.GetSize(width, height);
401  windowDesc.videoMode = bs::VideoMode(
402  width, height, Pimpl->Description.primaryWindowDesc.videoMode.refreshRate, 0);
403 
404 #ifdef _WIN32
405  windowDesc.platformSpecific["externalWindowHandle"] =
406  std::to_string((uint64_t)window.GetNativeHandle());
407 #else
408  windowDesc.platformSpecific["externalWindowHandle"] =
409  std::to_string(window.GetNativeHandle());
410 
411  windowDesc.platformSpecific["externalDisplay"] =
412  std::to_string(window.GetWindowXDisplay());
413 #endif
414 
415  auto window = bs::RenderWindow::create(windowDesc);
416 
417  if(!window)
418  LOG_FATAL("Failed to create additional BSF window");
419 
420  return window;
421 
422  } else {
423  // Finish initializing graphics
424  FirstWindowCreated = true;
425  LOG_INFO("Graphics: doing bs::framework initialization after creating first window");
426 
427  // Setup first window properties
428  auto& windowDesc = Pimpl->Description.primaryWindowDesc;
429  windowDesc.depthBuffer = true;
430 
431  int multiSample;
432 
433  ObjectFileProcessor::LoadValueFromNamedVars<int>(
434  Engine::Get()->GetDefinition()->GetValues(), "WindowMultiSampleCount", multiSample,
435  1);
436 
437  windowDesc.multisampleCount = multiSample;
438  // windowDesc.multisampleHint = "";
439  // Not sure what all settings need to be copied
440  windowDesc.fullscreen = /* window.IsFullScreen() */ false;
441  windowDesc.vsync = false;
442 
443  // Fill video mode info from SDL
444  SDL_DisplayMode dm;
445  if(SDL_GetDesktopDisplayMode(0, &dm) != 0) {
446  LOG_ERROR("Graphics: RegisterCreatedWindow: failed to get desktop display mode:" +
447  std::string(SDL_GetError()));
448  return nullptr;
449  }
450 
451  int32_t width, height;
452  window.GetSize(width, height);
453  windowDesc.videoMode = bs::VideoMode(width, height, dm.refresh_rate, 0);
454 
455 #ifdef _WIN32
456  windowDesc.platformSpecific["externalWindowHandle"] =
457  std::to_string((uint64_t)window.GetNativeHandle());
458 #else
459  windowDesc.platformSpecific["externalWindowHandle"] =
460  std::to_string(window.GetNativeHandle());
461 
462  windowDesc.platformSpecific["externalDisplay"] =
463  std::to_string(window.GetWindowXDisplay());
464 #endif
465 
466  bs::Application::startUp<LeviathanBSFApplication>(Pimpl->Description);
467 
468  Pimpl->OurApp =
469  static_cast<LeviathanBSFApplication*>(bs::CoreApplication::instancePtr());
470 
471  bs::SPtr<bs::RenderWindow> bsWindow =
472  bs::CoreApplication::instance().getPrimaryWindow();
473 
474  LEVIATHAN_ASSERT(bsWindow, "window creation failed");
475 
476  // Notify engine to register threads to work with Ogre //
477  // Engine::GetEngine()->_NotifyThreadsRegisterOgre();
478 
479  auto shader =
480  bs::gImporter().import<bs::Shader>("Data/Shaders/CoreShaders/ScreenSpaceGUI.bsl");
481 
482  auto material = bs::Material::create(shader);
483 
484  Pimpl->OurApp->GUIRenderer =
485  bs::RendererExtension::create<GUIOverlayRenderer>(GUIOverlayInitializationData{
486  GeometryHelpers::CreateScreenSpaceQuad(-1, -1, 2, 2)->getCore(),
487  material->getCore()});
488 
489  Pimpl->OurApp->beginMainLoop();
490  return bsWindow;
491  }
492 }
493 
495 {
496  if(Pimpl) {
497  Pimpl->OurApp->waitUntilFrameFinished();
498  }
499 
500  if(window.GetBSFWindow() == bs::CoreApplication::instance().getPrimaryWindow()) {
501  LOG_INFO("Graphics: primary window is closing, hiding it instead until shutdown");
502  return true;
503  }
504 
505  // TODO: additional window unregister
506  return false;
507 }
508 
509 void Graphics::ShutdownBSF()
510 {
511  LEVIATHAN_ASSERT(Pimpl, "ShutdownBSF called when it isn't valid to do so");
512 
513  // One more frame needs to be rendered here to not crash if the outer main loop has
514  // done stuff since the last frame.
515  Pimpl->OurApp->runMainLoopFrame();
516  Pimpl->OurApp->endMainLoop();
517  Pimpl->OurApp->GUIRenderer = nullptr;
518 
519  bs::Application::shutDown();
520  Pimpl->OurApp = nullptr;
521 }
522 // ------------------------------------ //
524 {
525  // Logic for this frame is already ready, just tell bsf to render once
526  Pimpl->OurApp->runMainLoopFrame();
527 
528  // At this point the frame render operation is happening on the BSF core thread, but it is
529  // safe to use non-core thread objects normally, only in special cases do we need to wait
530  // for a frame to end
531  return true;
532 }
533 // ------------------------------------ //
535  bs::RenderTarget& target, const std::vector<bs::SPtr<bs::Texture>>& overlays)
536 {
537  const auto targetRenderTarget = reinterpret_cast<uint64_t>(target.getCore().get());
538 
539  std::vector<bs::SPtr<bs::ct::Texture>> coreVersion;
540  coreVersion.reserve(overlays.size());
541 
542  std::transform(overlays.begin(), overlays.end(), std::back_inserter(coreVersion),
543  [](const bs::SPtr<bs::Texture>& item) { return item->getCore(); });
544 
545  std::weak_ptr<GUIOverlayRenderer> rendererExtension = Pimpl->OurApp->GUIRenderer;
546 
547  bs::gCoreThread().queueCommand(
548  [rendererExtension, targetRenderTarget, coreVersion = std::move(coreVersion)]() {
549  const auto locked = rendererExtension.lock();
550  if(locked)
551  locked->UpdateShownOverlays(targetRenderTarget, coreVersion);
552  });
553 }
554 
556 {
557  const auto capabilities = bs::ct::RenderAPI::instance().getCapabilities(0);
558 
559  return capabilities.conventions.ndcYAxis != bs::Conventions::Axis::Down;
560 }
561 // ------------------------------------ //
562 // Resource loading helpers
563 DLLEXPORT bs::HShader Graphics::LoadShaderByName(const std::string& name)
564 {
565  // TODO: .asset detection
566 
568  // Leviathan::StringOperations::RemoveExtension(name, true),
570  // Leviathan::StringOperations::GetExtension(name)
571  "asset");
572 
573  if(file.empty()) {
574  LOG_ERROR("Graphics: LoadShaderByName: could not find resource with name: " + name);
575  return nullptr;
576  }
577 
578  return Pimpl->LoadResource<bs::Shader>(std::filesystem::absolute(file).string().c_str());
579 }
580 
581 DLLEXPORT bs::HTexture Graphics::LoadTextureByName(const std::string& name)
582 {
584  // Leviathan::StringOperations::RemoveExtension(name, true),
586  // Leviathan::StringOperations::GetExtension(name)
587  "asset");
588 
589  if(file.empty()) {
590  LOG_ERROR("Graphics: LoadTextureByName: could not find resource with name: " + name);
591  return nullptr;
592  }
593 
594  return Pimpl->LoadResource<bs::Texture>(std::filesystem::absolute(file).string().c_str());
595 }
596 
597 DLLEXPORT bs::HMesh Graphics::LoadMeshByName(const std::string& name)
598 {
600  // Leviathan::StringOperations::RemoveExtension(name, true),
602  // Leviathan::StringOperations::GetExtension(name)
603  "asset");
604 
605  if(file.empty()) {
606  LOG_ERROR("Graphics: LoadMeshByName: could not find resource with name: " + name);
607  return nullptr;
608  }
609 
610  return Pimpl->LoadResource<bs::Mesh>(std::filesystem::absolute(file).string().c_str());
611 }
612 
613 DLLEXPORT bs::HAnimationClip Graphics::LoadAnimationClipByName(const std::string& name)
614 {
616  // Leviathan::StringOperations::RemoveExtension(name, true),
618  // Leviathan::StringOperations::GetExtension(name)
619  "asset");
620 
621  if(file.empty()) {
622  LOG_ERROR(
623  "Graphics: LoadAnimationClipByName: could not find resource with name: " + name);
624  return nullptr;
625  }
626 
627  return Pimpl->LoadResource<bs::AnimationClip>(
628  std::filesystem::absolute(file).string().c_str());
629 }
630 
631 // ------------------------------------ //
632 // X11 errors
633 #ifdef __linux
634 DLLEXPORT bool Graphics::HasX11ErrorOccured()
635 {
636  if(HasX11Error) {
637  HasX11Error = false;
638  return true;
639  }
640 
641  return false;
642 }
643 #endif
LeviathanBSFApplication(const bs::START_UP_DESC &desc)
Definition: Graphics.cpp:94
static DLLEXPORT bs::HMesh CreateScreenSpaceQuad(float x, float y, float width, float height, bool autoflipUV=true)
Creates a screen space plane with UV coordinates.
DLLEXPORT unsigned long GetNativeHandle() const
Definition: Window.cpp:917
DLLEXPORT bool Init(AppDef *appdef)
Definition: Graphics.cpp:166
DLLEXPORT bs::HMesh LoadMeshByName(const std::string &name)
Works the same as LoadShaderByName.
Definition: Graphics.cpp:597
static const StringTypeN RemovePath(const StringTypeN &filepath)
DLLEXPORT void GetSize(int32_t &width, int32_t &height) const
Definition: Window.cpp:896
#define LOG_INFO(x)
Definition: Define.h:88
bs::SPtr< bs::RenderWindow > RegisterCreatedWindow(Window &window)
Called when Window objects are created to register them with bsf and with the case of the first windo...
Definition: Graphics.cpp:378
#define LOG_ERROR(x)
Definition: Define.h:90
LeviathanBSFApplication * OurApp
Definition: Graphics.cpp:137
DLLEXPORT const auto & GetBSFWindow() const
Definition: Window.h:166
#define LOG_FATAL(x)
Definition: Define.h:92
DLLEXPORT bool IsVerticalUVFlipped() const
Definition: Graphics.cpp:555
DLLEXPORT ~Graphics()
Definition: Graphics.cpp:161
auto LoadResource(const bs::String &path)
Definition: Graphics.cpp:111
DLLEXPORT void UpdateShownOverlays(bs::RenderTarget &target, const std::vector< bs::SPtr< bs::Texture >> &overlays)
Definition: Graphics.cpp:534
DLLEXPORT bs::HTexture LoadTextureByName(const std::string &name)
Works the same as LoadShaderByName.
Definition: Graphics.cpp:581
#define LOG_WARNING(x)
Definition: Define.h:89
DLLEXPORT bs::HAnimationClip LoadAnimationClipByName(const std::string &name)
Works the same as LoadShaderByName.
Definition: Graphics.cpp:613
DLLEXPORT bool Frame()
Definition: Graphics.cpp:523
bs::START_UP_DESC Description
Definition: Graphics.cpp:136
static void DoBreakpadCrashDumpIfRegistered()
Triggers Breakpad callback if registered.
DLLEXPORT Graphics()
Definition: Graphics.cpp:159
DLLEXPORT NamedVars * GetValues()
Definition: AppDefine.cpp:40
bool BSFLogForwarder(const bs::String &message, bs::LogVerbosity verbosity, bs::UINT32 category)
Definition: Graphics.cpp:43
DLLEXPORT bs::HShader LoadShaderByName(const std::string &name)
Finds and loads a shader with the name.
Definition: Graphics.cpp:563
#define LOG_WRITE(x)
Definition: Define.h:91
Definition: SFMLPackets.h:18
static DLLEXPORT FileSystem * Get()
Definition: FileSystem.cpp:74
#define LEVIATHAN_ASSERT(x, msg)
Definition: Define.h:98
bs::SPtr< bs::IShaderIncludeHandler > getShaderIncludeHandler() const override
Definition: Graphics.cpp:96
static std::string ToString(const T &val)
Definition: Convert.h:72
static DLLEXPORT bool IsBreakpadRegistered()
std::unordered_set< bs::String > RegisteredAssets
Definition: Graphics.cpp:134
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106
bs::SPtr< GUIOverlayRenderer > GUIRenderer
Definition: Graphics.cpp:101
static DLLEXPORT bool FileExists(const std::string &name)
Definition: FileSystem.cpp:451
DLLEXPORT std::string SearchForFile(FILEGROUP which, const std::string &name, const std::string &extensions, bool searchall=true)
Searches for a file.
Definition: FileSystem.cpp:666
virtual bs::HShaderInclude findInclude(const bs::String &name) const override
Definition: Graphics.cpp:65
static void DoBreakpadSEHCrashDumpIfRegistered(void *data)
Triggers Breakpad callback if registered.
#define DLLEXPORT
Definition: Include.h:84
Private(const bs::START_UP_DESC &desc)
Definition: Graphics.cpp:107
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:85
DLLEXPORT void Release()
Definition: Graphics.cpp:243
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
DLLEXPORT void Error(const std::string &data) override
Definition: Logger.cpp:177
bool UnRegisterWindow(Window &window)
Called just before a window is destroyed. This needs to stop rendering to it.
Definition: Graphics.cpp:494