Game Development Community

Object doesnt want to render!??!

by Max Robinson · in Torque Game Engine · 08/28/2002 (12:30 am) · 6 replies

I'm working on something similar to the currently used splash class. It's basically a textured cone that follows a projectile. If I could get it working, it'd be awesome, however... The renderObject just ISNT happening! I've tried putting a console echo in all 3 of the render functions (preprender, renderobject, render) and it never comes up, but if I put one in ANY of the splash's 3 functions, it will echo like mad (of course). Does anyone have any idea what I could be doing wrong? Is there a list of classes that are rendered? Is there a variable that might make it not render (I even hardcoded alpha and fade values to 1.0f!)???

This is the last barrier between me and my sweet cone effect that I will soon have!!

#1
08/28/2002 (2:27 am)
Max,

Things to check are:-

- The object should be based upon a SceneObject.
- It should override the OnAdd/OnRemove with at least...

bool MyConeObj::onAdd()
{
	if(!Parent::onAdd()) return(false);

	// Set initial object-space bounding box.
	mObjBox.min.set( -0.5f, -0.5f, -0.5f );
	mObjBox.max.set(  0.5f,  0.5f,  0.5f );

	// Reset the World Box.
	resetWorldBox();

	// Set the Render Transform.
	setRenderTransform(mObjToWorld);

	// Add to Scene.
	addToScene();

	// Return OK.
	return(true);
}

void MyConeObj::onRemove()
{
	// Remove from Scene.
	removeFromScene();

	// Do Parent.
	Parent::onRemove();
}

- A minimal prepRenderImage function like...

bool MyConeObj::prepRenderImage(	SceneState* state, const U32 stateKey, const U32 startZone,
								const bool modifyBaseZoneState)
{
	// Return if last state.
	if (isLastState(state, stateKey)) return false;
	// Set Last State.
	setLastState(state, stateKey);

   // Is Object Rendered?
   if (state->isObjectRendered(this))
   {	   
		// Yes, so get a SceneRenderImage.
		SceneRenderImage* image = new SceneRenderImage;
		// Populate it.
		image->obj = this;
		image->isTranslucent = false;
		image->sortType = SceneRenderImage::Normal;
		
		// Insert it into the scene images.
		state->insertRenderImage(image);
   }

   return false;
}

- Make sure you are at least passing the appropriate positional information from server to client...

U32 MyConeObj::packUpdate(NetConnection * con, U32 mask, BitStream * stream)
{
	// Pack Parent.
	U32 retMask = Parent::packUpdate(con, mask, stream);

	// Write MyConeObj Mask Flag.
	if (stream->writeFlag(mask & MyConeObjMask))
	{
		stream->writeAffineTransform(mObjToWorld);
	}

	// Were done ...
	return(retMask);
}

void MyConeObj::unpackUpdate(NetConnection * con, BitStream * stream)
{
	// Unpack Parent.
	Parent::unpackUpdate(con, stream);

	// Read MyConeObjMask Flag.
	if(stream->readFlag())
	{
		MatrixF		MyConeObjObjectMatrix;

		stream->readAffineTransform(&MyConeObjObjectMatrix);

		// Set Transform.
		setTransform(MyConeObjObjectMatrix);
	}
}


- Make sure that your object-space box (above) completely encapsulates your object otherwise it will be culled.

Failing all that, send me the code, I'll be glad to check it out for you.

All the best,

- Melv.
#2
08/28/2002 (8:29 pm)
It looks like it all should work!!
Here is my onAdd, onRemove, prepRenderImage, and pack/unpack data. Note that I just tried that mask thing for pack/unpack data, and I'm not 100% sure what that mask thing is, however I did a little combination of that and what they did in vehicle.cc/.h which makes sense. Is this done so that you wont have to update position all the time? For instance, you only setMaskBits for the position mask if you have changed position? Also, I recently set the objbox to size 10 just in case... theoretically these cones could be pretty large. It would be ideal to rotate the cone etc... is rotating automatic with these or would this have to be done along with rotating the object?

Well, to the code:
bool Shockcone::onAdd()
{
   if(!Parent::onAdd())
      return false;

   if(mDataBlock->lifetimeMS != 0)
	mEndingMS = mDataBlock->lifetimeMS + sgRandom.randI( -mDataBlock->lifetimeVariance, mDataBlock->lifetimeVariance );
   else
	mEndingMS = 0;

   mRadius = mDataBlock->startRadius;
   mVelocity = mDataBlock->velocity;
   mLength = mDataBlock->length;

   mObjBox.min = Point3F( -10.0f, -10.0f, -10.0f );
   mObjBox.max = Point3F(  10.0f,  10.0f,  10.0f );
   resetWorldBox();

   setRenderTransform(mObjToWorld);

   gClientContainer.addObject(this);
   gClientSceneGraph->addObjectToScene(this);

   removeFromProcessList();
   gClientProcessList.addObject(this);

   //addToScene();

   return true;
}

