Page 1 of 1

Replacing a model texture at runtime

Posted: Tue Mar 07, 2006 8:36 am
by theandrew80
Hi all.
I'm trying to replace the content of a texture (statically applied to the material using a 3d model tool) with the content of a bitmap, using the following code:

Code: Select all

IAnimatedMesh mesh = m_Device.SceneManager.GetMesh(@"Card.x");
m_FullCardMeshNode = m_Device.SceneManager.AddAnimatedMeshSceneNode(mesh, null, -1);
m_FullCardMeshNode.AnimationSpeed = 0;
m_FullCardTextureFront = m_FullCardMeshNode.GetMaterial(0).Texture1;

// Get card bitmap pixels
System.Drawing.Imaging.BitmapData bmpdata = m_FullCardBitmap.LockBits( 
	new Rectangle(0, 0, m_FullCardBitmap.Width, m_FullCardBitmap.Height), 
	System.Drawing.Imaging.ImageLockMode.ReadOnly, m_FullCardBitmap.PixelFormat);
uint* pNewData = (uint*)bmpdata.Scan0.ToPointer();

// Get card texture pixels
uint* pOldData = (uint*)m_FullCardTextureFront.Lock();

try
{
	// Copy bitmap into texture
	for(int i = 0; i < m_FullCardBitmap.Width * m_FullCardBitmap.Height; i++)
	{
		*pOldData =	*pNewData;
		pNewData++;
		pOldData++;
	}
}
finally
{
	m_FullCardTextureFront.Unlock();
	m_FullCardBitmap.UnlockBits(bmpdata);
}
This works fine: I can see the new image applied in front of my model.

The problem is that if I zoom away from my model, the new image disappear and the old image comes back on the texture. I think that my function replaces the largest bitmap of the texture, but the other smallest images (mipmaps) remains the same.

Do anyone know how I can replace all mipmaps or how I can tell to engine to do this for me?

Thanks! :wink:

Posted: Tue Mar 07, 2006 10:17 am
by Martins
Hello theandrew80!

This is super cool what you are doing and exactly what I need in my project.
I have never used unsafe code in my managed applications, but I needed
to manipulate textures directly in-memory like you did!

I had a look at C++ implementation, and ITexture has a virtual
method ITexture::regenerateMipMapLevels(). And I guess it is what you
need. But it seems that it is not implemented on .NET side though.

Probably you have an idea how to call it directly? Please, let me
know if you find the solution. I am very interested!!!

P.S. The source code of .NET part, that comes with irrlicht is not complete, is it?

Posted: Tue Mar 07, 2006 11:41 am
by Braneloc
Martins wrote:The source code of .NET part, that comes with irrlicht is not complete, is it?
Nope :(

Posted: Tue Mar 07, 2006 12:15 pm
by Martins
I went to sourceforge CVS and it has full .NET source code. I will try to add missing method definition to ITexture and try this out later when I get home.

And sorry for my ignorace, but is the posted code C++ or C#? Can I do pointers like this in C#?
And regarding data copying, could it be done with Marshal.Copy() instead?

Posted: Tue Mar 07, 2006 12:31 pm
by theandrew80
Martins wrote:I had a look at C++ implementation, and ITexture has a virtual
method ITexture::regenerateMipMapLevels().
Very interesting! I'll try to call it from my c# code.
Martins wrote:I will try to add missing method definition to ITexture and try this out later when I get home.
Ok! Please, let me know the results! :D
Martins wrote:Is the posted code C++ or C#? Can I do pointers like this in C#?
The code is in C#, the class that include it is unsafe; with unsafe you can use pointers like the c++ ones.
Martins wrote:And regarding data copying, could it be done with Marshal.Copy() instead?
Sorry but I never used it, i don't know... :?

Posted: Tue Mar 07, 2006 1:35 pm
by theandrew80
Martins wrote:I went to sourceforge CVS and it has full .NET source code.
Please can you post the link for sourceforge CVS? Thanks!

Posted: Tue Mar 07, 2006 2:20 pm
by Martins
theandrew80 wrote: Please can you post the link for sourceforge CVS? Thanks!
http://cvs.sourceforge.net/viewcvs.py/i ... licht.NET/

Yet it's better to download code with some CVS client like explained here:
http://sourceforge.net/cvs/?group_id=74339

Posted: Tue Mar 07, 2006 3:23 pm
by theandrew80
I've downloaded the Irrlicht.NET source from CVS using WinCvs and I've added the RegenerateMipMapLevels() method to the .NET ITexture interface.
Now all works well :D !!!

Thanks Martin for your help!