Jump to content
  • Advertisement
Sign in to follow this  
matt77hias

Vertex and Index buffer to file and back issue

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

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];
};

Writing:

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

    WriteString(MAGE_MSH_MAGIC);

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

    WriteValueArray(m_vertices.data(), m_vertices.size());
    WriteValueArray(m_indices.data(), 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);
}

Output:

Vertices written to file:   

m_vertices[14].p
{...}
    DirectX::XMFLOAT3: {x=0.145450994 y=0.0825065970 z=-0.0557818040 }
m_vertices[15].p
{...}
    DirectX::XMFLOAT3: {x=0.143553764 y=0.0836364701 z=-0.0570492297 }
m_vertices[16].p
{...}
    DirectX::XMFLOAT3: {x=0.146553487 y=0.0869268700 z=-0.0555770397 }
m_vertices[17].p
{...}
    DirectX::XMFLOAT3: {x=0.148384243 y=0.0828642547 z=-0.0549440682 }

Vertices read from file:

vertices[14].p
{...}
    DirectX::XMFLOAT3: {x=0.145450994 y=0.0825065970 z=-0.0557818040 }
vertices[15].p
{...}
    DirectX::XMFLOAT3: {x=0.143553764 y=0.0836364701 z=-0.0570492297 }
vertices[16].p
{...}
    DirectX::XMFLOAT3: {x=0.146553487 y=0.0869268700 z=-0.0555770397 }
vertices[17].p
{...}
    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
Advertisement

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");

MSDN:

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

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.

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!