[Solved] Need help computing indices

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.

[Solved] Need help computing indices

Postby randomMesh » Fri May 19, 2017 8:03 pm

Hi,

i try to render a cube in a mesh buffer. It should be possible to remove arbitrary faces during the construction of this buffer, e.g. render the cube with only the right face. (The construction method is called every frame).

Minimal compilable example to render all faces:
cpp Code: Select all
 
#include <irrlicht.h>
 
int main()
{
    irr::IrrlichtDevice* const device = irr::createDevice(
            irr::video::EDT_OPENGL);
    if (!device)
        return 1;
 
    irr::video::IVideoDriver* const driver = device->getVideoDriver();
    irr::scene::ISceneManager* const smgr = device->getSceneManager();
 
    smgr->addCameraSceneNode(0, irr::core::vector3df(0.5, 0.5, -2));
 
    irr::video::SMaterial material;
    material.Lighting = false;
 
    irr::video::ITexture* const texture = driver->getTexture(
            "./irrlicht-svn/media/wall.bmp");
    if (texture)
        material.setTexture(0, texture);
 
    const unsigned int numIndices = 36;
    const unsigned short indices[numIndices] =
    {
        //front
        0, 2, 1,
        0, 3, 2,
 
        //right
        1, 5, 4,
        1, 2, 5,
 
        //back
        4, 6, 7,
        4, 5, 6,
 
        //left
        7, 3, 0,
        7, 6, 3,
 
        //top
        9, 5, 2,
        9, 8, 5,
 
        //bottom
        0, 11, 10,
        0, 10, 7
    };
 
    irr::scene::SMeshBuffer buffer;
 
    irr::video::SColor color(255, 255, 255, 255);
 
    irr::f32 cubeSize = 1.0f;
    irr::f32 xPos = 0.0f;
    irr::f32 yPos = 0.0f;
 
    //0 [front, left, bottom]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos, 0, yPos, -1, -1, -1, color, 0, 1));
 
    //1 [front, right]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos + cubeSize, 0, yPos, 1, -1, -1, color, 1,
                    1));
 
    //2 [front, right, top]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos + cubeSize, 1, yPos, 1, 1, -1, color, 1,
                    0));
 
    //3 [front, left]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos, 1, yPos, -1, 1, -1, color, 0, 0));
 
    //4 [right, back]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos + cubeSize, 0, yPos + 1, 1, -1, 1, color,
                    0, 1));
 
    //5 [right, back, top]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos + cubeSize, 1, yPos + 1, 1, 1, 1, color,
                    0, 0));
 
    //6 [back, left]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos, 1, yPos + cubeSize, -1, 1, 1, color, 1,
                    0));
 
    //7 [back, left, bottom]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos, 0, yPos + cubeSize, -1, -1, 1, color, 1,
                    1));
 
    //8 [top]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos, 1, yPos + cubeSize, -1, 1, 1, color, 0,
                    1));
 
    //9 [top]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos, 1, yPos, -1, 1, -1, color, 1, 1));
 
    //10 [bottom]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos + cubeSize, 0, yPos + cubeSize, 1, -1, 1,
                    color, 1, 0));
 
    //11 [bottom]
    buffer.Vertices.push_back(
            irr::video::S3DVertex(xPos + cubeSize, 0, yPos, 1, -1, -1, color, 0,
                    0));
 
    for (irr::u32 j = 0; j < numIndices; ++j)
    {
        buffer.Indices.push_back(indices[j]);
    }
 
    while (device->run())
    {
        driver->beginScene();
 
        driver->setTransform(irr::video::ETS_WORLD, irr::core::IdentityMatrix);
        driver->setMaterial(material);
        driver->drawMeshBuffer(&buffer);
 
        smgr->drawAll();
 
        driver->endScene();
    }
 
    device->drop();
 
    return 0;
}
 


In order to render only the faces i want to, i tried this:
cpp Code: Select all
 
bool drawFront = false; //will be set with a function
bool drawRight = false;
bool drawBack = false;
bool drawLeft = false;
bool drawTop = true;
bool drawBottom = false;
 
//0 front, left, bottom
if (drawFront || drawLeft || drawBottom)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos, 0, yPos, -1, -1, -1, color, 0, 1));
}
 
//1 front, right
if (drawFront || drawRight)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos + cubeSize, 0, yPos, 1, -1,    -1, color, 1, 1));
}
 
//2 front, right, top
if (drawFront || drawRight || drawTop)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos + cubeSize, 1, yPos, 1, 1, -1, color, 1, 0));
}
 
//3 front, left
if (drawFront || drawLeft)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos, 1, yPos, -1, 1, -1, color, 0, 0));
}
 
