Terrain Texture Painter
by Kyle Goodwin · in Torque Game Engine Advanced · 11/21/2004 (10:39 am) · 10 replies
Could anyone offer any assistance on what could be causing the TSE Terrain texture Painter to exit with no error message in the console log or segfault etc. when I attempt to change a texture? This happens both in the editor in the TSE demo and also when I try to do it in my game directory (based on a ported starter.fps).
Thanks. :)
Thanks. :)
About the author
#2
11/21/2004 (3:35 pm)
Actually I'd liek to change the texture used for one of the previously defined textures if that makes sense. In this case there is a grass texture for the terrain, but because of absolute paths it wants it out of the demo folder. I'd like to change it to a different texture without having to repaint. You can do this in TGE, but it crashes (generally on the second change if originally it can't find any and they're all black).
#3
11/22/2004 (3:01 pm)
I'm having this same issue. I can change one or two textures and then the next one causes a crash. Gonna debug it now.
#4
In this code 'y' == 0 and not NIL (which is the &nil).
Testing in plain TGE i can change the textures via Terrain Painter all i want without a crash.
Testing in TSE when i change a texture in Terrain Painter it causes a crash.
So it's clear it's either something that was patched in TGE between the TSE branch and 1.3 or a new bug in TSE.
I'll spend a bit longer on it, but will just work around it by using TGE to correct the paths. I guess i could try the memory debugging routines. Any other suggestions?
11/22/2004 (3:45 pm)
Uggh... it's crashing deep in Memory::treeRemove while it's trying to allocate another GBitmap. Specificly on line 486 of platformMemory.cpp:y = z->right;
while(y->left != NIL) // crash!
y = y->left;In this code 'y' == 0 and not NIL (which is the &nil).
Testing in plain TGE i can change the textures via Terrain Painter all i want without a crash.
Testing in TSE when i change a texture in Terrain Painter it causes a crash.
So it's clear it's either something that was patched in TGE between the TSE branch and 1.3 or a new bug in TSE.
I'll spend a bit longer on it, but will just work around it by using TGE to correct the paths. I guess i could try the memory debugging routines. Any other suggestions?
#5
tex->mD3DTexture == 0xcececece which according to platformMemory is the fill value for previously freed memory blocks. Part of the members of the 'texture' argument are also 0xcececece. Looking further up the call stack it's coming from a bad texture in guiBitmapCtrl.cpp in the function GuiBitmapCtrl::onRender:
Gonna see if i can now find out why this is and get a fix for it.
11/22/2004 (4:42 pm)
I turned on DEBUG_GAURD and it now crashes in gfxD3DDevice.cpp in the function GFXD3DDevice::setTextureInternal:void GFXD3DDevice::setTextureInternal( U32 textureUnit, const GFXTextureObject *texture)
{
if( texture == NULL )
{
mD3DDevice->SetTexture( textureUnit, NULL );
return;
}
GFXD3DTextureObject *tex = (GFXD3DTextureObject *) texture;
mD3DDevice->SetTexture( textureUnit, tex->mD3DTexture ); // crash!
}tex->mD3DTexture == 0xcececece which according to platformMemory is the fill value for previously freed memory blocks. Part of the members of the 'texture' argument are also 0xcececece. Looking further up the call stack it's coming from a bad texture in guiBitmapCtrl.cpp in the function GuiBitmapCtrl::onRender:
GFX->drawBitmapStretchSR(texture,dstRegion, srcRegion); // texture is borked!
Gonna see if i can now find out why this is and get a fix for it.
#6
What's happening is that 'createTexture' is returning the *same* GFXTextureObject as the current ref from the texture cache. The problem is that RefObjectRef::set will decrement the reference first, which deletes the GFXTextureObject, then set the now deleted pointer!
My simple suggestion is to fix:
I'll post the fix to the bugs forum too.
11/22/2004 (5:14 pm)
I fixed the bug. It's a serious flaw in RefObjectRef::set:bool GFXTexHandle::set( StringTableEntry texName, GFXTextureProfile *profile )
{
AssertFatal( texName, "Texture name is NULL" );
RefObjectRef::set( GFX->mTextureManager->createTexture( texName, profile ) );
return isValid();
}
void RefObjectRef::set(RefBase *object)
{
decRef();
mObject = object;
incRef();
}What's happening is that 'createTexture' is returning the *same* GFXTextureObject as the current ref from the texture cache. The problem is that RefObjectRef::set will decrement the reference first, which deletes the GFXTextureObject, then set the now deleted pointer!
My simple suggestion is to fix:
void RefObjectRef::set(RefBase *object)
{
if ( mObject != object ) {
decRef();
mObject = object;
incRef();
}
}I'll post the fix to the bugs forum too.
#7
11/23/2004 (12:40 pm)
Fix is checked in, thanks Tom.
#8
You are correct. Having looked at the code I can see that RefObjectRef first attempts to decrement the reference count for the object it was previously pointing at. It then tries to assign the new object and increments the new objects ref count.
It does not check to see if it has been assigned the same object twice.
This leads to situations where you assign texture A once (this works as the object is newly created). You accidentally try to assign texture A again.
In the above case RefObjectRef will decrement texture A's reference count. If the count is zero (and it will be in most cases) then RefObjectRef triggers an object delete. RefObjectRef then tries to assign the deleted object as it's new reference.
Guess I should download the new stuff now
11/23/2004 (1:07 pm)
@Tom You are correct. Having looked at the code I can see that RefObjectRef first attempts to decrement the reference count for the object it was previously pointing at. It then tries to assign the new object and increments the new objects ref count.
It does not check to see if it has been assigned the same object twice.
This leads to situations where you assign texture A once (this works as the object is newly created). You accidentally try to assign texture A again.
In the above case RefObjectRef will decrement texture A's reference count. If the count is zero (and it will be in most cases) then RefObjectRef triggers an object delete. RefObjectRef then tries to assign the deleted object as it's new reference.
Guess I should download the new stuff now
#9
11/23/2004 (1:24 pm)
It's always amazing to me how such simple code can contain the most spectacular bugs.
#10
I dont ahve time to check the code and see if its a similar cause as I'm about to leave work and go home but I'll check it out tomorrow.. in the meantime I wanted to post htis here in case it was something different.. although it sounds the same...
09/14/2006 (3:40 pm)
Not sure if anyone looks at this anymore... but this bug that was fond adn "fixed" in 2004... is happening again in the new ms 3.5 TSE the exact error from the crash when u try to change textures is:GFXD3DDevice::setActiveRenderSurface - Cannot have an active render target bound to a texture sampler!!
I dont ahve time to check the code and see if its a similar cause as I'm about to leave work and go home but I'll check it out tomorrow.. in the meantime I wanted to post htis here in case it was something different.. although it sounds the same...
Torque 3D Owner David Erenger