Using 3D functions to draw 2D stuff?

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
Clash
Posts: 80
Joined: Thu Apr 19, 2007 4:20 pm

Using 3D functions to draw 2D stuff?

Post by Clash »

Hello!
I'm making a 2D game but now I regret using draw2D for everything, drawing the tiles, images, and etc. Draw2D is very limited, I can't rotate images or do special effects with it, so I decided to use the 3D functions, but I'm completely lost with that, I used to have my own 2D camera, but now I think I need to use irrlicht camera. The question is, at which position so I would always see the images with the perspective from the top and with the image's size? Can someone give me a little guide?
Thanks in advance, I've tried the search function, but the words I use to search always give me results that have nothing to do with what I want, thanks again!
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Here's one I did earlier.

That's a very raw demonstration of the functionality. Wrapping your "sprites" in a custom scene node might be more extensible.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Clash
Posts: 80
Joined: Thu Apr 19, 2007 4:20 pm

Post by Clash »

rogerborg wrote:Here's one I did earlier.

That's a very raw demonstration of the functionality. Wrapping your "sprites" in a custom scene node might be more extensible.
Hi, I've used your other code from (should I use that one or the one that you just linked me?) http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=27015 and set camera->setIsOrthogonal(true);
The rotation works PERFECTLY, but, I have one trouble, as I am a true newbie with 3D, how can I make the sprite look on the screen the actual size it is. I mean, like for example, I have a 20x20 sprite, but on the screen it looks a lot bigger. Thanks a lot!
Last edited by Clash on Tue Apr 08, 2008 11:18 pm, edited 1 time in total.
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

setScale() maybe..? :wink:
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
Clash
Posts: 80
Joined: Thu Apr 19, 2007 4:20 pm

Post by Clash »

With the code at http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=24728,
mk1 on #irrlicht helped me, he gave me this code
nodes[node]->setScale(vector3df(texture->getSize().Width*.5, texture->getSize().Height*.5, 1));

orthoMatrix.buildProjectionMatrixOrthoLH(640.f, 480.f, 5.f, 100.f);

But, the last line is displayed at the first place, lines goes like this
Last
First
Second
Third
...

I believe the code for rotating is a little bugged, it rotatates a little weird

The code here, http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=26735, also by you, rotates PERFECTLY, but then, I have no no idea how to display it on real size...
suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

Post by suliman »

couldnt you just try and error until you find the right constant to scale it correctly to your screen-resolution? And then always use that constant.
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Clash wrote:how can I make the sprite look on the screen the actual size it is. I mean, like for example, I have a 20x20 sprite, but on the screen it looks a lot bigger. Thanks a lot!
The apparent size of the sprite is dependent on the sprite size and the camera view size.

In the example I gave, the camera has a width of 20 and a height of 15, and the sprites have size 1x1, i.e. 1/20th of the width and 1/15th of the height of the screen.

You can scale the sprites and/or change the camera size. For example, you could set the camera to have the same height and width as the screen, then the size of each sprite in pixels should be the same as its size in units.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Clash
Posts: 80
Joined: Thu Apr 19, 2007 4:20 pm

Post by Clash »

Hello!
I finally got it to the real size, but how do I make it so the image does not get distorted? http://img520.imageshack.us/img520/7269 ... bleqf3.png (Skull at real size and zoomed 500%)
The skull at the bottom is how it's suppose to look like, it does look like sometimes, but only on certains camera positions

Edit: I think disabling mip maps fixed.
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Nicely worked out!
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Thanks :wink:
Clash
Posts: 80
Joined: Thu Apr 19, 2007 4:20 pm

Post by Clash »

Yeah, hybrid gave me the tip! Thanks hybrid, but now I have a new doubt, which I do believe hybrid told me I have to use billboards, but then I fall again on the trouble of rotating billboards, which do not rotate as smooth as the CSprite class rogerborg made.

Why doing this to SceneNode doesn't work? [Code from http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=27015]

Code: Select all

//this being a CSprite (ISceneNode), later added with SceneManager->registerNodeForRendering(this);
            this->setMaterialFlag(video::EMF_LIGHTING, false);
            this->setMaterialTexture(0, driver->getTexture
                                                   ("images/explosion_1.png"));
            this->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
            this->setPosition(core::vector3df(0.f,0.f,0.f));
            this->setMaterialFlag(video::EMF_ZBUFFER,false);
While doing this works?

