gpt4 book ai didi

C++ 3D 模型 io、二进制文件读取 (badbit) 和 #DEN 问题

转载 作者:太空宇宙 更新时间:2023-11-04 14:03:23 25 4
gpt4 key购买 nike

我目前正在为我的路径追踪器开发基础框架。我正在尝试创建一个简单的二进制模型加载器(读取和写入),但我在回读文件时遇到了问题。提供更多背景信息:

写入我的数据似乎进展顺利,即没有抛出异常并且文件大小似乎不错。当我开始读取数据时,一切似乎都很好,直到某个时候(在读取所有顶点位置和一些法线之后)我的数据被破坏。当我调试时,所有数字都是正确的,但很明显,在某些时候我得到的是#DEN 而不是正确的浮点值。在某些时候我的所有网格都会发生同样的情况,所以在读取 UV 或三角形等时可能会发生这种情况。

(图片 #DEN 在第 54 正常(第 3 个 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;
}
}

读取法线按预期进行,但在一定数量的 float (法线)后出现错误。我尝试使用 for 循环读取整个法线数组,然后将所有元素复制到 vector 中,但这不是问题所在。读取三角形数据时(以类似方式完成),设置 badbit(或读取三角形之前的某处)。在下图中,我在读取三角形和 badbit 时正在调试。

(图片显示打印......没有足够的声誉)

我尝试读/写的数据结构不包含虚函数,并且全部由 float 组成(三角形除外,它有 3 个无符号整数)。点(3 个 float )、UV(2 个 float )、法线(3 个 float )、三角形(3 个无符号整数)。

编辑:这是法线的定义

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

编辑2:文件打开(在创建和销毁 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
}

如果我忘记了什么请告诉我,因为这是我关于 stackoverflow 的第一个问题。

我真的希望有人能帮助我,因为我暂时解决了这个问题(处理渲染器的其他部分)。

提前致谢!

最佳答案

除了你的 new/delete 古董(避免指针)之外,我猜你的问题是写数据。我的建议:尝试编写一个非(!)二进制文件,在编辑器中查看它。

关于C++ 3D 模型 io、二进制文件读取 (badbit) 和 #DEN 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18164656/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com