A voxel engine with Ogre

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

A voxel engine with Ogre

Post by nicolay1 »

Hey community of Ogre :D
That's my first post, I'm just begginning whith 3D and object programming so please be kind ^^ (I'm a C and web 19 years old programmer)

My problem is that, I followed a french tutorial and understood the base of Ogre, the Scene, the notion of Node, Entities, Camera, textures, ressources etc...
I would like creating a minecraft-like 3D engine so I decided to create it :)
Shame on me, I programmed it the baddest way you could programmed it (I think), in fact, it's slow with only 100*100 cubes on the screen ! :o
my code to create this evil program (please bless me ^^')
Everything is in this little part, world is defined before and contain here a 100*100*100 array, just a layer of 100*100 is filled by the 1 value (and puttend on the screen)

Code: Select all

void AppDemarrage::AfficherSol()
{
int x,y,z;
    Ogre::Entity ** cubesTab = new Ogre::Entity * [world->getNbCube()];
    Ogre::SceneNode ** cubesNodeTab = new Ogre::SceneNode * [world->getNbCube()];

    Ogre::SceneNode * mainNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

    for(z=0;z!=world->p();z++)
    {
        for(y=0;y!=world->h();y++)
        {
            for(x=0;x!=world->w();x++)
            {
                int valCase=world->getCase(x,y,z);
                int indexCase=world->ind(x,y,z);
                if(valCase!=0)
                {
                    // we create the cube
                    cubesTab[indexCase]=mSceneMgr->createEntity("cube"+intToStr(x)+"-"+intToStr(y)+"-"+intToStr(z), "cube.mesh");
                    cubesNodeTab[indexCase] = mainNode->createChildSceneNode();
                    cubesNodeTab[indexCase]->attachObject(cubesTab[indexCase]);
                    cubesNodeTab[indexCase]->setPosition(x*100,y*100,z*100);
                    // we apply the texture in function of the block's type...
                    switch(valCase)
                    {
                    case 1:
                        cubesTab[indexCase]->setMaterialName("cube");
                        break;
                    }
                }
            }
        }
    }
}
And the result :
http://hpics.li/88aacec
I know this is really dirty, I would appreciate know which direction choose to improve it, I know a little about Chunk, ManualObject, Culling... I don't know what is REALLY important.
User avatar
spacegaier
OGRE Team Member
OGRE Team Member
Posts: 4304
Joined: Mon Feb 04, 2008 2:02 pm
Location: Germany
x 135
Contact:

Re: A voxel engine with Ogre

Post by spacegaier »

Please use the forum search function! There are a lot of similar threads here already, since you are not the first person trying to use a voxel / mind-craft approach with Ogre3D ;) . You should find many useful information that way.
Ogre Admin [Admin, Dev, PR, Finance, Wiki, etc.] | BasicOgreFramework | AdvancedOgreFramework
Don't know what to do in your spare time? Help the Ogre wiki grow! Or squash a bug...
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

Re: A voxel engine with Ogre

Post by nicolay1 »

yeah I know ^^ but I really don't know what I'm looking for in fact, I am seeing this tutorial now : is it important ? http://www.ogre3d.org/tikiwiki/ManualObject
Or maybe that ^^ http://www.volumesoffun.com/polyvox-download/
... It's really not a good feeling be a newbie...
User avatar
spacegaier
OGRE Team Member
OGRE Team Member
Posts: 4304
Joined: Mon Feb 04, 2008 2:02 pm
Location: Germany
x 135
Contact:

Re: A voxel engine with Ogre

Post by spacegaier »

"Instancing" is a good search term and check out this thread for some more ideas: http://ogre3d.org/forums/viewtopic.php?f=2&t=67854
Ogre Admin [Admin, Dev, PR, Finance, Wiki, etc.] | BasicOgreFramework | AdvancedOgreFramework
Don't know what to do in your spare time? Help the Ogre wiki grow! Or squash a bug...
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

Re: A voxel engine with Ogre

Post by nicolay1 »

Thank you for that link ^^ it will be very helpful I think :) I more understand this story about ManualObject,

