Irr1.8c++| How can i project a useable grid on to my Terrain

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.
STTrife
Posts: 33
Joined: Sun Jan 13, 2013 3:43 pm

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by STTrife »

Don't know if it matters to you but I'm guessing that you now draw 4 lines for each cell? That would mean you are drawing a lot of double lines if you draw the whole grid like that. If that's the case then you might consider making it draw only 2 lines per cell, except for the cells at the end.
shader idea is much faster, but you need to know how to write and implement shaders :)
Ultraporing
Posts: 34
Joined: Tue Nov 06, 2007 7:22 pm
Location: Würzburg, Germany

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by Ultraporing »

I dont know how to write and implement shaders :(.

I cant even get my ISceneNode class working :(.
I basicly copied the constructor from the CGridSceneNode but everytime I try to use it like this:

Code: Select all

 
//CGridSceneNode* grid = new CGridSceneNode(scnMgr->getRootSceneNode(), scnMgr);
EDE_GridSceneNode* gridS = new EDE_GridSceneNode(scnMgr->getRootSceneNode(), scnMgr);
 
You see I use it like CGridSceneNode, I get a compiler error saying: "error C2259: 'EDE_GridSceneNode':Instance of a abstract class can't be created".
I translated the error since I use a german VS2010.

Can you please take a look and help me resolve this?
Thank you

EDE_GridSceneNode.h
http://ideone.com/dlqpsA

EDE_GridSceneNode.cpp
http://ideone.com/E68YhA
STTrife
Posts: 33
Joined: Sun Jan 13, 2013 3:43 pm

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by STTrife »

if you make your own scenenode you HAVE to implement some functions that it needs... they are OnRegisterSceneNode, render, getBoundingBox, getMaterialCount and getMaterial.

see http://irrlicht.sourceforge.net/docu/example003.html for an example. they are not hard to implement.

I don't fully understand why there is no default version of OnRegisterSceneNode, but the other functions:
render - need to make your own render code
getBoundingBox - you need to make your own bounding box
getMaterialCount - you need to let it know how much materials it uses
getMaterial - you need to return a material

those functions do not have a default implementation because yeah... render is obvious, you make your own node so you need to render it yourself. bounding box is used for frustum culling, but since you do your own scenenode you also have to specify what the bounding box is...
I guess they could have made some default system for a single material scenenode but they didn't so you can just use the stuff from the example if you have a single material.
Ultraporing
Posts: 34
Joined: Tue Nov 06, 2007 7:22 pm
Location: Würzburg, Germany

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by Ultraporing »

Thank you for your help, I draw now a flat grid :).
Can you please explain how did you mean draw only 2 lines? i have no idea how to make this work :O

Image

Can i get somehow the dimensions of the terrainNode? X and Z axis. I need to know how big it is.
Ultraporing
Posts: 34
Joined: Tue Nov 06, 2007 7:22 pm
Location: Würzburg, Germany

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by Ultraporing »

Ok this is what I got so far, but if I increase the terrain size or make the cells smaller and got around 4k*4k cells i get some wiered mlock.h (std::bad_alloc) error while initializing the 2DArray.
And when I reduce the cell count to arount 400*400 my frames go to nearly 0.

It also renders more cells a than the Terrain is wide and then they drop into infinity. I need to get somehow the real dimensions of the terrain but i dont know how. I use a highmap and use the bounding box to get the terrain size which is inacurate.

Image

can you please help me improve the grid rendering to get more performance and maybe avoid this.

#Edit: I think I get the alloc error because the array gets too large with 4k*4k cells which are 16 Million cells. Now is the question what to do about it.


Current Code and How I use it atm:

EDE_GridSceneNode.cpp
http://ideone.com/5Sr5DI

EDE_GridSceneNode.h
http://ideone.com/iysrsD

How I use it atm:

Code: Select all

 
ITerrainSceneNode* scnNode = scnMgr->addTerrainSceneNode(
        "heightmap.bmp",
        scnMgr->getRootSceneNode(),
        -1,                 // node id
        core::vector3df(0.f, 0.f, 0.f),     // position
        core::vector3df(0.f, 0.f, 0.f),     // rotation
        core::vector3df(4.f, 1.0f, 4.f),  // scale
        video::SColor ( 255, 255, 255, 255 ),   // vertexColor
        5,                  // maxLOD
        scene::ETPS_17,             // patchSize
        4                   // smoothFactor
        );
 
    scnNode->setMaterialFlag(video::EMF_LIGHTING, false);
    scnNode->setMaterialTexture(0, videoDrv->getTexture("free-grass-texture-013.jpg"));
    vector3d<f32> *ed = new vector3d<f32>[8];
    for (int i = 0; i < 8; i++)
    {
        ed[i] = vector3d<f32>((f32) 0);
    }
 
    scnNode->getTransformedBoundingBox().getEdges(ed);
 
    int w = floor(ed[4].X - ed[0].X);
    int h = floor(ed[2].Z - ed[0].Z);
    
    //ITriangleSelector* triSel = scnNode->getTriangleSelector();
    
    //CGridSceneNode* grid = new CGridSceneNode(scnMgr->getRootSceneNode(), scnMgr);
    EDE_GridSceneNode* gridS = new EDE_GridSceneNode(scnNode, scnMgr);
    gridS->init(w, h, SColor(255, 255, 255, 255), vector3df(0.0f, 0.0f, 0.0f), 10.0f);
    gridS->createGridOnTerrain(scnNode);
 
STTrife
Posts: 33
Joined: Sun Jan 13, 2013 3:43 pm

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by STTrife »

As far as I know, the terrainnode treats every pixel in the bitmap as a heightpoint. So if the bmp = 100x100, then you have 99x99 cells.
What you can do is read the bmp as a texture (see loading texture tutotials) and get the width and height from there. (cells = width-1 etc.)

not sure about the malloc. You should be able to make an array with 4000 pointers without getting a malloc I think? try debugging and finding the exact line it gives an error, and what the witdth and height etc. are at that point. probably something going wrong there :)

