Page 1 of 1

Using 3D functions to draw 2D stuff?

Posted: Tue Apr 08, 2008 4:22 pm
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!

Posted: Tue Apr 08, 2008 5:00 pm
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.

Posted: Tue Apr 08, 2008 10:26 pm
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!

Posted: Tue Apr 08, 2008 11:05 pm
by MasterGod
setScale() maybe..? :wink:

Posted: Tue Apr 08, 2008 11:21 pm
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...

Posted: Wed Apr 09, 2008 7:42 am
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.

Posted: Wed Apr 09, 2008 8:24 am
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.

Posted: Wed Apr 09, 2008 4:23 pm
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.

Posted: Wed Apr 09, 2008 8:44 pm
by rogerborg
Nicely worked out!

Posted: Wed Apr 09, 2008 9:48 pm
by hybrid
Thanks :wink:

Posted: Wed Apr 09, 2008 10:16 pm
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);

Posted: Wed Apr 09, 2008 10:48 pm
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.

Posted: Wed Apr 09, 2008 10:59 pm
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; } 

};