所以,我在OpenGL中为我的项目制作了一个模型加载器。 我正在加载Wavefront OBJ模型文件。 它加载很好,但最大的问题是加载MTL文件时。
我使用sscanf从文件中读取数据。 MTL材料在文件中告知图像的名称。
类似于:map_Kd image.bmp
当我从文件中读取图像名称时出现问题。
我使用LoadImage()函数从位图文件中获取像素数据。 当我告诉它加载给定文件名时,它会抛出一个Unhandled Exception消息()。 是的,我有项目文件夹中的图像及其所有子文件夹,以防出现问题。
这是消息:
Unhandled exception at 0x57e1d51c (msvcr100d.dll) in OBJ MODEL LOADER.exe: 0xC0000005: Access violation reading location 0x622e656d.
这是我用来加载图片的功能:
GLuint load_texture(char* path)
{
GLuint tex;
HBITMAP bm = 0;
bm = (HBITMAP)LoadImage(NULL, path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
BITMAP b;
GetObject(bm, sizeof(b), &b);
glEnable(GL_TEXTURE_2D);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, b.bmWidth, b.bmHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, b.bmBits);
return tex;
}
这是获取图像名称的功能(等等......):
void load_material(char* mtlpath, int loc, MODEL &m)
{
std::ifstream a(mtlpath);
std::vector<std::string*> file;
char buff[255];
if(!a.is_open())
{
MessageBox(g_hwnd, "Error when loading a specific material in the MTL file", "MTL(II) ERROR", 0);
}
while(!a.eof())
{
a.getline(buff, 255);
file.push_back(new std::string(buff));
}
char* name;
char* image;
GLuint ii;
sscanf(file[loc]->c_str(), "newmtl %c*",&name);
for(int i = loc; i < file.size(); i++)
{
if((file[i]->c_str()[0] == 'm'))// && (file[i]->c_str()[1] == 'a') && (file[i]->c_str()[2] == 'p') && (file[i]->c_str()[3] == '_') && (file[i]->c_str()[4] == 'K') && (file[i]->c_str()[5] == 'd'))
{
sscanf(file[i]->c_str(), "map_Kd %s", &image);
SetWindowText(g_hwnd, image);
break;
}
}
std::ofstream s("aa.txt");
s << image;
s.close();
ii = 0;
m.m.push_back(new material(name, image, ii));
a.close();
}
我已经尝试将%s(sscanf调用)更改为%* c,%c,%* c,%c [^]和其他多个。
我还要提一下,我试图直接将我的图像名称放在&#34;图像&#34;变量没有从文件中检索它,它完全像那样。
如何从字符串中成功检索图像名称?
顺便说一下,我不想使用任何其他东西(MCI,SDL);
答案 0 :(得分:0)
简而言之:将std::vector<std::string*>
替换为std::vector<std::string>
,将scanf
替换为std::stringstream
。
答案 1 :(得分:0)
%c
读取单个字符,但您尝试读取字符串,因此需要使用%s
。
将%s
与sscanf()
一起使用时,必须事先预先分配目标缓冲区,但您没有这样做。您正在将未初始化的char*
指针传递给sscanf()
,因此它会尝试将字符串数据写入随机内存,从而导致崩溃。
尝试更像这样的东西:
void load_material(char* mtlpath, int loc, MODEL &m)
{
std::ifstream a(mtlpath);
std::vector<std::string> file;
char buff[256];
if (!a.is_open())
{
MessageBox(g_hwnd, "Error when loading a specific material in the MTL file", "MTL(II) ERROR", 0);
}
while (a.getline(buff, 255))
{
buff[a.gcount()] = '\0';
file.push_back(buff);
}
a.close();
char name[256] = {0};
char image[256] = {0};
GLuint ii;
sscanf(file[loc].c_str(), "newmtl %255s", name);
for(int i = loc; i < file.size(); i++)
{
if (sscanf(file[i].c_str(), "map_Kd %255s", image) == 1)
{
SetWindowText(g_hwnd, image);
break;
}
}
std::ofstream s("aa.txt");
s << image;
s.close();
ii = 0;
m.m.push_back(new material(name, image, ii));
}
或者,摆脱sscanf()
,在这种情况下你真的不需要它:
void load_material(char* mtlpath, int loc, MODEL &m)
{
std::ifstream a(mtlpath);
std::vector<std::string> file;
std::string buff;
if (!a.is_open())
{
MessageBox(g_hwnd, "Error when loading a specific material in the MTL file", "MTL(II) ERROR", 0);
}
while (std::getline(a, buff))
file.push_back(buff);
a.close();
std::string name;
std::string image;
GLuint ii;
if (file[loc].compare(0, 7, "newmtl ", 7) == 0)
name = file[loc].substr(7);
for(int i = loc; i < file.size(); i++)
{
if (file[i].compare(0, 7, "map_Kd ", 7) == 0)
{
image = file[i].substr(7);
SetWindowText(g_hwnd, image.c_str());
break;
}
}
std::ofstream s("aa.txt");
s << image;
s.close();
ii = 0;
m.m.push_back(new material(name.c_str(), image.c_str(), ii));
}