2D images on 3D plane issue

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
fuby
Posts: 14
Joined: Fri Apr 06, 2012 1:39 pm

2D images on 3D plane issue

Post by fuby »

I am having trouble with nodes that I'm trying to use.

Pretty much I'm attempting to put textures on 3D planes.
However, even though the positions are set correctly (i.e. the PC (player character) is 10 increments close than the Terrain node to the Camera) the PC suddenly is drawn behind the Terrain texture when it leaves the center of the camera targeting area.

To Summarize: I want to guy to NOT go behind the Terrain.

I have done searches on this forum however I am not familiar with 3D terminology would describe my issue.

Any help with this would be appreciated.

Source code - http://www.fuzzybunnyos.com/mydocs/needhelp.zip
Screen shot - http://www.fuzzybunnyos.com/mydocs/mypics/needhelp.png

4/7/2012 EDIT: Cleaning up original post to try to make more sense.
Last edited by fuby on Sat Apr 07, 2012 1:45 pm, edited 2 times in total.
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: 2D images on 3D plane issue

Post by REDDemon »

I'm not sure to understand your problem. What you want to happen and what happens?


it seems that the character moved behind the plane. that should be correct if it disappears. If you want the transition smoother you can try to increment to 10 at smaller intervals.. or just using a translation animator. (not sure if I answered the right question)
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
fuby
Posts: 14
Joined: Fri Apr 06, 2012 1:39 pm

Re: 2D images on 3D plane issue

Post by fuby »

The problem I'm having is I want the character to stay in front of the plane the entire time.

The camera is at 0,-41,335 and facing 0,-41,0.

The character is at (x, y, 10)
The plane is at (0, 0, 0)
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: 2D images on 3D plane issue

Post by REDDemon »

maybe the plane is not parallel to the camera. Are you turning a mesh or are you using custom vertices for the plane? because custom vertices makes that easier.

need to be

POSITION OF Vertex 1: (somex, somey, 0)

POSITION OF Vertex 2: (somex, somey, 0)

POSITION OF Vertex 3: (somex, somey, 0)

POSITION OF Vertex 4: (somex, somey, 0)

in general every point on the plane is (somex,somey,0)

so given two vectors

K(0,1,0) and T(1,0,0)



all the points on the plane are
A*K + B*T.

where A and B are floating point values of your choice.

A,B are the coordinates of your character, so if you change the Z value of K and T from 0 to 10 you have the position of the character, wich needs to be updated only in A and B. pos = A*K + B*T. That works also for planes with any angle.

You should use orthogonal camera anyway. Else the character will move in a strange way. Yep because if it's on the center of the screen you can't see "behind it", but when he moves to corners of the screen you can see bheind it: let's see that:

Image

you can see point p1 because if you trace a line from eye to p1 there is no object blocking that line.
You caN'T see point p2 because if you trace a line from eye to p2 the line will be blocked by character 2 (c2).
you should also note that C1 is partially out of the screen in that image.

The custom scene node example is enough for you to make custom vertices for that plane.
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
fuby
Posts: 14
Joined: Fri Apr 06, 2012 1:39 pm

Re: 2D images on 3D plane issue

Post by fuby »

1st thanks for responding.

I am using Custom Vertices, in fact I shameless stole it from the custom node example.

I'm going to post code of what I had done before my original post.

Code: Select all

 
#ifndef __C_CANVAS_SCENE_NODE_H_INCLUDED__
#define __C_CANVAS_SCENE_NODE_H_INCLUDED__
 
#include <irrlicht.h>
 
using namespace irr;
 
//update 4/4/2012 - for simple usage
class CCanvasSceneNode : public scene::ISceneNode
{
   core::aabbox3d<f32> Box;
   video::S3DVertex Vertices[4];
   video::SMaterial Material;
   video::SColor Color;
   s32 width;
   s32 height;
 