Code: Select all

            scene::IBillboardSceneNode* light = 0;
            light = mgr->addBillboardSceneNode(0,
            core::dimension2d<f32>(255, 255));
            light->setMaterialFlag(video::EMF_LIGHTING, false);
            light->setMaterialTexture(0, driver->getTexture
                                                   ("images/explosion_1.png"));
            light->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
            light->setPosition(core::vector3df(0.f,0.f,0.f));
            light->setMaterialFlag(video::EMF_ZBUFFER,false);
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Well, I said that I don't know about the sprite class. The class seems to do the necessary things to make your code work, I don't know why it doesn't work.
Clash
Posts: 80
Joined: Thu Apr 19, 2007 4:20 pm

Post by Clash »

Does billboard do anything special in terms of EMT_TRANSPARENT_ADD_COLOR? Maybe rogerborg owner of the CSprite knows why?

Btw: thanks guys

Code: Select all

class CSprite : public ISceneNode 
{ 
    aabbox3d<f32> Box; // Implementation elided for brevity 
    S3DVertex     Vertices[4]; 
    SMaterial     Material; 
    dimension2df  Size; 
    f32           Rotation; 

public: 

    CSprite(dimension2df size, char const * textureName, E_MATERIAL_TYPE materialType, 
            bool makeColourKey, IVideoDriver * driver, ISceneNode* parent, ISceneManager* mgr, 
            s32 id = -1) 
        : ISceneNode(parent, mgr, id) 
    { 
        Material.Wireframe = false; 
        Material.Lighting = false; 
        Material.MaterialType = materialType; 

        if(driver && textureName) 
        { 
            ITexture * texture = driver->getTexture(textureName); 

            if(texture) 
            { 
                if(makeColourKey) 
                   driver->makeColorKeyTexture(texture, core::position2d<s32>(0,0)); 

                Material.setTexture(0, texture); 
            } 
        } 


        Size = size; 
        Rotation = 0.f; 

        Vertices[0].TCoords.set(1.f, 0.f); 
        Vertices[1].TCoords.set(1.f, 1.f); 
        Vertices[2].TCoords.set(0.f, 1.f); 
        Vertices[3].TCoords.set(0.f, 0.f); 
    } 

    virtual void OnRegisterSceneNode() 
    { 
        if (IsVisible) 
            SceneManager->registerNodeForRendering(this); 

        ISceneNode::OnRegisterSceneNode(); 
    } 

    virtual void render() 
    { 
        IVideoDriver* driver = SceneManager->getVideoDriver(); 
        ICameraSceneNode* camera = SceneManager->getActiveCamera(); 

        vector3df cameraView = camera->getTarget() - camera->getAbsolutePosition(); 
        cameraView.normalize(); 

        vector3df up = camera->getUpVector(); 
        up.normalize(); 

        quaternion quat; 
        quat.fromAngleAxis(Rotation * DEGTORAD, cameraView); 

        matrix4 const rotationMatrix = quat.getMatrix(); 
        rotationMatrix.transformVect(up); 

        vector3df horizontal = cameraView.crossProduct(up).normalize(); 
        vector3df const vertical = cameraView.crossProduct(horizontal).normalize() * Size.Height * 0.5f; 
        horizontal *= Size.Width * 0.5f; 

        for (s32 i=0; i<4; ++i) 
            Vertices[i].Normal = -cameraView; 

        vector3df const myPosition = AbsoluteTransformation.getTranslation(); 
        Vertices[0].Pos = myPosition - horizontal - vertical; 
        Vertices[1].Pos = myPosition - horizontal + vertical; 
        Vertices[2].Pos = myPosition + horizontal + vertical; 
        Vertices[3].Pos = myPosition + horizontal - vertical; 

        static u16 const indices[] = { 0, 1, 2, 0, 2, 3 }; 

        driver->setMaterial(Material); 
        driver->setTransform(ETS_WORLD, IdentityMatrix); 
        driver->drawIndexedTriangleList(Vertices, 4, indices, 2); 
    } 

    const aabbox3d<f32>& getBoundingBox() const { return Box; } 

    u32 getMaterialCount() const { return 1; } 

    SMaterial& getMaterial(u32 i) { return Material; } 

    void setSpriteRotation(f32 rotation) 
    { 
        Rotation = rotation; 
        while(Rotation >= 360.f) 
            Rotation -= 360.f; 
        while(Rotation < 0.f) 
            Rotation += 360.f; 
    } 

    f32 getSpriteRotation(void) const { return Rotation; } 

    dimension2df const & getSize(void) const { return Size; } 

    void setSize(dimension2df const & size) { Size = size; } 

};
Last edited by Clash on Wed Apr 09, 2008 11:05 pm, edited 1 time in total.
Post Reply