void Shockcone::onRemove()
{
   mSceneManager->removeObjectFromScene(this);
   getContainer()->removeObject(this);

   Parent::onRemove();
}

bool Shockcone::prepRenderImage(SceneState* state, const U32 stateKey,
                             const U32 /*startZone*/, const bool /*modifyBaseState*/)
{

   if (isLastState(state, stateKey))
      return false;
   setLastState(state, stateKey);

   // This should be sufficient for most objects that don't manage zones, and
   //  don't need to return a specialized RenderImage...
   if (state->isObjectRendered(this)) {
      mFog = 0.0;

      SceneRenderImage* image = new SceneRenderImage;
      image->obj = this;
      image->isTranslucent = true;
      image->sortType = SceneRenderImage::Point;
      image->textureSortKey = U32(mDataBlock);
      state->setImageRefPoint(this, image);
      state->insertRenderImage(image);
   }
   return false;
}

U32 Shockcone::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
{
   U32 retMask = Parent::packUpdate(con, mask, stream);

	if (stream->writeFlag(mask & PositionMask))
	{
		stream->writeAffineTransform(mObjToWorld);
	}


   return retMask;
}

//--------------------------------------------------------------------------
// unpackUpdate
//--------------------------------------------------------------------------
void Shockcone::unpackUpdate(NetConnection* con, BitStream* stream)
{
   Parent::unpackUpdate(con, stream);

	if(stream->readFlag())
	{
		MatrixF		MyConeObjObjectMatrix;

		stream->readAffineTransform(&MyConeObjObjectMatrix);

		// Set Transform.
		setTransform(MyConeObjObjectMatrix);
	}
}

Also just in case, here are processTick and advanceTime, but I dont think these are the problem. It's just not running any of the render functions.
void Shockcone::processTick(const Move*)
{
   mCurrMS += TickMs;
   mArbTicks++;

   if(mEndingMS != 0 && mCurrMS >= mEndingMS && isServerObject())
	{
		deleteObject();
	}
	else if(!mActive)
	{
		deleteObject();
	}

   setMaskBits(PositionMask);
}

void Shockcone::advanceTime(F32 dt)
{
	Parent::advanceTime(dt);

   if (dt == 0.0 || !mActive)
      return;

   mElapsedTime += dt;

   updateWave( dt ); // move outwards
	updateRing(); // apply movement to rings
}
#3
08/28/2002 (10:05 pm)
Note that my shockring class isn't having this trouble...
www.planettribes.com/talonrules/rings.jpg
Which is wierd because these 2 classes are very similar.
#4
08/28/2002 (11:50 pm)
Ah and melv, how do you use glTexCoord2f? Is it is for translating the texture's position? I've done even more work with those shockrings, and they are basically just untextured t2 lookalkies.... beutiful.... but untextured.
#5
08/29/2002 (12:13 am)
Max,

Sorry about that, I go to bed weekdays around 10pm GMT+0 so don't think I'm ignoring you. ;)

I don't really see any major major problems in your code so it's difficult to help you further. I did notice that you are using datablocks. These can be a little tricky if you're not used to them. I presume you have a class for these including the server->client pack/unpack functions etc.

Have you confirmed that you are getting valid data sent to your datablocks?

As to your other question, the glTexCoord2f command specifies the texture coordinate (S,T) of the current vertex. You issue this command *before* issuing the glVertex*** command. The values here are normalised against the texture e.g. 0->1.

For example, if you have a set of vertices that define a square (moving clockwise) v0,v1,v2,v3, before you issue the vertex commands you could associate an appropriate texture coordinate with each to texture map it like so..

glTexCoord2f(0,0)
glVertex2fv(v0)
glTexCoord2f(1,0)
glVertex2fv(v1)
glTexCoord2f(1,1)
glVertex2fv(v2)
glTexCoord2f(0,1)
glVertex2fv(v3)

The first coordinate is associated with the first component of the vertex e.g. X and the second with Y. If the texture mode is GL_REPEAT then specifying a texture coordinate greater than one causes the texture to be tessellated across your polygon.

Hey, I'm not the greatest tutor in the world. ;) There are lots of references to this subject around the net. I can point a few out if you want.

I'd be glad to look over your code if you want to send it to me. Don't worry, I won't steal it. ;)

All the best,

- Melv.
#6
08/29/2002 (2:24 pm)
Hehe I guessed... I've been going to sleep at 4 am in east coast USA (9 am for you?) and waking up at 12 pm, so I'm not really expecting other people to work on my schedule.

Anyway... well I got my shockwaves textured, turns out it just wasnt reading the ~ in the filename. I even got texture wrapping as a decimal variable on the datablock. I think I'll just redo much of the shockCone class using my working shockRing class, since the problem is just too wierd.