Is there a way to terminate a point with drawVertexPrimitive

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.
Post Reply
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Is there a way to terminate a point with drawVertexPrimitive

Post by pandoragami »

Hello,

What I'm trying to do is use the drawVertexPrimitiveList method with EPT_LINE_STRIP and render several polygons in different locations not adjacent to each other. I'm assuming I would have to call drawVertexPrimitiveList for each polygon in order to prevent a line connecting to different polygons set distances apart, is that correct, or is there a way to terminate each set of lines and then call drawVertexPrimitiveList to draw several polygons?

Thanks!
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Is there a way to terminate a point with drawVertexPrimi

Post by pandoragami »

I looked at this page on stackoverflow and saw a way to draw a cube with points and indices in GL. The terminating points were 1e101 with an index of -1. https://stackoverflow.com/questions/251 ... r-of-steps

Any ideas if this could work in Irrlicht with drawVertexPrimitiveList?

Code: Select all

 
 
//---------------------------------------------------------------------------
#define a 0.5
double pnt[]=
    {
    -a,-a,-a, // point 0
    -a,-a,+a,
    -a,+a,-a,
    -a,+a,+a,
    +a,-a,-a,
    +a,-a,+a,
    +a,+a,-a,
    +a,+a,+a, // point 7
    1e101,1e101,1e101, // end tag
    };
#undef a
int lin[]=
    {
    0,1,
    0,2,
    0,4,
    1,3,
    1,5,
    2,3,
    2,6,
    3,7,
    4,5,
    4,6,
    5,7,
    6,7,
    -1,-1, // end tag
    };
// int solution[]={ 0, 1, 3, 1, 5, 4, 0, 2, 3, 7, 5, 4, 6, 2, 6, 7, -1 }; // found polyline solution
    //---------------------------------------------------------------------------
void draw_lin(double *pnt,int *lin)
    {
    glBegin(GL_LINES);
    for (int i=0;lin[i]>=0;)
        {
        glVertex3dv(pnt+(lin[i]*3)); i++;
        glVertex3dv(pnt+(lin[i]*3)); i++;
        }
    glEnd();
    }
//---------------------------------------------------------------------------
void draw_pol(double *pnt,int *pol)
    {
    glBegin(GL_LINE_STRIP);
    for (int i=0;pol[i]>=0;i++) glVertex3dv(pnt+(pol[i]*3));
    glEnd();
    }
//---------------
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Is there a way to terminate a point with drawVertexPrimi

Post by pandoragami »

Thus far this is the code I've tried to come up with, it doesn't work but it's supposed to create a triangle polygon by first creating the indices and then the corresponding points represented by them. I assume someone could help make this work or let me know where it's wrong. thanks

Code: Select all

 
#include "irrlicht.h"
#include <cstdlib>
#include <iostream>
 
using namespace irr;
 
class EventReceiver : public irr::IEventReceiver
{
    public:
 
    virtual bool OnEvent(const irr::SEvent& event);
    virtual bool IsKeyDown( irr::EKEY_CODE keyCode) const;
    EventReceiver();
 
private:
 
    bool KeyIsDown[ irr::KEY_KEY_CODES_COUNT];
};
bool EventReceiver::OnEvent(const irr::SEvent& event)
{
 
    if (event.EventType == irr::EET_KEY_INPUT_EVENT)
        KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
 
    return false;
}
bool EventReceiver::IsKeyDown( irr::EKEY_CODE keyCode) const
{
    return KeyIsDown[keyCode];
}
 
EventReceiver::EventReceiver()
{
    for ( irr::u32 i = 0; i < irr::KEY_KEY_CODES_COUNT; ++i)
        KeyIsDown[i] = false;
}
 
scene::SMeshBuffer Buffer;
video::IVideoDriver* driver;
 
