CQuake3ShaderSceneNode Bugfix and Texture Matrix...

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
jef
Posts: 18
Joined: Sat Nov 13, 2004 10:10 pm

CQuake3ShaderSceneNode Bugfix and Texture Matrix...

Post by jef »

In CQuake3ShaderSceneNode::render(), driver->setMaterial overwrites
the animated texture matrix with an identity matrix.

Code: Select all

	driver->setTransform ( video::ETS_TEXTURE_0, texture );

	driver->setMaterial( material );
should be...

Code: Select all

	driver->setMaterial( material );

	driver->setTransform ( video::ETS_TEXTURE_0, texture );
Texture Matrix...

Unfortunately, since revision 1031 texture translation has no
longer been working in CQuake3ShaderSceneNode.

I did a search in the code for buildTextureTransform,
setTextureScale, setTextureRotationCenter, setTextureScaleCenter
and setTextureTranslate and find out that buildTextureTransform
is not used at all and the other functions are only used in
CQuake3ShaderSceneNode.

It seems to me that the author of CQuake3ShaderSceneNode is also the
author of the texture matrix functions and the intention was to
transpose the animated texture matrix. So therefore I suggest that
the setTextureTranslate function is restored to what it was before
revision 1031.


I have created a simple application to test all functions. I have no
idea how to use buildTextureTransform correctly but with some trial
and error I got it to work. Math is not one of my strengths but I
think there is bug in buildTextureTransform. To get the rotatecenter
in center I had to do this...

Code: Select all

	m_rotatecenter.Y *= scale.Y;
there it should be...

Code: Select all

	m_rotatecenter *= scale;
The test application (source code included)

Image
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

The setTextureTranslate() function was wrong before r1031. Not only was it wrong [i.e. it didn't work], but it is not consistent with the buildTextureMatrix() function. If you look at buildTextureMatrix() you can see that the position goes into elements 8 and 9.

Here is a simple test...

Code: Select all

#include <irrlicht.h>
using namespace irr;

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

void matrix_setTextureTranslateOld (core::matrix4& m, f32 x, f32 y )
{
   m[2] = x;
   m[6] = y;
}

void matrix_setTextureTranslateNew (core::matrix4& m, f32 x, f32 y )
{
   m[8] = x;
   m[9] = y;
}

// comment out to use fixed translate
#define USE_OLD_MATRIX_TRANSLATE 1

int main()
{
   IrrlichtDevice* device =
      createDevice(video::EDT_OPENGL, core::dimension2d<s32>(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::ISceneNode* cube = smgr->addCubeSceneNode();
   cube->setMaterialFlag(video::EMF_LIGHTING, false);
   cube->setMaterialTexture(0, driver->getTexture("../../media/dotnetback.jpg"));

   f32 offset = 0.f;

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

   while(device->run())
   {
      if (device->isWindowActive())
      {
         if (driver->beginScene(true, true, video::SColor(0,200,200,200)))
         {
            u32 now = device->getTimer()->getTime();
            offset += (now - then) / 5000.f;
            then = now;

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

            core::matrix4 m;

#if USE_OLD_MATRIX_TRANSLATE
            matrix_setTextureTranslateOld(m, offset, 0.f);
#else
            matrix_setTextureTranslateNew(m, offset, 0.f);
#endif

            cube->getMaterial(0).setTextureMatrix(0, m);

            smgr->drawAll();

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

   device->drop();
   
   return 0;
}
If there is a problem now with the quake stuff, that is because the quake stuff depended on the bug in the matrix class.

Travis
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I can see that the other matrix methods setTextureRotationCenter() and setTextureScaleCenter() have the same problem that setTextureTranslate() had. The offset is being put into the wrong elements of the matrix.

Travis
jef
Posts: 18
Joined: Sat Nov 13, 2004 10:10 pm

Post by jef »

I have tested your example and I can see what you mean, but You
can also do it as in the quake3 shader code.

Code: Select all

#if USE_OLD_MATRIX_TRANSLATE
#if USE_OLD_MATRIX_TRANSLATE_TRANSPOSED
            core::matrix4 m2;
            m2.setTextureTranslate( offset, 0.f );
            m2.getTransposed( m );
#else
            matrix_setTextureTranslateOld(m, offset, 0.f);
#endif

#else
            matrix_setTextureTranslateNew(m, offset, 0.f);
#endif
I understand that there is probably a problem with these functions but is it
not better to leave the functions as they are until there is a complete patch?
If there is a problem now with the quake stuff, that is because the quake stuff depended on the bug in the matrix class.
The only functional problem in CQuake3ShaderSceneNode before revision r1031 was
that the animated texture matrix was overwritten in the render function.

I have tested the modified code with the maps in pak0.pk3 from Quake3
and the textures translates and rotates nicely.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

If you don't start to fix something, you'll never finish it... Some guys want core::matrix4 to behave correctly, others will want the shader node to work correctly. The best thing to do is fix them.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Sorry, I'm not setup to use SVN from this machine, but here is a pseudo-patch of the changes I had to make to the Q3 node after fixing the matrix functions. I pasted the fixed versions of the matrix4 functions here.

Code: Select all


 + 	core::matrix4 mat;
 - 	core::matrix4 texturem;
 - 	core::matrix4 m2;
 + 					texture.makeIdentity ();
 - 					texturem.makeIdentity ();
 + 				mat.makeIdentity ();
 - 				m2.makeIdentity ();
 + 				mat.setTextureTranslate ( f0, f1 );
 - 				m2.setTextureTranslate ( f0, f1 );
 + 				mat.setTextureScale ( f0, f1 );
 - 				m2.setTextureScale ( f0, f1 );
 + 				mat.setTextureRotationCenter ( quake3::getAsFloat ( v.content, pos ) * core::DEGTORAD * dt );
 - 				m2.setTextureRotationCenter ( quake3::getAsFloat ( v.content, pos ) * core::DEGTORAD * dt );
 + 						mat.setTextureScaleCenter ( f0, f0 );
 - 						m2.setTextureScaleCenter ( f0, f0 );
 + 						mat.setTextureTranslate ( f1, f0 );
 - 						m2.setTextureTranslate ( f1, f0 );
 + 				texture *= mat;
 - 				texturem *= m2;
 + 	textureMatrixFound += tcgen ( dt, function, texture );
 - 	textureMatrixFound += tcgen ( dt, function, texturem );
 - 
 - 	//if ( textureMatrixFound )
 - 	//{
 - 	//	texturem.getTransposed ( texture );
 - 	//}
jef
Posts: 18
Joined: Sat Nov 13, 2004 10:10 pm

Post by jef »

vitek thanks for your engagement in this.

The reason I took up this topic is that I thought it would be good if the
CQuake3ShaderSceneNode worked as intended. The two simple changes
I suggested really make it work but it's probably better to fix the matrix
once for all.
Post Reply