[2.3] color individual wire of mesh

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
nqdev
Gnoblar
Posts: 20
Joined: Sun Sep 09, 2018 12:59 am

[2.3] color individual wire of mesh

Post by nqdev »

I've created a large static wireframe manual object, very much like the ApiUsage tutorial DynamicGeometry. What I'm looking to do is change the color of some of the wires on a mesh and not sure of the best way to go about doing so.

Currently I do item->setDatablock() with an HlmsUnlitDatablock to change the color of the entire mesh, but in this case I'm looking to change the color of a single edge/wire within the mesh.

I was curious to know if anyone else had done this or had suggestions on the best way to go about it.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: [2.3] color individual wire of mesh

Post by dark_sylinc »

If you are using HlmsUnlit (HlmsPbs does not support this) you can use vertex colours.

just add another semantic to your vertex format:

Code: Select all

vertexElements.push_back( VertexElement2( VET_UBYTE4, VES_DIFFUSE ) );
and use an uint32 to represent your RGBA colour per vertex:

Code: Select all

struct MyVertex
{
   float position[4];
   uint32 colour;
};

myVertex[i].colour = ColourValue( r, g, b, a ).getAsRGBA();
You can use a float4 to represent your RGBA colour, but that's usually overkill and takes 4x as much memory per vertex.

This will only work if the material attached to your object is Unlit, as Pbs will not handle vertex colour as colour information.
nqdev
Gnoblar
Posts: 20
Joined: Sun Sep 09, 2018 12:59 am

Re: [2.3] color individual wire of mesh

Post by nqdev »

I've managed to change the color of my manual object by adding the new color field to the Vertex along with

Code: Select all

vertexElements.push_back( VertexElement2( VET_UBYTE4, VES_DIFFUSE));
However, I'm wondering how a single edge of a triangle is changed on an already created manual object and I'm guessing that recreating the static mesh (i.e., create mesh, create submesh, fill data, etc...) is not the way, seems inefficient.

Is there a way to query a Mesh, identify just the elements and then which edge of the element to change? Something more efficient when displaying a large mesh?
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5433
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1341

Re: [2.3] color individual wire of mesh

Post by dark_sylinc »

I'm not sure what you're asking so I'll try to cover most possibilities:

1. You have e.g. 10.000 lines and you only want 4 lines being coloured.
You can either:

a. Make all lines have colour. Wastes a bit more of VRAM but may not really matter

b. Use 2 submeshes. One with 9.996 uncoloured lines, another submesh with 4 lines coloured (no matter which colour). Needs 2 drawcalls (more CPU usage) but avoids wasting VRAM. Also if you have 1 Million uncoloured lines, it may make a difference.

2. You have 10.000 coloured lines, but you want to change the colour of 4 lines. You think re-uploading 10.000 lines is wasteful.
You can either:

a. Reupload everything again. Sometimes this is the fastest route unless you have to modify 200 vertices out of a mesh made of 10 million vertices.

b. Use BT_DEFAULT (you can't use BT_DYNAMIC_* buffers for this). Whenever you identify which lines have changed, use buffer->upload( newData, elementStart, elementCount ) to reupload a partial region. You can issue more than one call.
This is great for modifying single vertices.
But if you want to modify e.g. 3000 vertices, do not make 3000 upload() calls. Sometimes it's better to re-upload an entire segment. For example if your mesh is 30.000 vertices; and vertices in range [100;400) are dirty but only the even vertices are dirty (i.e. odd vertices do are not dirty); do not issue 150 upload() calls. It's just better to call upload() once reuploading all 300 vertices with buffer->upload( newData, 100, 300 );

I hope this answer your question

Cheers
Matias