Possible GuiObjectView Bug?
by Jason Guzzardo · in Torque 3D Professional · 07/20/2009 (10:38 am) · 7 replies
I tried to add a GuiObjectView to one of my GUIs and got the following error when I ran the GUI:
LightManager::registerGlobalLight - The light is already registered!
The following code, in GuiObjectView.cpp, seems to be where the issue is:
I used the following horrible hack to make sure the light is only set once and everything seems to work just fine:
I was wondering if someone could explain what's going on here so I can come up with a better solution for this. Obviously I would not want to use the above hack in production code. I'm not exactly sure what's going on with this setSpecialLight method.
LightManager::registerGlobalLight - The light is already registered!
The following code, in GuiObjectView.cpp, seems to be where the issue is:
LightManager* lm = gClientSceneGraph->getLightManager(); lm->setSpecialLight(LightManager::slSunLightType, mFakeSun);
I used the following horrible hack to make sure the light is only set once and everything seems to work just fine:
static int once = 0;
if(once == 0)
{
LightManager* lm = gClientSceneGraph->getLightManager();
lm->setSpecialLight(LightManager::slSunLightType, mFakeSun);
once++;
}I was wondering if someone could explain what's going on here so I can come up with a better solution for this. Obviously I would not want to use the above hack in production code. I'm not exactly sure what's going on with this setSpecialLight method.
About the author
#2
07/21/2009 (12:24 pm)
I can confirm: this is a new bug in Beta4, it wasn't in Beta3
#3
Remove these 2 lines from the renderWorld function
With Beta3 I haven't had these problems.
07/21/2009 (1:08 pm)
I've tried to fix this bug in this way:Remove these 2 lines from the renderWorld function
LightManager* lm = gClientSceneGraph->getLightManager(); lm->setSpecialLight(LightManager::slSunLightType, mFakeSun);And add these lines to the end of the onWake function,
LightManager* lm = gClientSceneGraph->getLightManager();
if (lm->getSpecialLight(LightManager::slSunLightType) != mFakeSun)
lm->setSpecialLight(LightManager::slSunLightType, mFakeSun);
return(true);
}It works, if you are not in mission, if you show the GuiObjectView while in a mission, all the objects are rendered black.With Beta3 I haven't had these problems.
#4
07/21/2009 (1:17 pm)
Well, ok ... instead of moving those lines in the onWake function leave them in the renderWorld function and it works correctly. :)
#5
07/21/2009 (5:45 pm)
hey thanks davide...I'm actually using this before I enter a mission but it looks like it will work either way by implementing your fix in renderWorld.
#6
code for console method setSeq:
Here is the code for renderWorld:
That's it! With this you should be able to call setSeq after setModel to set up an animation. I haven't tried this inside a mission yet but it works fine outside a mission. Again, if there is a better way to do this please let me know.
07/22/2009 (1:14 pm)
I got animation working in the GuiObjectView using setSeq. I'm not that familiar with T3D yet so if there is a better way to do this let me know. However, it's working good enouph for my needs right now.code for console method setSeq:
void GuiObjectView::setObjectAnimation(S32 index)
{
if ((0 > index) || (index > MAX_ANIMATIONS))
{
Con::warnf(avar("GuiObjectView: The index %d is outside the permissible range. Please specify an animation index in the range [0, %d]", index, MAX_ANIMATIONS));
return;
}
if(!mModel)
{
Con::warnf(avar("GuiObjectView: A valid model must be set using setModel() before choosing an animation sequence!"));
return;
}
if(runThread != NULL)
{
mModel->destroyThread(runThread);
runThread = NULL;
}
mAnimationSeq = index;
runThread = mModel->addThread();
mModel->setSequence(runThread, mAnimationSeq, 0);
}Here is the code for renderWorld:
void GuiObjectView::renderWorld(const RectI &updateRect)
{
if ((! mModel) && (! mMountedModel))
{
// nothing to render, punt
return;
}
// Determine the camera position, and store off render state...
MatrixF modelview;
MatrixF mv;
Point3F cp;
modelview = GFX->getWorldMatrix();
mv = modelview;
mv.inverse();
mv.getColumn(3, &cp);
RenderPassManager *renderPass = gClientSceneGraph->getRenderPass();
LightManager* lm = gClientSceneGraph->getLightManager();
if (lm->getSpecialLight(LightManager::slSunLightType) != mFakeSun)
lm->setSpecialLight(LightManager::slSunLightType, mFakeSun);
GFX->setStateBlock(mDefaultGuiSB);
MatrixF meshCamTrans(true);
F32 left, right, top, bottom, nearPlane, farPlane;
bool isOrtho;
GFX->getFrustum( &left, &right, &bottom, &top, &nearPlane, &farPlane, &isOrtho);
Frustum frust( false, left, right, top, bottom, nearPlane, farPlane, meshCamTrans );
SceneState state(
NULL,
gClientSceneGraph,
SPT_Diffuse,
1,
frust,
GFX->getViewport(),
meshCamTrans,
false );
// Set up our TS render state here.
TSRenderState rdata;
rdata.setCamTransform( meshCamTrans );
rdata.setSceneState( &state );
if (mModel)
{
if(runThread != NULL)
{
S32 time = Platform::getVirtualMilliseconds();
S32 dt = time - lastRenderTime;
lastRenderTime = time;
F32 fdt = dt;
mModel->advanceTime( fdt/1000.f, runThread );
mModel->animate();
}
mModel->render( rdata );
}
if (mMountedModel)
{
// render a weapon
MatrixF mat;
getMountedObjTransform(&mat);
GFX->pushWorldMatrix();
GFX->multWorld( mat );
mMountedModel->render( rdata );
GFX->popWorldMatrix();
}
renderPass->renderPass(&state);
}That's it! With this you should be able to call setSeq after setModel to set up an animation. I haven't tried this inside a mission yet but it works fine outside a mission. Again, if there is a better way to do this please let me know.
#7
10/05/2009 (9:52 pm)
thanks for this post Davide, totally hit this bug and here was the fix !
Torque 3D Owner Jason Guzzardo
Is GuiObjectView still under development due to beta or are these real issues i'm finding?