Hacker News new | ask | show | jobs
by yassim 3932 days ago
Hi, Another Game dev here. Firstly, neat article, thanks for writing it.

I'm curious as to the problem you're exploring/solving here?

"Concatenated struct's in single chunk" is a neat trick. The use case seems a bit broken[1], but I'm assuming that it's from the original video, and your c++-ifying it? Or at least trying to find a nicer way to write this style of code?

If you'r going this route, I'd be tempted not to use pointers at all, and just use offsets and accessors.[2]

  * Lack of pointers means you can load in 1 read. (endian needs to be watched, and assumes you can get the entire size elsewhere)
  * You can also shuffle it around in memory should you be doing something fancy. (defragging heaps might be useful if doing a sandbox)
  * Better encapsulation? maybe..
But the basic point I'd like to make is, there is no nice way to write this type of code, because c and c++ gives us no nice[3] way of expressing it.

[1] Verts and Indices are generally uploaded to a GPU then discarded, but this has the counts, which is needed CPU side for draw calls, in the same chunk so would need to be copied before freeing.

[2]

  struct Mesh 
  {
  	int32_t num_indices, 
  		num_verts;

  	// inline to this struct.. 
  	// assumes Vector3 is aligned 4 bytes.
  	// and that Mesh has been alloced to same alignment.
  	//
  	// Vector3 positions[num_verts];
  	// int32_t indices[num_indices];
  	// Vector2 uvs[num_verts];
  
	inline const Vector3* PositionsBegin() const { return reinterpret_cast<const Vector3*>(this + 1); }
  	inline const Vector3* PositionsEnd() const { return PositionsBegin() + num_verts; }
  	inline const int32_t* IndicesBegin() const { return reinterpret_cast<const int32_t*>(PositionsEnd()); }
  	inline const int32_t* IndicesEnd() const { return IndicesBegin() + num_indices; }
  	// etc
  };
[3] Maintainable, fast at runtime, low mental friction to people other than the author, etc
1 comments

Hi, thanks yassim. Yes, the use case is from the original article. Yes, that is certainly another way to go, you could just provide the unique_ptr and a bunch of integer offsets. In this post, my data structure is trying to balance performance and code cleanliness, it's advantageous to provide standalone ArrayView which can't just be two integers. In the follow up post I'll be trying to make the data structure itself generic, so it will more easily allow for space optimizations.

I guess we'll agree to disagree, I think that C++ gives us some nice ways of writing it, I think that's what the post shows :-)