   //setups everything so it ready for rendering
   void resetCanvas()
   {
      f32 xright =  ((f32)width)/2;
      f32 xleft = xright * -1;
      f32 ztop = ((f32)height)/2;
      f32 zbottom = xright * -1;
 
      Vertices[0] = video::S3DVertex(xleft,    ztop,0, 0, 0,0, Color,1,0);
      Vertices[1] = video::S3DVertex(xright,   ztop,0, 0, 0,0, Color,0,0);
      Vertices[2] = video::S3DVertex(xright,zbottom,0, 0, 0,0, Color,0,1);
      Vertices[3] = video::S3DVertex(xleft, zbottom,0, 0, 0,0, Color,1,1);
   }
 
        public:
 
   //Constructor - usage: this = new CCanvasSceneNode(smgr->getRootSceneNode(), smgr, ##)
   CCanvasSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
           s32 newWidth = 32, s32 newHeight = 32) : scene::ISceneNode(parent, mgr, id)
   {
      Material.Wireframe = false;
      Material.Lighting = false;
 
      setAutomaticCulling(scene::EAC_OFF);
          Color.set(255, 255, 255, 255);
          width = newWidth;
          height = newHeight;
 
          resetCanvas();
   }
 
   //changes width of canvas
   void setCanvasWidth(s32 newWidth)
   {
           width = newWidth;
 
           resetCanvas();
   }
   
   //changes height of canvas
   void setCanvasHeight(s32 newHeight)
   {
           height = newHeight;
 
           resetCanvas();
   }
 
   //changes the color - alpha probably still doesnt work
   void setCanvasColor(video::SColor newColor)
   {
           Color = newColor;
 
           resetCanvas();
   }
 
   //returns width of canvas
   s32 getCanvasWidth()
   {
           return width;
   }
   
   //rteurns height of canvas
   s32 getCanvasHeight()
   {
           return height;
   }
 
   //returns color of canvas
   video::SColor getCanvasColor()
   {
           return Color;
   }
 
   //Register Node function
   virtual void OnRegisterSceneNode()
   {
      if (IsVisible)
         SceneManager->registerNodeForRendering(this);
 
      ISceneNode::OnRegisterSceneNode();
   }
 
   /*
   In the render() method most of the interesting stuff happens: The
   Scene node renders itself. We override this method and draw the
   Canvas.
   */
   virtual void render()
   {
      u16 indices[] = {   0,2,3, 2,1,3, 1,0,3, 2,0,1   };
      video::IVideoDriver* driver = SceneManager->getVideoDriver();
 
      driver->setMaterial(Material);
      driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
      driver->drawVertexPrimitiveList(&Vertices[0], 4, &indices[0], 4, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
   }
 
   /*
   And finally we create three small additional methods.
   irr::scene::ISceneNode::getBoundingBox() returns the bounding box of
   this scene node, irr::scene::ISceneNode::getMaterialCount() returns the
   amount of materials in this scene node (our tetraeder only has one
   material), and irr::scene::ISceneNode::getMaterial() returns the
   material at an index. Because we have only one material here, we can
   return the only one material, assuming that no one ever calls
   getMaterial() with an index greater than 0.
   */
   virtual const core::aabbox3d<f32>& getBoundingBox() const
   {
      return Box;
   }
 
   virtual u32 getMaterialCount() const
   {
      return 1;
   }
 
   virtual video::SMaterial& getMaterial(u32 i)
   {
      return Material;
   }
};
#endif
 
Last edited by fuby on Sat Apr 07, 2012 1:43 pm, edited 1 time in total.
fuby
Posts: 14
Joined: Fri Apr 06, 2012 1:39 pm

Re: 2D images on 3D plane issue

Post by fuby »

... In multiple parts because it's too big to put in one post

Code: Select all

 
#ifndef __C_SPRITE_DATA_H_INCLUDED__
#define __C_SPRITE_DATA_H_INCLUDED__
 