I have another question maybe stupid by I can't easily formulate it, Ogre is a 3D engine and I think it's a bit optimised when he show a world, I read that a cone of visibility is applied but I don't know if he display chunk which are entirely hidden by other chunck "more near" to us, I read some things about A* and understood thoses algorithm was implemented for this.
That really surprise me the fact that Ogre doesn't make it itself :o

Scuse for that really bad english, hard sentences to make :S
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: A voxel engine with Ogre

Post by Kojack »

nicolay1 wrote: I read that a cone of visibility is applied
Yep. This is called frustum culling (the frustum is the pyramid shape of the camera's view. So not a cone, but the same idea).
nicolay1 wrote:but I don't know if he display chunk which are entirely hidden by other chunck "more near" to us
This is called occlusion culling. This is a really tricky area. That's why the Umbra library that game engines often use can charge $50,000+.
Ogre doesn't have occlusion culling.
You could look into hardware occlusion culling, some people have done that with ogre, but I don't know how compatible with recent ogre it is.

Ogre does have the Portal Connected Zone Scene Manager. This is a special scene manager that uses portals for visibility. It can do a form of occlusion culling, such as if you have two rooms connected by a doorway, it won't draw the second room if the doorway isn't visible. But it's not automatic, you have to tell it all the portal data. It's not a generic real time system like Umbra.
nicolay1 wrote:I read some things about A* and understood thoses algorithm was implemented for this.
A* is a path finding algorithm used for calculating movement through a world. It has nothing to do with rendering.
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

Re: A voxel engine with Ogre

Post by nicolay1 »

Thank you very much for this answer Kojack ^^ I know more understanc problematics behind Ogre about it :)

In an other context (the voxel creation one) I have a new problem, actually I have two problem ^^' I tested two ways to improve my voxel engine and with each one there is a problem :

------------------------------------------------------------------------------------------------------------------------------------------------
- The Static Geometry one :
I create this static geometry method extracted from one of your tutoriel :

Code: Select all

Ogre::StaticGeometry * AppDemarrage::createSolStaticGeometry()
{
    Ogre::Entity *grass = mSceneMgr->createEntity("cube", Ogre::SceneManager::PT_CUBE);
    grass->setMaterialName("cube");
    Ogre::StaticGeometry *sg = mSceneMgr->createStaticGeometry("GrassArea");

    sg->setRegionDimensions(Ogre::Vector3(50*100, 50*100, 50*100));
    sg->setOrigin(Ogre::Vector3(50*100, 500, 50*100));
    for (int x = 0; x < 50; x += 1)
    {
            for (int z = 0; z < 50; z += 1)
            {
                    Ogre::Vector3 pos(x*100, x*50+z*50, z*100);
                    sg->addEntity(grass,pos);
            }
    }
    sg->build();
}
That works pretty well ! But I have a little problem... It's make a huge time rendering, when I rise the number of cube with 10000 cube I have to wait 2 or 3 second to make the staticGeometry loaded, I'm pretty sure that I'm doing the affectation of the entities to the sg wrong but I don't know how improving it...

