[Solved]Irrlicht crashes at vertex array sized 65535?

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.
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

[Solved]Irrlicht crashes at vertex array sized 65535?

Post by pandoragami »

Hi All,

I tried compiling and running the following code several times using different sizes, once for 10000 vertices (works) and another try at the drawvertexprimitivelist buffer limit at 65535 vertices (crashes); but it crashes at the line

Code: Select all

irr::video::S3DVertex Vertices[65535];
Not sure why. The [url = http://irrlicht.sourceforge.net/docu/cl ... b3b1e2f4fb]documentation[/url] does mention the limit as 65535 vertices when using the drawvertexprimitivelist but with this crashing I can't see how that's even possible?

thanks,

P.S. Not sure why the URL link is screwed up, I did format it as advertised.

Code: Select all

 
#include <irrlicht.h>
#include <iostream>
 
using namespace irr;
 
int main()
{
    IrrlichtDevice* device = 0;
 
    device = createDevice( video::EDT_OPENGL, core::dimension2d<u32>(1280, 960));
 
    if (device == 0)
        return 1;
 
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
 
    scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS( 0, 50.0f, 0.01f, -1, 0, 0, false, 0.0f, false, true);
    cam->setPosition(core::vector3df(0,0,0));
    cam->setTarget(core::vector3df(0,0,0));
    device->getCursorControl()->setVisible(false);
 
    irr::video::SMaterial cube_material;
 
    irr::video::S3DVertex Vertices[65535];
 
     irr::u16 indices[32767];
 
 
    while(device->run())
    if (device->isWindowActive())
    {
        driver->beginScene(true, true, video::SColor(255,0,0,0));
        smgr->drawAll();
 
        cube_material.BackfaceCulling = false;
        cube_material.Wireframe = false;
        cube_material.Lighting = false;
        driver->setMaterial(cube_material);
        driver->setTransform(irr::video::ETS_WORLD, irr::core::matrix4());
        driver->drawVertexPrimitiveList( &Vertices, 4, &indices,  2, irr::video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
 
        driver->endScene();
        device->sleep(50);
    }
 
    device->drop();
 
    return 0;
}
 
Last edited by pandoragami on Thu Nov 13, 2014 7:58 am, edited 3 times in total.
ralian
Posts: 28
Joined: Tue Nov 11, 2014 1:00 am

Re: Irrlicht crashes at vertex array sized 65535?

Post by ralian »

It's not irrlicht crashing, it's the code in general. It can't cope with 65535 vertices smack dab in the middle of it. Try replacing your declaration line with something that declares the memory externally, like

Code: Select all

irr::video::S3DVertex *Vertices = (irr::video::S3DVertex*) malloc(sizeof(irr::video::S3DVertex) * 65535);
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Irrlicht crashes at vertex array sized 65535?

Post by pandoragami »

Thanks a lot works now! On another note do you know the limit of indices array that I can pass into drawvertexprimitivelist? I'm assuming that too is 65535 but not sure. Anyways I'll mark this as solved, thanks for your help.
ralian
Posts: 28
Joined: Tue Nov 11, 2014 1:00 am

Re: [solved] Irrlicht crashes at vertex array sized 65535?

Post by ralian »

Good question,
The limit is actually 4294967295, because you use a u32 to reference it in the function call. However, to have your indices
access more than 65535 vertices, you must call the function with EIT_32BIT instead of EIT_16BIT. Note that this will also
double the memory used for each index.

Hope that helps. :)
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: [solved] Irrlicht crashes at vertex array sized 65535?

Post by pandoragami »

ralian wrote:Good question,
The limit is actually 4294967295, because you use a u32 to reference it in the function call. However, to have your indices
access more than 65535 vertices, you must call the function with EIT_32BIT instead of EIT_16BIT. Note that this will also
double the memory used for each index.

Hope that helps. :)
If you can reference more than 65535 vertices using 32-bit how would it work to pass an array larger than 65535 vertices (into drawvertexprimitivelist) when the limit is 16 bit?
ralian
Posts: 28
Joined: Tue Nov 11, 2014 1:00 am

