Creating Effect Classes From Pipeline
Hey, I have a BasicPaletteEffect, which is like basiceffect, except it also contains a matrix palette. In my processor, if mesh has bone index and vertex weight channels, and if it doesn't already have an external reference to another effect, I want to set it's effect to an instance of BasicPaletteEffect (inside the content pipeline). Is there any way I can do this?
Thanks.
[385 byte] By [
leclerc9] at [2007-12-26]
I realize I can do that, but I wanted to include this in an API (library of animation components).
My current solution is to write the shader code to the project directory then tell XNA to compile it into an XNB file. Kind of a hack but it's the only way I can get it to work opaquely.
This is definitely possible. In order to do this, you'll need to write another design time class. The content pipeline doesn't have access to a graphics device at build time, so you'll need to follow a pattern similar to how EffectMaterialContent works. You can follow the help document "Developing a New XNA Framework Processor" for the syntax of all this.
Basically, the idea is that you'll have two types: a design time one, and a runtime one. The design time one won't be tied to a graphics device, so it can be used at build time. The ContentTypeWriter for the design time type will override the GetRuntimeType function to enforce the relationship between the design time and runtime classes. Your design time type can be a subclass of EffectMaterialContent, and the constructor can automatically fill the Effect property.
By the way, I think you'll find most .x and .fbx files will have materials in them already, so the "if it doesn't already have an effect" part might never be true. if you want to change the effect, but keep all the parameters on the old one, try copying the contents of the OpaqueDataDictionary.
Thanks for the feedback. I actually found that extending MaterialContent was better than extending EffectMaterialContent because I want to compile my effect from a string and not from an external reference. Also, I replace the BasicMaterialContent with my own class after the base processor does the dirty work of creating the texture contents. What I meant by not already having an effect is not already having a custom effect (denoted by EffectInstance in X files). So, if a material is an instance of BasicMaterialContent and the mesh contains skinning channels, then I want to convert it.
I just have one more question: during the writing phase, I need to write the texture data from a TextureContent so that the reader can convert it into a runtime texture. Can I just do this for a normal 2D texture by creating a new byte[] that is the sum of all the bytes in the mipmapchain?
I don't remember the syntax off the top of my head, but you can just call writer.WriteExternalReference( theTexture ) directly. the writer will locate the ContentTypeWriter for TextureContents automatically, and call it. this isn't something you need to worry about. Your reader will be similar, call ReadExternalReference.
Alright, thanks. I had figured out that I can just load the file, but was using the filename attached to the external reference.
effect.Texture = input.ReadExternalReference<
Texture2D>();Is a neat trick though.