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