Re: [solved] Irrlicht crashes at vertex array sized 65535?

Post by ralian »

If I'm correct, you should just create your 'indices' array as an array of u32 instead of u16, then you can reference vertices past the u16 referencing limit.
Really, you shouldn't be trying to cram that many polys into a scene though, unless you're doing something graphical that will be rendered once :) You'll find
that drawing that many polygons will be quite slow.
CuteAlien
Admin
Posts: 9716
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: [solved] Irrlicht crashes at vertex array sized 65535?

Post by CuteAlien »

On a quick look I'd say the first try crashed because you passed &Vertices instead of Vertices or &Vertices[0] (just "Vertices" is a pointer to the first element, so those two are identical).

If you want to stay with EIT_16BIT and need more vertices you have to split up your mesh into smaller blocks so you can use several calls. In Irrlicht terms - you split up a mesh into meshbuffers where each meshbuffer isn't larger than 65535 vertices.

edit: And yeah - like ralian said - use u32 for EIT_32BIT.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: [solved] Irrlicht crashes at vertex array sized 65535?

Post by pandoragami »

Thanks guys so far... Now the drawvertexprimitivelist crashes for some reason. Also note the output where

index_offset32852 vertex_count: -2142076847

Somehow the variable vertex_count is "garbaged" I can't see why though. Here's the code.

It tries to draw 20k planes randomly spaced in 3d (trying to make a star grid to make it look like star trek). It works fine if

Code: Select all

irr::video::S3DVertex *Vertices = (irr::video::S3DVertex*) malloc(sizeof(irr::video::S3DVertex) * 40000);
and

Code: Select all

int vertex_limit = 20000;
are used.

Code: Select all

 
#include <irrlicht.h>
#include <iostream>
 
using namespace irr;
 