------------------------------------------------------------------------------------------------------------------------------------------------
- The Manual Object one :
My idea was to create a geant Mesh, in the same idea that the Static Geometry method but whith Manual Object... But I have some problem to render it and i don't know why they are...
The idea is to create a method which add 12 triangle to a manual object while it 's being "drawing" (and that allow future really good optimisation in my mind), this is the method :
Array are declared as in this page (I won't create a too long post) : https://developer.mozilla.org/en-US/doc ... sing_WebGL

Code: Select all

int AppDemarrage::addCubeToManualObject(Ogre::ManualObject * manual, int scale, int x, int y, int z, int index) {
    scale/=2;
    double vertices [3*4*6] = {...};
    for(int i=0;i!=4*6;i++)
    {
        manual->position(vertices[i*3]*scale+x,vertices[i*3+1]*scale+y,vertices[i*3+2]*scale+z);
        switch(i%4)
        {
        case 0:
            manual->textureCoord(0,1);
        case 1:
            manual->textureCoord(1,1);
        case 2:
            manual->textureCoord(1,0);
        case 3:
            manual->textureCoord(0,0);
        }
    }
    int cubeVertexIndices [3*2*6] = {...};
    for(int i=0;i!=2*6;i++)
    {
        manual->triangle(cubeVertexIndices[i*3]+index,cubeVertexIndices[i*3+1]+index,cubeVertexIndices[i*3+2]+index);
    }
    return index+24;
}
That code work pretty well to render one cube but it become desatrous when I try to add more,
The code to create the big mesh :

Code: Select all

Ogre::SceneNode * AppDemarrage::createManualObject()
{
    Ogre::ManualObject* manual = mSceneMgr->createManualObject("manual");
    manual->begin("cube", Ogre::RenderOperation::OT_TRIANGLE_LIST);

    int index=0;
    for(int x=0;x!=10;x++)
    {
        index+=addCubeToManualObject(manual,100,x*100,0,0,index);
    }
    manual->end();
    mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
}
That only show cubes which number is a multiple of 2 :o
=>
Image

I'm trying to understant this tutorial to improve it : http://www.ogre3d.org/tikiwiki/tiki-ind ... ing+A+Mesh (I don't know what is the more optimised :o)
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: A voxel engine with Ogre

Post by Kojack »

One thing I spotted: addCubeToManualObject's switch statement doesn't have breaks in each case, so cases 0, 1 and 2 will fall through and run other cases too.

If you are generating voxels in a manual object, the best thing for performance is to make sure you only generate faces that are exposed to emptiness. A solid voxel surrounded on all 6 sides by solid voxels should generate no faces of it's own. That makes the code trickier, but it's much better for performance.

You might want to check out polyvox. It's a voxel support library that works with various engines (including ogre, last I saw).
http://www.volumesoffun.com/polyvox-about
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

Re: A voxel engine with Ogre

Post by nicolay1 »

break added, thank's !

It's exactly what I was going to do :D but now some cube are hidden without any tricky code so... I would prefere show those block first ^^ do you have any idea where the problem is coming from ?

I now about this library :) if I can't help myself I will use it but I want torture my brain a little more... altough, thank's for the link !
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: A voxel engine with Ogre

Post by Kojack »

Ah, spotted it.

Code: Select all

index+=addCubeToManualObject(manual,100,x*100,0,0,index);
That should be:

Code: Select all

index=addCubeToManualObject(manual,100,x*100,0,0,index);
Otherwise it's the equivalent of doing index = index + index + 24
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

Re: A voxel engine with Ogre

Post by nicolay1 »

Greate ! This is that :D I have been very stupid there ^^'
thank you very much for all the help !
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

Re: A voxel engine with Ogre

Post by nicolay1 »

Hey :D

Already a new problem ^^' it's a simple problem but I don't know how to fix it, I created a biiiiig manual object (128*128 cubes) but when I render It shadows doesn't appaers, with staticGeometry they appaers...
At the left : Manual object , At the right : Static Geometry.
Image

I tried the solution presented on this topic : http://www.ogre3d.org/forums/viewtopic. ... 86#p478686
without any success... I just make the FPS going down and cause graphic problems :/

I used :

Code: Select all

mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
and

Code: Select all

((Ogre::VertexData*)(manual->getEdgeList()->edgeGroups.at(0).vertexData))->prepareForShadowVolume();
And I checked for polyvox but how it will help me ? ^^'
Last edited by nicolay1 on Wed Mar 05, 2014 8:46 pm, edited 1 time in total.
User avatar
tod
Troll
Posts: 1394
Joined: Wed Aug 02, 2006 9:41 am
Location: Bucharest
x 94
Contact:

Re: A voxel engine with Ogre

Post by tod »

I don't see any shadow in the second picture either. You seem to be missing shading, meaning light influence, not shadows.
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

Re: A voxel engine with Ogre

Post by nicolay1 »

