Lock texture bug

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
pippy
Posts: 49
Joined: Sun Jul 08, 2007 11:31 pm

Lock texture bug

Post by pippy »

I have a texture that gets reused a lot, so I lock it. It has an alpha channel. I use driver->makeColorKeyTexture on to give it alpha channel, multiple times. Because its locked it shouldn't change.

In DirectX this works, but if I use software or OpenGL the texture become corrupted

Is this a bug in the Irrlicht, or should I make my own data type to protect the textures?

I had a good look through the API, and couldn't find a "isLocked()" return function. I could add it easily. However I did notice a Iimage (or something to that effect) class. I'm wounding if should change to this class
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

I guess that you have interpreted the lock() method wrongly. Locking a texture means that you disable access to it from anywhere except your main thread. That way you can be sure that you can change the texture as you want. But the changes won't be back propagated into the render thread until you unlock it. So lock and unlock is only needed when changing parts of the texture from within your main app.
You also may have to regenerate mipmaps of the texture in order to get the changes propagated into mipmaps.
WoodKeeper
Posts: 2
Joined: Fri Sep 14, 2007 2:03 pm

Post by WoodKeeper »

Hi,

I am posting in here because i have a relevated issue.

I need to access the pixels of a RenderTargetTexture. The only way i found out yet is to lock the RT Texture, thus returning a pointer to access the pixels.

The RTT size in my project can differ, so i can not use Direct3D as long its RTT Size is limited (window Size && power of 2).

But when i use OpenGL, to avoid these limitations "lock()" always returns a null pointer. I can access the pixels only in Direct3D. It might have something to do with the FBO Usage for the RTT in OpenGL.

I looked in the code of irrlicht 1.3.1. While
void* CD3D8Texture::lock() and void* CD3D9Texture::lock() are full of code, void* COpenGLTexture::lock() seem to return only the standard return value (0) of the virtual method IImage::lock().
I can be wrong, because i am new to irrlicht and only did a qick investigation of my problem.

My guess is: under OpenGL the texture is not locked, and therefore the textures in the topicstarters project can be altered and may get corrupt.

Any hints for my problem though?

Edit: seem to be the same for the softwarerenderer but burningvideo works

bye woodkeeper
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

lock() is unsupported for most render targets, the Direct3D version was posted as a patch for irrlicht 0.14. If you really need this feature and decide to implement it, please post to code so we can add it :)
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
pippy
Posts: 49
Joined: Sun Jul 08, 2007 11:31 pm

Post by pippy »

I had a look at Iimage, its useless as you have to convert it from a texture.

I think that irrlicht engine creates a mipmap upon creating an alpha channel so

Code: Select all

if(TileTexture->hasMipMaps() != NULL){
	driver->makeColorKeyTexture(Texture, video::SColor(255,255,0,255));
}
should work, but doesn't. however this code does fix the problem in the burning software driver.

A hasAlpha() function would be great, or getColorKey()

I'll try to make a change to the irrlicht engine, it would only take a boolean value and two get/set methods. This would mean compiling the engine, and mucking around for a long time.
pippy
Posts: 49
Joined: Sun Jul 08, 2007 11:31 pm

Post by pippy »

I modified the Irrlicht Engine to include two functions: getAlphaSet() and setAlphabit(). the bool gets set to 0 when create an Itexture, and if the user changes the alpha it gets set to 1. You can check if you have added alpha using the getAlphaSet() method.

This did solve my transparency problems, however the textures are still corrupt, even after removing the lock function.

In the 2d tutorial there are no problems with the alpha channel, and I'm using the same method. It could be the type of .BMP, but to my knowledge this shouldn't matter.

http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=23833 This guy also has the same problem

You can see the corruption in this image:
Image
The mouse is the wrong size, and the alpha channel around each image is incorrect.

EDIT: I would bitplane, but I have no knowledge on how to do something like that
Yarcanox
Posts: 33
Joined: Sat Apr 14, 2007 11:23 pm

Post by Yarcanox »

How can I convert an ITexture to an IImage? I fear I'll need a working lock() for that, won't I? And I have no idea how to fix/implement it, so how can I get an ITexture into an IImage now :?
I'm not a native English speaker.
pippy
Posts: 49
Joined: Sun Jul 08, 2007 11:31 pm

Post by pippy »

I tried a lot of things to get the scale right. Nothing seems to work, I've spent the last 2 days trying to fix it. I even changed the engine to no avail.

http://irrlicht.sourceforge.net/phpBB2/ ... ytoscaling
One thing I did was modify this function to read in the size before and after loading a texture, and it gets the dimensions right, but just to put salt on the wound the image snaps to the wrong size