#include <irrlicht.h>
#include "CCanvasSceneNode.h"
 
using namespace irr;
 
class CSpriteInterface
{
   CCanvasSceneNode * canvas; //pointer to Node that the sprite is put on
   video::ITexture * maintexture; //copy of the full texture used for this sprite for later slicing
   video::SColor Color; //color for paletting
   u32 currentAlpha; //current alpha channel being used
 
 
   //structure and variables below are for use with Animation system based on Michal Švantner's design
   struct Animation
    {
        s32 start;
        s32 end;
        u32 speed;
        bool loop;
        bool reverse;
    };
 
   core::array< core::dimension2d<s32> > frame; //frame location on the main texture
   s32 currentFrame; //the frame that will displayed at time of rendering
   s32 frameWidth;  //width of the frames
   s32 frameHeight; //height of frames
 
   core::array<Animation> animation; //data for group frames for different animations
   u32 currentAnim; // the current animation being displayed
 
   u32 oldTime; // last recorded time when updating animations
 
   //put the piece of texture on the canvas
   //scene::ISceneManager* mgr - point engine components
   //s32 nx - starting position x on main texture
   //s32 ny - starting position y on main texture
   //u32 width - width the subsized texture
   //u32 height - height the subsized texture
   void setTeaxtureToCanvas(scene::ISceneManager* mgr, s32 nx, s32 ny, u32 width, u32 height)
   {
      //setup driver and dimensions
      video::IVideoDriver* driver = mgr->getVideoDriver();
      core::position2d<s32> start_square(nx, ny);
      core::dimension2d<u32> end_square(width, height);
          
          //copy section of texture to image and then put it on the Canvas
      if(maintexture && maintexture !=0)
      {
         video::IImage* image = driver->createImage(maintexture, start_square, end_square);
         video::ITexture* texture = driver->addTexture("temp", image);
 
         canvas->setMaterialTexture( 0, texture);
         canvas->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL); //needed to make canvas clear
      }
   }
 