int main()
{
    IrrlichtDevice* device = 0;
 
    device = createDevice( video::EDT_OPENGL, core::dimension2d<u32>(1280, 960));
 
    if (device == 0)
        return 1;
 
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
 
    scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS( 0, 50.0f, 0.01f, -1, 0, 0, false, 0.0f, false, true);
    cam->setPosition(core::vector3df(0,0,0));
    cam->setTarget(core::vector3df(0,0,0));
    device->getCursorControl()->setVisible(false);
 
    irr::video::SMaterial cube_material;
 
     irr::video::S3DVertex *Vertices = (irr::video::S3DVertex*) malloc(sizeof(irr::video::S3DVertex) * 65535);
     irr::u16 indices[32767];
 
     int x, y, z, l;
     x = y = z = 0;
     l = 1;
 
//Bottom
     int R, G, B;
 
     R = rand()%255;
     G = rand()%255;
     B = rand()%255;
     x = rand()%200;
     y = rand()%200;
     z = rand()%200;
 
     int vertex_count = 0;
     int vertex_limit = 25000;
 
    while(vertex_count < vertex_limit)
    {
         Vertices[vertex_count] = irr::video::S3DVertex(
                        x, y, z, 1,1,0,
                        irr::video::SColor(255, R, G, B), 0, 1);
         vertex_count++;
 
         Vertices[vertex_count] = irr::video::S3DVertex(
                       x+l, y, z, 1,0,0,
                       irr::video::SColor(255, R, G, B), 1, 1);
         vertex_count++;
 
         Vertices[vertex_count] = irr::video::S3DVertex(
                       x+l, y, z+l, 0,1,1,
                       irr::video::SColor(255, R, G, B), 1, 0);
         vertex_count++;
 
         Vertices[vertex_count] = irr::video::S3DVertex(
                       x, y, z+l, 0,0,1,
                       irr::video::SColor(255, R, G, B), 0, 0);
         vertex_count++;
 
         x = rand()%200;
         y = rand()%200;
         z = rand()%200;
         R = rand()%255;
         G = rand()%255;
         B = rand()%255;
         //std::cout<<x<<","<<y<<","<<z<<" vertex_count: "<<vertex_count<<std::endl;
    };
 
    std::cout<<" vertex_count: "<<vertex_count<<std::endl;
 
    int index_count = 0;
    int index_offset = 0;
 
    while(index_offset < vertex_limit)
    {
            indices[index_count] = 0 + index_offset;
            index_count++;
            indices[index_count] = 1 + index_offset;
            index_count++;
            indices[index_count] = 2 + index_offset;
            index_count++;
            indices[index_count] = 0 + index_offset;
            index_count++;
            indices[index_count] = 2 + index_offset;
            index_count++;
            indices[index_count] = 3 + index_offset;
            index_count++;
            index_offset+=4;
    }
    std::cout<<"index_offset" <<index_offset<<" vertex_count: "<<vertex_count<<std::endl;
 
    while(device->run())
    {
        driver->beginScene(true, true, video::SColor(255,0,0,0));
        smgr->drawAll();
 
        cube_material.BackfaceCulling = false;
        cube_material.Wireframe = false;
        cube_material.Lighting = false;
        driver->setMaterial(cube_material);
        driver->setTransform(irr::video::ETS_WORLD, irr::core::matrix4());
        driver->drawVertexPrimitiveList( &Vertices[0], vertex_limit, &indices[0],  index_offset/2, irr::video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
 
        driver->endScene();
        device->sleep(50);
    }
 
    device->drop();
 
    return 0;
}
 
 
 
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: [solved] Irrlicht crashes at vertex array sized 65535?

Post by mongoose7 »

There are six indices per four vertices. 25000*6/4 = 37500. Your index array can only hold 32767. (I don't know why you want to size it to 2^n -1; I guess you are confused between size of an array and largest index.)
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: [solved] Irrlicht crashes at vertex array sized 65535?

Post by pandoragami »

mongoose7 wrote:There are six indices per four vertices. 25000*6/4 = 37500. Your index array can only hold 32767. (I don't know why you want to size it to 2^n -1; I guess you are confused between size of an array and largest index.)
Oh. Sorry I counted wrong thanks for answering so quickly.

By the way is there an easy way to add different textures to different planes and still make one buffer call. I know I can use a single texture every call by setting the SMaterial but is there a way to set the S3DVertex similarly to the position, color, etc; or are texture coordinates used for that purpose? I still wouldn't know how to load the texture and fix it to the 4 vertices, pseudocode please if possible..

thanks.
ralian
Posts: 28
Joined: Tue Nov 11, 2014 1:00 am

Re: [solved] Irrlicht crashes at vertex array sized 65535?

Post by ralian »

Honestly, if you could comment your code a bit better, that would be great ;)
However, here were some things I saw:
* Camera position and target both set to 0? That's undefined behavior, I think. If you're not using the camera, just declare it with the default values.
* Use the irrlicht logger, or at least printf, instead of cout. I mean, that's more of a recommendation, but that would make your life easier I think
* Using the irrlicht randomizer will also make your life easier
* You've also got a lot of magic numbers and things that just don't make sense to me: Why is x, y, and z declared to each other then immediately set to a random number? Comments would help clear up that sort of thing.

The actual problem is a bad reference to, seemingly, all of the irrlicht engine (the device, driver, and scene manager) that was somehow changed in the middle of the code? How was that even managed? I'll look at this more later, but I think the code needs some revising either way. I'll be happy to answer further questions, but could you please take solved out of the title while you continue to ask? You get more help if people know you aren't finished with questions :)

Best luck, ralian
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: [solved] Irrlicht crashes at vertex array sized 65535?

Post by pandoragami »

ralian wrote:Honestly, if you could comment your code a bit better, that would be great ;)
However, here were some things I saw:
* Camera position and target both set to 0? That's undefined behavior, I think. If you're not using the camera, just declare it with the default values.
* Use the irrlicht logger, or at least printf, instead of cout. I mean, that's more of a recommendation, but that would make your life easier I think
* Using the irrlicht randomizer will also make your life easier
* You've also got a lot of magic numbers and things that just don't make sense to me: Why is x, y, and z declared to each other then immediately set to a random number? Comments would help clear up that sort of thing.

The actual problem is a bad reference to, seemingly, all of the irrlicht engine (the device, driver, and scene manager) that was somehow changed in the middle of the code? How was that even managed? I'll look at this more later, but I think the code needs some revising either way. I'll be happy to answer further questions, but could you please take solved out of the title while you continue to ask? You get more help if people know you aren't finished with questions :)

Best luck, ralian

Here's the newer code.

Things considered,

*The camera position is now -10 on the z axis and looks (somewhat) at the center of field of planes.
*I kept the std::cout due to preference as this is C++, would it be better to use printf ( I never use it anywhere, std::cout has never failed me)? Never used Irrlicht logger by the way, don't even know the codes for it.
*Irrlicht randomizer is something I'll lookup but rand() should be fine for now.
*I added comments to the most important parts of the code, ask for a specific line if you're still unsure.

The bad reference was probably due to the overflow in the indices from the code where it's too small I guess. The memory segment around the indices was probably overwritten and became corrupt... maybe.

thanks.

Code: Select all

#include <irrlicht.h>
#include <iostream>
 
using namespace irr;
 
int main()
{
    IrrlichtDevice* device = 0;
 
    device = createDevice( video::EDT_OPENGL, core::dimension2d<u32>(1280, 960));
 
    if (device == 0)
        return 1;
 
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
 
    scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS( 0, 50.0f, 0.01f, -1, 0, 0, false, 0.0f, false, true);
    cam->setPosition(core::vector3df(0,0,-10));
    cam->setTarget(core::vector3df(100,100,0));
    device->getCursorControl()->setVisible(false);
 
    irr::video::SMaterial cube_material;
 
     irr::video::S3DVertex *Vertices = (irr::video::S3DVertex*) malloc(sizeof(irr::video::S3DVertex) * 65535);
     irr::u16 indices[310000];
 
     int x, y, z, l;//this initializes the positions
     x = y = z = 0;
     l = 1;
 
//Bottom
     int R, G, B;//used for coloring vertices
 
     R = rand()%255;
     G = rand()%255;
     B = rand()%255;
     x = rand()%200;
     y = rand()%200;
     z = rand()%200;
 
     int vertex_count = 0;//the counter for the vertices, 4 per face/plane
     int vertex_limit = 65500;//the total number of vertices
 
    while(vertex_count < vertex_limit)
    {
         Vertices[vertex_count] = irr::video::S3DVertex(
                        x, y, z, 1,1,0,
                        irr::video::SColor(255, R, G, B), 0, 1);
         vertex_count++;
 
         Vertices[vertex_count] = irr::video::S3DVertex(
                       x+l, y, z, 1,0,0,
                       irr::video::SColor(255, R, G, B), 1, 1);
         vertex_count++;
 
         Vertices[vertex_count] = irr::video::S3DVertex(
                       x+l, y, z+l, 0,1,1,
                       irr::video::SColor(255, R, G, B), 1, 0);
         vertex_count++;
 
         Vertices[vertex_count] = irr::video::S3DVertex(
                       x, y, z+l, 0,0,1,
                       irr::video::SColor(255, R, G, B), 0, 0);
         vertex_count++;
 
         x = rand()%200;//this reinitializes the positions (within a box of 200 irrlicht units of distance) and colors 
         y = rand()%200;
         z = rand()%200;
         R = rand()%255;
         G = rand()%255;
         B = rand()%255;
         //std::cout<<x<<","<<y<<","<<z<<" vertex_count: "<<vertex_count<<std::endl;
    };
 
    std::cout<<" vertex_count: "<<vertex_count<<std::endl;
 
    int index_count = 0;//the counter for the indices
    int index_offset = 0;//this is the offset used to keep the indices separate in the array when rendering
 
    while(index_offset < vertex_limit)
    {
            indices[index_count] = 0 + index_offset;
            index_count++;
            indices[index_count] = 1 + index_offset;
            index_count++;
            indices[index_count] = 2 + index_offset;
            index_count++;
            indices[index_count] = 0 + index_offset;
            index_count++;
            indices[index_count] = 2 + index_offset;
            index_count++;
            indices[index_count] = 3 + index_offset;
            index_count++;
            index_offset+=4;
    }
    std::cout<<"index_offset" <<index_offset<<" vertex_count: "<<vertex_count<<std::endl;
 
    while(device->run())
    {
        driver->beginScene(true, true, video::SColor(255,0,0,0));
        smgr->drawAll();
 
        cube_material.BackfaceCulling = false;
        cube_material.Wireframe = false;
        cube_material.Lighting = false;
        driver->setMaterial(cube_material);
        driver->setTransform(irr::video::ETS_WORLD, irr::core::matrix4());
        driver->drawVertexPrimitiveList( &Vertices[0], vertex_limit, &indices[0],  index_offset/2, irr::video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
 
        driver->endScene();
        device->sleep(50);
    }
 
    device->drop();
 
    return 0;
}
 
 
 
 
ralian
Posts: 28
Joined: Tue Nov 11, 2014 1:00 am

Re: Irrlicht crashes at vertex array sized 65535?

Post by ralian »

Woah, that looks cool! I didn't even know what to expect when I ran it, but now I see sort of what you were doing :mrgreen:
Thanks for fixing up some of the code for me, it's a bit clearer now.
By the way, that first point about the camera was completely my mistake x)... I didn't see that it had an animator
attached to it. That clears things up a bit

All things considered, it looks cool and works just fine. (I guess it's solved now?)
I'm still not sure what went wrong earlier, but I guess that fixed itself.

As for the Irrlicht logger, I like it because it has neat features like logging levels (warnings, errors, information, debug, etc.), and it's easy
to create a subclass of the logger that outputs custom prefixes.

Good job :) -ralian
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Irrlicht crashes at vertex array sized 65535?

Post by pandoragami »

ralian wrote:Woah, that looks cool! I didn't even know what to expect when I ran it, but now I see sort of what you were doing :mrgreen:
Thanks for fixing up some of the code for me, it's a bit clearer now.
By the way, that first point about the camera was completely my mistake x)... I didn't see that it had an animator
attached to it. That clears things up a bit

All things considered, it looks cool and works just fine. (I guess it's solved now?)
I'm still not sure what went wrong earlier, but I guess that fixed itself.

As for the Irrlicht logger, I like it because it has neat features like logging levels (warnings, errors, information, debug, etc.), and it's easy
to create a subclass of the logger that outputs custom prefixes.

Good job :) -ralian
Thanks I'll mark it as solved. I will start a different thread about creating textures for the polygon faces.
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Re: [Solved]Irrlicht crashes at vertex array sized 65535?

Post by randomMesh »

Hi,

Code: Select all

irr::video::S3DVertex *Vertices = (irr::video::S3DVertex*) malloc(sizeof(irr::video::S3DVertex) * 65535);
In C++, you never should use malloc but new:

Code: Select all

irr::video::S3DVertex *Vertices = new irr::video::S3DVertex[65535];
And there is a memory leak because you don't free the allocated memory.
Place this at the end of your code (after changing the allocation to use new:

Code: Select all

delete[] Vertices;
"Whoops..."
Post Reply