For speed: you should reduce the number of drawing calls per frame. You now call 4 drawLines per cell, per frame, and for each cell you also call setmaterial and settransform stuff, which are not neccesary. In fact you should't try to draw each cell seperatly. You can still keep the cell-class and objects if you need them for other stuff ofcourse.

You should take a look at drawVertexPrimitiveList, using either EPT_LINE_STRIP , or EPT_LINES. If you use linestrips, the idea is that you could draw a grid of 100x100 height points with 200 line strips. 100 horizontal linestrips and 100 vertical linestrips. that would be 200 draw calls per frame. In your way you make 99x99 = 9801 cells, which all use 4 calls is 39204 calls
so 200 vs 39204 should make quit a difference.
If you don't understand what I mean, try to draw a 3x3 grid for playing that game with the cross and circles (don't know the english name). you don't draw each cell seperatly but you draw 3 lines vertically and 3 horizontally. (if you want to close the cells like in your project, you would draw 4 lines).

If you use EPT LINES, you can do it in 1 draw call, but you will have to use more indices cause you don't reuse any. You must create an array of 99*2*99 + 99*2*99 = 39600 indices to do a 100x100 heightmap in a single call. You probably can't use that methode with huge terrains because the array will be too big.
Btw for bigger terrains, try to use chunking (diving terrain up in several terrainnodes)
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by CuteAlien »

Yeah, use drawVertexPrimitiveList - that other flat grid-scenenode is also doing that if you need an example for it. And if possible do the allocating for the grid-lines one time for the whole area instead of doing that each render-call.
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
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by hendu »

The shader approach would have only a small performance hit over rendering the terrain as is - less than 5% slower would be a decent guess. ;)

No additional draw calls, no memory overhead.
Ultraporing
Posts: 34
Joined: Tue Nov 06, 2007 7:22 pm
Location: Würzburg, Germany

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by Ultraporing »

