Using bf::framework as a graphics library


#1

Hi,

I’m working on an open source engine and a game (as part of a team, https://revolutionarygamesstudio.com/) and I’m wondering how feasible it would be to use bs::framework as just a rendering engine. Right now we are using Ogre, but there is a big issue with it currently and there’s also been issues in the past. So I’ve been looking for alternatives every now and then. I just found bsf and it seems very interesting. I’m particularly impressed by the clean manual and the small amount of code needed to do graphics things. Because right now we have no one on the team who is a graphics programming expert, I know some things, but I constantly run into issues.

To me it seems like with the ease of rendering and doing graphical effects like HDR and MSAA etc. with bsf we could greatly improve the visual quality of Thrive (the game I’m working on), and get unstuck from the problems (https://forums.ogre3d.org/viewtopic.php?f=2&t=95009).

However, I have some concerns regarding how bsf can be used as part of existing code. I looked through some parts of the manual and some of the API reference and from that I got the impression that the following features that we’d need are missing:

  • Rendering to existing windows, I’d like to keep all the input handling etc. working. I’m using SDL2 for that, so a way to create a bsf window from an SDL window would be great.
  • Separate scenes that can be switched between on a window. I saw something about this in the February progress update, but I’m not sure if this is fully done yet. Also rendering different scenes to different windows.
  • Having a custom main loop that could just call some bsf rendering / event pump method, instead of bsf having control of the main loop

Besides that there’s a few things I’m unsure whether they are already done or not, that we would need:

  • Rendering layered 2D (GUI) objects on a window. Or alternatively TrueType fonts and scaling for the inbuilt GUI. I might be interested in helping improve this instead of writing my own GUI
  • Full screen shader effects, like a lens distortion
  • Possibility of selecting the rendering backend dynamically on start (instead of with a cmake option) after detecting if vulkan is supported on the host computer or not
  • Customizing a shader with skeletal animation

This is quite a lot, but if someone could answer some of these, that would help me in making a decision about whether to start experimenting with bsf or not. I’m definitely looking forward seeing what the future holds for bs::framework.


#2

Hey,

You can add “externalWindowHandle” to RENDER_WINDOW_DESC::platformSpecific map to use an external window on creation. I don’t think anyone uses this at the moment so you might need to submit a bug report if it doesn’t work.

Not at the moment, but in the works. You can currently use per-object layers to achieve similar functionality.

Possible. See http://docs.bsframework.io/latest/non_component_approach.html.

GUI is supported, and you can render elements on top of other elements (if that’s what you mean by layers). Font rendering is also supported - all fonts need to be baked so scaling requires you to specify required font sizes during baking, but this is something I’d like to improve and make dynamic.

We don’t have a user API for this yet. It can be done relatively easily by modifying the renderer and adding new render nodes. I’d like to add an user API for this, but don’t have a timeframe.

This is possible. You need to manually build the other rendering system .dlls, and then you can switch between them when starting your application using START_UP_DESC::renderAPI.

You can customize animated shaders, including their geometry, surface lighting and general lighting calculation. See http://docs.bsframework.io/latest/surface_shaders.html.


#3

Thanks for the reply. I’ve decided to give bsf a go.

I managed to get the sample application code to compile and run inside my engine (I basically replaced my initialization code with it). I hit a few issues along the way:

Bugs:

  • libbsfNullPhysics.so doesn’t seem to get installed by cmake

And some things that I had to workaround due to the way my project is setup. I’d like to see the following added to bsf to resolve these:

  • Option to build all valid render APIs at once (my custom build setup scripts need modifying to work with having to build bsf twice, so I’d like the option to build all render APIs at once)
  • Option to build with type info enabled. I want to build my code with rtti enabled, and for linking to work, bsf needs to be built with rtti enabled. I did a quick and dirty edit to the bsf cmake files to remove the flag
  • Allow specifying a prefix for the dynamic library loading. I have all my .so files copied to a lib subdirectory and I’d like to have a way of telling bsf to load modules from there. I worked around this by hardcoding the prefix
  • There are some conflicting names in the global namespace in the file BsThreading.h. All of the things like Lock and RecursiveLock should be put inside the bs namespace.

And one more minor thing is that I’d like to be able to put all the bsf engine asset files to a sub folder like Data/BSF/ as I’m using the Data folder myself, there aren’t any name conflicts currently but I think it would be cleaner in the long run to not have the game assets mingled in the same folder. Alternatively it would be nice to be able to hook into bsf path resolving and do custom resolving there. Sorry if I missed one if that already exists.

That was my setup experience. Now onto actually getting something usable working.

Did I miss something? I don’t see any simple functions for rendering a single frame. I had a look at bsf/Source/Foundation/bsfCore/BsCoreApplication.cpp and it seems that I need to copy-paste the parts that I need from there. Or is there a simpler way?

I’ll try that next.

Also, I decided to become a patron for now as this is promising.


#4

Thanks for becoming a Patron!

All of these sound like valid complaints. I’ll add them to my task list, and I’d even more gladly accept a PR as I am pretty swamped at the moment. Most these could be handled with some extra cmake parameters.

Sadly all you get is call backs, you don’t have full control over the loop. If you have a good idea how to handle this design-wise, I’d consider adding it. Also take a look at the LowLevelRenderingExample


#5

I’m not really sure, but from looking at the main loop, I think that if the second part of the loop (after the frame limiting) was a separate function that could be called with the elapsed time I could use that. Similarly to how Ogre has a single function that renders a single frame on all windows.

I can probably help with that, though I have limited time currently. I’m also unsure how I should go about it, I don’t want to end up making a bad pull request that doesn’t fit. I’ll try to get everything hacked together first on my computer and then try to find a cleaner solution.


#6

I understand better now regarding the loop. I haven’t thought about it much, but it could potentially be reorganized so it handles just one frame and can be called externally. Might be issues with the rendering/core thread. Needs further investigation definitely.

I might some more time towards the end of the week. I’ll take a look at the bugs and perhaps handle some of the build stuff you need, or just try to give you more information on where to start.


#7

Null physics library install has been fixed. Threading primitives have been moved to the bs namespace. BUILD_ALL_RENDER_API option has been added that will force all render APIs to be built at once.

Note I haven’t tested the last one. If you have issues let me know.


#8

CMake fails for me when I enable that option:

-- Looking for snappy installation...
-- ...snappy OK.
-- Looking for nvtt installation...
-- ...nvtt OK.
-- Looking for LibUUID...
-- ...LibUUID OK.
-- Looking for LibICU installation...
-- ...LibICU OK.
-- Looking for Vulkan installation...
-- ...Vulkan OK.
-- Looking for glslang installation...
-- ...glslang OK.
-- Looking for FBXSDK installation...
-- ...FBXSDK OK.
-- Looking for freetype installation...
-- ...freetype OK.
-- Looking for freeimg installation...
-- ...freeimg OK.
-- Looking for XShaderCompiler installation...
-- ...XShaderCompiler OK.
-- Configuring done
CMake Error at Source/CMake/HelperMethods.cmake:20 (add_dependencies):
  The dependency target "bsfGLRenderAPI" of target "bsfImportTool" does not
  exist.
Call Stack (most recent call first):
  Source/CMake/HelperMethods.cmake:10 (add_engine_dependencies2)
  Source/CMakeLists.txt:229 (add_engine_dependencies)


CMake Error at Source/CMake/HelperMethods.cmake:20 (add_dependencies):
  The dependency target "bsfNullRenderAPI" of target "bsfImportTool" does not
  exist.
Call Stack (most recent call first):
  Source/CMake/HelperMethods.cmake:10 (add_engine_dependencies2)
  Source/CMakeLists.txt:229 (add_engine_dependencies)

These are my CMake options:

$ cmake .. -L -N
-- Cache values
AUDIO_MODULE:STRING=Null
BUILD_ALL_RENDER_API:BOOL=true
BUILD_BSL:BOOL=OFF
BUILD_TESTS:BOOL=OFF
CMAKE_BUILD_TYPE:STRING=RelWithDebInfo
CMAKE_INSTALL_PREFIX:PATH=/home/hhyyrylainen/Projects/Leviathan/build/ThirdParty
ENABLE_COTIRE:BOOL=false
EXPERIMENTAL_ENABLE_NETWORKING:BOOL=OFF
INCLUDE_ALL_IN_WORKFLOW:BOOL=OFF
INCLUDE_ASSET_PACKAGING_SCRIPTS:BOOL=OFF
OBJCOPY_TOOL:FILEPATH=/usr/bin/objcopy
PHYSICS_MODULE:STRING=Null
RENDERER_MODULE:STRING=RenderBeast
RENDER_API_MODULE:STRING=Vulkan
SCRIPT_API:STRING=None
SCRIPT_BINDING_GENERATION:BOOL=OFF
UPLOAD_ASSETS:BOOL=OFF
USE_BUNDLED_LIBRARIES:BOOL=ON

#9

Should be fixed now, let me know if you run into more issues.


#10

Okay, CMake and the install is working now. But this https://github.com/GameFoundry/bsf/commit/6cbb3620a1acdd62953e2c22201aa30a9a441185 doesn’t work with the vulkan renderer. That file is duplicated at: bsf/Source/Plugins/bsfVulkanRenderAPI/Linux/BsLinuxVideoModeInfo.cpp so that also needs the fix (or maybe that should use the same file).


#11

Good catch. Ultimately it should use the same file but I have a WIP commit for macOS to handle plugin file sharing, so I’ll defer that until then to avoid conflicts, and just copy over the changes for now.


#12

It’s working now. I’ll try to get rendering to an existing window going next.

The default window (without nothing being drawn on it) keeps printing these warnings, but it’s likely nothing too major:

[WARNING] WARNING: [Validation] Code -1:  [ UNASSIGNED-CoreValidation-Shader-OutputNotConsumed ] Object: 0x3b3 (Type = 15) | fragment shader writes to output location 0 with no matching attachment

		 in VkBool32 bs::ct::debugMsgCallback(VkDebugReportFlagsEXT, VkDebugReportObjectTypeEXT, uint64_t, size_t, int32_t, const char*, const char*, void*) [/home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Plugins/bsfVulkanRenderAPI/BsVulkanRenderAPI.cpp:77]

Edit: ran into a proper issue, it looks like the externally created window option is not implemented for Linux:

$ ag externalWindowHandle
Source/Plugins/bsfGLRenderAPI/Win32/BsWin32RenderWindow.cpp
161:		opt = mDesc.platformSpecific.find("externalWindowHandle");

Source/Plugins/bsfVulkanRenderAPI/Win32/BsWin32RenderWindow.cpp
140:		opt = mDesc.platformSpecific.find("externalWindowHandle");

Source/Plugins/bsfD3D11RenderAPI/BsD3D11RenderWindow.cpp
154:		opt = mDesc.platformSpecific.find("externalWindowHandle");

It seems that property is not implemented for linux. And looking at Source/Plugins/bsfVulkanRenderAPI/Linux/BsLinuxRenderWindow.cpp seems to confirm that it will always attempt to create a new window.

Another update: I duplicated the BsCoreApplication startup code and that seems to get me somewhere, but it ends up creating two windows (I couldn’t test it yet as I have still some parts trying to use Ogre so the program crashes in there). This is my code: https://github.com/hhyyrylainen/Leviathan/commit/4d0786bf175edb3030db25a178742f78063b0572


#13

If you get a chance open up a github issue about the external window stuff, it’s the safest way to guarantee it will be added.


#14

I created an issue:


Let me know if I should add more details.


#15

Looks good, thank you.


#16

Now I’ve gotten the initialization code copied over and I’m trying to render a mesh. It is crashing in bs::ct::RenderBeast::initializeCore so I think I have something wrong with the initialization:

#0  0x00007ffeda40164a in bs::ct::RendererMaterial<bs::ct::IrradianceComputeSHMat>::get(bs::ShaderVariation const&) (variation=...) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Utility/BsSmallVector.h:232
#1  0x00007ffeda40164a in bs::ct::IrradianceComputeSHMat::getVariation(int) (order=<optimized out>) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Plugins/bsfRenderBeast/BsRenderBeastIBLUtility.cpp:170
#2  0x00007ffeda401b83 in bs::ct::RenderBeastIBLUtility::filterCubemapForIrradiance(std::shared_ptr<bs::ct::Texture> const&, std::shared_ptr<bs::ct::Texture> const&) const (this=<optimized out>, cubemap=std::shared_ptr<bs::ct::Texture> (use count 1, weak count 1) = {...}, output=std::shared_ptr<bs::ct::Texture> (use count 1, weak count 1) = {...}) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Plugins/bsfRenderBeast/BsRenderBeastIBLUtility.cpp:463
#3  0x00007ffeda4a0b5d in bs::ct::generateDefaultIndirect() () at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Plugins/bsfRenderBeast/Utility/BsRendererTextures.cpp:233
#4  0x00007ffeda4a0d10 in bs::ct::RendererTextures::startUp() () at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Plugins/bsfRenderBeast/Utility/BsRendererTextures.cpp:246
#5  0x00007ffeda393548 in bs::ct::RenderBeast::initializeCore() (this=0x53b190) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Plugins/bsfRenderBeast/BsRenderBeast.cpp:86
#6  0x00007fffed92b802 in std::function<void ()>::operator()() const (this=0x7ffee0100cc0) at /usr/include/c++/8/bits/std_function.h:682
#7  0x00007fffed92b802 in bs::CommandQueueBase::playbackWithNotify(std::queue<bs::QueuedCommand, std::deque<bs::QueuedCommand, bs::StdAlloc<bs::QueuedCommand, bs::GenAlloc> > >*, std::function<void (unsigned int)>) (this=this@entry=0xadd640, commands=<optimized out>, commands@entry=0x7ffee0100b90, notifyCallback=...) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfCore/CoreThread/BsCommandQueue.cpp:124
#8  0x00007fffed9384d8 in bs::CoreThread::runCoreThread() (this=0x632800) at /usr/include/c++/8/bits/std_function.h:87
#9  0x00007fffed8b75fb in std::function<void ()>::operator()() const (this=0x7ffeef66da20) at /usr/include/c++/8/bits/std_function.h:682
#10 0x00007fffed8b75fb in bs::PooledThread::run() (this=0xae03a0) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Threading/BsThreadPool.cpp:122
#11 0x00007fffeef5b9a3 in  () at /lib64/libstdc++.so.6
#12 0x00007fffef03858e in start_thread () at /lib64/libpthread.so.0
#13 0x00007fffeec2e683 in clone () at /lib64/libc.so.6

Even when commenting out my mesh creation (so that there is only a single camera) it crashes there.


#17

Hard to tell. Looks like it cannot find the built-in shaders used by the renderer, or at least something related to that. If you break at the point of the crash and examine the locals it should be more clear what exactly is going wrong.


#18

When stepping through I got to the get function at bsfEngine/Renderer/BsRendererMaterial.h:148 before I tried to run to the end of that function but that triggers the crash. It seems that there is stuff in the shader variant list, so it has managed to load something.

When running with valgrind I get this:

==26513== Invalid write of size 4
==26513==    at 0xEF7A499: _Rb_tree_header (stl_tree.h:175)
==26513==    by 0xEF7A499: _Rb_tree_impl (stl_tree.h:703)
==26513==    by 0xEF7A499: _Rb_tree (stl_tree.h:929)
==26513==    by 0xEF7A499: set (stl_set.h:167)
==26513==    by 0xEF7A499: bs::ResourceListenerManager::ResourceListenerManager() (BsResourceListenerManager.cpp:12)
==26513==    by 0x4AD9371: bs_new<bs::ResourceListenerManager> (new:169)
==26513==    by 0x4AD9371: startUp<> (BsModule.h:71)
==26513==    by 0x4AD9371: Leviathan::Graphics::InitializeBSF(Leviathan::AppDef*) (Graphics.cpp:386)
==26513==    by 0x4ADC74C: Leviathan::Graphics::Init(Leviathan::AppDef*) (Graphics.cpp:282)
==26513==    by 0x49F9302: Leviathan::Engine::Init(Leviathan::AppDef*, Leviathan::NETWORKED_TYPE, Leviathan::NetworkInterface*) (Engine.cpp:370)
==26513==    by 0x4ABEA5B: Leviathan::LeviathanApplication::Initialize(Leviathan::AppDef*) (Application.cpp:48)
==26513==    by 0x404FAE: main (Main.cpp:214)
==26513==  Address 0x5c05ac88 is 8 bytes after a block of size 384 alloc'd
==26513==    at 0x483880B: malloc (vg_replace_malloc.c:309)
==26513==    by 0x4AD9366: allocate (BsMemoryAllocator.h:152)
==26513==    by 0x4AD9366: bs_alloc<bs::ResourceListenerManager, bs::GenAlloc> (BsMemoryAllocator.h:234)
==26513==    by 0x4AD9366: bs_new<bs::ResourceListenerManager> (BsMemoryAllocator.h:354)
==26513==    by 0x4AD9366: startUp<> (BsModule.h:71)
==26513==    by 0x4AD9366: Leviathan::Graphics::InitializeBSF(Leviathan::AppDef*) (Graphics.cpp:386)
==26513==    by 0x4ADC74C: Leviathan::Graphics::Init(Leviathan::AppDef*) (Graphics.cpp:282)
==26513==    by 0x49F9302: Leviathan::Engine::Init(Leviathan::AppDef*, Leviathan::NETWORKED_TYPE, Leviathan::NetworkInterface*) (Engine.cpp:370)
==26513==    by 0x4ABEA5B: Leviathan::LeviathanApplication::Initialize(Leviathan::AppDef*) (Application.cpp:48)
==26513==    by 0x404FAE: main (Main.cpp:214)
==26513== 
==26513== Invalid write of size 8
==26513==    at 0xEF7A4A3: _M_reset (stl_tree.h:208)
==26513==    by 0xEF7A4A3: _Rb_tree_header (stl_tree.h:176)
==26513==    by 0xEF7A4A3: _Rb_tree_impl (stl_tree.h:703)
==26513==    by 0xEF7A4A3: _Rb_tree (stl_tree.h:929)
==26513==    by 0xEF7A4A3: set (stl_set.h:167)
==26513==    by 0xEF7A4A3: bs::ResourceListenerManager::ResourceListenerManager() (BsResourceListenerManager.cpp:12)
==26513==    by 0x4AD9371: bs_new<bs::ResourceListenerManager> (new:169)
==26513==    by 0x4AD9371: startUp<> (BsModule.h:71)
==26513==    by 0x4AD9371: Leviathan::Graphics::InitializeBSF(Leviathan::AppDef*) (Graphics.cpp:386)
==26513==    by 0x4ADC74C: Leviathan::Graphics::Init(Leviathan::AppDef*) (Graphics.cpp:282)
==26513==    by 0x49F9302: Leviathan::Engine::Init(Leviathan::AppDef*, Leviathan::NETWORKED_TYPE, Leviathan::NetworkInterface*) (Engine.cpp:370)
==26513==    by 0x4ABEA5B: Leviathan::LeviathanApplication::Initialize(Leviathan::AppDef*) (Application.cpp:48)
==26513==    by 0x404FAE: main (Main.cpp:214)
==26513==  Address 0x5c05ac90 is 16 bytes after a block of size 384 alloc'd
==26513==    at 0x483880B: malloc (vg_replace_malloc.c:309)
==26513==    by 0x4AD9366: allocate (BsMemoryAllocator.h:152)
==26513==    by 0x4AD9366: bs_alloc<bs::ResourceListenerManager, bs::GenAlloc> (BsMemoryAllocator.h:234)
==26513==    by 0x4AD9366: bs_new<bs::ResourceListenerManager> (BsMemoryAllocator.h:354)
==26513==    by 0x4AD9366: startUp<> (BsModule.h:71)
==26513==    by 0x4AD9366: Leviathan::Graphics::InitializeBSF(Leviathan::AppDef*) (Graphics.cpp:386)
==26513==    by 0x4ADC74C: Leviathan::Graphics::Init(Leviathan::AppDef*) (Graphics.cpp:282)
==26513==    by 0x49F9302: Leviathan::Engine::Init(Leviathan::AppDef*, Leviathan::NETWORKED_TYPE, Leviathan::NetworkInterface*) (Engine.cpp:370)
==26513==    by 0x4ABEA5B: Leviathan::LeviathanApplication::Initialize(Leviathan::AppDef*) (Application.cpp:48)
==26513==    by 0x404FAE: main (Main.cpp:214)
==26513== 
==26513== Invalid write of size 8
==26513==    at 0xEF7A4AE: _M_reset (stl_tree.h:209)
==26513==    by 0xEF7A4AE: _Rb_tree_header (stl_tree.h:176)
==26513==    by 0xEF7A4AE: _Rb_tree_impl (stl_tree.h:703)
==26513==    by 0xEF7A4AE: _Rb_tree (stl_tree.h:929)
==26513==    by 0xEF7A4AE: set (stl_set.h:167)
==26513==    by 0xEF7A4AE: bs::ResourceListenerManager::ResourceListenerManager() (BsResourceListenerManager.cpp:12)
==26513==    by 0x4AD9371: bs_new<bs::ResourceListenerManager> (new:169)
==26513==    by 0x4AD9371: startUp<> (BsModule.h:71)
==26513==    by 0x4AD9371: Leviathan::Graphics::InitializeBSF(Leviathan::AppDef*) (Graphics.cpp:386)
==26513==    by 0x4ADC74C: Leviathan::Graphics::Init(Leviathan::AppDef*) (Graphics.cpp:282)
==26513==    by 0x49F9302: Leviathan::Engine::Init(Leviathan::AppDef*, Leviathan::NETWORKED_TYPE, Leviathan::NetworkInterface*) (Engine.cpp:370)
==26513==    by 0x4ABEA5B: Leviathan::LeviathanApplication::Initialize(Leviathan::AppDef*) (Application.cpp:48)
==26513==    by 0x404FAE: main (Main.cpp:214)
==26513==  Address 0x5c05ac98 is 24 bytes after a block of size 384 in arena "client"
==26513== 

valgrind: m_mallocfree.c:307 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 448, hi = 1543875720.
This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata.  If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away.  Please try that before reporting this as a bug.

So maybe that other code has corrupted the heap and the issue causes a crash there?

Edit: when commenting out the listener I get where it crashed:

==29210== Invalid read of size 8
==29210==    at 0x736C864A: get (BsRendererMaterial.h:154)
==29210==    by 0x736C864A: bs::ct::IrradianceComputeSHMat::getVariation(int) (BsRenderBeastIBLUtility.cpp:170)
==29210==    by 0x736C8B82: bs::ct::RenderBeastIBLUtility::filterCubemapForIrradiance(std::shared_ptr<bs::ct::Texture> const&, std::shared_ptr<bs::ct::Texture> const&) const (BsRenderBeastIBLUtility.cpp:463)
==29210==    by 0x73767B5C: bs::ct::generateDefaultIndirect() (BsRendererTextures.cpp:233)
==29210==    by 0x73767D0F: bs::ct::RendererTextures::startUp() (BsRendererTextures.cpp:246)
==29210==    by 0x7365A547: bs::ct::RenderBeast::initializeCore() (BsRenderBeast.cpp:86)
==29210==    by 0xEC19801: operator() (std_function.h:687)
==29210==    by 0xEC19801: bs::CommandQueueBase::playbackWithNotify(std::queue<bs::QueuedCommand, std::deque<bs::QueuedCommand, bs::StdAlloc<bs::QueuedCommand, bs::GenAlloc> > >*, std::function<void (unsigned int)>) (BsCommandQueue.cpp:124)
==29210==    by 0xEC264D7: bs::CoreThread::runCoreThread() (BsCoreThread.cpp:117)
==29210==    by 0xEBA55FA: operator() (std_function.h:687)
==29210==    by 0xEBA55FA: bs::PooledThread::run() (BsThreadPool.cpp:122)
==29210==    by 0xD8A39A2: ??? (in /usr/lib64/libstdc++.so.6.0.25)
==29210==    by 0xD7C658D: start_thread (in /usr/lib64/libpthread-2.28.so)
==29210==    by 0xDC16682: clone (in /usr/lib64/libc-2.28.so)
==29210==  Address 0x8737a0438 is not stack'd, malloc'd or (recently) free'd

This is what the variation object looks like in that get function:

p variation
$10 = (const bs::ShaderVariation &) @0x7ffeda4ea3c0: {
  <bs::IReflectable> = {
    _vptr.IReflectable = 0x7fffee17b018 <vtable for bs::ShaderVariation+16>
  }, 
  members of bs::ShaderVariation: 
  mParams = std::unordered_map with 1 element = {
    [{
      mData = 0x4466c0
    }] = {
      {
        i = 5, 
        ui = 5, 
        f = 7.00649232e-45
      }, 
      name = {
        mData = 0x4466c0
      }, 
      type = bs::ShaderVariation::Int
    }
  }, 
  mIdx = 4294967295
}

So maybe the variation is not found? Which files I need to have where to have the correct files?


#19

The files should be in Data/Shaders (This one in particular Data/Shaders/IrradianceComputeSH.bsl).

The shaders get loaded in RendererMaterialManager constructor. If you step through there you should be able to at least tell if the files are getting found.


#20

I have a bunch of .bsl.asset files in Data/Shaders including that file.

But when I put a breakpoint in RendererMaterialManager::RendererMaterialManager() it is never triggered (at least before the crash).

Edit: I just found about Source/Foundation/bsfEngine/BsApplication.cpp which has a bunch of startup functions I’m not calling…

Second edit: after copying a bunch more of the initialization code the material manager is now initialized, but the program crashes in there:

filePath = $11 = (const bs::Path &) @0x7fffffffce00: {
  mDirectories = std::vector of length 8, capacity 8 = {
    "home",
    "hhyyrylainen",
    "Projects",
    "Leviathan",
    "build",
    "bin",
    "Data",
    "Shaders"
  }, 
  mDevice = "", 
  mFilename = "GpuParticleCurveInject.bsl.asset", 
  mNode = "", 
  mIsAbsolute = true
}
(gdb) bt
#0  0x00007fffeeb6657f in raise () at /lib64/libc.so.6
#1  0x00007fffeeb50895 in abort () at /lib64/libc.so.6
#2  0x00007fffeeba99c7 in __libc_message () at /lib64/libc.so.6
#3  0x00007fffeebb02cc in  () at /lib64/libc.so.6
#4  0x00007fffeebb1adc in _int_free () at /lib64/libc.so.6
#5  0x00007fffedab5be0 in bs::MemoryAllocator<bs::GenAlloc>::free(void*) (ptr=0x61b990) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Allocators/BsMemoryAllocator.h:360
#6  0x00007fffedab5be0 in bs::bs_free(void*) (ptr=0x61b990) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Allocators/BsMemoryAllocator.h:360
#7  0x00007fffedab5be0 in bs::RTTIPlainType<std::__cxx11::basic_string<char, std::char_traits<char>, bs::StdAlloc<char, bs::GenAlloc> > >::fromMemory(std::__cxx11::basic_string<char, std::char_traits<char>, bs::StdAlloc<char, bs::GenAlloc> >&, char*) (memory=<optimized out>, data="\t\r\n\t\tstruct VertexInput\r\n\t\t{\r\n\t\t\tfloat4 color : TEXCOORD0;\r\n\t\t\tfloat2 dataUV : TEXCOORD1;\r\n\t\t\tfloat2 uv0 : TEXCOORD2;\r\n\t\t};\t\r\n\t\r\n\t\tstruct VStoFS\r\n\t\t{\r\n\t\t\tfloat4 position : SV_POSITION;\r\n\t\t\tfloat4 colo"...) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/String/BsString.h:821
#8  0x00007fffedab5be0 in bs::RTTIPlainField<bs::SerializedGpuProgramDataRTTI, std::__cxx11::basic_string<char, std::char_traits<char>, bs::StdAlloc<char, bs::GenAlloc> >, bs::SerializedGpuProgramData>::fromBuffer(bs::RTTITypeBase*, void*, void*) (this=0x4661d0, rtti=0x4e6a4ac, object=0x624c460, buffer=<optimized out>) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Reflection/BsRTTIPlainField.h:271
#9  0x00007fffed8d5db3 in bs::BinarySerializer::decodeEntry(std::shared_ptr<bs::DataStream> const&, unsigned long, std::shared_ptr<bs::IReflectable> const&) (this=0x7fffffffc800, data=std::shared_ptr<bs::DataStream> (use count 1, weak count 0) = {...}, dataEnd=<optimized out>, output=...) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Serialization/BsBinarySerializer.cpp:860
#10 0x00007fffed8d52a9 in bs::BinarySerializer::decodeEntry(std::shared_ptr<bs::DataStream> const&, unsigned long, std::shared_ptr<bs::IReflectable> const&) (this=0x7fffffffc800, data=std::shared_ptr<bs::DataStream> (use count 1, weak count 0) = {...}, dataEnd=<optimized out>, output=...) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Serialization/BsBinarySerializer.cpp:831
#11 0x00007fffed8d5846 in bs::BinarySerializer::decodeEntry(std::shared_ptr<bs::DataStream> const&, unsigned long, std::shared_ptr<bs::IReflectable> const&) (this=0x7fffffffc800, data=std::shared_ptr<bs::DataStream> (use count 1, weak count 0) = {...}, dataEnd=<optimized out>, output=...) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Serialization/BsBinarySerializer.cpp:692
#12 0x00007fffed8d5846 in bs::BinarySerializer::decodeEntry(std::shared_ptr<bs::DataStream> const&, unsigned long, std::shared_ptr<bs::IReflectable> const&) (this=this@entry=0x7fffffffc800, data=std::shared_ptr<bs::DataStream> (use count 1, weak count 0) = {...}, dataEnd=dataEnd@entry=35143, output=std::shared_ptr<bs::IReflectable> (use count 2, weak count 1) = {...}) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Serialization/BsBinarySerializer.cpp:692
#13 0x00007fffed8d9317 in bs::BinarySerializer::decode(std::shared_ptr<bs::DataStream> const&, unsigned int, bs::SerializationContext*, std::function<void (float)>) (this=this@entry=0x7fffffffc800, data=std::shared_ptr<bs::DataStream> (use count 1, weak count 0) = {...}, dataLength=<optimized out>, context=context@entry=0x7fffffffc7d0, progress=...) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Serialization/BsBinarySerializer.cpp:234
#14 0x00007fffeda8df22 in bs::Resources::loadFromDiskAndDeserialize(bs::Path const&, bool, std::atomic<float>&) (this=this@entry=0x98b960, filePath=..., loadWithSaveData=loadWithSaveData@entry=false, progress=...) at /usr/include/c++/8/new:169
#15 0x00007fffeda92ceb in bs::Resources::loadCallback(bs::Path const&, bs::TResourceHandle<bs::Resource, false>&, bool) (this=this@entry=0x98b960, filePath=..., resource=..., loadWithSaveData=<optimized out>) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfCore/Resources/BsResources.cpp:1020
#16 0x00007fffeda93dbf in bs::Resources::loadInternal(bs::UUID const&, bs::Path const&, bool, bs::Flags<bs::ResourceLoadFlag, unsigned int>) (this=this@entry=0x98b960, uuid=..., filePath=..., synchronous=synchronous@entry=true, loadFlags=...) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Utility/BsFlags.h:36
#17 0x00007fffeda94d80 in bs::Resources::load(bs::Path const&, bs::Flags<bs::ResourceLoadFlag, unsigned int>) (this=0x98b960, filePath=..., loadFlags=...) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Utility/BsFlags.h:25
#18 0x00007fffedd51f42 in bs::Resources::load<bs::Shader>(bs::Path const&, bs::Flags<bs::ResourceLoadFlag, unsigned int>) (loadFlags=..., filePath=..., this=<optimized out>) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfUtility/Utility/BsFlags.h:25
#19 0x00007fffedd51f42 in bs::BuiltinResources::getShader(bs::Path const&) const (this=this@entry=0x93c250, path=...) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfEngine/Resources/BsBuiltinResources.cpp:212
#20 0x00007fffede1f8b4 in bs::RendererMaterialManager::RendererMaterialManager() (this=<optimized out>) at /home/hhyyrylainen/Projects/Leviathan/ThirdParty/bsf/Source/Foundation/bsfEngine/Renderer/BsRendererMaterialManager.cpp:20
#21 0x00007ffff7d2f666 in bs::bs_new<bs::RendererMaterialManager>() () at /usr/include/c++/8/new:169
#22 0x00007ffff7d2f666 in bs::Module<bs::RendererMaterialManager>::startUp<>() () at /home/hhyyrylainen/Projects/Leviathan/build/ThirdParty/include/bsfUtility/Utility/BsModule.h:71
#23 0x00007ffff7d2f666 in Leviathan::Graphics::RegisterCreatedWindow(Leviathan::Window&) (this=this@entry=0x633e50, window=...) at /home/hhyyrylainen/Projects/Leviathan/Engine/Rendering/Graphics.cpp:502
#24 0x00007ffff7c58c11 in Leviathan::Window::Window(Leviathan::Graphics*, Leviathan::AppDef*) (this=0xa7c8e0, windowcreater=0x633e50, windowproperties=<optimized out>) at /home/hhyyrylainen/Projects/Leviathan/Engine/Window.cpp:125
#25 0x00007ffff7c503ea in Leviathan::Engine::Init(Leviathan::AppDef*, Leviathan::NETWORKED_TYPE, Leviathan::NetworkInterface*) (this=this@entry=0x626800, definition=0x549fa0, ntype=<optimized out>, packethandler=packethandler@entry=0x63d8f0) at /home/hhyyrylainen/Projects/Leviathan/Engine/Engine.cpp:376
#26 0x00007ffff7d15b1c in Leviathan::LeviathanApplication::Initialize(Leviathan::AppDef*) (this=this@entry=0x7fffffffd820, configuration=configuration@entry=0x549fa0) at /home/hhyyrylainen/Projects/Leviathan/Engine/Application/Application.cpp:48
#27 0x0000000000404faf in main(int, char**) (argcount=0, args=0x7fffffffda20) at /home/hhyyrylainen/Projects/Leviathan/Editor/Main.cpp:214
(gdb) 

Edit 3: I cleared out the shader files and reinstalled them and now it gets past that. Only to fail in RenderWindowManager::instance()._update();
because of this line: SPtr<RenderWindow> primaryWindow = gCoreApplication().getPrimaryWindow(); as I don’t have a CoreApplication object.

After commenting that out I can run the rendering loop. Next I’ll need to try to get something rendered on the window or try to get the existing window using working.