[SOLVED] merging MeshBuffers / sharing them with many Meshes

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
arrival
Posts: 8
Joined: Mon Feb 27, 2012 9:50 am
Location: Poland

[SOLVED] merging MeshBuffers / sharing them with many Meshes

Post by arrival »

Hi.
I barely started using Irrlicht and I'm having an issue with managing meshes data.
I was trying to copy one mesh to the other one by appending ones mesh buffer to the others. But it looks like its not working.
I used CDynamicMeshBuffer::append( CDynamicMeshBuffer* _mbuff ). I digged thru Irrlicht source code and I was unable to find any implementation of this method. Is it purely virtual, future planned?

Code snipped:

Code: Select all

        scene::IMesh* planeMesh = smgr->getGeometryCreator()->createPlaneMesh(core::dimension2df( TILE_SIZE, TILE_SIZE), core::dimension2d<u32>(1, 1), 0, core::dimension2df(1, 1) );
        planeMesh->setHardwareMappingHint(scene::EHM_STREAM);
        
        scene::SMesh* templateMesh = new scene::SMesh();
        scene::CDynamicMeshBuffer* mybuf = 0;
        if(!templateMesh->getMeshBufferCount()) {
                printf("> Creating new dynamic mesh buffer.\n");
                mybuf = new scene::CDynamicMeshBuffer(planeMesh->getMeshBuffer(0)->getVertexType(), planeMesh->getMeshBuffer(0)->getIndexType());
                templateMesh->addMeshBuffer(mybuf);
        }
        scene::IMeshSceneNode* newNode = smgr->addMeshSceneNode(templateMesh);
        newNode->setPosition(core::vector3df(240,0,250));
        newNode->setMaterialTexture(0, driver->getTexture("./world.png"));
        newNode->setMaterialFlag( video::EMF_BILINEAR_FILTER, false);
        newNode->setMaterialFlag(video::EMF_LIGHTING, false);
        newNode->setMaterialType(video::EMT_SOLID);
 
        printf("\n> Vertex count in buffer: %i\n", templateMesh->getMeshBuffer(0)->getVertexCount() );
        printf("> Merging with buffer containing: %i vertices\n", planeMesh->getMeshBuffer(0)->getVertexCount() );
 
        mybuf->append(planeMesh->getMeshBuffer(0));             //NOT IMPLEMENTED??
        //templateMesh->getMeshBuffer(0)->append( planeMesh->getMeshBuffer(0) );        //does not work either
 
        templateMesh->getMeshBuffer(0)->setDirty();
        printf("> Merged buffer vertex count: %i\n", templateMesh->getMeshBuffer(0)->getVertexCount() );
Output log:
  • Irrlicht Engine version 1.8.0-alpha
    Microsoft Windows 7 Professional Edition Service Pack 1 (Build 7601)
    WGL_extensions: WGL_ARB_extensions_string WGL_ARB_pixel_format WGL_ATI_pixel_for
    mat_float WGL_ARB_pixel_format_float WGL_ARB_multisample WGL_EXT_swap_control WG
    L_EXT_swap_control_tear WGL_ARB_pbuffer WGL_ARB_render_texture WGL_ARB_make_curr
    ent_read WGL_EXT_extensions_string WGL_ARB_buffer_region WGL_EXT_framebuffer_sRG
    B WGL_ATI_render_texture_rectangle WGL_EXT_pixel_format_packed_float WGL_I3D_gen
    lock WGL_NV_swap_group WGL_ARB_create_context WGL_AMD_gpu_association WGL_AMDX_g
    pu_association WGL_ARB_create_context_profile WGL_NV_float_buffer
    Pixel Format: 2
    Using renderer: OpenGL 3.3.11318
    ATI Radeon HD 3600 Series: ATI Technologies Inc.
    OpenGL driver version is 1.2 or better.
    Free texture memory (kB): 219320
    Free VBO memory (kB): 219320
    Free render buffer memory (kB): 219320
    GLSL version: 3.3
    Could not load sprite bank because the file does not exist: #DefaultFont
    > Creating new dynamic mesh buffer.
    Loaded texture: C:/.../visual studio 2010/Projects/IrrHello/Irr
    Hello/world.png

    > Vertex count in buffer: 0
    > Merging with buffer containing: 4 vertices
    > Merged buffer vertex count: 0

    Resizing window (1280 720)
As you can see from the log no vertices were copied. But why?
Thanks in advance.
Last edited by arrival on Thu Mar 15, 2012 11:22 am, edited 2 times in total.
Mel
Competition winner
Posts: 2293
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: merging Mesh Buffers

Post by Mel »

CDynamicMesh doesn't have implemented append method. Use a SMeshBuffer instead.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: merging Mesh Buffers

Post by smso »

Mesh combiner might be useful for reference. Search in the forum.

Regards
smso
arrival
Posts: 8
Joined: Mon Feb 27, 2012 9:50 am
Location: Poland

Re: merging Mesh Buffers

Post by arrival »

What does "Dynamic" means than?

CMeshBuffer::virtual void append(const IMeshBuffer* const other) is also not implemented ( commented out, actually - unstable? ), but
CMeshBuffer::virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) is, and it seams to be working fine.
I've found CBatchingMesh but it looks rather like an agregation of multiple buffers under one scene node and not buffers merger. I will look closer to the mesh combiner.

Thanks.
arrival
Posts: 8
Joined: Mon Feb 27, 2012 9:50 am
Location: Poland

Sharing single Mesh Buffer.

Post by arrival »

Hi. I'm back.

I was doing many appends to CMeshBuffer in runtime, and I find it veary slow, because of memory reallocation triggered every time.
Since irr::core::array allows us to choose ALLOC_STRATEGY there should be

Code: Select all

if( Vertices.allocated_size() < vertexCount+numVertices )
just before reallocation, to make this strategy usefull here.
Original code (without allocated memory check):

Code: Select all

 
                virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices)
                {
                        if (vertices == getVertices())
                                return;
 
                        const u32 vertexCount = getVertexCount();
                        u32 i;
                        Vertices.reallocate(vertexCount+numVertices);
                        for (i=0; i<numVertices; ++i)
                        {
                                Vertices.push_back(reinterpret_cast<const T*>(vertices)[i]);
                                BoundingBox.addInternalPoint(reinterpret_cast<const T*>(vertices)[i].Pos);
                        }
 
                        Indices.reallocate(getIndexCount()+numIndices);
                        for (i=0; i<numIndices; ++i)
                        {
                                Indices.push_back(indices[i]+vertexCount);
                        }
                }
 
Ofcourse there is a walkaround for this by writing own buffer appending function.

I have a single Scene Node ( tile map ) containing many tiles (ommiting tile chunks - buffers). Since there isn't many different tiles i thought I need just few mesh buffers shared across many tiles ( SMeshes ).
But since the only scene node added to Scene Manager is whole map, and SMeshes does not have their individual positions, all tiles sharing the same buffer are being rendered in the same position (coord taken directly form shared mesh buffer). Any idea how to solve this problem. To put it simple I need to render many objects sharing the same Mesh buffer without adding them all as Scene Nodes to be able to set their positions.

Scene Manager must be doing some temporary translations just before rendereing if Meshes sharing the same Buffers are being put into scene as Scene Nodes, so there must be a way.

[EDIT]
Ok, I solved it by storing each tiles translation matrix, and by setting correct transformation matrix in video driver before each tile is being rendered. And of course transforming temporarily each meshes buffer before its being appended to chunks mesh buffer.
Memory consuption dropped down a bit but still even with chunks rendered instead each individual tile I'm limited by framerate. Probably because of to many triangles on the screen.
Post Reply