Sign in to follow this  

Vertex and Index buffer to file and back issue

Recommended Posts

I wrote a custom file format that stores my vertex and index buffer in binary format. Unfortunately, I could not reload the data correctly from file.

My vertices:

struct VertexPositionNormalTexture final {

    VertexPositionNormalTexture() = default;
    explicit VertexPositionNormalTexture(const Point3 &p, const Normal3 &n, const UV &tex)
        : p(p), n(n), tex(tex) {}
    VertexPositionNormalTexture(const VertexPositionNormalTexture &vertex) = default;
    VertexPositionNormalTexture(VertexPositionNormalTexture &&vertex) = default;
    ~VertexPositionNormalTexture() = default;
    VertexPositionNormalTexture &operator=(const VertexPositionNormalTexture &vertex) = default;
    VertexPositionNormalTexture &operator=(VertexPositionNormalTexture &&vertex) = default;

    // 32 bytes (= 8 floats)
    Point3 p;   // subclass of XMFLOAT3 with the same size as XMFLOAT3
    Normal3 n;  // subclass of XMFLOAT3 with the same size as XMFLOAT3
    UV tex;     // subclass of XMFLOAT2 with the same size as XMFLOAT2

    static const uint32_t nb_input_elements = 3;
    static const D3D11_INPUT_ELEMENT_DESC input_element_desc[nb_input_elements];


template< typename VertexT, typename IndexT >
HRESULT MSHWriter< VertexT, IndexT >::Write() {


    const uint32_t nb_vertices = static_cast< uint32_t >(m_vertices.size());
    const uint32_t nb_indices  = static_cast< uint32_t >(m_indices.size());

    WriteValueArray(, m_vertices.size());
    WriteValueArray(, m_indices.size());

    return S_OK;
template< typename DataT >
inline void Writer::WriteValueArray(const DataT *data, size_t count) {
    const size_t count_written = fwrite(data, sizeof(DataT), count, m_file);
    Assert(count == count_written);

Reading: (works fine for other files and pod data types; note that my vertices are no pods according to std::pod although they contain only floats)

template< typename VertexT, typename IndexT >
HRESULT MSHReader< VertexT, IndexT >::Read() {

    if (!IsHeaderValid()) {
        Error("%ls: invalid mesh header.", GetFilename().c_str());
        return E_FAIL;

    const uint32_t nb_vertices = ReadValue< uint32_t >(); // ok
    const uint32_t nb_indices  = ReadValue< uint32_t >(); // ok

    const VertexT *vertices = ReadValueArray< VertexT >(nb_vertices);
    m_vertices.assign(vertices, vertices + nb_vertices); // only partially ok????

    const IndexT *indices   = ReadValueArray< IndexT >(nb_indices);
    m_indices.assign(indices, indices + nb_indices);

   return S_OK;
template< typename ValueT >
const ValueT *BigEndianBinaryReader::ReadValueArray(size_t size) {
    const uint8_t *new_pos = m_pos + sizeof(ValueT) * size;
    if (new_pos < m_pos) {
        Error("%ls: overflow: no %llu values found.", GetFilename().c_str(), size);
        return nullptr;
    if (m_end < new_pos) {
       Error("%ls: end of file: no %llu values found.", GetFilename().c_str(), size);
       return nullptr;

    const ValueT *result = BytesBigEndianToValue< ValueT >(m_pos);
    m_pos = new_pos;
    return result;
template < typename ValueT >
inline const ValueT *BytesBigEndianToValue(const uint8_t *bytes) {
    return reinterpret_cast< const ValueT * >(bytes);


Vertices written to file:   

    DirectX::XMFLOAT3: {x=0.145450994 y=0.0825065970 z=-0.0557818040 }
    DirectX::XMFLOAT3: {x=0.143553764 y=0.0836364701 z=-0.0570492297 }
    DirectX::XMFLOAT3: {x=0.146553487 y=0.0869268700 z=-0.0555770397 }
    DirectX::XMFLOAT3: {x=0.148384243 y=0.0828642547 z=-0.0549440682 }

Vertices read from file:

    DirectX::XMFLOAT3: {x=0.145450994 y=0.0825065970 z=-0.0557818040 }
    DirectX::XMFLOAT3: {x=0.143553764 y=0.0836364701 z=-0.0570492297 }
    DirectX::XMFLOAT3: {x=0.146553487 y=0.0869268700 z=-0.0555770397 }
    DirectX::XMFLOAT3: {x=1.56414206e-24 y=-8.02626059e-14 z=1.62599034e+20 }

So only 16 vertices (= 512B) are correct? Why do things go wrong at vertex 17?

Edited by matt77hias

Share this post

Link to post
Share on other sites

Solved! I used

const errno_t result_fopen_s = _wfopen_s(&m_file, GetFilename().c_str(), L"w");

instead of

const errno_t result_fopen_s = _wfopen_s(&m_file, GetFilename().c_str(), L"wb");


"Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed."

Share this post

Link to post
Share on other sites

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