more texture matrix functions wrong

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

more texture matrix functions wrong

Post by vitek »

In a discussion with jef, we found that several fo the texture matrix functions are wrong. Specifically, the position offset was being stored in the transposed positions [i.e. offset stored in indexes 2 and 6 instead of 8 and 9]. Another thing that I've noticed, but not changed, is that positive texture offsets actually move the texture up and to the left. I would expect this to move the texture down and to the right, but I'm not really sure I'm right. Anyone?

Code: Select all

// removed until correct matrices can be created.
Travis
Last edited by vitek on Fri Oct 26, 2007 6:05 pm, edited 1 time in total.
jef
Posts: 18
Joined: Sat Nov 13, 2004 10:10 pm

Post by jef »

I think it is correct.

"Q3A Shader Editor" a program specialized on texture matrix transformations also moves the texture up and to the left on positive offsets and (correct me if I am wrong) in translation Irrlicht only put values in m[8] and m[9] and it is the underlying API (Direct3D|OpenGL) that does the actual transformation, the result from this is as you describe, positive offsets move the texture up and to the left. I can't see why m[8] and m[9] should be reversed.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I forgot that I'm using the cube scene node in my tests and I don't know off the top of my head what the order of the vertices are when rendering and what their texture coordinates are. Given a quad laid out like the one below, I would expect the texture to scroll to the right with positive x translations, and down with positive y. Obviously if you change the texture coordinates around then the direction would change.

Code: Select all

 (0, 0)  +---------+ (1, 0)
         | \       |
         |   \     |
         |     \   |
         |       \ |
 (0, 1)  +---------+ (1, 1)
I'll verify later tonight.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Yes, that is how the current implementation behaves. Here is my test code.

Code: Select all

#include <irrlicht.h>
using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

int main()
{
   IrrlichtDevice* device =
      createDevice(video::EDT_DIRECT3D8, core::dimension2di(640, 480), 32, false, false);
   if (device == 0)
      return 1; // could not create selected driver.

   video::IVideoDriver* driver = device->getVideoDriver();
   scene::ISceneManager* smgr = device->getSceneManager();

   smgr->addCameraSceneNodeFPS(0, 50, 50);

   scene::SMeshBuffer mb;

   // 0  +---------+ 2
   //    | \       | 
   //    |   \     | 
   //    |     \   | 
   //    |       \ | 
   // 1  +---------+ 3

   for (u32 i = 0; i < 4; ++i)
   {
     video::S3DVertex v;
     
     // (0, 0) (1, 0)
     // (0, 1) (1, 1)
     v.TCoords.X = i & 2 ? 1.f : 0.f;
     v.TCoords.Y = i & 1 ? 1.f : 0.f;

     // (  0,   0, 255) (255,   0, 255)         blue  purple
     // (  0, 255, 255) (255, 255, 255)  i.e.   teal  white
     v.Color.set(255, u32(v.TCoords.X * 255), u32(v.TCoords.Y * 255), 255);

     // (-5,  5) (5,  5)
     // (-5, -5) (5, -5)
     v.Pos.X = -5.f + v.TCoords.X * 10.f;
     v.Pos.Y = 5.f + v.TCoords.Y * -10.f;
     v.Pos.Z = 10.f;

     // normal points at camera
     v.Normal.set (0, 0, -1);

     mb.Vertices.push_back(v);
   }

   mb.Indices.push_back(0);
   mb.Indices.push_back(3);
   mb.Indices.push_back(1);
   mb.Indices.push_back(0);
   mb.Indices.push_back(2);
   mb.Indices.push_back(3);

   mb.Material.Lighting = false;
   mb.Material.setTexture(0, driver->getTexture("../../media/dotnetback.jpg"));

   f32 offset = 1.f;

   u32 then = device->getTimer()->getTime();

   while(device->run())
   {
      if (device->isWindowActive())
      {
         if (driver->beginScene(true, true, video::SColor(0,60,60,60)))
         {
            smgr->drawAll(); // camera needs this to move

            u32 now = device->getTimer()->getTime();
            offset += (now - then) / 20000.f;
            then = now;

            if (1.f < offset)
               offset = 0.f;

            core::matrix4 m;

            driver->setTransform(video::ETS_WORLD, m);
            driver->setMaterial(mb.Material);

            m.setTextureTranslate(offset * 2, offset / 2); // move right and down slow
            driver->setTransform(video::ETS_TEXTURE_0, m);

            driver->drawMeshBuffer(&mb);

            driver->endScene();
         }
      }
      else
      {
         device->sleep(125);
      }
   }

   device->drop();
   
   return 0;
}
jef
Posts: 18
Joined: Sat Nov 13, 2004 10:10 pm

Post by jef »

Code: Select all

// move right and down slow
From that comment I suppose the texture should move down and to the right, but on my machine with your test code the texture moves up and to the left.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

jef,

You're absolutely right. My late night code changes included the sign inversion in setTextureTranslate(). I think i need to tweak a few of the above matrix methods.

Travis
Post Reply