Search code examples
c++openglcpp-core-guidelines

Suggestions for returning memory from a class


I have a class which is supposed to keep pixel data (floats for the position, floats for the color). I'm trying to use a C++ style in data members (the data is kept in std::array<float, N> instead of plain C arrays). The class has other getters, setters and functions meant to be "helpers" to populate these fields.

Now I need to create an OpenGL vertex data buffer where I should write out

  4 floats for xyzw
  4 floats for rgba
  2 floats for UV coords

in this order. I'm wondering how should I do this.. I tried doing

class MyVertexData {
  std::array<float, 4> pos;
  std::array<float, 4> rgba;
  std::array<float, 2> uv;
public:
  void writeData(float *ptrToMemory) {
    if(ptrToMemory == nullptr)
      throw std::runtime_exception("Null pointer");

    std::array<float, 10> output;

    output= {
      pos[0], pos[1], pos[2], pos[3],
      rgba[0], rgba[1], rgba[2], rgba[3],
      uv[0], uv[1]
    };

    memcpy(memory, out.data(), 10 * sizeof(float));
  }
};


// Caller code
std::vector<float[10]> buffer(4);
vertex0.writeElements(buffer[0]);
vertex1.writeElements(buffer[1]);
vertex2.writeElements(buffer[2]);
vertex3.writeElements(buffer[3]);

but this approach has two problems:

  1. I need to trust the caller to have allocated memory to store 10 floats
  2. No C++11+ signature, I just get a float pointer

I can't just return a std::unique_ptr since I need a contiguous memory area (buffer) where the elements are to be stored, but I also need a distinction between the different elements (that would also make the code more readable).

It would be nice to return a smart pointer or something similar whose memory I can easily "concatenate" to other elements so I can safely pass this stuff to OpenGL.


Solution

  • CppCoreGuidelines introduces span which is a view of contiguous element, so you may use something like:

    void writeData(gsl::span<float, 10> ptrToMemory)
    

    to express the intend.