1

私は現在、パス トレーサーの基本フレームワークに取り組んでいます。シンプルなバイナリ モデル ローダー (読み取りと書き込み) を作成しようとしていますが、ファイルの読み取りで問題が発生しました。もう少しコンテキストを与えるには:

私のデータの書き込みは順調に進んでいるようです。つまり、例外はスローされず、ファイルサイズも問題ないようです。データの読み取りを開始すると、(すべての頂点位置といくつかの法線を読み取った後) データが破損するまで、すべて問題ないように見えます。デバッグすると、すべての数値は正しいのですが、ある時点で正しい float 値ではなく #DEN が返されることは明らかです。同じことがある時点ですべてのメッシュで発生するため、UV や三角形などを読み取るときに発生する可能性があります。

(画像 #DEN at 54th Normal (3rd float) ...評判が足りない)

すべての法線 (1 つのサブメッシュ) を一度に読み取りました。ifstream を見ると、ファイルの先頭にリセットされます。三角形のインデックス (新しい stream.read()) の読み取りを開始すると、badbit が設定されます。

Visual Studio 2010 Ultimate を使用しており、Windows 7 Professional x64 で実行しています。私はCとC++を使用しています。

重要なコードのみを表示しようとします。

if(meshHeader.numberOfNormals > 0)
{           
    Normal* _normals = Read<Normal>(meshHeader.numberOfNormals);

    if(_normals)
    {
        // Copy from array to vector
        _normalsVec = new vector<Normal>(_normals, _normals + meshHeader.numberOfNormals);

        // Cleanup              
        delete[] _normals;
    }
    else
    {
        // Cleanup
        delete[] _normals;
        throw runtime_error("Failed reading vertex normals");
    }
}

読み取り方法:

template <typename T> 
T* BinaryModelIO::Read(unsigned int _size)
{
    T* _data = new T[_size];
    unsigned int _numberOfBytes = Read(sizeof(T) * _size, static_cast<void*>(_data));

    if(_numberOfBytes != (sizeof(T) * _size))
    {
        delete[] _data;
        _data = 0;
    }

    return _data;
}

( static_cast(_data) が原因ではありません) 続きを読む:

unsigned int BinaryModelIO::Read(unsigned int _numberOfBytes, void *_buffer)
{
    if(isWriter)
        return 0;
    // no fail bit set?
    if(!readStream->fail())
    {
        try
        {
            readStream->read((char*)_buffer, _numberOfBytes);
        }
        catch(exception &e)
        {
            cerr << e.what() << endl;
            //return 0;
        }
        return _numberOfBytes;
    }
    else
    {
        if(readStream->badbit)
            cerr << "badbit" << endl;
        else if(readStream->eofbit)
            cerr << "eofbit" << endl;
        return 0;
    }
}

法線の読み取りは期待どおりに行われますが、ある程度のフロート (法線) の後ではうまくいきません。for ループで法線の配列全体を読み取ってから、すべての要素をベクターにコピーしようとしましたが、これは問題ではありませんでした。Triangle データを読み取るとき (同様の方法で実行)、badbit が設定されます (または、Triangle が読み取られる前のどこかに)。下の画像では、三角形を読み取りながらデバッグしていて、badbit が出力されています。

(印刷物を示す画像...評判が足りない)

読み取り/書き込みしようとしているデータ構造には仮想関数が含まれておらず、すべてフロートで構成されています (3 つの unsigned int を持つ三角形を除く)。ポイント (3 つの float)、UV (2 つの float)、Normal (3 つの float)、Triangle (3 つの unsigned int)。

編集:これが法線の定義です

class Normal 
{
public:
    // Vector Public Methods
    Normal(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f) : x(_x), y(_y), z(_z) {   }
        explicit Normal(const Vector3& _vector);
        explicit Normal(const Point& _point);

    // Overloaded Operators
    Normal operator+(const Normal& _norm) const 
    {
        return Normal(x + _norm.x, y + _norm.y, z + _norm.z);
    }   
    Normal& operator+=(const Normal& _norm) 
    {
        x += _norm.x; 
        y += _norm.y; 
        z += _norm.z;
        return *this;
    }
    Normal operator-(const Normal& _norm) const 
    {
        return Normal(x - _norm.x, y - _norm.y, z - _norm.z);
    }   
    Normal& operator-=(const Normal& _norm) 
    {
        x -= _norm.x;
        y -= _norm.y; 
        z -= _norm.z;
        return *this;
    }
    bool operator==(const Normal& _norm) const 
    {
        return x == _norm.x && y == _norm.y && z == _norm.z;
    }
    bool operator!=(const Normal& _norm) const 
    {
        return x != _norm.x || y != _norm.y || z == _norm.z;
    }
    Normal operator*(float _f) const 
    {
        return Normal(_f * x, _f * y, _f * z);
    }   
    Normal &operator*=(float _f) 
    {
        x *= _f; 
        y *= _f; 
        z *= _f;
        return *this;
    }
    Normal operator/(float _f) const 
    {
        // One division, 3 multiplications ^^
        float _inverse = 1.f / _f;
        return Normal(x * _inverse, y * _inverse, z * _inverse);
    }
    Normal &operator/=(float _f) 
    {
        float _inverse = 1.f / _f;
        x *= _inverse; 
        y *= _inverse; 
        z *= _inverse;
        return *this;
    }
    Normal operator-() const 
    {
        return Normal(-x, -y, -z);
    }
    float operator[](int _i) const 
    {
        // Return x, y or z
        return (&x)[_i];
    }   
    float &operator[](int _i) 
    {
        return (&x)[_i];
    }

    float LengthSquared() const 
    { 
        return x * x + y * y + z * z; 
    }
    float Length() const 
    { 
        return sqrtf(LengthSquared()); 
    }

    // Public Variables
    float x, y, z;
}; // 12 Byte

edit2: ファイルのオープン (Loader オブジェクトの作成および破棄時に実行)

bool AbstractStream::OpenFile()
{
    bool _return = false;

    // We should open file to write or to read
    if(isWriter)
    {
        // Check if the file is already open
        if(!writeStream->is_open())
            writeStream->open(fileName, ios::in | ios::binary);

        if(!writeStream->fail())
            _return = true; // File could be opened
    }
    else
    {
        // Check if the file is already open
        if(!readStream->is_open())
            readStream->open(fileName, ios::in | ios::binary);

        if(!readStream->fail())
            _return = true; // File could be opened
    }

    return _return; // File could be opened
}

これがスタックオーバーフローに関する私の最初の質問であるため、何かを忘れた場合は教えてください。

私はしばらくこの問題を回避したので、誰かが私を助けてくれることを本当に願っています(レンダラーの他の部分に取り組んでいます)。

前もって感謝します!

4

1 に答える 1

0

新規作成/削除の古い私たちに加えて(ポインタを避けてください)、あなたの問題はデータの書き込みにあると思います。私の提案:非(!)バイナリファイルを書いてみて、エディタで見てください。

于 2013-08-10T18:20:45.057 に答える