Ah yeah maybe ^^' but where exactly is the problem ? :o I'm wondering about the fact that I didn't calculate normal and UV, are they important to do this ? :)

Edit : that was the fact normal vertices was not defined :D

But I have another little problem :o a big square is splashed on my big mesh I don't know why... Did you have ever seen something like this ? :
Image
That's sound like an area where the diffuse light is not showed :/ ... And that move with my camera (it depends of the position but now the rotation)
Last edited by nicolay1 on Wed Mar 05, 2014 9:50 pm, edited 1 time in total.
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: A voxel engine with Ogre

Post by scrawl »

Normals are required to get correct shading. UVs are only needed if you want to texture the object.
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

Re: A voxel engine with Ogre

Post by nicolay1 »

I was wonderging about textur, I can only use one texture... So I said to myself :
Hey dude can you put all you texture in one file, use it in the material and chose the texture you want with coord ? ^^'
Is that possible and "optimised" ? ^^'

-- Do you think I have to use UV there ? ^^ and what is the words behind it ? to get the mathematics formule :)
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: A voxel engine with Ogre

Post by scrawl »

Yep that is called a "texture atlas" and it's a good way to reduce the batch count.
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

Re: A voxel engine with Ogre

Post by nicolay1 »

Thank you ! That's great !
But will I have to use UV coordinate, I can't find out what they are use for, I made some research, that deals with coordinate on texture but which ones ?

And I up for my "ugly shadow" cube ^^
User avatar
tod
Troll
Posts: 1394
Joined: Wed Aug 02, 2006 9:41 am
Location: Bucharest
x 94
Contact:

Re: A voxel engine with Ogre

Post by tod »

UV coordinates are pretty much standard stuff. Lots of tutorials. You can look at Blender tutorials, or whatever.
No idea what the cube is? It is a shadow? Do you have something that could cast that shadows?
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

Re: A voxel engine with Ogre

Post by nicolay1 »

I don't have any other entities ^^'
I now know what is it, it's a shadow, but I don't know why it's there... With a spotLight, the shadow is like this :
Image
And my code for camera / light... maybe ? ^^

Code: Select all

mCamera = mSceneMgr->createCamera("Camera");
    mCamera->setPosition(Ogre::Vector3(100*64, 50*64, 100*64));
    mCamera->lookAt(Ogre::Vector3(0,-1,0));
    mCamera->setNearClipDistance(5);
    Ogre::Viewport* vp = mWindow->addViewport(mCamera);
    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));

    mCamera->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));

    mSceneMgr->setAmbientLight(Ogre::ColourValue(1, 1, 1));

    mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_ADDITIVE);

    Ogre::Light * light=mSceneMgr->createLight("directionalLight");
    light->setType(Ogre::Light::LT_DIRECTIONAL);
    light->setPosition(Ogre::Vector3( 3200, 2000, 3200 ));
    light->setDirection(1,-1,1);
    light->setDiffuseColour(Ogre::ColourValue(1, 1, 1));
And I don't have any problem like this when I use static geometry... I'm using manual object int the wrong way again --"

My code creating the manual object :

Code: Select all

Ogre::SceneNode * AppDemarrage::createManualObject()
{
    Ogre::ManualObject* manual = mSceneMgr->createManualObject("manual");
    manual->begin("textureAtlas", Ogre::RenderOperation::OT_TRIANGLE_LIST);

    bitmap_image image("heightmap.bmp");
    unsigned char red;
    unsigned char green;
    unsigned char blue;

    int index=0;
    float textPose=0;
    for(int x=0;x!=64;x++)
    {
        for(int z=0;z!=64;z++)
        {
            image.get_pixel(x,z,red,green,blue);
            if(red<50)textPose=0;
            else if(red<150)textPose=2.0/3.0;
            else textPose=1.0/3.0;
            index=addCubeToManualObject(manual,100,x*100,red*10,z*100,textPose,index);
        }
    }
    manual->end();
    //((Ogre::VertexData*)(manual->getEdgeList()->edgeGroups.at(0).vertexData))->prepareForShadowVolume();

    Ogre::SceneNode * node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    node1->attachObject(manual);
}
My code adding cube to this manual object :