public:
 
   //Constructor
        /*
        normal usage:
                this = new CSpriteInterface(canvas);
                this->initMainTexture(smgr, driver->getTexture("file"));
                this->setupFrames(fx, fy);
                i = this->addAnimation(fstart, fend, speed-milliseconds, if_loops);
                this->setAnimation(device, i);
                
        during main loop:
                this->play(device, smgr);
 
        */
   CSpriteInterface(CCanvasSceneNode * CanvasNode, s32 newFWidth = 32, s32 newFHeight = 32)
   {
      canvas = CanvasNode;
          Color.set(255, 255, 255, 255);
          currentAlpha = 255;
          
          frameWidth = newFWidth;
          frameHeight = newFHeight;
 
          currentAnim = 0;
          currentFrame = 0;
   }
 
   //loads the main texture and filters out the keycolor alpha channel
   //scene::ISceneManager* mgr - point engine components
   //video::ITexture * texture - texture to be stored for later slicing
   //bool filter - use the filter system? default: true
   void initMainTexture(scene::ISceneManager* mgr, video::ITexture * texture, bool filter = true)
   {
      if(!texture)
         return;
 
          //if requested skip filtering alpha channel for keycolor, just copy texture to class
          if(filter == false)
          {
                  maintexture = texture;
                  return;
          }
 
      //get size of texture
      core::dimension2d<s32> textureSize(texture->getSize());          
 
      u32 rawwidth = textureSize.Width;
      u32 rawheight = textureSize.Height;
 
      // load the video driver
      video::IVideoDriver* driver = mgr->getVideoDriver();
 
      //copy whole texture to image
      video::IImage * image = driver->createImage (texture,
                                             core::position2d<s32> (0, 0),
                                             core::dimension2d<u32> (rawwidth, rawheight));
 
      //get the color key, upper left hand corner of image
      video::SColor ColorKey = image->getPixel(0, 0);
 
      //prepare a transparent pixel to replace keycolor pixels with
      video::SColor NewColor= image->getPixel(0, 0);
      NewColor.setAlpha(0);
 
      //Scan and replace keycolor pixels
      for (u32 i=0; i<rawwidth ; ++i)
      {
        for (u32 j=0; j<rawheight ; ++j)
        {
            if (image->getPixel(i, j) == ColorKey)
            {
               image->setPixel(i, j, NewColor, false);
            }
         }
      }
 
          //put back texture and attempt to stop memory leak with pointer to image
      maintexture = driver->addTexture("temp-sprite", image);
          image->drop();
   }
   
   void setTextureAlpha(scene::ISceneManager* mgr, u32 newAlpha)
   {
           //if no texture FAIL!
           if(!maintexture)
                   return;
 
           //if no changes FAIL!  
           if(currentAlpha == newAlpha)
                   return;
 
           //also can't have alpha at 0 or will mess up keyColor
           if(newAlpha < 1)
                   newAlpha = 1;
 
      //get size of texture
      core::dimension2d<s32> textureSize(maintexture->getSize());          
 
      u32 rawwidth = textureSize.Width;
      u32 rawheight = textureSize.Height;
 
          // load the video driver
      video::IVideoDriver* driver = mgr->getVideoDriver();
 
      //copy whole texture to image
      video::IImage * image = driver->createImage (maintexture,
                                             core::position2d<s32> (0, 0),
                                             core::dimension2d<u32> (rawwidth, rawheight));
 
          video::SColor Pixel;
      //Scan and replace keycolor pixels
      for (u32 i=0; i<rawwidth ; ++i)
      {
         for (u32 j=0; j<rawheight ; ++j)
         {
            Pixel = image->getPixel(i, j);
 
                        if (Pixel.getAlpha() != 0)
                        {
                                Pixel.setAlpha(newAlpha);
                                image->setPixel(i, j, Pixel, false);
                        }
         }
      }
 
          //update current alpah color
          currentAlpha = newAlpha;
          
          //put back texture and attempt to stop memory leak with pointer to image
          if(maintexture)
                  maintexture->drop();
      maintexture = driver->addTexture("temp", image);
          image->drop();
   }
 
 
   //setup frame information
   //s32 divX - number of frames across texture - default: 1
   //s32 divY - number of frames down texture - default: 1
   void setupFrames(s32 divX = 1, s32 divY = 1)
   {
           //if no texture FAIL!
           if(!maintexture || maintexture == 0)
                   return;
 
           //get size of the main texture
           core::dimension2d<s32> spriteSize(maintexture->getSize());
           frameWidth = spriteSize.Width / divX;
           frameHeight = spriteSize.Height / divY;
           
           //set canvas to size of the frames, best viewed at distance away 90
           //canvas->setSizeofCanvas(frameWidth, frameHeight, Color);
 
           //setup number of frames needed
       frame.set_used(divX * divY);
 
           //assign locations on texture to frames
       u32 n = 0;
 
       for(s32 j=0; j<divY; j++)
                   for(s32 i=0; i<divX; i++)
           {
                frame[n] = core::dimension2d<s32>(i*frameWidth, j*frameHeight);
                n++;
           }
                   
                //initialize frame and animation selections
                currentFrame = 0;
                currentAnim = 0;
   }
   
   // play sprite - time to figure out which frame is being used
    void play(IrrlichtDevice *Device, scene::ISceneManager* mgr)
    {
        if(animation.empty())
        {
            return;
        }
 
        //get current time
        u32 time = Device->getTimer()->getTime();
       
        //check if enough time has gone by
        if(oldTime + animation[currentAnim].speed <= time)
        {
            if(animation[currentAnim].reverse)
            {
                currentFrame--;
                if(currentFrame < animation[currentAnim].start)
                {
                    if(animation[currentAnim].loop)currentFrame = animation[currentAnim].end;
                    else currentFrame++;
                }
            }
            else
            {
                currentFrame++;
 
                if(currentFrame > animation[currentAnim].end)
                {
                    if(animation[currentAnim].loop)currentFrame = animation[currentAnim].start;
                    else currentFrame--;
                }
            }
 
            //record current time
            oldTime = time;
        }
                //the information to the canvas painter
                setTeaxtureToCanvas(mgr, frame[currentFrame].Width, frame[currentFrame].Height, frameWidth, frameHeight);
    }
 
    // add new animation
    // returns id number of animation
    // \param start -start frame number
    // \param end - end frame number
    // \param speed - animation speed in miliseconds
    // \param loop - true if animation should loop, false if not
    // \param reverse - true if animation should play reversed, false if not
    u32 addAnimation(u32 start, u32 end, u32 speed, bool loop = false, bool reverse = false)
    {
        Animation tmp;
        tmp.start = start;
        tmp.end = end;
        tmp.speed = speed;
        tmp.loop = loop;
        tmp.reverse = reverse;
 
        animation.push_back(tmp);
 
        return animation.size()-1;
    }
 
    // remove animation
    // \param num -animation id number
    void removeAnimation(u32 num)
    {
        animation.erase(num);
 
        if(currentAnim == num)
        {
            currentAnim = 0;
            currentFrame = 0;
        }
 
        if(currentAnim > num) currentAnim--;
    }
 
    // remove all animations
    void clearAnimations()
    {
        animation.clear();
 
        currentAnim = 0;
        currentFrame = 0;
    }
 
    // set animation to play
    // \param num -animation id number
    void setAnimation(IrrlichtDevice *Device, u32 num)
    {
        currentAnim = num;
 
        if(animation[currentAnim].reverse)
            currentFrame = animation[currentAnim].end;
        else
            currentFrame = animation[currentAnim].start;
 
        oldTime = Device->getTimer()->getTime();
    }
 
    // return id number of animation played
    u32 getCurrentAnimation()
    {
        return currentAnim;
    }
 
    // set speed of animation
    // \param num -animation id number
    // \param newspeed -new animation speed in miliseconds
    void setAnimationSpeed(u32 num, u32 newspeed)
    {
        if(animation.empty()) return;
 
        animation[num].speed = newspeed;
    }
 
    // return speed of animation
    // \param num -animation id number
    u32 getAnimationSpeed(u32 num)
    {
        if(animation.empty()) return 0;
 
        return animation[num].speed;
    }
 
    // return id number of animation start frame
    // \param num -animation id number
    u32 getAnimationStart(u32 num)
    {
        return animation[num].start;
    }
 
    // return id number of animation end frame
    // \param num -animation id number
    u32 getAnimationEnd(u32 num)
    {
        return animation[num].end;
    }
 
    // set animation loop state
    // \param num -animation id number
    // \param loop -true if animation should loop, false if not
    void setAnimationLoopState(u32 num, bool loop)
    {
        animation[num].loop = loop;
    }
 
    // return true if animation loopes, false if not
    // \param num -animation id number
    bool getAnimationLoopState(u32 num)
    {
        return animation[num].loop;
    }
 
    // set animation reverse state
    // \param num -animation id number
    // \param reverse -true if animation should play reversed, false if not
    void reverseAnimation(u32 num, bool reverse)
    {
        animation[num].reverse = reverse;
    }
 
    // return true if animation play reverse, false if not
    // \param num -animation id number
    bool isAnimationReversed(u32 num)
    {
        return animation[num].reverse;
    }
 
        // set the position of the Canvas
        void setPosition(const core::vector3df newpos)
        {
                canvas->setPosition(newpos);
        }
 
        // return position of Canvas
        core::vector3df getPosition()
        {
                return canvas->getPosition();
        }
};
#endif
 
