Sign in to follow this  

How to customize XML boost::serialization

This topic is 4198 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been playing around with boost::serialization library and it works great for what I want to do with it. I'm using it for binary saving and loading of meshes and texture packs. I also need my meshes to be serialized in XML format so that I can easily write an exporter for Blender or Max. I'm posting in the General Programming forum because my question is not specific to game programming. Here is my problem. My mesh class looks like this:
class Mesh
{
	friend class boost::serialization::access;
	template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
	{
		ar & boost::serialization::make_nvp("vertices", vertexBuffer);
		ar & boost::serialization::make_nvp("indices", indexBuffer);
	}

public:
	std::vector<VertexFormat> vertexBuffer;
	std::vector<int> indexBuffer;

	void Draw() const;
};

The VertexFormat is:
struct VertexFormat
{
	Vector2 uv;
	Vector3 normal;
	Vector3 position;

private:
	friend class boost::serialization::access;
	template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
	{
		ar & BOOST_SERIALIZATION_NVP(uv);
		ar & BOOST_SERIALIZATION_NVP(normal);
		ar & BOOST_SERIALIZATION_NVP(position);
	}
};

The problem is that the XML formatter makes too many tags (one tag per variable) and the file becomes huge. Here is what the XML file looks like after I serialize it:
<mesh class_id="0" tracking_level="0" version="0">
	<vertices class_id="1" tracking_level="0" version="0">
		<count>1000</count>
		<item class_id="2" tracking_level="0" version="0">
			<uv class_id="3" tracking_level="0" version="0">
				<x>1</x>
				<y>200</y>
			</uv>
			<normal class_id="4" tracking_level="0" version="0">
				<x>3</x>
				<y>4</y>
				<z>5</z>
			</normal>
			<position>
				<x>6</x>
				<y>7</y>
				<z>8</z>
			</position>
		</item>

Okay, so that was like an array of structs, but what I really want is something like this, where a bunch of data is grouped together (struct of arrays):
<mesh>
	<vertices>
		<count>1000</count>
		<data>1.0 0.0 1.0 ...</data>
	<normals>
		<count>1000</count>
		<data>0.0 1.0 0.0 ...</data>
	<uvs>
		<count>1000</count>
		<data>0.0 0.0 ...</data>
	<indices>
		<count>100</count>
		<data>0 1 2...</data>

Is this kind of customization possible with boost::serialization or do I have to write my own XML parser for this? How do I make my classes have both binary and XML serialization? So far I was able to achive this with #ifdefs and macro hacks but that only gives me a choice at compile-time.

Share this post


Link to post
Share on other sites
You might want to take this up on the Boost-Users mailing list. Robert Ramey is usually very responsive. FWIW, I think you would need to make your own archiving class derived off of one of Boost's to customize the serialization. To do both binary and XML, you can just instantiate two different archives depending on some bool. This can be set at run-time or compile-time, doesn't make a difference.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You should reconsider what you're doing. Using boost serialization along with XML is a horrible way to serialize geometry data. In fact, it's the slowest way to read that kind of stuff short of storing it on tape.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
You should reconsider what you're doing. Using boost serialization along with XML is a horrible way to serialize geometry data. In fact, it's the slowest way to read that kind of stuff short of storing it on tape.


I only need XML for the exporter plugin. My crunch app will turn that into a binary file.

Quote:
Original post by mfawcett
I think you would need to make your own archiving class derived off of one of Boost's to customize the serialization. To do both binary and XML, you can just instantiate two different archives depending on some bool. This can be set at run-time or compile-time, doesn't make a difference.


That makes sense, thanks.

BTW, I actually figured out how to serialize the std::vector so that it doesn't use the extra tags by doing a loop:


float* fp = (float*)&vertexBuffer[i];
for(int i=0; i<vertexBuffer.size() * 8; i++)
ar & fp;



but that broke the loading, so I gave up. I will look into deriving a custom formatter class.

Share this post


Link to post
Share on other sites

This topic is 4198 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this