• Advertisement


  • Content count

  • Joined

  • Last visited

Community Reputation

887 Good


About nickyc95

  • Rank

Personal Information

  • Interests
  1. C++ OOP and DOD methodologies

    Thanks for that I have seen that presentation before and it's one of the better ones in my opinion. Initially I did interpret it as anti-oop but I understand what you mean - there are different "levels" of DOD. Many of the talks I have seen tend to cram the "No More Virtuals!" as the major point (which I can understand). The main points to take away from it is: Organise your data so that its contiguous in memory (avoid jumping around, better cache use) (better performance) Avoid virtual (if possible) when writing performance code (avoids the lookups and allows better inline-ability) (even better)
  2. C++ OOP and DOD methodologies

    Interesting.. Do people typically do that? (use DOD when writing performance code and OOP for other things) I only ask because a lot of the existing engines (open source) / people in industry either love or hate each one and will use a single technique pretty much exclusively. It also seems a little weird that you would have two pretty distinct techniques used in the same project.. Im curious Thanks
  3. C++ OOP and DOD methodologies

    Sorry - Data Oriented Design I'll update the main post too
  4. Hi. I'm kind of late to this party but I thought I would ask anyway as I haven't found a concrete answer. When creating a game engine, when should you choose one methodology over another (more specifically OOP and DOD)? Which areas benefit from DOD? Which areas benefit from OOP? Do people typically mix multiple methodologies throughout a project? I.e. certain sub-systems created in one, and others in the another? DOD - Data Oriented Design OOP - Object Oriented Design Pretty simple Thanks
  5. OK cool, thats pretty much what I thought. Having had some free time to look into this type of system, I have a few more questions: How do you handle draws that need to be done in a specified order? My current thought are with things like Post-Processing where you might need to do things in a specific order (Draw Bloom, then draw DOF (definitely a bad example but hopefully you understand, also please correct me if my thinking is wrong / this would never be an issue)) How do you clear your render targets? How do you ensure that happens before you render? Do you explicitly do it before rendering your DrawItems (via the RenderPipeline)? How do you update your Uniforms / Constant buffers? Are they part of the DrawItem and get set when drawing that item? How would you handle Compute in this system? Is a DrawItem a Base class for other Render Operations / is it derived from some GPUCommand class that can be used to submit different commands? That all for now Thanks
  6. Thats fair I've read through your presentation previously and had a quick glance over it again recently. From what I gather: You gather all the visible objects You build a list of DrawItems - which basically contain all the data for a single draw call (state, resources, vertex data) Sort the draw items Renderer executes the DrawItems (all at once at the end of a frame?) Is that a good simplified example of what your engine does? Also, does your engine use this for all type of drawing? i.e. Model, UI, Particles etc
  7. Hi, I posted on here a while back about rendering architecture and came away with some great information. I am planning on implementing a render queue which collects the visible objects in the scene and sorts them based on different criteria to minimise state change etc.. The thing I am currently undecided about is: what is the best way to submit my draw calls? (I am wanting to support both OpenGL and Vulkan) At the moment I have two ideas for how I can handle it. The renderable handles the rendering (i.e. It calls renderContext->BindVertexBuffer(...) etc) and setup the renderer state Pro- Each renderable is full in control of how it renders Con - Have to manually manage state The renderable pushes RenderCommands (DrawMesh, DrawMeshIndexed etc) into a CommandBuffer that gets executed by the RenderBacked at the end of the frame Pro - Stateless Con - Seems more difficult to extend with new features Pro/Con - The front end only has a subset of rendering capabilities There are more pros / cons for each, but I have listed a couple to help show my thinking.. Any one have any comments on either of these two approaches or any other approaches that are typically used? Thanks
  8. Asynchronus Resource Manager

    Yeah pretty much like that, except in your version there's no point in having the allocate callback as you don't make use of the allocated memory in anyway. You read the file into your own in-memory buffer and then pass your buffer to the factory in the completion callback. What I do is stream the file directly into the factory's allocation, and then notify the factory once this operation is complete. //THREAD 1 size_t allocSize = calcAllocSize(filepath); void* data = factory.allocate(handle, allocSize); FileStream f = fs.open(filepath); f.read(data, allocSize); //Loads all the data from the file into memory //MAIN THREAD - Callback from thread 1 factory.onCompletion(handle, data); //Deserializes the data to construct the resource //Resource is now ready to use & handle is populated I try to structure most of my formats so that there is minimal deserialization required, and most of them deserialize in-place without extra allocations. When in-place deserialization isn't possible, then the memory allocated in factory.allocate will be released during factory.onCompletion. Each material may use a different shader, and each shader may declare a different amount of uniform variables and textures. That means that different materials can greatly differ in size :) Off topic but FWIW, I don't store individual materials as assets, instead I have a "material pack" asset. Each model file will likely contain many materials (for different parts of the model), so when importing a model from an artist, it generates a material-pack asset to go alongside that model's geometry asset. Internally on Windows I use the native async file system API (see the lpOverlapped parameter of ReadFileEx)... however, this API still sometimes blocks on occasion (I think when you have too many async operations in flight), so whenever I need to call one of those functions I push a job to a background thread / thread pool so that the main thread(s) won't stall. The main thread(s) poll the blob loader once per frame to check if any file streaming operations have completed, and if so the completion callbacks are triggered (so these happen on the main threads). However, I limit the number of callbacks that can be called per frame, again to avoid stalling the main threads, as certain deserialization operations can be expensive. I plan to develop a system where each factory can provide a hint of how expensive it's callbacks are to help the blob loader manage this. When I create a blob loader, I pass it an enum value of which kind of implementation I'd like it to create internally (local loose files, packed archive file, remote/network file system).  I have something similar to your ResourceHandle<T>, but mine's just called Asset and is basically a union{void* ptr; ptrdiff_t id;}; The different asset types (T) implement wrappers around this common handle that let you gain access to the deserialized type in their own way. e.g. my renderer's actual texture type is TextureId, so the asset version of a texture is called TextureAsset and it has a GetId member function that returns a TextureId (this is equivalent to having ResourceHandle<TextureId>). It's only safe to call GetId once the texture has finished loading though, so there's two mechanisms to determine that. Instead of allowing you to query Assets (TexureAssets/etc) as to whether they're finished loading or not, I load all assets in batches and associate them with this batch-managing object, called an AssetScope. When loading an object, you need a factory, an asset-scope, an asset-name to load, and a blob-loader. Once you've finished adding load requests into the batch, you can call Close on the AssetScope to tell it that no more assets will be added to this batch. The first way to tell when the AssetScope is complete is to periodically poll it: struct Example { AssetScope m_assets; TextureAsset* m_foo; TextureAsset* m_bar; bool m_loaded; Example(BlobLoader& loader, TextureFactory& textureFactory) : m_loaded() { AssetName nameFoo("foo.tex"); AssetName nameBar("foo.tex"); m_foo = textureFactory.Load( nameFoo, m_assets, loader ); m_bar = textureFactory.Load( nameBar, m_assets, loader ); m_assets.Close(); } void Update() { if( m_assets.Update() == AssetScope::Loaded ) m_loaded = true; } bool Loaded() const { return m_loaded; } void Draw() { if( !m_loaded ) return; TextureId foo = m_foo->GetId(); DrawSomething(foo); } }; And the other is to register a call-back before closing the asset-scope: struct Example { AssetScope m_assets; TextureAsset* m_foo; TextureAsset* m_bar; bool m_loaded; Example(BlobLoader& loader, TextureFactory& textureFactory) : m_loaded() { m_foo = textureFactory.Load( AssetName("foo.tex"), m_assets, loader ); m_bar = textureFactory.Load( AssetName("foo.tex"), m_assets, loader ); m_assets.OnLoaded( [this](){ m_loaded = true }, Task::CurrentThread() ); // code to run on completion, and which thread to run it on m_assets.Close(); } bool Loaded() const { return m_loaded; } void Draw() { if( !m_loaded ) return; TextureId foo = m_foo->GetId(); DrawSomething(foo); } }; Fantastic!  This explains pretty much everything I needed to know, thanks for taking the time to write it  :D If I have any more questions, I'll post them here  :P   Thanks @Hodgman
  9. Asynchronus Resource Manager

    This is pretty much what I want to support. I looked through your post on the other thread and have a few questions. Do you run a single thread for this system or is it part of a larger thread pool? How do you handle the different file types (archives, etc)? Would your system work something similar to the following: //MAIN THREAD ResourceHandle<T> handle; pushAsyncRequest(handle, filepath, factory); return handle; //THREAD 1 size_t allocSize = calcAllocSize(filepath); void* data = factory.allocate(allocSize); FileStream f = fs.open(filepath); MemoryStream mem(f); //Loads all the data from the file into memory //MAIN THREAD - Callback from thread 1 factory.onCompletion(mem); //Deserializes the data to consturct the resource //Resource is now ready to use & handle is populated  Could you provide more detail on how you system is laid out (particularly in terms of async loading, i.e. how does your system take the initial sys.m_materialFactory.Load call and output a Material) If you are using a Material factory to load a material, wont all materials be the same size? What does the measuring stage actually do because wouldn't you just need to allocate a new Material then read the uncompressed data into it? Please let me know if I am missing something  :P   Thanks 
  10. Asynchronus Resource Manager

    Thats interesting, thanks! Didn't realise it was a similar topic (because of the title). The approach that I have listed is similar to what Hodgman posted (#12). 
  11. Hi, So I am building a resource manager for my engine and I have currently gotten stumped as to what approach to take with regards async behaviour. I have an idea at the moment but i'm not sure if it would be a good approach. (I will just post the ideas for async as it will be very similar for non-async)   Approach Request to the resource manager to load a file asynchronously  Check the file isn't loaded / already loading  The resource manager creates a new AsyncFileRequest with a callback to load the data from the file, this request is placed in a queue that is handled by the file manager. When the manager picks up the request, it will open the disk file (possibly loaded into a memory stream asynchronously) Then calls the callback so that the data can be extracted from the file and the resource can "load" itself using that data   What are your thoughts and suggestions? How do you architect an Async resource manager   Thanks   ** Can a Mod change the title to be spelt correctly please: Asynchronous Resource Manager **
  12. Hi guys,   So I need a game idea that involves objects that can attract and repel from the player.     This needs to be a project that could be completed within a few weeks time frame.   Either 2d or 3d       Thanks
  13. OpenGL Shader Permutations

    Thank you, this is what I needed to know.   Don't know where I got UBOs being in 4.5, must have been something else I was looking at..   EDIT: I remember what it was now... I was looking at compute shaders, which are only available on 4.3+    Thanks 
  14. OpenGL Shader Permutations

      How can you do this?   When you add the uniforms to the shader you have to specify a shader program 
  15. OpenGL Shader Permutations

      So how would I get around this?     Thanks for input btw :)
  • Advertisement