Last edited by fuby on Sat Apr 07, 2012 1:42 pm, edited 1 time in total.
fuby
Posts: 14
Joined: Fri Apr 06, 2012 1:39 pm

Re: 2D images on 3D plane issue

Post by fuby »

Code: Select all

 
#ifndef __C_TERRAIN_INTERFACE_H_INCLUDED__
#define __C_TERRAIN_INTERFACE_H_INCLUDED__
 
#include <irrlicht.h>
#include "CCanvasSceneNode.h"
 
using namespace irr;
 
class CTerrainInterface
{
   CCanvasSceneNode * canvas; //pointer to Node that the sprite is put on
   video::ITexture * texture; //copy of the full texture used for this sprite for later slicing
   video::SColor Color; //color for paletting
 
   //put the piece of texture on the canvas
   void setTeaxtureToCanvas()
   {
          //copy section of texture to image and then put it on the Canvas
      if(texture && texture !=0)
      {
         canvas->setMaterialTexture( 0, texture);
         canvas->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL); //needed to make canvas clear
      }
   }
 
public:
 
   CTerrainInterface(CCanvasSceneNode * CanvasNode)
   {
      canvas = CanvasNode;
          Color.set(255, 255, 255, 255);
   }
 
   void initTexture(scene::ISceneManager* mgr, video::ITexture * newTexture, bool filter = true)
   {
      if(!newTexture)
         return;
 
          //if requested skip filtering alpha channel for keycolor, just copy texture to class
          if(filter == false)
          {
                  texture = newTexture;
                  setTeaxtureToCanvas();
                  return;
          }
 
      //get size of texture
      core::dimension2d<s32> textureSize(newTexture->getSize());          
 
      u32 rawwidth = textureSize.Width;
      u32 rawheight = textureSize.Height;
 
      // load the video driver
      video::IVideoDriver* driver = mgr->getVideoDriver();
 
      //copy whole texture to image
      video::IImage * image = driver->createImage (newTexture,
                                             core::position2d<s32> (0, 0),
                                             core::dimension2d<u32> (rawwidth, rawheight));
 
      //get the color key, upper left hand corner of image
      video::SColor ColorKey = image->getPixel(0, 0);
 
      //prepare a transparent pixel to replace keycolor pixels with
      video::SColor NewColor= image->getPixel(0, 0);
      NewColor.setAlpha(0);
 
      //Scan and replace keycolor pixels
      for (u32 i=0; i<rawwidth ; ++i)
      {
        for (u32 j=0; j<rawheight ; ++j)
        {
            if (image->getPixel(i, j) == ColorKey)
            {
               image->setPixel(i, j, NewColor, false);
            }
         }
      }
 
          //put back texture and attempt to stop memory leak with pointer to image
      texture = driver->addTexture("temp-floor-tile", image);
          image->drop();
 
          setTeaxtureToCanvas();
   }
 
        // set the position of the Canvas
        void setPosition(const core::vector3df newpos)
        {
                canvas->setPosition(newpos);
        }
};
#endif
 

