Page 4 of 5
Posted: Thu Apr 23, 2009 1:24 pm
by Teoh
I downloaded the latest version of your grid, and i must say it looks great and it works alsmost perfect. I say almost because i came across something that doesn't work like it is supposed to.
This is the render() method. If i set the axislinestate variable false in the constructor AND set it false with the SetAxisLineActive() method. The grid still get drawn, but it is supposed to be hidden.
So i took a quick look at the render() code and i do have a question. Why even bother to set the video driver and do all the prep to render if the grid isn't drawn anyway?
I suggest you check if the m_AxisLineState variable is false before you do anything in the render() method instead of waiting until the actual call to the drive to draw a 3D line. (see the code below).
This small change might even boost the performance if the grid is not drawn, because the render() method doesn't have to do anything except check the variable.
Code: Select all
void CGridSceneNode::render()
{
// Axis Lines are only drawn if the State is true
if(m_AxisLineState)
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
//Prep to render
if(driver)
{
driver->setMaterial(Buffer.Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawVertexPrimitiveList(Buffer.getVertices(), Buffer.getVertexCount(), Buffer.getIndices(), Buffer.getVertexCount()/2, video::EVT_STANDARD, scene::EPT_LINES, video::EIT_16BIT);
driver->draw3DLine(core::vector3df((f32)m_size,0,0),core::vector3df(-(f32)m_size,0,0),m_XLineColor);
driver->draw3DLine(core::vector3df(0,0,(f32)m_size),core::vector3df(0,0,-(f32)m_size),m_ZLineColor);
}
}
}
Posted: Thu Apr 23, 2009 5:08 pm
by Dark_Kilauea
I'm afraid you misunderstood what SetAxisLineActive() is for. The idea is to control the special lines that run in the middle of the grid for denoting where x, y, or z is equal to 0, relative to the position of the grid. If you wish the entire grid to be hidden, use the standard scenenode function (setVisible()) to disable the node. That should prevent any code in the render function from executing.
Posted: Fri Apr 24, 2009 7:38 am
by Teoh
Ok, i totally missed the point there. But this does explain a lot, thnx. I was allready wondering why you were trying to implement a method allready inherited from the scenenode. But you were not.
I don't know if i'm the only who misunderstands some functions of your grid. But it might be usefull to add more comment to your code to explain these kind of idea's. Or is there some documentation (besides the comment in de code) that i also missed?
Posted: Fri Jul 31, 2009 1:03 am
by Virion
strange. this only works in debug mode. when i run my app in release mode it closes itself after launched. i comment out everything to do with the grid and my app can be opened again.
I debugged, no error found.
Posted: Fri Jul 31, 2009 10:30 am
by Dark_Kilauea
Strange, I cannot see anything in the code that would cause this issue, perhaps something else is to blame?
Posted: Fri Jul 31, 2009 3:10 pm
by psychophoniac
i once had similar problems when drawing custom scene nodes, but i dont know the circumstances, its a long time ago.
i think it has something to do with the drawPrimitiveList function.
Posted: Sat Aug 01, 2009 4:02 am
by Dark_Kilauea
Double check to make sure both the irrlicht library and your application are compiled in Release mode.
Posted: Sat Aug 01, 2009 5:38 am
by Virion
Dark_Kilauea wrote:Double check to make sure both the irrlicht library and your application are compiled in Release mode.
still the same problem

Posted: Sat Aug 01, 2009 2:19 pm
by sio2
Breakpoints at all functions of custom scene node. Run debug. Single-step as required.
Posted: Sun Aug 02, 2009 8:48 pm
by Dark_Kilauea
I cannot duplicate the bug on my end with the latest stable and svn release. I'm afraid you will have to debug this on your own. If you do find something wrong with the node, I will be happy to update it.
Posted: Sun Aug 16, 2009 10:01 pm
by vins
I just tried the Grid. It's very usefull but it craches in release mode here too. I'm using Irrlicht 1.5.1. And same is with 1.5; I did some investigation. I wasn't able to fix that yet as debugging is hard in release mode. I found that it sometimes crashes in RegenerateGrid(); I tried increasing the m_numVertices and m_numVertices with 1 and it stopped crashing there. Next it crashes at "void CGridSceneNode::render()" on the line that do the "drawVertexPrimitiveList". Vertex count in all test was between 400-600. I found that it can also crash in Debug if I set the render device to EDT_BURNINGSVIDEO. It chrashes on drawVertexPrimitiveList but it didn't crach in RegenerateGrid as it does in Release.
I don't know what to try now. I'll do more investigation and post back if I find something.
PS: I'm using MingW as a compiler.
Posted: Sun Aug 16, 2009 10:27 pm
by hybrid
The drawVertexPrimitive function is broken in the SW renderers. A fix is not simple here. Just make sure it runs with the hw drivers.
Posted: Mon Aug 17, 2009 2:23 pm
by vins
Ok I'm not sure what is the problem but I got a fix for it.
The problem seems to be in all the temporary buffers in RegenerateGrid. Maybe they get free, deleted or something. I'm not really sure but I tried to create the whole function step by step and it started crashing from the begin. I'm very confused as this only happens in Release build. At first I guess it was something wrong with me but I saw Virion has the same problem.
Anyway here is what I did:
1) Removed the m_vertexBuffer and m_indexBuffer buffers;
2) Removed Buffer.append...
3) Changed the section that checks if the arrays are created to a check if vertices are <= 65535
4) Replaced:
Code: Select all
m_vertexBuffer[vertIndex++] = video::S3DVertex(start, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f));
m_vertexBuffer[vertIndex++] = video::S3DVertex(end, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f));
m_indexBuffer[indexIndex] = indexIndex++;
m_indexBuffer[indexIndex] = indexIndex++;
with
Code: Select all
Buffer.Vertices.push_back(video::S3DVertex(start, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f)));
Buffer.Vertices.push_back(video::S3DVertex(end, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f)));
Buffer.Indices.push_back(indexIndex++);
Buffer.Indices.push_back(indexIndex++);
Irr::core::array happens to be a very usefull class - I use it all the time

