Jump to content
  • Advertisement
Sign in to follow this  
panic

Interleaved databuffer with XNA?

This topic is 2645 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

Hey.

I'm working on porting a project from C++ to Windows Phone and have run into a little problem.
I have a semi-arbitrary databuffer where I store data in an interleaved manner, kind of like a vertex buffer. In C++ I will access the various parts of the data using pointers to which I both read and write back new data.
I'm using this as part of a data driven particle system which may or may not contain all available attributes, it's interleaved because there will be lots of particles processed and I'm concerned of cache performance.

Here's some "pseudo code" of the C++ implementation.

Buffer class implementation


class Buffer
{
public:

// Attribute bit-flags
enum Attribute
{
Attrib_Position = 1<<0,
Attrib_Size = 1<<1,
Attrib_TTL = 1<<2,
Attrib_Velocity = 1<<3,
Attrib_Rotation = 1<<4,

// and so forth
};

// Constructor
Buffer( int maxCount )
: m_stride(0)
, m_attributes(0)
, m_maxCount(maxCount)
{
memset( m_attributePtrs, 0, sizeof(unsigned char*) * 32 );
memset( m_attributeSizes, 0, sizeof(int) * 32 );
}


void addAttribute( Attribute attribute, int size )
{
// 4-byte alignment
int aligned_size = ( size + 3 ) & ~3;

// increment total stride
m_stride += aligned_size;

// count trailing zeros of attribute bit to get an index
int attribute_index = bit2index(attribute);

m_attributeSizes[attribute_index] = aligned_size;

m_attributes |= attribute;
}

void initialize()
{
// allocate memory to hold all attributes
m_attributeArray = new unsigned char[ m_stride * m_maxCount ];
memset( m_attributeArray, 0, m_stride * m_maxCount );

// setup "access pointers" to the first instance
// of the attributes in the attribute array
int offset = 0;
for( int i = 0; i < 32; ++i )
{
if( m_attributes & (1<<i))
{
m_attributePtrs = m_attributeArray + offset;
offset += m_attributeSizes;
}
}
}

template<typename T>
inline T* getAttributePtr(Attribute attribute, int index )
{
if( (attribute & m_attributes) == 0 )
return NULL; // attribute didn't exist

// count trailing zeros of attribute bit to get an index
int attrib_index = bit2index(attribute);

// return a pointer to the requested attribute at requested index
return reinterpret_cast<T*>(m_attribPtr[attrib_index] + m_stride * index);
}

int getMaxCount() { return m_maxCount; }

private:

int m_attributes;
int m_stride;
int m_maxCount;
unsigned char* m_attributeArray;

unsigned char* m_attributePtrs[32];
int m_attributeSizes[32];
};



Initialization and usage


void example_init()
{
Buffer buffer = new Buffer(100);

// Add some attributes
buffer->addAttribute( Buffer::Attrib_Position, sizeof(Vector3));
buffer->addAttribute( Buffer::Attrib_Size, sizeof(Vector2));
buffer->addAttribute( Buffer::Attrib_Velocity, sizeof(Vector3));
buffer->addAttribute( Buffer::Attrib_TTL, sizeof(float));

buffer->initialize()
}

void example_usage( Buffer& buffer, float delta )
{
for( int i = 0; i < buffer.getMaxCount(); ++i )
{
Vector3* position = buffer.getAttributePtr<Vector3>(Buffer::Attrib_Position, i);
Vector2* size = buffer.getAttributePtr<Vector2>(Buffer::Attrib_Size, i);
Vector3* velocity = buffer.getAttributePtr<Vector3>(Buffer::Attrib_Velocity, i);
float* ttl = buffer.getAttributePtr<float>(Buffer::Attrib_TTL, i);

// read/write data
*ttl -= delta;

*velocity -= kGravity;

*position += *velocity * delta;

*size = lerp( minsize, maxsize, (maxttl - *ttl) / maxttl);
}
}



I don't know how to migrate this to XNA for Windows Phone in a good and efficient way. I obviously can't use pointers, so what would be a suitable approach if I want to keep the cache friendliness of this implementation?

Thanks.

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!