Game Development Community

Render Order? Rendering an object last?

by Cinder Games · in Torque Game Engine · 05/22/2006 (5:28 pm) · 15 replies

I'm doing some work on my battle system and it's targeting system.
img70.imageshack.us/img70/4045/screenshot00500004b7kx.jpgHere's a screenshot.
The effect i'd like is to render the targeting object last, so the circles are completely visible, like it's a GUI or something to that effect.

If the object was rendered last in the process, it would create this effect. Any clue how to go about this? or maybe theres an alternative...?

#1
05/22/2006 (5:49 pm)
It's totally doable, I had a GL quad that was rendering on top of everything once, but I'm don't know if Torque has a method for any of it's existing classes to do this. Someone who knows the rendering path of TGE better could probably make it so you have a variable you can tweak to make the render order work like that...
#2
05/22/2006 (8:39 pm)
Every object has it's own render function. In this particular case, find your player's render function, and render the circle literally in code before the player itself is rendered.

Keep in mind that this technique does not transfer to TSE, since TSE manages rendering order differently in MS3 and follow-on milestones to optimize via batching.
#3
05/22/2006 (8:47 pm)
If the targeting object is a separate object, then you should be able to set the sortType in ::prepRenderImage() to SceneRenderImage::EndSort to get it to render last.

Otherwise, if the selection is a part of the object, you might need to do a conditional for that object in its ::prepRenderImage() from SceneRenderImage::Point to SceneRenderImage::EndSort when a selection flag is set.
#4
05/22/2006 (8:48 pm)
It's a separate object. I'm simply placing it at the location of a "targeted" character.
#5
05/22/2006 (9:43 pm)
The only place i really see any mention of the sortType is where it's looping for mounted images to the object.
for (U32 i = 0; i < MaxMountedImages; i++)
......
               rimage->sortType = SceneRenderImage::Point;
.....


How would changing this give me the effects i want?
#6
05/22/2006 (10:19 pm)
In order to get it on top, you will need to disable the depth test. E.g. glDisable(GL_DEPTH_TEST);

It seems like it needs to be a custom object derived off of ShapeBase that is sorted last using SceneRenderImage::EndSort as the sortType, and disabled the depth test in its ::renderObject.

or try this hack that modifies shapebase:

add this to class ShapeBaseData in shapebase.h
bool mRenderLast;

add this to class ShapeBaseData::ShapeBaseData() in shapebase.cc
mRenderLast = false;

add this to ShapeBaseData::initPersistFields() in shapebase.cc
addField("renderLast",     TypeBool,       Offset(mRenderLast ,     ShapeBaseData));

add this to very end of ShapeBaseData::packData(...) in shapebase.cc
stream->writeFlag(mRenderLast );

add this to very end of ShapeBaseData::unpackData(...) in shapebase.cc
mRenderLast  = stream->readFlag();

after the code in ShapeBaseData::prepRenderImage(...) in shapebase.cc
if (mCloakLevel == 0.0f && mShapeInstance->hasSolid() && mFadeVal == 1.0f)
      {
         SceneRenderImage* image = new SceneRenderImage;
         image->obj = this;
         image->isTranslucent = false;
add
if(mDataBlock && mDataBlock->mRenderLast)
{
    image->isTranslucent = true;
    image->sortType = SceneRenderImage::EndSort;
}
else
{
    image->sortType = SceneRenderImage::Normal;
}

replace this in ShapeBaseData::renderObject(...) in shapebase.cc
renderImage(state, image);
with
if(mDataBlock && mDataBlock->mRenderLast)
			glDisable(GL_DEPTH_TEST);

		renderImage(state, image);

		if(mDataBlock && mDataBlock->mRenderLast)
			glEnable(GL_DEPTH_TEST);
#7
05/22/2006 (10:22 pm)
Wow, that looks like it might be just what i need. I'll try and patch that in tomorrow and let you know how it works.
#8
05/23/2006 (4:15 pm)
img60.imageshack.us/img60/8806/screenshot006000035og.jpg
Alright. it did infact render the object on top of the rest. Good code
However, i was using... sorta a celshade type effect for the arrow objects using extruded/flipped polys to get a black line around them. But disabling the depth check caused it to draw them all in black. Not a big deal. I can find a work around.
Thanks for the code.
#9
05/23/2006 (4:33 pm)
Not sure if this would help, but is it possible to get what ever is exporting your arrow selection model to put the 'outline' higher on the lists, so when it is exported, its triangles get rendered first, followed by the arrows?
#10
05/23/2006 (9:06 pm)
img235.imageshack.us/img235/2820/error6jd.jpg
been playing around with it more and noticed it doesn't render last after all, all the time.... seems like if i rotate the cam around sometimes it's in front, sometime's it's not.

Seems to be related to the objects centers.
#11
05/23/2006 (9:41 pm)
I did find a bug in the code I posted

The following should be changed
if(mDataBlock && mDataBlock->mRenderLast)
    image->sortType = SceneRenderImage::EndSort;
else
    image->sortType = SceneRenderImage::Point;

to this:

if(mDataBlock && mDataBlock->mRenderLast)
    image->sortType = SceneRenderImage::EndSort;
else
    image->sortType = SceneRenderImage::Normal;

So normal objects will be sorted normally.

(I edited the original post to reflect the change)
#12
05/24/2006 (4:55 pm)
Hmmm made the fix. nothing seems to have changed.
#13
05/24/2006 (6:52 pm)
The fact that you had the render order issue means that you knew to add the following, but I am showing the following in case anyone else is following along:

Need to add variable to datablock of item that you want to render last:
datablock PlayerData(?????)
{
...
renderLast = true;
}.

I am not sure what is currently happening differently with your set up.
#14
05/24/2006 (7:06 pm)
Yeah, i know you didn't say to do so, but i did do that. That did enable the object to render on top of other objects.

I should also state that the "targeter object" is actually two separate objects, one is an inner ring, and the other is an outer ring. both are at the same position. they're just able to rotate independantly.

It's just that it doesn't do so all the time, It will be drawn last at one camera angle, and if i move the camera it sometimes changes. Here's some more pics....

Here behind a wall, the outline is drawn correctly.
img149.imageshack.us/img149/9173/screenshot008000085qt.jpg
3/4 view or so....
img146.imageshack.us/img146/6745/screenshot008000063pw.jpg
a low shot
img105.imageshack.us/img105/2882/screenshot008000094su.jpg

and here's a shot of it actually working.
img152.imageshack.us/img152/9488/screenshot008000021ip.jpg

I can rotate of move the camera in any of the shots and get it to render improperly.
#15
06/10/2006 (12:18 am)
I think I found the solution while looking into something else.

Turns out, only translucent objects get sorted special, so to get something to end sort, you need to set isTranslucent = true

E.g.,

if(mDataBlock && mDataBlock->mRenderLast)
{
    image->isTranslucent = true;
    image->sortType = SceneRenderImage::EndSort;
}
else
{
    image->sortType = SceneRenderImage::Normal;
}

I have modified the original message to match this change.