Hi,
I needed to integrate the XNA billboards example with sunburn and is facing a few problems.
Well the situation is a little complex as I am already using a Sunburn enabled version of XNA Height Map Collision Pipeline. So I have no physical model to begin with.
I tried using the following method; After the
"MeshContent terrainMesh = builder.FinishMesh();"
method call in the height map collision pipeline, I added the call,
"GenerateVegetation(terrainMesh, directory);"
of the billboards example and added the relevant methods from the billboards example to the height map collision pipeline and did the necessary changes to integrate those method with the architecture of height map collision pipeline (E.g. :- parameter of type Content identity can be replaced by a simple string containing the directory because the only use taken from the former is discover the directory).
This GenerateVegetation method and all the methods that it calls upon executes fine. The conflict arises when the compiler comes to the line,
"ModelContent model = context.Convert<MeshContent, ModelContent>(terrainMesh, "LightingSystemModelProcessor");"
As you can see I have replaced "ModelProcessor" of the regular code to "LightingSystemModelProcessor" in order to accommodate Sunburn.
Here it throws an exception which has the stack trace as shown below,
Error 28 Building content threw Exception: 0x8007000e at Microsoft.Xna.Framework.Content.Pipeline.Interop.MeshInterop.GenerateTangentFrame(IList`1 positions, IList`1 indices, IList`1 normals, IList`1 textureCoordinates, Single partialEdgeThreshold, Single singularPointThreshold, Single normalEdgeThreshold, Int32[]& newIndices, Int32[]& vertexReorderMap, Vector3[]& tangents, Vector3[]& binormals) at Microsoft.Xna.Framework.Content.Pipeline.Graphics.MeshHelper.CalculateTangentFrames(MeshContent mesh, String textureCoordinateChannelName, String tangentChannelName, String binormalChannelName) at SynapseGaming.LightingSystem.Processors.BaseLightingSystemModelProcessor`1.I(NodeContent , ContentProcessorContext ) at SynapseGaming.LightingSystem.Processors.BaseLightingSystemModelProcessor`1.Process(NodeContent input, ContentProcessorContext context) at Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor`2.Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.Process(Object input, ContentProcessorContext context) at Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorContext.Convert[TInput,TOutput](TInput input, String processorName, OpaqueDataDictionary processorParameters) at Microsoft.Xna.Framework.Content.Pipeline.ContentProcessorContext.Convert[TInput,TOutput](TInput input, String processorName) at HeightmapCollisionPipeline.TerrainProcessor.Process(Texture2DContent input, ContentProcessorContext context) in D:\Nisansa\Work\SunBurnGame3\SunBurnGame3\HeightmapCollisionPipeline\TerrainProcessor.cs:line 311 at Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor`2.Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.Process(Object input, ContentProcessorContext context) at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.BuildAssetWorker(BuildItem item) at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.BuildAsset(BuildItem item) at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.RunTheBuild() at Microsoft.Xna.Framework.Content.Pipeline.Tasks.BuildContent.RemoteProxy.RunTheBuild(BuildCoordinatorSettings settings, TimestampCache timestampCache, ITaskItem[] sourceAssets, String[]& outputContent, String[]& rebuiltContent, String[]& intermediates, Dictionary`2& dependencyTimestamps, KeyValuePair`2[]& warnings) D:\Nisansa\Work\SunBurnGame3\SunBurnGame3\Content\Models\Maps\Map1\terrain.bmp SunBurnGame3
My question is is there a way to debug this and if not can some one provide a sunburn safe billboards example.
Thank you in advance.
Hi gamoslk,
You can debug content processors and importers by calling .Net's Debugger.Launch() in your code where you'd like it to halt for debugging (more info).
From the stack trace I'm guessing the XNA example already uses the tangent space vertex channels (likely for the billboard calculations), which is causing a problem when SunBurn tries to use the channels for bump map information.
There is a SunBurn billboard resource in the Community Created Resources section, and though it's for 1.2.x the bulk of the code should work fine. The only difference would be to pack the billboard into a SceneObject and update its World transform every frame using the combined scale and billboard transforms.
If you'd prefer not to use the resource or want to adapt it to your project, here's how it works: it creates a simple quad oriented on the x/y plane (ie facing up the z axis) and uses xna's Matrix.CreateConstrainedBillboard() to rotate the quad relative to the camera.
Let me know if this helps!
Follow me on Twitter – development and personal tweetsAwesome XNA Videos – Lighting, Rendering, and game videos
Thanks for the tip. I started working on the SunBurn billboard resource and converted it to 1.3. But there it throws an exception at the line,
" obMan.Submit(new SceneObject( _Effect, _BillboardResource.BoundingSphere, scaletransform * billboardtransform, _BillboardResource.VertexBuffer, _BillboardResource.VertexDeclaration, _BillboardResource.PrimitiveType, _BillboardResource.PrimitiveCount, _BillboardResource.VertexBase, _BillboardResource.VertexStreamOffset, _BillboardResource.SizeInBytes));
"
saying that there is a Null reference (i.e. Object not initialized) but when I checked all the parameters were initialized and was with values. Almost all the parameters were from the 1.2 sample that you provided. The only new addition is how I used to initialize the "_Effect" I used the following code for it;
new BasicEffect(game.GraphicsDevice,new EffectPool())
Can you spot the error here?
Hmm, make sure obMan is set to the current ObjectManager. Also try setting the effect pool to null in the BasicEffect constructor (to disable pooling).
Hi John,
I forgot to mention the "obman" is also correctly initialized. And unfortunately changing the effect pool to "null" did not do any good either. :-(
I ran a quick test with the resource and didn't see any problems. The problem you're running into might be a bug introduced when converting the resource over to 1.3.
I've updated the resource with the code I used for testing against 1.3. It contains an updated Billboard class, which creates and submits a scene object, then updates the transform (with the billboard transform) every frame.
Try giving the updated resource a try it should work correctly for you without any changes.
Hi Jhon,
Yes. Your updated Billboard class works fine. I've given below some screen shots from the game.
1) With a new instance of BasicEffect
2 ) With a custom Effect
P.S. :- Until I get a decent foliage texture from our graphics designer I have used the same texture that I have for my tree leaves ;-)
How do you get transparency on your billboards?
You'd want to set your billboard's effect transparency property to TransparencyMode.Clip, and then set the alpha clip value depending on how extreme you want the clipping to be (ranges from 0.0f to 1.0f).
I'm not sure which version of SunBurn you're using, but back in version 1.3.x if you wanted to add billboards using their code example you'd do something like:
// Initialize the effect.
LightingEffect effect = new LightingEffect(GraphicsDevice);
// Turn on clipping for transparency, set the alpha, and set the texture that'll be used for the billboard.
effect.SetTransparencyModeAndMap(TransparencyMode.Clip, 0.2f, billboardTexture);
// (Optional) I usually turn this on for things like grass.
effect.DoubleSided = true;
// Finally add the billboard
Billboard bbObject = new Billboard(sceneInterface, bbResource, effect, position, scale);
If you're just trying to set a material's transparency, you can also do that from inside the SunBurn editor. There should be a check box for transparency.
Awesome, thank you. I am using 1.3.x so this should be fine.
edit -- nevermind, I'll just extend the billboard class some. should take care of it.
Annotations on screenspace are best done not with billboards. Billboards have significant overhead and are only really used for rendering millions of similar looking items.
What you need to do is as follows.
Vector3 screenSpacePosition = GraphicsDevice.Viewport.Project(shipPosition, ProjectionMatrix, ViewMatrix, Matrix.Identity);
spriteBatch.DrawString(font, text, new Vector2(screenSpacePosition.X, screenSpacePosition.Y, Color.Red);
EDIT: In case anyone is confused, I was replying to a post that was edited by the author. Don't mean to derail the conversation here.
Andorov, yes, thank you. That's a good solution. And sorry, I did edit my post there! I was looking to use billboards here because I want my game to work with nvidia 3d vision and it's always nice to draw text in 3D so it doesn't bug out your eyes.