Code: Select all

 
#ifndef __C_EVENT_RECEIVER_H_INCLUDED__
#define __C_EVENT_RECEIVER_H_INCLUDED__
 
#include <irrlicht.h>
#include "CCanvasSceneNode.h"
#include "CSpriteInterface.h"
 
using namespace irr;
 
class CEventReceiver : public IEventReceiver
{
 
        bool KeyIsDown[KEY_KEY_CODES_COUNT]; // We use this array to store the current state of each key
        CSpriteInterface *hero; //the sprite we are going to track
 
        void updatePositions(scene::ICameraSceneNode * camera, core::vector3df nodePosition)
        {
                const f32 MAX_Y = 125;
                const f32 MAX_X = 275, MIN_X = -275;
                const f32 MIN_Y = -250;
 
                //check boundries for sprite
                if(nodePosition.X > MAX_X)
                        nodePosition.X = MAX_X;
                if(nodePosition.X < MIN_X)
                        nodePosition.X = MIN_X;
 
                if(nodePosition.Y > MAX_Y)
                        nodePosition.Y = MAX_Y;
                if(nodePosition.Y < MIN_Y)
                        nodePosition.Y = MIN_Y;
 
                //set position of hero
                hero->setPosition(nodePosition);
        }
 
public:
 
        CEventReceiver()
        {
                for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
                        KeyIsDown[i] = false;
        }
 