This is incredibly frustrating.

Even if I directly tell Irrlicht to make the texture right it still does it wrong

I guess we'll just have to hope that this bug gets fixed in the next version, or I'll have to port my game to another engine :/
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Maybe you should start posting code and useful information instead of confusing fragments. You still did not answer to my first assumption. Moreover, even if you avoid lock and unlock the makeColorKeyTexture method will call it (because that's the only way to change a texture).
So did you choose a proper texture size (power of two), do ou lock and unlock properly and do you regenerate mipmaps (in case mipmaps are needed) :?:
pippy
Posts: 49
Joined: Sun Jul 08, 2007 11:31 pm

Post by pippy »

hybrid wrote:Maybe you should start posting code and useful information instead of confusing fragments. You still did not answer to my first assumption. Moreover, even if you avoid lock and unlock the makeColorKeyTexture method will call it (because that's the only way to change a texture).
So did you choose a proper texture size (power of two), do ou lock and unlock properly and do you regenerate mipmaps (in case mipmaps are needed) :?:
I realized after reading other forum threads that the lock() function does not work in openGL, so I had to substitute my own. I fixed that problem.

makeColorKeyTexture is NOT the only way to change a texture. You can convert a texture to an image, manipulate it, then change it back.

Here's some code to demonstrate what I mean. 1.png is a 200x100 image with an alpha channel. The problem also arises when I manually select the transparency.

Code: Select all

video::ITexture* texture1 = driver->getTexture("1.png");

std::cout << texture1->getSize ().Height << " , " << texture1->getSize ().Width << " : " <<texture1->getOriginalSize ().Height<<" , "<<texture1->getOriginalSize ().Width << "\n";

driver->draw2DImage(texture1, core::position2d<s32>(50,200), core::rect<s32>(0,0,200,100), 0, video::SColor(255,255,255,255), true)
In openGL it prints: 100 , 200 : 128 , 256
In DirectX: 128 , 256 : 100 , 200

A first reaction would be to write a function that resizes the image if the original size it greater than the current size. But like I said before, it snaps to the incorrect size
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

The lock function does work under OpenGL, but not for rendertarget textures.
I did not say that makeCKT is the only way to change a texture, but that you cn only change a texture by locking it first.
The DirectX output is correct. This is due to a bug in OpenGL in 1.3.1. simply exchange the constens of getSize and getOriginalSize in COpenGLTexture.cpp
pippy
Posts: 49
Joined: Sun Jul 08, 2007 11:31 pm

Post by pippy »

hybrid wrote:The lock function does work under OpenGL, but not for rendertarget textures.
I did not say that makeCKT is the only way to change a texture, but that you cn only change a texture by locking it first.
The DirectX output is correct. This is due to a bug in OpenGL in 1.3.1. simply exchange the constens of getSize and getOriginalSize in COpenGLTexture.cpp
Ah! thanks, that got it working perfect in OpenGL! =D

In order to help other people out, What should I do about my DLL I compiled? there was another person getting headaches over this problem too. I take it that developers of Irrlicht already know about this bug, but should I try and fix it in the other software devices? no matter how trivial, don't I have to share what I just edited?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

The OpenGL bug has been removed in the development version for several month already. But the Software devices are often neglected. So if you have some fixes there, too, you should post them in the bug forum.
Please note that you should use the SVN version of Irrlicht in order to have the latest development code. Moreover, this will simplify code additions for a new release - otherwise we have to port you code changes to the most recent code versions.
cpaganucci
Posts: 4
Joined: Tue Nov 13, 2007 9:18 pm

Post by cpaganucci »

Sorry, I'm a little confused...

Pippy - are you saying that you solved the locking problem for rendertarget textures in OpenGL? I tried hybrid's suggestion of swapping getSize and getOriginalSize in COpenGLTexture.cpp, but that didn't seem to do anything.

What I'm ultimately trying to do is directly modify a texture that I've rendered text to, but without the ability to lock a rendertarget texture I don't see a way to do it.

FYI - I'm using 1.3.1. I tried switching to 1.4 beta, but that breaks a bunch of other things, and I'd prefer to just modify the 1.3.1 code at this point.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Locking an RTT under OpenGL does not give you an editable images, yet. I'm not usre if it only affects FBO RTTs, or also usual ones. But I suppose that you could have success by disabling FBO support in the OpenGL driver:
Replace if (queryFeature(EVDF_FRAMEBUFFER_OBJECT)) by if(false) and you should get plain texture RTTs which might be lockable (but also much slower).
Post Reply