//4 right, back
if (drawRight || drawBack)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos + cubeSize, 0, yPos + 1, 1, -1, 1, color, 0, 1));
}
 
//5 right, back, top
if (drawRight || drawBack || drawTop)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos + cubeSize, 1, yPos + 1, 1, 1, 1, color, 0, 0));
}
 
//6 back, left
if (drawBack || drawLeft)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos, 1, yPos + cubeSize, -1, 1, 1, color, 1, 0));
}
 
//7 back, left, bottom
if (drawBack || drawLeft || drawBottom)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos, 0, yPos + cubeSize, -1, -1, 1, color, 1, 1));
}
 
//8 top
if (drawTop)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos, 1, yPos + cubeSize, -1, 1, 1, color, 0, 1));
}
 
//9 top
if (drawTop)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos, 1, yPos, -1, 1, -1, color, 1, 1));
}
 
//10 bottom
if (drawBottom)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos + cubeSize, 0, yPos + cubeSize, 1, -1, 1, color, 1, 0));
}
 
//11 bottom
if (drawBottom)
{
    buffer.Vertices.push_back(irr::video::S3DVertex(
        xPos + cubeSize, 0, yPos, 1, -1, -1, color, 0, 0));
}
 
 
if (drawFront)
{
    buffer.Indices.push_back(0);
    buffer.Indices.push_back(2);
    buffer.Indices.push_back(1);
 
    buffer.Indices.push_back(0);
    buffer.Indices.push_back(3);
    buffer.Indices.push_back(2);
}
 
if (drawRight)
{
    buffer.Indices.push_back(1);
    buffer.Indices.push_back(5);
    buffer.Indices.push_back(4);
 
    buffer.Indices.push_back(1);
    buffer.Indices.push_back(2);
    buffer.Indices.push_back(5);
}
 
if (drawBack)
{
    buffer.Indices.push_back(4);
    buffer.Indices.push_back(6);
    buffer.Indices.push_back(7);
 
    buffer.Indices.push_back(4);
    buffer.Indices.push_back(5);
    buffer.Indices.push_back(6);
}
 
if (drawLeft)
{
    buffer.Indices.push_back(7);
    buffer.Indices.push_back(3);
    buffer.Indices.push_back(0);
 
    buffer.Indices.push_back(7);
    buffer.Indices.push_back(6);
    buffer.Indices.push_back(3);
}
 
if (drawTop)
{
    buffer.Indices.push_back(9);
    buffer.Indices.push_back(5);
    buffer.Indices.push_back(2);
 
    buffer.Indices.push_back(9);
    buffer.Indices.push_back(8);
    buffer.Indices.push_back(5);
}
 
if (drawBottom)
{
    buffer.Indices.push_back(0);
    buffer.Indices.push_back(11);
    buffer.Indices.push_back(10);
 
    buffer.Indices.push_back(0);
    buffer.Indices.push_back(10);
    buffer.Indices.push_back(7);
}
 


This won't work since the indices are wrong. (Imagine, only bottom face should be rendered, the indices 0, 11, 10 become 0, 2, 1 and so on).

So how to get the indices right?
Last edited by randomMesh on Sun May 21, 2017 7:31 pm, edited 2 times in total.
"Whoops..."
User avatar
randomMesh
 
Posts: 1164
Joined: Fri Dec 29, 2006 12:04 am

Re: Need help computing indices

Postby CuteAlien » Sat May 20, 2017 10:56 am

Easiest way - always push all vertices. You could even make them static (thought you would have to set IVideoDriver::setMinHardwareBufferVertexCount to a lower number or Irrlicht ignores static for such small meshbuffers).

Otherwise you would need to use one more array which remembers which index you used for which vertex (aka you write into it on push_back and read from it when using the indices).
IRC: #irrlicht on irc.freenode.net
Code snippets, patches&stuff: http://www.michaelzeilfelder.de/irrlicht.htm
Free racer created with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
User avatar
CuteAlien
Admin
 
Posts: 8136
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany

Re: Need help computing indices

Postby randomMesh » Sat May 20, 2017 11:07 am

Hi,

thank you for your answer.
CuteAlien wrote:Easiest way - always push all vertices.

I want to avoid this since this isn't the only cube. I try to render lots of them in the same buffer (no, no Minecraft clone. Really. ;) ). I just reduced the code for the sake of readability.

CuteAlien wrote:Otherwise you would need to use one more array which remembers which index you used for which vertex (aka you write into it on push_back and read from it when using the indices).

I have no clue yet how this should look like, but i'll try.
"Whoops..."
User avatar
randomMesh
 
Posts: 1164
Joined: Fri Dec 29, 2006 12:04 am


Return to Beginners Help

Who is online

Users browsing this forum: kornwaretm, Yahoo [Bot] and 1 guest