hendu wrote:The shader approach would have only a small performance hit over rendering the terrain as is - less than 5% slower would be a decent guess. ;)

No additional draw calls, no memory overhead.
Unforuniently I dont have a clue how to use or write shaders.


Thanks for the hints I try to optimise it the way you said. Its momentarily pretty hard for me because I picked Irrlicht up at the date i posted this thread and im still learning. I did till now only 2D projects.
Ultraporing
Posts: 34
Joined: Tue Nov 06, 2007 7:22 pm
Location: Würzburg, Germany

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by Ultraporing »

Ok i draw now with vertices but how can I draw a grid with those triangles?
Now everything is white because it draws the white squares over the terrain :/
STTrife
Posts: 33
Joined: Sun Jan 13, 2013 3:43 pm

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by STTrife »

vertices != triangles.

If you call drawvertexprimitivelist, you can specify what type of primive you want to draw. triangles is just one of them. the vertices you pass are just the points of your heightgrid, and the indices are references (array-indexes) to those vertices, and depending on what type of primitive type you draw the indices are read in a certain way.

if you use line-strips, it will treat each index in the indices (referencing to a vertex) as a next point on the line. sort of connect the dots. so if you pass it all the vertices of for example a horizontal line in your grid, and you pass an array of [0,1,2,3,4,5...] as indices, it will draw a line trough all the vertices you given.

So basically, in the vertices you specify: these are the points that my 'object' is made out of, and the indices are a way of telling the graphics card/driver how to connect those vertices to form the drawing you want. in the case of traingles you connect 3 vertices, but there are also triangle fans etc if you follow/read the documention on the drawvertexprimitivelist, it will tell you how the different types of primitives work. it's quite understandable.
Last edited by STTrife on Sat Feb 02, 2013 4:50 pm, edited 1 time in total.
Ultraporing
Posts: 34
Joined: Tue Nov 06, 2007 7:22 pm
Location: Würzburg, Germany

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by Ultraporing »

STTrife wrote:vertices != triangles.

If you call drawvertexprimitivelist, you can specify what type of primive you want to draw. triangles is just one of them. the vertices you pass are just the points of your heightgrid, and the indices are references (array-indexes) to those vertices, and depending on what type of primitive type you draw the indices are read in a certain way.

if you use line-strips, it will treat each index in the indices (referencing to a vertex) as a next point on the line. sort of connect the dots. so if you pass it all the vertices of for example a horizontal line in your grid, and you pass an array of [0,1,2,3,4,5...] as indices, it will draw a line trough all the vertices you given.

So basically, in the vertices you specify: these are the points that my 'object' is made out of, and the indices are a way of telling the graphics card/driver how to connect those vertices to form the drawing you want. in the case of traingles. if you follow/read the documention on the drawvertexprimitivelist, it will tell you how the different types of primitives work. it's quite understandable.
Thank you for constantly helping me out by expaining stuff to me I should have learned before picking up Irrlicht, i mean it.
Ok now I have to figure out how to iterate over my terrain, store it in vertex arrays and draw it the right way.

You guys have helped me a lot :)
STTrife
Posts: 33
Joined: Sun Jan 13, 2013 3:43 pm

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by STTrife »

No problem :)
Ultraporing
Posts: 34
Joined: Tue Nov 06, 2007 7:22 pm
Location: Würzburg, Germany

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by Ultraporing »

I have still the problem that i get the right size of the heighmap and it is used in my gridcreation. But the patchsize of the terrain node is changeing the total terrain size so my grid calculations are off and I draw outside of the terrain.
Knows anyone how the terrain size is calculated using the patchsize?
STTrife
Posts: 33
Joined: Sun Jan 13, 2013 3:43 pm

Re: Irr1.8c++| How can i project a useable grid on to my Ter

Post by STTrife »

what do you want to know, the amount (width and height) of heighpoints? or the amount (width height) of patches, or do you want to know the total size (width height in units) of the terrain it's drawing?
Post Reply