Code: Select all

int AppDemarrage::addCubeToManualObject(Ogre::ManualObject * manual, int scale, int x, int y, int z, float textPos, int index) {
     //https://developer.mozilla.org/en-US/docs/Web/WebGL/Creating_3D_objects_using_WebGL
    //http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Generating+A+Mesh
    scale/=2;
    float textStep=1.0/3.0;
    const float sqrt13 = 0.577350269f;
    double normal [3*6*4] = {
        0,0,1,0,0,1,0,0,1,0,0,1, // Front
        0,0,-1,0,0,-1,0,0,-1,0,0,-1, // Back
        0,1,0,0,1,0,0,1,0,0,1,0, // Top
        0,-1,0,0,-1,0,0,-1,0,0,-1,0, // Bottom
        1,0,0,1,0,0,1,0,0,1,0,0, //Right
        -1,0,0,-1,0,0,-1,0,0,-1,0,0, // Left
    };
    double vertices [3*4*6] = {
    // Front face
    -1.0, -1.0,  1.0, // 4
     1.0, -1.0,  1.0, // 5
     1.0,  1.0,  1.0, // 7
    -1.0,  1.0,  1.0, // 6
    // Back face
    -1.0, -1.0, -1.0, // 0
    -1.0,  1.0, -1.0, // 2
     1.0,  1.0, -1.0, // 3
     1.0, -1.0, -1.0, // 1
    // Top face
    -1.0,  1.0, -1.0, // 2
    -1.0,  1.0,  1.0, // 6
     1.0,  1.0,  1.0, // 7
     1.0,  1.0, -1.0, // 3
    // Bottom face
    -1.0, -1.0, -1.0, // 0
     1.0, -1.0, -1.0, // 1
     1.0, -1.0,  1.0, // 5
    -1.0, -1.0,  1.0, // 4
    // Right face
     1.0, -1.0, -1.0, // 1
     1.0,  1.0, -1.0, // 3
     1.0,  1.0,  1.0, // 7
     1.0, -1.0,  1.0, // 5
    // Left face
    -1.0, -1.0, -1.0, // 0
    -1.0, -1.0,  1.0, // 4
    -1.0,  1.0,  1.0, // 6
    -1.0,  1.0, -1.0  // 2
    };
    for(int i=0;i!=24;i++)
    {
        manual->position(vertices[i*3]*scale+x,vertices[i*3+1]*scale+y,vertices[i*3+2]*scale+z);
        manual->normal(normal[i*3],normal[i*3+1],normal[i*3+2]);
        switch(i%4)
        {
        case 0:
            manual->textureCoord(textPos,1);
            break;
        case 1:
            manual->textureCoord(textPos+textStep,1);
            break;
        case 2:
            manual->textureCoord(textPos+textStep,0);
            break;
        case 3:
            manual->textureCoord(textPos,0);
            break;
        }
    }
    int faces [3*2*6] = {
    0,  1,  2,      0,  2,  3,    // front
    4,  5,  6,      4,  6,  7,    // back
    8,  9,  10,     8,  10, 11,   // top
    12, 13, 14,     12, 14, 15,   // bottom
    16, 17, 18,     16, 18, 19,   // right
    20, 21, 22,     20, 22, 23    // left
    };
    for(int i=0;i!=12;i++)
    {
        manual->triangle(faces[i*3]+index,faces[i*3+1]+index,faces[i*3+2]+index);
    }
    return index+24;
}
nicolay1
Gnoblar
Posts: 12
Joined: Thu Feb 27, 2014 12:15 am

Re: A voxel engine with Ogre

Post by nicolay1 »

This is not an up :roll: anyone answering so I thing my problem was too random, I would like express my feeling about it :

This is a textured shadow problem, and it have a strong link with the camera beacause it move with it, so how camera and textured shadow would be connected ? Is there is any connection ? Maybe a sort of big cube around the camera where textured shadow arn't apply ? I don't have so much idea :/
Post Reply