void init_points()
{
    video::SColor color( 255, 255, 0, 0);
 
    Buffer.Vertices.push_back( video::S3DVertex( 0, 0, 5, 0, 1, 0, color, 0, 0));
    Buffer.Vertices.push_back( video::S3DVertex( 1, 0, 5, 0, 1, 0, color, 0, 0));
    Buffer.Vertices.push_back( video::S3DVertex( 1, 1, 5, 0, 1, 0, color, 0, 0));
}
void init_indices()//this is supposed to create a triangle polygon. The indices represent the points of the vertices and the point zero is the beginning and endpoint.
{
    int index = Buffer.Indices.size();
 
     Buffer.Indices.push_back( 0+index);
     Buffer.Indices.push_back( 1+index);
 
     Buffer.Indices.push_back( 1+index);
     Buffer.Indices.push_back( 2+index);
 
     Buffer.Indices.push_back( 2+index);
     Buffer.Indices.push_back( 0+index);
 
    std::cout<<"Buffer.getVertices(). "<<Buffer.getVertices();
    std::cout<<", Buffer.getVertexCount(). "<<Buffer.getVertexCount();
    std::cout<<", Buffer.getIndices(). "<<Buffer.getIndices();
    std::cout<<", Buffer.Indices.size()-1. "<<Buffer.Indices.size()-1<<std::endl;
}
void render()
{
   driver->drawVertexPrimitiveList
                                        (
                                        Buffer.getVertices(),
                                        Buffer.getVertexCount(),
                                        Buffer.getIndices(),
                                        Buffer.Indices.size()-1,
                                        video::EVT_STANDARD,
                                        irr::scene::EPT_LINE_STRIP,
                                        video::EIT_16BIT
                                        );
}
int main()
{
    EventReceiver receiver;
    IrrlichtDevice *device = createDevice( irr::video::EDT_OPENGL,
                                       irr::core::dimension2d< irr::u32>( 1024, 768),
                                       16,
                                       false,
                                       false,
                                       false,
                                       &receiver);
 
    if (device == 0)
        return 1;
 
    device->setWindowCaption(L"IRRLICHT");
    driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    driver->setTextureCreationFlag( irr::video::ETCF_CREATE_MIP_MAPS, true);
    irr::scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS( 0, 60.0f, 0.001f, -1, 0, 0, false, 0.0f, false, true);
    device->getCursorControl()->setVisible( false);
 
    init_points();
    init_indices();
 
    u32 frames=0;
    while(device->run())
    {
        driver->beginScene( true, true, video::SColor( 0, 0, 0, 0));
        render();
        smgr->drawAll();
 
        driver->endScene();
        if (++frames==100)
        {
            core::stringw str = L"Irrlicht Engine [";
            str += driver->getName();
            str += L"] FPS: ";
            str += (s32)driver->getFPS();
 
            device->setWindowCaption(str.c_str());
            frames=0;
        }
    }
 
    device->drop();
 
    return 0;
}
 
 
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

Re: Is there a way to terminate a point with drawVertexPrimi

Post by chronologicaldot »

Before rendering, you need to set the material.

Code: Select all

 
    video::SMaterial material;
    material.Wireframe = false;
    material.Lighting = false;
 
    driver->setMaterial(material);
 
Also, you're camera is hiding where you stuff is drawing. It's there, but it's hard to find with the camera you are using. Try this instead:

Code: Select all

 
    smgr->addCameraSceneNode(0, core::vector3df(0,0,10), core::vector3df(0,0,0), 0, true);
 
In answer to your primary question: Irrlicht's drawVertexPrimitiveList() doesn't automatically connect lines and triangles. You have to specify them. Isn't that nice?
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Is there a way to terminate a point with drawVertexPrimi

Post by pandoragami »

https://imgur.com/jcHZ9Rp

@chronologicaldot

Above is the image of the output for the code below, it now works but the problem is apparent that a line connects the two polygons. Is there a way to fix this problem?

Code: Select all

 
#include "irrlicht.h"
#include <cstdlib>
#include <iostream>
 
using namespace irr;
 
class EventReceiver : public irr::IEventReceiver
{
    public:
 
    virtual bool OnEvent(const irr::SEvent& event);
    virtual bool IsKeyDown( irr::EKEY_CODE keyCode) const;
    EventReceiver();
 
private:
 
    bool KeyIsDown[ irr::KEY_KEY_CODES_COUNT];
};
bool EventReceiver::OnEvent(const irr::SEvent& event)
{
 
    if (event.EventType == irr::EET_KEY_INPUT_EVENT)
        KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
 
    return false;
}
bool EventReceiver::IsKeyDown( irr::EKEY_CODE keyCode) const
{
    return KeyIsDown[keyCode];
}
 
EventReceiver::EventReceiver()
{
    for ( irr::u32 i = 0; i < irr::KEY_KEY_CODES_COUNT; ++i)
        KeyIsDown[i] = false;
}
 
scene::SMeshBuffer Buffer;
video::IVideoDriver* driver;
 