So this fix the problem and it all works fine now.
So here is the whole function:
Code: Select all
void CGridSceneNode::RegenerateGrid()
{
//Clean up memory
Buffer.Indices.clear();
Buffer.Vertices.clear();
u32 m_numVertices = ((m_size / m_spacing) + 1) * 2 * 2;
if (m_accentlineoffset) m_numVertices += ((m_size / (m_spacing * m_accentlineoffset)) + 1) * 2 * 2;
if ( m_numVertices > 65535) {
//Too many vertices on 16 bit for for 16bit indices of SMeshBuffer
//Returning with a blank buffer to avoid segfaulting the entire application
return;
}
//Set our left corner
core::vector3df leftMost = core::vector3df(0,0,0);
leftMost.X -= m_size/2;
leftMost.Z -= m_size/2;
//Set our right corner
core::vector3df rightMost = core::vector3df(0,0,0);
rightMost.X += m_size/2;
rightMost.Z += m_size/2;
u32 indexIndex = 0;
//X-axis lines
for(u32 x = 0; x <= m_size; x+= m_spacing)
{
core::vector3df start = leftMost;
start.X += x ;
core::vector3df end = rightMost;
end.X = start.X;
Buffer.Vertices.push_back(video::S3DVertex(start, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f)));
Buffer.Vertices.push_back(video::S3DVertex(end, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f)));
Buffer.Indices.push_back(indexIndex++);
Buffer.Indices.push_back(indexIndex++);
}
//Z-axis lines
for(u32 z = 0; z <= m_size; z+= m_spacing)
{
core::vector3df start = leftMost;
start.Z += z ;
core::vector3df end = rightMost;
end.Z = start.Z;
Buffer.Vertices.push_back(video::S3DVertex(start, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f)));
Buffer.Vertices.push_back(video::S3DVertex(end, core::vector3df(0,1,0), m_gridcolor, core::vector2df(0.0f, 0.0f)));
Buffer.Indices.push_back(indexIndex++);
Buffer.Indices.push_back(indexIndex++);
}
//Accent lines are only drawn if the offset is greater than 0
if(m_accentlineoffset > 0)
{
//X-axis
for(u32 x = 0; x <= m_size; x+= m_spacing*m_accentlineoffset)
{
core::vector3df start = leftMost;
start.X += x ;
core::vector3df end = rightMost;
end.X = start.X;
Buffer.Vertices.push_back(video::S3DVertex(start, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f)));
Buffer.Vertices.push_back(video::S3DVertex(end, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f)));
Buffer.Indices.push_back(indexIndex++);
Buffer.Indices.push_back(indexIndex++);
}
//Z-axis
for(u32 z = 0; z <= m_size; z+= m_spacing*m_accentlineoffset)
{
core::vector3df start = leftMost;
start.Z += z ;
core::vector3df end = rightMost;
end.Z = start.Z;
Buffer.Vertices.push_back(video::S3DVertex(start, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f)));
Buffer.Vertices.push_back(video::S3DVertex(end, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f)));
Buffer.Indices.push_back(indexIndex++);
Buffer.Indices.push_back(indexIndex++);
}
}
// Create our box, it is the size of the grid exactly, plus 1 in the Y axis
Buffer.BoundingBox = core::aabbox3df(-(f32)m_size/2,-0.5f,-(f32)m_size/2,(f32)m_size/2,0.5f,(f32)m_size/2);
}
[/b]
Posted: Fri Aug 21, 2009 8:20 pm
by Dark_Kilauea
Thanks for the fix, I tested it with both the lastest stable and svn and it seems to work fine here. The node has been updated and a new link posted on the initial post.
Also the fix has an added side effect of reducing memory usage slightly.
Posted: Fri Sep 25, 2009 10:16 pm
by ceyron
Great code Dark_Kilauea and thanks for sharing but i have a little problem with it.
When active the axis lines keep flickering when i move/rotate my camera around, is it any way to prevent that?