        // This is the one method that we have to implement
        virtual bool OnEvent(const SEvent& event)
        {
                // Remember whether each key is down or up
                if (event.EventType == irr::EET_KEY_INPUT_EVENT)
                        KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
                return false;
        }
        
        // This is used to check whether a key is being held down
        virtual bool IsKeyDown(EKEY_CODE keyCode) const
        {
                return KeyIsDown[keyCode];
        }
 
        //stick to guy like glue
        virtual void setHero(CSpriteInterface *sprite)
        {
                hero = sprite;
        }
 
        virtual u32 checkInput(scene::ICameraSceneNode * camera, u32 now, u32 then, f32 movement_speed)
        {
                const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
                then = now;
                
                core::vector3df nodePosition = hero->getPosition();
                
                if(IsKeyDown(irr::KEY_KEY_W))
                        nodePosition.Y += movement_speed * frameDeltaTime;
                else if(IsKeyDown(irr::KEY_KEY_S))
                        nodePosition.Y -= movement_speed * frameDeltaTime;
                
                if(IsKeyDown(irr::KEY_KEY_A))
                        nodePosition.X += movement_speed * frameDeltaTime;
                else if(IsKeyDown(irr::KEY_KEY_D))
                        nodePosition.X -= movement_speed * frameDeltaTime;
 
                updatePositions(camera, nodePosition);
                
                return then;
        }
 
};
 
#endif
 
fuby
Posts: 14
Joined: Fri Apr 06, 2012 1:39 pm

Re: 2D images on 3D plane issue

Post by fuby »

And Finally... The Main function

Code: Select all

 
#include <irrlicht.h>
#ifdef _IRR_WINDOWS_
#include <windows.h>
#endif
 
#include <stdio.h>
#include "CCanvasSceneNode.h"
#include "CSpriteInterface.h"
#include "CTerrainInterface.h"
#include "CEventReceiver.h"
 
using namespace irr;
 
#ifdef _WIN32
 
