Jump to content
  • Advertisement
Sign in to follow this  
chronozphere

Buffer system

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

Hi all, In a game-engine you often encouter buffers filled with binary data, for example: vertexbuffers, indexbuffers, pixel-buffers, normals, colors, and other attributes. I'm considering to write a generic buffer system to provide access to these kind of buffers through API functions, instead of giving the user of the API a pointer to write to. It should work like this: The buffer system has a number of buffer slots. You can bind a buffer to a slot. If we want to access a texture, we would call: Texture_BindPixels(TextureID) Which locks the texture and returns a bufferslot. In consequence, you can call one of the following routines: Buf_Readi(Slot) //reads integer from buffer Buf_Readf(Slot) //reads float... Buf_Readf3(Slot) //reads float vector etc... Buf_Writei(Slot, Value) Buf_Writef(Slot, Value) Buf_Writef3(Slot, Value) Buf_Seek(Slot, Offset, SeekMethod) //Moves the pointer in the buffer Etc... When you are done, you simply call Texture_UnbindPixels(TextureID), which unlocks the texture again. Each object containing a buffer implements an interface containing read/write/seek methods. All the API methods mentioned above call the interface to read/write their data. Here are some reasons for implementing it: > It can be used for any kind of buffer throughout the whole engine > It can support many datatypes like numbers, vectors, matrices, strings etc... > It generates errors if the application tries to write outside the buffer > The code is easy to read. You cleary see what's going on. > It "might" prevent duplicate code, which means less bugs. Here are some reasons for not implementing it: > It's extra work to implement this... doh! > More code is executed per read/write operation which can result in bad performance So what do you think? Is it usefull or rubbish? Please motivate your answer. =) Thanks a bunch!

Share this post


Link to post
Share on other sites
Advertisement
The canonical way to deal with this (in C++ at least) is a std::vector<foo> for each buffer type. In other words, you'd write code based on a std::vector<Vertex> for a vertex buffer, std::vector<float> for a flat buffer of floating point data, and so on.

This provides five important things:
  • Safe control over allocated memory

  • Bounds checking, if used correctly

  • Clarity in the code

  • Type safety

  • Alignment safety


You don't have to worry about memory leaks, because the buffer will be freed automatically when the vector goes out of scope (or is deleted manually, if you use a vector*). You get free bounds checking in debug builds, but no performance overhead in release builds. The code is easy to read because it's immediately obvious what you're doing ("oh, hey, this vector<foo> is a buffer of foo data!"). You can't screw up the types without trying fairly hard - i.e. if you're storing a complex structure in the buffer, you can access it just like any other structure, which means you don't have to worry about updating all of your Read/Write code any time you introduce a new structure member, or rearrange members. And last but certainly not least, you don't have to worry about manually dealing with structure padding like you would if you used direct read/write functions on the raw memory.


What advantages does your approach offer, especially by comparison to this method? You might be able to provide leak-proof behaviour if you're careful, and certainly a rough imitation of bounds checking, but the code is going to be very cryptic, you have zero type safety whatsoever, and it'd be hideously easy to accidentally mangle the data because you forget a couple of padding bytes between fields.

Not worth it, in my book.

Share this post


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

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!