• 12
• 12
• 9
• 10
• 13
• ### Similar Content

• 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.
• By abarnes
Hello All!
I am currently pursuing a degree in video game programming, so far I have completed an intro to programming course and object oriented programming course. Both were taught using C++ as the programming langauge which I know is very popular for game development, but in these classes we do not actually do any game development. I would like to start to build my skills with C++ for game development as that is a common required thing for a job and am looking for ways to do this. Any recommendations such as books to read or youtube videos to watch will be greatly appreciated!
• By Orella
I'm having problems rotating GameObjects in my engine. I'm trying to rotate in 2 ways.
I'm using MathGeoLib to calculate maths in the engine.
First way: Rotates correctly around axis but if I want to rotate back, if I don't do it following the inverse order then rotation doesn't work properly.
e.g:
Rotate X axis 50 degrees, Rotate Y axis 30 degrees -> Rotate Y axis -50 degrees, Rotate X axis -30 degrees. Works.
Rotate X axis 50 degrees, Rotate Y axis 30 degrees -> Rotate X axis -50 degrees, Rotate Y axis -30 degrees. Doesn't.

Code:
void ComponentTransform::SetRotation(float3 euler_rotation) { float3 diff = euler_rotation - editor_rotation; editor_rotation = euler_rotation; math::Quat mod = math::Quat::FromEulerXYZ(diff.x * DEGTORAD, diff.y * DEGTORAD, diff.z * DEGTORAD); quat_rotation = quat_rotation * mod; UpdateMatrix();  } Second way: Starts rotating good around axis but after rotating some times, then it stops to rotate correctly around axis, but if I rotate it back regardless of the rotation order it works, not like the first way.

Code:
void ComponentTransform::SetRotation(float3 euler_rotation) { editor_rotation = euler_rotation; quat_rotation = math::Quat::FromEulerXYZ(euler_rotation.x * DEGTORAD, euler_rotation.y * DEGTORAD, euler_rotation.z * DEGTORAD); UpdateMatrix();  }
Rest of code:
#define DEGTORAD 0.0174532925199432957f void ComponentTransform::UpdateMatrix() { if (!this->GetGameObject()->IsParent()) { //Get parent transform component ComponentTransform* parent_transform = (ComponentTransform*)this->GetGameObject()->GetParent()->GetComponent(Component::CompTransform); //Create matrix from position, rotation(quaternion) and scale transform_matrix = math::float4x4::FromTRS(position, quat_rotation, scale); //Multiply the object transform by parent transform transform_matrix = parent_transform->transform_matrix * transform_matrix; //If object have childs, call this function in childs objects for (std::list<GameObject*>::iterator it = this->GetGameObject()->childs.begin(); it != this->GetGameObject()->childs.end(); it++) { ComponentTransform* child_transform = (ComponentTransform*)(*it)->GetComponent(Component::CompTransform); child_transform->UpdateMatrix(); } } else { //Create matrix from position, rotation(quaternion) and scale transform_matrix = math::float4x4::FromTRS(position, quat_rotation, scale); //If object have childs, call this function in childs objects for (std::list<GameObject*>::iterator it = this->GetGameObject()->childs.begin(); it != this->GetGameObject()->childs.end(); it++) { ComponentTransform* child_transform = (ComponentTransform*)(*it)->GetComponent(Component::CompTransform); child_transform->UpdateMatrix(); } } } MathGeoLib: Quat MUST_USE_RESULT Quat::FromEulerXYZ(float x, float y, float z) { return (Quat::RotateX(x) * Quat::RotateY(y) * Quat::RotateZ(z)).Normalized(); } Quat MUST_USE_RESULT Quat::RotateX(float angle) { return Quat(float3(1,0,0), angle); } Quat MUST_USE_RESULT Quat::RotateY(float angle) { return Quat(float3(0,1,0), angle); } Quat MUST_USE_RESULT Quat::RotateZ(float angle) { return Quat(float3(0,0,1), angle); } Quat(const float3 &rotationAxis, float rotationAngleRadians) { SetFromAxisAngle(rotationAxis, rotationAngleRadians); } void Quat::SetFromAxisAngle(const float3 &axis, float angle) { assume1(axis.IsNormalized(), axis); assume1(MATH_NS::IsFinite(angle), angle); float sinz, cosz; SinCos(angle*0.5f, sinz, cosz); x = axis.x * sinz; y = axis.y * sinz; z = axis.z * sinz; w = cosz; } Any help?
Thanks.

# C++ Material-Pipeline-Mesh Architecture

## Recommended Posts

Hey guys, so as I'm revamping my entire rendering system, I decided to go by an object-centric draw cycle to a pipeline-centric one. So basically I bind pipelines, then materials, then the mesh, rather than the buffers for the entire model and then go looking for the pipeline. I'm having issues designing the architecture for this. I figured I'd have:

MaterialSystem:
vector<RenderPassContainer>
map<string, Pipeline *>
map<string, Material *>

RenderPassContainer:
RenderPassObject
vector<PipelineContainer>

PipelineContainer:
PipelineObject
vector<Material>

Material:
TextureBinding (group of textures)
vector<Mesh *>

Mesh:
BaseVertix
BaseIndex
NumIndices
Material *

So the issue here is that when I create new materials, the map and all pointers are pointing to the wrong area in memory. Any ideas for a better architecture? Keep in mind I need to: Add Materials, Add Pipelines, Add meshes Remove Meshes (and materials and pipelines if there are no instances left), and Update materials and pipelines at runtime. Thanks!

##### Share on other sites

If I'm understanding the problem, anytime you mess with the vectors of RenderPassContainer, PipelineContainer or Material, you are going to have a bunch of invalid pointers correct?  I.e. this is the standard problem of iterator invalidation after modification in most stl containers.

There are a number of ways around the issue but you need to clarify your intentions.  The first and easiest, if you don't need the content to be contiguous in memory, is to remove ownership from the containers and use pointers instead.  The extra indirection solves the problem for the most part at a minimal cost, given that this sort of thing is a couple hundred times a frame, it should have limited to no noticeable overhead.

A second solution which is a bit more complicated but maintains the linear memory layout would be not using pointers but instead use indexes into the arrays.  Adding new items will work without problems, removing items just means walking through all the vectors looking for indices >= the removed item and erasing it or subtracting one.  This means that you need to move the add/remove interface to a top level owner of all the vectors so it can iterate them, but that's generally a good idea to centralize the API anyway.

The third solution is even a little more complicated but has properties which I needed in my system.  I extend the index idea by adding a version tag to each index.  Since I'm promising myself I will never have more than 65k materials in the system at any given time, this handle is a simple 32 bit value, 16 bits of index and 16 bits of version.  Now, when I go to get the material via the handle, I first check that the version stored in the handle and the version in the slot match, if not I return nullptr.  If the callers gets a nullptr they look up the material by hash and assuming is still exists they fix their internal handle.  The reason for this solution is that I only ever add/remove things dynamically in tools or debug builds and the whole check and re-fetch thing compiles out to nothing in release, but it is still fast enough that debug builds are not hobbled by a bunch of overhead.

Again though, this all circles back to what are the requirements for you.  I'd personally start with the second solution as it is easy, fast and leaves the important properties of your layout in place.  The third solution is not suggested unless you start doing a lot of hot reloading, which is why I wanted it.

##### Share on other sites
2 hours ago, Hiwas said:

If I'm understanding the problem, anytime you mess with the vectors of RenderPassContainer, PipelineContainer or Material, you are going to have a bunch of invalid pointers correct?  I.e. this is the standard problem of iterator invalidation after modification in most stl containers.

There are a number of ways around the issue but you need to clarify your intentions.  The first and easiest, if you don't need the content to be contiguous in memory, is to remove ownership from the containers and use pointers instead.  The extra indirection solves the problem for the most part at a minimal cost, given that this sort of thing is a couple hundred times a frame, it should have limited to no noticeable overhead.

A second solution which is a bit more complicated but maintains the linear memory layout would be not using pointers but instead use indexes into the arrays.  Adding new items will work without problems, removing items just means walking through all the vectors looking for indices >= the removed item and erasing it or subtracting one.  This means that you need to move the add/remove interface to a top level owner of all the vectors so it can iterate them, but that's generally a good idea to centralize the API anyway.

The third solution is even a little more complicated but has properties which I needed in my system.  I extend the index idea by adding a version tag to each index.  Since I'm promising myself I will never have more than 65k materials in the system at any given time, this handle is a simple 32 bit value, 16 bits of index and 16 bits of version.  Now, when I go to get the material via the handle, I first check that the version stored in the handle and the version in the slot match, if not I return nullptr.  If the callers gets a nullptr they look up the material by hash and assuming is still exists they fix their internal handle.  The reason for this solution is that I only ever add/remove things dynamically in tools or debug builds and the whole check and re-fetch thing compiles out to nothing in release, but it is still fast enough that debug builds are not hobbled by a bunch of overhead.

Again though, this all circles back to what are the requirements for you.  I'd personally start with the second solution as it is easy, fast and leaves the important properties of your layout in place.  The third solution is not suggested unless you start doing a lot of hot reloading, which is why I wanted it.

Thanks for the input. I was afraid that'd be the answer though. The first is impractical due to cache misses and the second is a lot of processing. I hadn't thought of the third but it sounds quite a lot like the second. I do plan on hot swapping but it's not a big priority. It can take even a couple seconds without it being a problem since it should happen rarely.

Anyways, after reading your post I came up with a better solution. Like two except when removing a material, I just swap it with the last one. This means I'll need to store the pipeline and render pass id's as well, but c'est la programming.