Mesh Component

Correct, changing size requires that you create a new buffer and copy over existing values.

You get the buffer (dmBuffer::GetBytes()) or stream (dmBuffer::GetStream())as a C array and ready/write to it. Example:

1 Like

Modifying the length of the buffer hasn’t really been something we’ve thought of I must admit.
In general recreating the buffer is usually enough, but is generally not done every frame.

Alternative is ofc to create degenerate triangles at the end of the buffer, which allows the graphics driver to cull those triangles.

2 Likes

Ah! Sorry, I didn’t read enough! :man_facepalming: Perfect, thanks!


@Mathias_Westerdahl What do you mean by “degenerate triangles” exactly? That’s exactly what I was hoping for: some way to tell it to not use some part of the buffer. In practice it seems to cost the same no matter what is in the buffer. Using a buffer with only zeros costs the same as one full of real data.

Profiler with buffer with only zeros (60k verts)

Profiler with filled buffer (60k verts)

[Edit] OK, I tested it again at higher resolution and it did cost substantially less while empty. I guess that makes sense, it still has to go through all the vertices and cull them, and just saves time it would have spent in the fragment shader.

1 Like

A degenerate triangle is a triangle that covers no pixels, i.e. it is a segment (two equal vertices, a different vertex) or a point (three equal vertices).

3 Likes

Another approach would be not to increase the buffer size each line draw, but to double it when you run out of space. That way, you spread out the reallocations in increasingly rare steps.

2 Likes

Another question about mesh component.
May someone explain me how to get an independet instances of mesh buffer?
What I mean: if you create an object with mesh, then another object with the same mesh (same buffer), etc. Then if modify any stream in this buffer you modify all instances of mesh at once.
Example:

On this example, green meshes are simple GO on scene, but brown ones created by factory. The only one object has an update function with vertex position modificator.

I tried to create Go with meshes by factory, no result.
Tried to create a new buffer by buffer.create. The same result.

The only way to create fully unique mesh is copy file of original buffer and set it to other mesh component. But in this case you can’t create unique instances by factory (All objects will have the same buffer).

What I missed?
Simple project to reproduce: test.zip (8.8 KB)

@Mathias_Westerdahl ?

1 Like

+1 on this. This is how we’re handling it for now (but it’s not pretty):

2 Likes

The thing is that resource.set_buffer(res, new_buffer) sets the resource named res to the contents of buffer.

If all mesh components use the same resource (in you case /main/quad.bufferc), you’ll get the scenario you now have.

As Marius hinted, there’s a way around this, by declaring resources for future use, as resource properties in your script. You can set such a resource, and then call go.set(mesh_url, "vertices", res) to change the resource that the mesh component uses.

Ideally, soon we’ll have a way to be able to create some resources on-the-fly. It’s not something we’ve had on the roadmap yet though, and I wouldn’t want to rush into making such an api, but I can see some benefits to it for very dynamic content.

5 Likes

Thanks! Now I understand that I missed the resource managment guide.

Seems resource.buffer() has not presented here:


and in the editor autocomplete too:
2020-06-25_17-35-29

3 Likes

@dapetcu21 Now that I wanted to add the missing documentation, I wonder how you actually use that anonymous buffer?

When I use this code, I get an error, since it cannot find the resource (the hash is empty):

go.property("my_buffer", resource.buffer())
function init(self)
	print("BUFFER", self.my_buffer)
	go.set("#mesh", "vertices", self.my_buffer)
end
2 Likes

yes, get an error:
go.set failed with error code -10

2 Likes

Those buffers properties are connected to some .buffer JSON files in the editor. In my case I don’t need to write into the buffers, I just use them as input for some mesh vertices (and for some manual collision calculations), but in @Dragosha’s case he could just create a bunch of files with empty data and do resource.set_buffer() on them.

:partying_face:

it’s ok, just need to keep in mind. Also need to remembering that each mesh component requires to one drawcall.

2 Likes

How to set a shader constant for Mesh?

I found this way:

msg.post("#mesh", "set_constant", {name_hash = hash("tint"), value = vmath.vector4(0.5, 0.5, 0.5, 0.5)})

Is it right?

I noticed that we do not have this documented. @JCash?

1 Like

To set shader constants, use go.set().

If the docs are missing, we’ll need to update them.
The ”set_constant” message is deprecated.

3 Likes

@Mathias_Westerdahl
Hi, there is an issue when create a mesh through a factory: original mesh blinks on the first frame at zero coordinate and going to set position on the next frame only.

See on center of this screencast (“prefab” doesn’t blink every time, because video didn’t captured at 60fps)

local p = vmath.vector3(x, y, z)
factory.create("#factory", p)
5 Likes

Thanks!
I’ll look into it!

Same here:

  timer.delay(0.2, true, function(self)
    local x = (math.random() - 0.5) * 2
    local y = (math.random() - 0.5) * 2
    local m = factory.create("#factory", vmath.vector3(x * 500, y * 300, 0))
  end)
5 Likes

Thanks for reporting.
We have a fix for this (#5051) coming in the next release.

9 Likes