"Billboard" class
by Ian Omroth Hardingham · in Torque 3D Professional · 12/01/2009 (8:18 am) · 35 replies
Hey guys.
I want to have an object which simply renders a bitmap at a 3d position and rotation. My current plan is to copy RenderObjectExample and do it like that. However, I'm wondering if anyone has any better ideas. I'm concerned that maybe it won't be as easy to add arbitrary shader effects etc to my bitmap rendering.
Thanks,
Ian
I want to have an object which simply renders a bitmap at a 3d position and rotation. My current plan is to copy RenderObjectExample and do it like that. However, I'm wondering if anyone has any better ideas. I'm concerned that maybe it won't be as easy to add arbitrary shader effects etc to my bitmap rendering.
Thanks,
Ian
About the author
Designer and lead programmer on Frozen Synapse, Frozen Endzone, and Determinance. Co-owner of Mode 7 Games.
#2
Would it not be better - or at least easier - to just use a billboard? I've a few billboard only DTS files with the mesh object being a plane with it's name ending in _BB to get the billboarding to work.
Or am I getting the wrong end of the stick here?
12/01/2009 (10:13 am)
Not terribly helpful but ...Would it not be better - or at least easier - to just use a billboard? I've a few billboard only DTS files with the mesh object being a plane with it's name ending in _BB to get the billboarding to work.
Or am I getting the wrong end of the stick here?
#3
To be honest, I'd quite like to make this class from the fundamentals - I'm probably going to need to make quite a few changes later on, and a really "clean" base would probably be best.
Ian
12/01/2009 (10:14 am)
Hi Steve.To be honest, I'd quite like to make this class from the fundamentals - I'm probably going to need to make quite a few changes later on, and a really "clean" base would probably be best.
Ian
#4
12/01/2009 (10:17 am)
I haven't used the RenderObjectExample yet, only the RenderMesh and RenderShape Examples, so I don't know why your code wouldn't work. But I did notice that your normals are backwards... the way you're drawing your polygons, your normals should be along the positive y-axis.
#5
12/01/2009 (10:30 am)
Hi Ryan. Thanks for that - I reversed the normals, but no change, still rendering solid white.
#6
Can you select the object and then bring up the Material Editor like you would do a normal mesh?
12/01/2009 (10:37 am)
@IanCan you select the object and then bring up the Material Editor like you would do a normal mesh?
#8
12/01/2009 (11:05 am)
Got it - the state block needs to be initialised with "samplersDefined"
#9
I'm having a billboard issue as well.
"I've a few billboard only DTS files with the mesh object being a plane with it's name ending in _BB to get the billboarding to work."
Do these meshes always face the camera? If so, might you be so kind as to provide the datablock of such a plane? It would help me out a load!
02/28/2010 (11:14 pm)
Steve,I'm having a billboard issue as well.
"I've a few billboard only DTS files with the mesh object being a plane with it's name ending in _BB to get the billboarding to work."
Do these meshes always face the camera? If so, might you be so kind as to provide the datablock of such a plane? It would help me out a load!
#10
BB and BBZ are designed to face the camera ... but you've got to export them facing the correct way, kinda depends on your modeling software (in Blender it's an reversed Y axis ...)
03/01/2010 (7:32 am)
TSstatic Model's don't usually have datablocks because they don't do anything.BB and BBZ are designed to face the camera ... but you've got to export them facing the correct way, kinda depends on your modeling software (in Blender it's an reversed Y axis ...)
#11
Still not billboarding tho, no motion of the billboards to face the camera regardless of orientation. Still looking...
03/01/2010 (10:00 am)
Thanks Steve,Still not billboarding tho, no motion of the billboards to face the camera regardless of orientation. Still looking...
#12
Try _BBZ instead of _BB, and make sure that it's named as your first _BBZ, eg: not mymodel_BBZ.001 or anything.
Also what modeling app are you using?
03/01/2010 (10:09 am)
Can you see the plane from high up with the camera? Is it rendering at all, and just not moving around to face the camera?Try _BBZ instead of _BB, and make sure that it's named as your first _BBZ, eg: not mymodel_BBZ.001 or anything.
Also what modeling app are you using?
#13
Just tried BBZ, looks the same.
I'm using Blender. Is there a specific method to use to orient the plane or just align it in object mode?
03/01/2010 (11:19 am)
Yes the plane can be seen (rendering fine) from any angle and its completely stationary.Just tried BBZ, looks the same.
I'm using Blender. Is there a specific method to use to orient the plane or just align it in object mode?
#14
03/01/2010 (11:40 am)
TsShapeConstructor is really designed to do that. You can setup imposters at certain LOD stages to create billboards. Might be able to set it up to do billboards all the time. It should take care of rotation as well. There is quite a bit of documentation done for it I believe along with a few posts.
#15
You are naming your "Mesh Object" _BB or _BBZ aren't you? And not the DTS file?
eg:
Hierarchy:
->shape
------->detail2
-------------->myMesh_BB
exported out as a model called: "mybillboard.dts"
Also remember that the front in Blender is actually facing "into" the viewport, so you want to be able to see the front of the plane (with it's texture) if you hit CTRL+Numpad1.
As Joshua also points out, if you're LODing an object you can use imposters, but I think you just want the billboard rather than a model ... (at least that was what the original post was about).
03/01/2010 (11:55 am)
Mike, You are naming your "Mesh Object" _BB or _BBZ aren't you? And not the DTS file?
eg:
Hierarchy:
->shape
------->detail2
-------------->myMesh_BB
exported out as a model called: "mybillboard.dts"
Also remember that the front in Blender is actually facing "into" the viewport, so you want to be able to see the front of the plane (with it's texture) if you hit CTRL+Numpad1.
As Joshua also points out, if you're LODing an object you can use imposters, but I think you just want the billboard rather than a model ... (at least that was what the original post was about).
#16
Yes I'm naming the Object and .dts as you said but the hierarchy in Show Tool Pro includes an additional subshape level.
And now I've got that orientation, didn't help.
You're right about the LODs and imposters, I need the billboard to render at the base level although I intend to combine it with a non-billboard model.
Joshua,
Been playing with TsShapeConstructor but no pay dirt yet. I'll keep at it.
03/01/2010 (1:49 pm)
Steve,Yes I'm naming the Object and .dts as you said but the hierarchy in Show Tool Pro includes an additional subshape level.
And now I've got that orientation, didn't help.
You're right about the LODs and imposters, I need the billboard to render at the base level although I intend to combine it with a non-billboard model.
Joshua,
Been playing with TsShapeConstructor but no pay dirt yet. I'll keep at it.
#17
03/01/2010 (3:23 pm)
ShowPro? Are you testing this in-game?
#18
03/01/2010 (4:04 pm)
Yes I am.
#19
03/01/2010 (5:21 pm)
Just checking ... ShowPro is old-hat, best to use 1.1b1's ShapeEditor, which apart from the current F11 load-time issue is rather nice.
#20
So you don't use TsShapeConstructor for billboards, right?
03/01/2010 (5:27 pm)
Just noticed the extra baggage in ShowPro and thought it might mean something to ya. And in the Shape Editor the only node is the mesh object itself.So you don't use TsShapeConstructor for billboards, right?
Associate Ian Omroth Hardingham
Mode 7 Games
void Billboard::createGeometry() { // Fill the vertex buffer VertexType *pVert = NULL; mVertexBuffer.set( GFX, 6, GFXBufferTypeStatic ); pVert = mVertexBuffer.lock(); // have to be anticlockwise pVert[0].point = Point3F(0,10,0); pVert[0].normal = Point3F(0,-1,0); pVert[0].texCoord = Point2F(0,0); pVert[1].point = Point3F(0,10,10); pVert[1].normal = Point3F(0,-1,0); pVert[1].texCoord = Point2F(0,1); pVert[2].point = Point3F(10,10,0); pVert[2].normal = Point3F(0,-1,0); pVert[2].texCoord = Point2F(1,0); pVert[3].point = Point3F(10,10,10); pVert[3].normal = Point3F(0,-1,0); pVert[3].texCoord = Point2F(1,1); pVert[4].point = Point3F(10,10,0); pVert[4].normal = Point3F(0,-1,0); pVert[4].texCoord = Point2F(1,0); pVert[5].point = Point3F(0,10,10); pVert[5].normal = Point3F(0,-1,0); pVert[5].texCoord = Point2F(0,1); mVertexBuffer.unlock(); // Set up our normal and reflection StateBlocks GFXStateBlockDesc desc; // The normal StateBlock only needs a default StateBlock mNormalSB = GFX->createStateBlock( desc ); // The reflection needs its culling reversed desc.cullDefined = true; desc.cullMode = GFXCullCW; mReflectSB = GFX->createStateBlock( desc ); } void Billboard::render( ObjectRenderInst *ri, SceneState *state, BaseMatInstance *overrideMat ) { GFX->getDrawUtil()->drawBitmapStretch(mTextureObject, RectI(0,0,200,200), GFXBitmapFlip_None, GFXTextureFilterLinear); if ( overrideMat ) return; if ( mVertexBuffer.isNull() ) return; PROFILE_SCOPE(RenderObjectExample_Render); // Set up a GFX debug event (this helps with debugging rendering events in external tools) GFXDEBUGEVENT_SCOPE( RenderObjectExample_Render, ColorI::RED ); // GFXTransformSaver is a handy helper class that restores // the current GFX matrices to their original values when // it goes out of scope at the end of the function GFXTransformSaver saver; // Calculate our object to world transform matrix MatrixF objectToWorld = getRenderTransform(); objectToWorld.scale( getScale() ); // Apply our object transform GFX->multWorld( objectToWorld ); // Deal with reflect pass otherwise // set the normal StateBlock if ( state->isReflectPass() ) GFX->setStateBlock( mReflectSB ); else GFX->setStateBlock( mNormalSB ); // Set up the "generic" shaders // These handle rendering on GFX layers that don't support // fixed function. Otherwise they disable shaders. GFX->setupGenericShaders( GFXDevice::GSModColorTexture ); GFX->setTexture(0, mTextureObject); // Set the vertex buffer GFX->setVertexBuffer( mVertexBuffer ); // Draw our triangles GFX->drawPrimitive( GFXTriangleList, 0, 2 ); }