Editor style Grid SceneNode [Updated: Sept. 27, 2009]
-
- Posts: 1638
- Joined: Mon Apr 30, 2007 3:24 am
- Location: Montreal, CANADA
- Contact:
-
- Posts: 34
- Joined: Sat Mar 08, 2008 12:46 pm
- Location: Germany, FFM
- Contact:
i just tested it and it worked. had a few warnings with values beeing initialized to late, but it worked
looks nice, i was about to write one myself those days, but i think i will use yours, so i can waste my time on other projects.
looks nice, i was about to write one myself those days, but i think i will use yours, so i can waste my time on other projects.
if life could only be written in C++...
so much features, money++, remove_childs(), choose parents, life = new life, and no more <IDIOT> templates !
if you're looking for an nerdy coding language: http://lolcode.com/
so much features, money++, remove_childs(), choose parents, life = new life, and no more <IDIOT> templates !
if you're looking for an nerdy coding language: http://lolcode.com/
-
- Posts: 368
- Joined: Tue Aug 21, 2007 1:43 am
- Location: The Middle of Nowhere
Damn! You did a great job! I'm using this in my level editor for sure!
I was trying to do someting like it with this piece of code:
But your SceneNode is much faster, and has more options! Great work!
I was trying to do someting like it with this piece of code:
Code: Select all
c8 i, j;
for (i=0; i!=64; i++)
for (j=0; j!=64; j++) {
driver->draw3DLine (core::vector3df (j, i, 0), core::vector3df (j, i+1, 0) );
driver->draw3DLine (core::vector3df (j+1, i, 0), core::vector3df (j+1, i+1, 0) );
driver->draw3DLine (core::vector3df (j, i, 0), core::vector3df (j+1, i, 0) );
driver->draw3DLine (core::vector3df (j, i+1, 0), core::vector3df (j+1, i+1, 0) );
}
Warnings
I got some warnings with GCC 4.1.2:
So, here's the patch:
Code: Select all
src/ext/CGridSceneNode.h:127: warning: ‘CGridSceneNode::m_accentlineoffset’ will be initialized after
src/ext/CGridSceneNode.h:126: warning: ‘irr::video::SColor CGridSceneNode::m_accentgridcolor’
src/ext/CGridSceneNode.h:26: warning: when initialized here
Code: Select all
src/ext/CGridSceneNode.h:133:34: warning: no newline at end of file
Code: Select all
wittus@hell ~/Projects/Irrlicht/ext $ diff -Naur CGridSceneNode.h CGridSceneNode_fixed.h
--- CGridSceneNode.h 2008-09-29 18:59:17.560709357 +0300
+++ CGridSceneNode_fixed.h 2008-09-29 18:59:21.432713933 +0300
@@ -25,8 +25,8 @@
u32 spacing = 8, u32 size = 1024, SColor gridcolor = SColor(255,128,128,128), u32 accentlineoffset = 8,
SColor accentgridcolor = SColor(255,192,192,192), bool axislinestate = false) : ISceneNode(parent_rootSceneNode, smgr, id),
m_spacing(spacing), m_size(size),
- m_gridcolor(gridcolor), m_accentlineoffset(accentlineoffset),
- m_accentgridcolor(accentgridcolor), m_AxisLineState(axislinestate),
+ m_gridcolor(gridcolor), m_accentgridcolor(accentgridcolor),
+ m_accentlineoffset(accentlineoffset), m_AxisLineState(axislinestate),
m_XLineColor(SColor(255,255,0,0)), m_ZLineColor(SColor(255,0,0,255))
{
// Set the material
@@ -131,3 +131,4 @@
};
#endif // __C_GRID_SCENE_NODE_H__
+
-
- Posts: 368
- Joined: Tue Aug 21, 2007 1:43 am
- Location: The Middle of Nowhere
Dark_Kilauea, very useful scene node as i've probably mentioned before in this thread. I've been using it in my latest project and i decided to optimise the rendering a tad, so here's an updated version which you may or may not be interested in putting on the front page in some way!
Basically in your version you're doing a call to driver->draw3DLine() for each line of the grid which doesn't give the best performance as it's a lot of draw calls which are vulnerable to stalls. So i've just wacked all the necessary vertices into a big buffer in the constructor so that in the render function you can just render them all in one draw call, should be quite a performance boost!
CGridSceneNode.h
CGridSceneNode.cpp
Basically in your version you're doing a call to driver->draw3DLine() for each line of the grid which doesn't give the best performance as it's a lot of draw calls which are vulnerable to stalls. So i've just wacked all the necessary vertices into a big buffer in the constructor so that in the render function you can just render them all in one draw call, should be quite a performance boost!
CGridSceneNode.h
Code: Select all
#ifndef INC_CGRIDSCENENODE_H
#define INC_CGRIDSCENENODE_H
// Original Author: Dark_Kilauea
// Optimised by: JP
// From: http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=24938
#include <irrlicht.h>
using namespace irr;
class CGridSceneNode : public scene::ISceneNode
{
public:
//Setting accentlineoffset to 0 causes accentlines to not be rendered.
//If you need a grid on the XY or ZY axis, simply rotate this node by 90 degrees in the appropiate axis.
//This node creates an XZ grid by default, which should be fine for normal use.
CGridSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id = -1, u32 spacing = 4, u32 size = 128, video::SColor gridcolor = video::SColor(255,0,200,0), s32 accentlineoffset = 8, video::SColor accentgridcolor = video::SColor(255,0,255,0));
//Inherited from ISceneNode
virtual void OnRegisterSceneNode();
virtual void render();
virtual const core::aabbox3d<f32>& getBoundingBox() const;
virtual u32 getMaterialCount();
virtual video::SMaterial& getMaterial(u32 i);
//Various Gets
s32 GetSpacing();
s32 GetSize();
video::SColor GetGridColor();
s32 GetAccentlineOffset();
video::SColor GetAccentlineColor();
//Various Sets
void SetSpacing(s32 newspacing);
void SetSize(s32 newsize);
void SetGridColor(video::SColor newcolor);
void SetAccentlineOffset(s32 newoffset);
void SetAccentlineColor(video::SColor newcolor);
private:
//These are mine! All Mine!
core::aabbox3d<f32> Box;
video::SMaterial Material;
u32 m_spacing;
u32 m_size;
video::SColor m_gridcolor;
video::SColor m_accentgridcolor;
s32 m_accentlineoffset;
video::S3DVertex* m_vertexBuffer;
u16* m_indexBuffer;
u32 m_numLines;
u32 m_numVertices;
};
#endif /* INC_CGRIDSCENENODE_H */
Code: Select all
#include "CGridSceneNode.h"
// Original Author: Dark_Kilauea
// Optimised by: JP
// From: http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=24938
//Setting accentlineoffset to 0 causes accentlines to not be rendered.
//If you need a grid on the XY or ZY axis, simply rotate this node by 90 degrees in the appropiate axis.
//This node creates an XZ grid by default, which should be fine for normal use.
CGridSceneNode::CGridSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, u32 spacing, u32 size, video::SColor gridcolor, s32 accentlineoffset, video::SColor accentgridcolor) : scene::ISceneNode(parent, mgr, id)
{
//Set the material
Material.Wireframe = false;
Material.Lighting = false;
Material.Thickness = 1;
Material.FogEnable = false;
//Set our internal variables to match the constructor
m_spacing = spacing;
m_size = size;
m_gridcolor = gridcolor;
m_accentlineoffset = accentlineoffset;
m_accentgridcolor = accentgridcolor;
//Create our box, it is the size of the grid exactly, plus 1 in the Y axis
Box = core::aabbox3df(-(s32)size/2.0f,-1.0f,-(s32)size/2.0f,size/2.0f,1.0f,size/2.0f);
m_numVertices = ((m_size / m_spacing) + 1) * 2 * 2;
if (m_accentlineoffset) m_numVertices += ((m_size / (m_spacing * m_accentlineoffset)) + 1) * 2 * 2;
m_numLines = m_numVertices / 2;
m_vertexBuffer = new video::S3DVertex[m_numVertices];
m_indexBuffer = new u16[m_numVertices];
//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 vertIndex = 0;
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;
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++;
}
//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;
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++;
}
//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;
m_vertexBuffer[vertIndex++] = video::S3DVertex(start, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f));
m_vertexBuffer[vertIndex++] = video::S3DVertex(end, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f));
m_indexBuffer[indexIndex] = indexIndex++;
m_indexBuffer[indexIndex] = 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;
m_vertexBuffer[vertIndex++] = video::S3DVertex(start, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f));
m_vertexBuffer[vertIndex++] = video::S3DVertex(end, core::vector3df(0,1,0), m_accentgridcolor, core::vector2df(0.0f, 0.0f));
m_indexBuffer[indexIndex] = indexIndex++;
m_indexBuffer[indexIndex] = indexIndex++;
}
}
}
//Pre-Register stuff
void CGridSceneNode::OnRegisterSceneNode()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
//Render our grid of 3D lines
void CGridSceneNode::render()
{
video::IVideoDriver* driver = SceneManager->getVideoDriver();
//Prep to render
driver->setMaterial(Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawVertexPrimitiveList(m_vertexBuffer, m_numVertices, m_indexBuffer, m_numLines, video::EVT_STANDARD, scene::EPT_LINES);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
//Returns our lovely bounding box
const core::aabbox3d<f32>& CGridSceneNode::getBoundingBox() const
{
return Box;
}
//Returns the total number of materials, in this case, only 1
u32 CGridSceneNode::getMaterialCount()
{
return 1;
}
//Returns the only material
video::SMaterial& CGridSceneNode::getMaterial(u32 i)
{
return Material;
}
//Returns the Spacing of the grid
s32 CGridSceneNode::GetSpacing()
{
return m_spacing;
}
//Returns the total size of the grid
s32 CGridSceneNode::GetSize()
{
return m_size;
}
//Returns the offset of the accent lines
s32 CGridSceneNode::GetAccentlineOffset()
{
return m_accentlineoffset;
}
//Returns the Accent Line Color
video::SColor CGridSceneNode::GetAccentlineColor()
{
return m_accentgridcolor;
}
//Returns the Grid Color
video::SColor CGridSceneNode::GetGridColor()
{
return m_gridcolor;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
//Sets Spacing
void CGridSceneNode::SetSpacing(s32 newspacing)
{
m_spacing = newspacing;
}
//Sets Size
void CGridSceneNode::SetSize(s32 newsize)
{
m_size = newsize;
}
//Sets the color of the accent lines
void CGridSceneNode::SetAccentlineColor(video::SColor newcolor)
{
m_accentgridcolor = newcolor;
}
//Sets the offset for the accent lines
void CGridSceneNode::SetAccentlineOffset(s32 newoffset)
{
m_accentlineoffset = newoffset;
}
//Sets the general grid color
void CGridSceneNode::SetGridColor(video::SColor newcolor)
{
m_gridcolor = newcolor;
}
-
- Posts: 168
- Joined: Sun Feb 04, 2007 3:30 pm
- Location: France
-
- Posts: 368
- Joined: Tue Aug 21, 2007 1:43 am
- Location: The Middle of Nowhere
Thanks JP for your optimization, I took your ideas and modified them a little. Now the vertex data is stored in a mesh buffer, making it simpler (at least for me) to understand where all the data is stored.
I also made it possible to regenerate the grid, as well as having the SetFoo() functions that modify the grid automatically regenerate the buffer. I also included a few minor bug fixes, like moving the node to the irr::scene namespace to remove those nasty using namespace declarations.
I highly recommend that past users update to this version.
I also made it possible to regenerate the grid, as well as having the SetFoo() functions that modify the grid automatically regenerate the buffer. I also included a few minor bug fixes, like moving the node to the irr::scene namespace to remove those nasty using namespace declarations.
I highly recommend that past users update to this version.
rogerborg wrote:Every time someone learns to use a debugger, an angel gets their wings.
Shocking!
Shows how much attention i paid to your code, i didn't realise there were setter methods to adjust the grid! lol
Storing it in a mesh buffer may be a sort of cleaner method i suppose, a bit safer perhaps! Basically does the same job but wrapped up nicely and if the mesh buffer got optimised in future or something then it would make this code better too!
Shows how much attention i paid to your code, i didn't realise there were setter methods to adjust the grid! lol
Storing it in a mesh buffer may be a sort of cleaner method i suppose, a bit safer perhaps! Basically does the same job but wrapped up nicely and if the mesh buffer got optimised in future or something then it would make this code better too!
-
- Posts: 168
- Joined: Sun Feb 04, 2007 3:30 pm
- Location: France
-
- Posts: 368
- Joined: Tue Aug 21, 2007 1:43 am
- Location: The Middle of Nowhere
Hi there is a bug (compile error), I think it's 1.5 related: Line 185 in the cpp file
change from
to
I'm so proud
change from
Code: Select all
driver->drawVertexPrimitiveList(Buffer.getVertices(), Buffer.getVertexCount(), Buffer.getIndices(), Buffer.getVertexCount()/2, video::EVT_STANDARD, scene::EPT_LINES);
Code: Select all
driver->drawVertexPrimitiveList(Buffer.getVertices(), Buffer.getVertexCount(), Buffer.getIndices(), Buffer.getVertexCount()/2, video::EVT_STANDARD, scene::EPT_LINES, video::EIT_16BIT);
-
- Posts: 368
- Joined: Tue Aug 21, 2007 1:43 am
- Location: The Middle of Nowhere
Hmm... that may be tricky to fix. If I add that last parameter to drawVertexPrimitiveList( ... ), then any Irrlicht version before 1.5 will be broken by it. I do find it strange that drawVertexPrimitiveList( ... ) does not have a default parameter of video::EIT_16BIT for backwards compatibility?
rogerborg wrote:Every time someone learns to use a debugger, an angel gets their wings.