void init_points( int x, int y, int z)
{
    video::SColor color( 255, std::rand()%255, std::rand()%255, std::rand()%255);
 
    Buffer.Vertices.push_back( video::S3DVertex( x   ,      y, z, 0, 1, 0, color, 0, 0));
    Buffer.Vertices.push_back( video::S3DVertex( x+1,     y, z, 0, 1, 0, color, 0, 0));
    Buffer.Vertices.push_back( video::S3DVertex( 1+x, 1+y, z, 0, 1, 0, color, 0, 0));
}
void init_indices()//this is supposed to create a triangle polygon. The indices represent the points of the vertices and the point zero is the beginning and endpoint.
{
    int index = Buffer.Indices.size();
 
     Buffer.Indices.push_back( 0+index/2);
     Buffer.Indices.push_back( 1+index/2);
 
     Buffer.Indices.push_back( 1+index/2);
     Buffer.Indices.push_back( 2+index/2);
 
     Buffer.Indices.push_back( 2+index/2);
     Buffer.Indices.push_back( 0+index/2);
 
    std::cout<<"Buffer.getVertices(). "<<Buffer.getVertices();
    std::cout<<", Buffer.getVertexCount(). "<<Buffer.getVertexCount();
    std::cout<<", Buffer.getIndices(). "<<Buffer.getIndices();
    std::cout<<", Buffer.Indices.size()-1. "<<Buffer.Indices.size()-1<<std::endl;
}
void render()
{
   video::SMaterial material;
   material.Wireframe = false;
   material.Lighting = false;
 
   driver->setMaterial(material);
 
   driver->drawVertexPrimitiveList
                                        (
                                        Buffer.getVertices(),
                                        Buffer.getVertexCount(),
                                        Buffer.getIndices(),
                                        Buffer.Indices.size()-1,
                                        video::EVT_STANDARD,
                                        irr::scene::EPT_LINE_STRIP,
                                        video::EIT_16BIT
                                        );
}
int main()
{
    EventReceiver receiver;
    IrrlichtDevice *device = createDevice( irr::video::EDT_OPENGL,
                                       irr::core::dimension2d< irr::u32>( 1024, 768),
                                       16,
                                       false,
                                       false,
                                       false,
                                       &receiver);
 
    if (device == 0)
        return 1;
 
    device->setWindowCaption(L"IRRLICHT");
    driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    driver->setTextureCreationFlag( irr::video::ETCF_CREATE_MIP_MAPS, true);
    irr::scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS( 0, 60.0f, 0.001f, -1, 0, 0, false, 0.0f, false, true);
    cam->setTarget( core::vector3df(0,0,0));
    cam->setPosition( core::vector3df(0,2,5));
 
    device->getCursorControl()->setVisible( false);
 
    init_points( 0, 0, 0);
    init_indices();
 
    init_points( 0, 2, 0);
    init_indices();
 
    u32 frames=0;
    while(device->run())
    {
        driver->beginScene( true, true, video::SColor( 0, 0, 0, 0));
        render();
        smgr->drawAll();
 
        driver->endScene();
        if (++frames==100)
        {
            core::stringw str = L"Irrlicht Engine [";
            str += driver->getName();
            str += L"] FPS: ";
            str += (s32)driver->getFPS();
 
            device->setWindowCaption(str.c_str());
            frames=0;
        }
    }
 
    device->drop();
 
    return 0;
}
 
 
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

Re: Is there a way to terminate a point with drawVertexPrimi

Post by chronologicaldot »

I'm sorry. Turns out, EPT_LINE_STRIP forms a single connected line, as given in the docs in EPrimitiveType.h. Each vertex is a single point along that strip. That said, you could just limit the indices that you draw to only half of those in your Buffer.Indices. It's two draw calls, but that's not bad.
Triangles aren't connected unless you draw a triangle strip or fan. I guess the name is a hint there.
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Is there a way to terminate a point with drawVertexPrimi

Post by pandoragami »

chronologicaldot wrote:I'm sorry. Turns out, EPT_LINE_STRIP forms a single connected line, as given in the docs in EPrimitiveType.h. Each vertex is a single point along that strip. That said, you could just limit the indices that you draw to only half of those in your Buffer.Indices. It's two draw calls, but that's not bad.
Triangles aren't connected unless you draw a triangle strip or fan. I guess the name is a hint there.

Thanks, that's fine. I just wanted to see if there is a simpler method to drawing polygons with the least number of lines but I guess lines strips are much too primitive and I need to go one level higher.

Do you know by the way if multiple triangle or quad vertices overlapping each other are treated as one. Say If I draw two quads where each quad has their edges joining the two quads together, so that two points or vertices are in the same location and a single line then connects two vertices; does the graphics card treat that line as a single line or are there two separate lines rendered?
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: Is there a way to terminate a point with drawVertexPrimi

Post by pandoragami »

I thought about another way to make the extra line vanish and that is to set its alpha to zero like

Code: Select all

 
void init_points( int x, int y, int z)
{
    video::SColor color( 0, 255, 0, 0);
 
    Buffer.Vertices.push_back( video::S3DVertex( x   ,      y, z, 0, 1, 0, color, 0, 0));
    Buffer.Vertices.push_back( video::S3DVertex( x+1,     y, z, 0, 1, 0, color, 0, 0));
    Buffer.Vertices.push_back( video::S3DVertex( 1+x, 1+y, z, 0, 1, 0, color, 0, 0));
}
 
But when I tried this in the complete code I posted earlier it turns out that the lines don't vanish as expected. Is that because the alpha channel only pertains to the polygon face itself and lines are not subject to changing the alpha component; the colors are red so that can be changed though?
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

Re: Is there a way to terminate a point with drawVertexPrimi

Post by chronologicaldot »

1) Overlapping polygons are NOT treated as one. They are distinct. The fact that they overlap is merely a visual coincidence.

2) Setting the alpha value to zero means nothing unless you set the correct material blending type. Have a look at the file SMaterial.h and the .h files it uses, and read the documentation on the enums. Currently, Irrlicht supports only certain kinds of alpha blending. If you don't want something visible, it's usually better to not draw it in the first place. Sorry there isn't a shortcut here.
Post Reply