#pragma comment(lib, "Irrlicht.lib")
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char* argv[])
#endif
{
        //setup event receiver
        CEventReceiver receiver;
        // create device 
        IrrlichtDevice *device = createDevice(video::EDT_OPENGL,
         core::dimension2d<u32>(640, 480), 16, false, false, false, &receiver);
        
        if (device == 0)
                return 1; // could not create selected driver.
        
        // create driver, scene manager, and camera
        device->setWindowCaption(L"Irrlicht Engine Demo");
        
        video::IVideoDriver* driver = device->getVideoDriver();
        scene::ISceneManager* smgr = device->getSceneManager();
 
        // setup camera and background
        scene::ICameraSceneNode * camera = smgr->addCameraSceneNode(0, core::vector3df(0, -41, 335), core::vector3df(0, -41, 0));
        smgr->addSkyBoxSceneNode(0, 0, 0, 0, driver->getTexture("media/blkbackground.png"), 0); 
 
        //test character
        CSpriteInterface *mySprite = 
                new CSpriteInterface(new CCanvasSceneNode(smgr->getRootSceneNode(), smgr, 666));
        mySprite->initMainTexture(smgr, driver->getTexture("media/chartest.png"));
        mySprite->setupFrames(8, 1);
        mySprite->setAnimation(device, mySprite->addAnimation(0, 7, 100, true));
        mySprite->setPosition(core::vector3df(0, 0, 10));
        receiver.setHero(mySprite);
 
        CTerrainInterface *myTerrain = 
                new CTerrainInterface(new CCanvasSceneNode(smgr->getRootSceneNode(), smgr, 665, 480, 320));
        myTerrain->initTexture(smgr, driver->getTexture("media/terrtest.png"));
        myTerrain->setPosition(core::vector3df(0,0,0));
 
   // In order to do framerate independent movement, we have to know
   // how long it was since the last frame
   u32 then = device->getTimer()->getTime();
   
   // This is the movemen speed in units per second.
   const f32 MOVEMENT_SPEED = 64.0f;
 
   /*
   Now draw everything and finish.
   */
 
   u32 frames=0;
   while(device->run())
   {
           const u32 now = device->getTimer()->getTime();
           //check receiver for input
           then = receiver.checkInput(camera, now, then, MOVEMENT_SPEED);
           
           // ***** update animations here ***** //
           mySprite->play(device, smgr);
           
           //scene manager
           driver->beginScene(true, true, video::SColor(0,100,100,100));
           smgr->drawAll();
 
           // ***** put everything not called by drawAll() here ***** //
           
           //end of scene
           driver->endScene();
 
           //calculate FPS
           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;
}
 
fuby
Posts: 14
Joined: Fri Apr 06, 2012 1:39 pm

Re: 2D images on 3D plane issue

Post by fuby »

Changing the camera to orthogonal did not seem to work.

using:

Code: Select all

        //http://irrlicht.sourceforge.net/forum/viewtopic.php?f=1&t=40323
        irr::core::matrix4 orthoMatrix;
        orthoMatrix.buildProjectionMatrixOrthoLH(640,480, 0.1f, 1000.f);
        camera->setProjectionMatrix(orthoMatrix, true); 
if the numbers should be different please let me know

Also, formula for A*K + B*T, wouldn't the same effect be achieved using:
Y = Y + movement_change
X = X + movement_change
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: 2D images on 3D plane issue

Post by REDDemon »

well that code is really to big ! i can't look right now. anyway yes. the formula will be the same :)
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
fuby
Posts: 14
Joined: Fri Apr 06, 2012 1:39 pm

Re: 2D images on 3D plane issue

Post by fuby »

Understood. Most folks are busy this weekend.
gerdb
Posts: 194
Joined: Wed Dec 02, 2009 8:21 pm
Location: Dresden, Germany

Re: 2D images on 3D plane issue

Post by gerdb »

hi, i tested this, and it seems to be a BUG in the material EMT_TRANSPARENT_ALPHA_CHANNEL

because it does not happen with EMT_SOLID.

i guess there is something not working with the Ortho Matrix in combination with that material, because it seems that the camera center point works,
but moving away from the center leads to a false zBuffer overwrite.

so --> the cam proj matrix still behaves like a perspective one, even for sprites and ortho matrix with that material.

SOLUTION for now: set the z pos of Sprite more near to camera --> like 100 or so, but i dont like it either

cya
CuteAlien
Admin
Posts: 9929
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: 2D images on 3D plane issue

Post by CuteAlien »

I think transparent polygons are sorted by the distance of their center to the camera. Didn't really dig into your problem much now, but it sounded from the description of it like that could be the problem.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
fuby
Posts: 14
Joined: Fri Apr 06, 2012 1:39 pm

Re: 2D images on 3D plane issue

Post by fuby »

@gerdb
I have done test with the sprite at 100 away from the terrain and it does still happen although farther away from center.

The reason I use the EMT_TRANSPARENT_ALPHA_CHANNEL is because KeyColor replacement available for draw2DImage function doesn't work with textures on 3D as far as I can tell. It would put the pink background back if I did not use the transparent alpha channel.

However, I will try EMT_SOLID when I get home tonight to verify the theory.

Thanks for the input.

@CuteAlien
Is there any options to have the engine sort it a different way?
CuteAlien
Admin
Posts: 9929
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: 2D images on 3D plane issue

Post by CuteAlien »

No option yet, I only know about it because it's something bothering us as well in a project.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply