• 15
• 15
• 11
• 9
• 10
• Similar Content

• Trying to get ideas here on how I could do this:
I have created a game for a university coursework assignment using a custom game engine (internal to my university, but it's based on OpenGL).
I know that I can use threading but am unsure how thread-safe the operation would be to init the game on another thread.

• I have a particle system with the following layout:
system / emitter / particle

particle is driven by particle data, which contains a range of over lifetime properties, where some can be random between two values or even two curves. to maintain a smooth evaluation between two ranges, i randomize a "lerp offset" on particle init and use that value when evaluating curves. the issue is that i'm using that same offset value for all properties (10ish) and as a result i'm seeing some patterns, which i'd like to remove. The obvious way is to just add more storage for floats, but i'd like to avoid that. The other way is to generate a seed of some sort and a random table, and use that to generate 10 values, ie: start with short/integer, mask it, then renormalize to float 0-1.

any other ideas?
• By dgi
Hey all ,
For a few days I'm trying to solve some problems with my engine's memory management.Basically what is have is a custom heap with pre allocated memory.Every block has a header and so on.I decided to leave it like that(not cache friendly) because my model is that every block will be large and I will have a pool allocators and stack allocators dealing with those blocks internally. So far so good I figure out how to place my per scene resources . There is one thing that I really don't know how to do and thats dealing with containers.What kind of allocation strategy to use here.
If I use vector for my scene objects(entities , cameras , particle emitters .. ) I will fragment my custom heap if I do it in a standard way , adding and removing objects will cause a lot of reallocations . If I use a linked list this will not fragment the memory but it's not cache friendly.I guess if a reserve large amount of memory for those vectors it will work but then I will waste a lot memory.I was thinking for some sort of mix between a vector and a linked list , where you have block of memory that can contain lets say 40 items and if you go over that number a new one will be created and re location of the data would not be needed.There would be some cache misses but it will reduce the fragmentation.

How you guys deal with that ? Do you just reserve a lot data ?

dgi
• By Hermetix
I am trying to setup the custom wizard for making a 3ds MAX 2018 plug-in (to export a character animation data), but I can't locate the wizard file folder to put the .vsz file in. In the 3ds MAX 2018 docs, it only mentions where the folder is in VS 2015 (VC/vcprojects). It's a VC++ project, but I don't see any folder in VC for the wizard files. I'm using VS 2017 update 15.5.6 Enterprise, and the folders in VC are: Auxiliary, Redist and Tools.

Thanks.
• By KarimIO
Hey guys! Three questions about uniform buffers:
1) Is there a benefit to Vulkan and DirectX's Shader State for the Constant/Uniform Buffer? In these APIs, and NOT in OpenGL, you must set which shader is going to take each buffer. Why is this? For allowing more slots?
2) I'm building an wrapper over these graphics APIs, and was wondering how to handle passing parameters. In addition, I used my own json format to describe material formats and shader formats. In this, I can describe which shaders get what uniform buffers. I was thinking of moving to support ShaderLab (Unity's shader format) instead, as this would allow people to jump over easily enough and ease up the learning curve. But ShaderLab does not support multiple Uniform Buffers at all, as I can tell, let alone what parameters go where.
So to fix this, I was just going to send all Uniform Buffers to all shaders. Is this that big of a problem?
3) Do you have any references on how to organize material uniform buffers? I may be optimizing too early, but I've seen people say what a toll this can take.

C++ IO approach in engine/framework

Recommended Posts

Hi,

During the journey of creating my 2nd 3D engine, I'm basing quite some of the approaches on the Game Engine Architecture book (Jason Gregory). I've now arrived on the topic: IO.
In short, the target platforms for me are PC, XBone and PS4.

With this main assumption I thought of the following logics/ guidelines to follow:

- I can assume file/folder structures will work on all 3 platforms, when I use '/' as a folder separator
-- I will define 1 global with the base folder for the application, the rest will 'inherit' from there
(which can be anything, independent of the 'mount' or drive)
-- for now I'll create 1 subfolder with data/files that might need write access, so later on I only have to worry about 1 subfolder (settings, configs etc.).
- file extensions can be longer than 3 characters (in Linux based FreeBSD on PS4)
- all class members functions needing to load a file, shouldn't have to now about the file structure of the logical application, so they will all take a full filename string including path
(combining root + subfolder + filename and separators is then the responsibility of the caller/ calling code)
- some functions will need to be passed a folder, because contents in that folder need to be read OR I can simply define a small list of defined subfolders (under root/ base), because it won't be more then 5 to 10 folders in total (data/shaders, data/textures, data/objects, data/sound etc.)

My questions:
- regarding the last point, which of the 2 options would you apply?
-- option 2 might work fine but feels a bit 'static', not very flexible (on the other hand, would you actually need flexibility here?)

Any input is appreciated, as always.

Share on other sites
52 minutes ago, cozzie said:

- all class members functions needing to load a file, shouldn't have to now about the file structure of the logical application, so they will all take a full filename string including path
(combining root + subfolder + filename and separators is then the responsibility of the caller/ calling code)
- some functions will need to be passed a folder, because contents in that folder need to be read OR I can simply define a small list of defined subfolders (under root/ base), because it won't be more then 5 to 10 folders in total (data/shaders, data/textures, data/objects, data/sound etc.)

Alternatively, you pass relative file-paths to functions, but use something like SetCurrentDirectory/chdir/... before to "fixup" the filepath. I've personally found that approach pretty viable at least for a lot of operations (ie. the asset-loader will change the current dir before scanning the content-folder for assets). You just have to make sure the change the directory back after the fact, which I decided to use a stack-based solution:

const WorkingDirectory dir(L"../Game"); // change  current directory from APPLICATION/Bin to APPLICATION/Game

{
const WorkingDirectory dir(L"Scenes"); // change to Game/Scenes
} // back to Game/

{
const WorkingDirectory dir(L"Assets"); // change to Game/Assets
} // back to Game/ again

Which is probably part of the reason why it works well for me in the first place. So this way, I seldomly have to pass a full filepath or a folder-path at all (even if I do I usually just create a WorkingDirectory-struct at the header of the function if it involves multiple file-operations, seems way cleaner to me then to string-construct all filepaths to the full-path).

Share on other sites

"I will define 1 global with the base folder for the application, the rest will 'inherit' from there" - it's not safe to assume that you can store all your read/write files in the same place as your read only files. Usually there is a different location for "program data" to that of "user data", not only because there could be more than one user accessing the same program, but for security reasons.

"file extensions can be longer than 3 characters (in Linux based FreeBSD on PS4)" - file extensions are irrelevant.

"I can simply define a small list of defined subfolders (under root/ base), because it won't be more then 5 to 10 folders in total (data/shaders, data/textures, data/objects, data/sound etc.) " - you probably do want a system like this of "well-known" locations, just don't assume they can all be located under one top level directory.

Consider Unity: it offers Application.dataPath (application data, considered read only), Application.persistentDataPath (per-user data), and Application.temporaryCachePath (scratch pad, not intended to persist). You would probably have your game assets relative to the dataPath, but configuration and settings relative to the persistentDataPath.

Share on other sites

Assuming you always want to load a whole file,instead of some part of it could be tricky, in particular if it also involves decompressing the file while reading.

(A plain archive format like tar that simply concatenates files is simpler, as you can simply seek to the correct spot, assuming the systems support file seeking.)

Share on other sites

Thanks all, this really helps.

I'm going to look into better separation of read/write and read data and maybe using the change cwd solution.

Share on other sites
On 9/24/2017 at 1:33 AM, cozzie said:

- all class members functions needing to load a file, shouldn't have to now about the file structure of the logical application, so they will all take a full filename string including path
(combining root + subfolder + filename and separators is then the responsibility of the caller/ calling code)
- some functions will need to be passed a folder, because contents in that folder need to be read OR I can simply define a small list of defined subfolders (under root/ base), because it won't be more then 5 to 10 folders in total (data/shaders, data/textures, data/objects, data/sound etc.)

Consider passing around streams instead of filenames and/or directories.

Most code only cares about accessing its data, not where it's stored or how it's organized with relation to other data, and a stream abstracts away those details. You can easily attach a stream to a disk file, a network source, a memory location, etc., or add in functionality like compression, without requiring any changes to code that only sees an I/O stream. This approach will also make archives (as @Alberth mentioned), which are fairly common in games, trivial to support.

Share on other sites

When working on console platforms PS4/XB1 your are anyways stuck to certain location you are allowed to read from and potentially another one you are allowed to read/write to for security reasons and the system model. Most engines try to go on those platforms in an async reading way and use memory mapped files to speedup I/O for vendor guideline and commit rule reasons so working with filenames is way more complicated here. Instead a stream interface working on a memory mapped page may make more sense

Share on other sites

You should not only avoid assuming all files exist within a common root, but also support a choice of multiple possible locations for various groups of writable or temporary files (e.g. saved games in the official recommended location in the user profile or in an arbitrary user-specified path on Windows, downloaded updates in a path with plenty of space and no backup) and a hierarchy of places to load read-only files from (e.g. levels from arbitrary user-selected archives, overriding user-installed packages of assets, overriding patch archives of changed and added core assets, overriding the originally shipped archive of game assets).

Note that some of these locations might not be proper files (e.g. some console-specific API for saved games and downloaded content, or virtual file systems from inside an archive); separate abstract locations and maybe names for various resource types from the lower-level concern of actual access to a file system.

Share on other sites

Thanks for the additional thoughts. Will also dig into file streams

Share on other sites
On 9/26/2017 at 3:53 PM, Zipster said:

Consider passing around streams instead of filenames and/or directories.

Most code only cares about accessing its data, not where it's stored or how it's organized with relation to other data, and a stream abstracts away those details. You can easily attach a stream to a disk file, a network source, a memory location, etc., or add in functionality like compression, without requiring any changes to code that only sees an I/O stream. This approach will also make archives (as @Alberth mentioned), which are fairly common in games, trivial to support.

One thing to be aware of with this approach is that even if the code itself doesn't care where the data is coming from, you as the programmer debugging the code probably will at some point. Debugging problems that appear only for specific assets is incredibly frustrating when you have no way to trace a particular piece of data back to its source asset. You may want to consider having at least some kind of debugging-only system that lets you do that.