Game Development Community

GuiSpeedometer pushWorldMatrix() mismatch

by Tony Richards · in Torque Game Engine Advanced · 09/03/2005 (5:02 pm) · 11 replies

I was playing around with the Racing Starter Kit in TSE and hit this bug.

In GuiSpeedometerHud::onRender() there's a GFX->pushWorldMatrix() without a GFX->popWorldMatrix();

Easy enough fix, just thought you might wanna know.

About the author

I am the founder of IndieZen.org, a website dedicated to the Indie 2.0 Revolution where a number of Indie game development studios and individuals collaborate and share a suite of custom built open source game development tools and middleware.


#1
10/03/2005 (9:41 pm)
Awesome, where exactly are we supposed to place the pop statement?
#2
10/03/2005 (9:43 pm)
I placed it at the very last line of the function...

//-----------------------------------------------------------------------------
/**
   Gui onRender method.
   Renders a health bar with filled background and border.
*/
void GuiSpeedometerHud::onRender(Point2I offset, const RectI &updateRect)
{
   // Must have a connection and player control object
   GameConnection* conn = GameConnection::getServerConnection();
   if (!conn)
      return;
   Vehicle* control = dynamic_cast<Vehicle*>(conn->getControlObject());
   if (!control)
      return;

   Parent::onRender(offset,updateRect);

   // Use the vehicle's velocity as it's speed...
   mSpeed = control->getVelocity().len();
   if (mSpeed > mMaxSpeed)
      mSpeed = mMaxSpeed;

   // Render the needle
   GFX->pushWorldMatrix();   // glPushMatrix();
   Point2F center = mCenter;
   if (isZero(center.x) && isZero(center.y))
   {
      center.x = mBounds.extent.x / 2;
      center.y = mBounds.extent.y / 2;
   }
   MatrixF newMat(1);

   newMat.setPosition(Point3F(mBounds.point.x + center.x,mBounds.point.y + center.y,0));

   F32 rotation = mMinAngle + (mMaxAngle - mMinAngle) * (mSpeed / mMaxSpeed);
   AngAxisF newRot(Point3F(0.0f,0.0f,-1.0f), rotation);

   newRot.setMatrix(&newMat);

   GFX->setAlphaBlendEnable( true );
   GFX->setSrcBlend(GFXBlendSrcAlpha);
   GFX->setDestBlend(GFXBlendInvSrcAlpha);

   GFX->setTextureStageColorOp(0, GFXTOPDisable);
   GFX->setTexture(0, NULL);

   PrimBuild::begin(GFXLineStrip, 5);
   PrimBuild::color4f(mColor.red, mColor.green, mColor.blue, mColor.alpha);

   PrimBuild::vertex2f(+mNeedleLength,-mNeedleWidth);
   PrimBuild::vertex2f(+mNeedleLength,+mNeedleWidth);
   PrimBuild::vertex2f(-mTailLength  ,+mNeedleWidth);
   PrimBuild::vertex2f(-mTailLength  ,-mNeedleWidth);

   // Get back to the start!
   PrimBuild::vertex2f(+mNeedleLength,-mNeedleWidth);

   PrimBuild::end();

   [b]GFX->popWorldMatrix();[/b]
}
#3
10/03/2005 (10:27 pm)
I've implemented the changes, but they don't solve my pink screen problem. Thanks, though.
#4
10/03/2005 (11:28 pm)
Oh well... but it does solve the general crash problem with the starter.racing scripts. ;-)
#5
10/28/2005 (7:07 am)
Quick question, does the actual needle draw for you? Not drawing for me.
#6
10/28/2005 (10:33 am)
No... I didn't really look into why it wasn't drawing either... it was good enough for me that it no longer crashed.

If I get a chance I'll take a look at it.
#7
10/29/2005 (8:13 am)
K. I took a bit of a look at it yesterday couldn't figure out why it wasn't rendering. It didn't seem all that important at the time though so I figured I'd go back to it later. Just figured I'd asked in case someone had already gone through it.
#8
07/04/2007 (8:58 am)
Sorry to startup a dead thread but I am needing something similar actually.

I am pretty sure these lines aren't doing what they're supposed to (no translation of the vertices are being done) so the speedometer doesn't draw on screen. It the speedometer draws, its just not centered into the control and is masked out.

newMat.setPosition(Point3F(mBounds.point.x + center.x,mBounds.point.y + center.y,0));

   F32 rotation = mMinAngle + (mMaxAngle - mMinAngle) * (mSpeed / mMaxSpeed);
   AngAxisF newRot(Point3F(0.0f,0.0f,-1.0f), rotation);

   newRot.setMatrix(&newMat);
#9
12/31/2007 (12:50 pm)
Has anyone gotten the needle to work again?
#10
04/29/2009 (11:59 pm)
well,I only try this in afx,but I am sure it works in tgea too.enjoy :)
void GuiSpeedometerHud::onRender(Point2I offset, const RectI &updateRect)
{
// Must have a connection and player control object
GameConnection* conn = GameConnection::getConnectionToServer();
if (!conn)
return;
Vehicle* control = dynamic_cast<Vehicle*>(conn->getControlObject());
if (!control)
return;

Parent::onRender(offset,updateRect);

// Use the vehicle's velocity as it's speed...
mSpeed = control->getVelocity().len();
if (mSpeed > mMaxSpeed)
mSpeed = mMaxSpeed;

// Render the needle
GFX->pushWorldMatrix(); // glPushMatrix();
Point2F center = mCenter;
if (isZero(center.x) && isZero(center.y))
{
center.x = getExtent().x / 2.0f;
center.y = getExtent().y / 2.0f;
}

MatrixF newMat(1);

F32 rotation = mMinAngle + (mMaxAngle - mMinAngle) * (mSpeed / mMaxSpeed);
AngAxisF newRot(Point3F(0.0f,0.0f,1.0f), mDegToRad(rotation));

newRot.setMatrix(&newMat);

newMat.setPosition(Point3F(getLeft() + center.x, getTop() + center.y, 0.0f));
GFX->multWorld(newMat);

GFX->setAlphaBlendEnable( true );
GFX->setSrcBlend(GFXBlendSrcAlpha);
GFX->setDestBlend(GFXBlendInvSrcAlpha);
GFX->setTextureStageColorOp(0, GFXTOPDisable);
GFX->setTexture(0, NULL);

PrimBuild::begin(GFXTriangleStrip, 5);//GFXLineStrip
PrimBuild::color4f(mColor.red, mColor.green, mColor.blue, mColor.alpha);

PrimBuild::vertex2f(+mNeedleLength,-mNeedleWidth);
PrimBuild::vertex2f(+mNeedleLength,+mNeedleWidth);
PrimBuild::vertex2f(-mTailLength ,+mNeedleWidth);
PrimBuild::vertex2f(-mTailLength ,-mNeedleWidth);

// Get back to the start!
PrimBuild::vertex2f(+mNeedleLength,-mNeedleWidth);

PrimBuild::end();

GFX->popWorldMatrix();
}
#11
04/30/2009 (12:25 am)
Fixed this in TGEA 1.8.x trunk. Also removed the Vehicle requirement, any control object will do.

Edit: It may take us four years, but bugs will be fixed dammit.