Search .mtl and texture from .obj's base dir.

Fix bad memory access.
This commit is contained in:
Syoyo Fujita
2016-12-07 00:54:12 +09:00
parent c2ff3f12fc
commit 2daec8be53

View File

@@ -143,7 +143,26 @@ float eye[3], lookat[3], up[3];
GLFWwindow* window; GLFWwindow* window;
void CheckErrors(std::string desc) { static std::string GetBaseDir(const std::string &filepath) {
if (filepath.find_last_of("/\\") != std::string::npos)
return filepath.substr(0, filepath.find_last_of("/\\"));
return "";
}
static bool FileExists(const std::string &abs_filename) {
bool ret;
FILE *fp = fopen(abs_filename.c_str(), "rb");
if (fp) {
ret = true;
fclose(fp);
} else {
ret = false;
}
return ret;
}
static void CheckErrors(std::string desc) {
GLenum e = glGetError(); GLenum e = glGetError();
if (e != GL_NO_ERROR) { if (e != GL_NO_ERROR) {
fprintf(stderr, "OpenGL error in \"%s\": %d (%d)\n", desc.c_str(), e, e); fprintf(stderr, "OpenGL error in \"%s\": %d (%d)\n", desc.c_str(), e, e);
@@ -151,7 +170,7 @@ void CheckErrors(std::string desc) {
} }
} }
void CalcNormal(float N[3], float v0[3], float v1[3], float v2[3]) { static void CalcNormal(float N[3], float v0[3], float v1[3], float v2[3]) {
float v10[3]; float v10[3];
v10[0] = v1[0] - v0[0]; v10[0] = v1[0] - v0[0];
v10[1] = v1[1] - v0[1]; v10[1] = v1[1] - v0[1];
@@ -175,7 +194,7 @@ void CalcNormal(float N[3], float v0[3], float v1[3], float v2[3]) {
} }
} }
bool LoadObjAndConvert(float bmin[3], float bmax[3], static bool LoadObjAndConvert(float bmin[3], float bmax[3],
std::vector<DrawObject>* drawObjects, std::vector<DrawObject>* drawObjects,
std::vector<tinyobj::material_t>& materials, std::vector<tinyobj::material_t>& materials,
std::map<std::string, GLuint>& textures, std::map<std::string, GLuint>& textures,
@@ -187,9 +206,16 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3],
tm.start(); tm.start();
std::string base_dir = GetBaseDir(filename);
#ifdef _WIN32
base_dir += "\\";
#else
base_dir += "/";
#endif
std::string err; std::string err;
bool ret = bool ret =
tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename, NULL); tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename, base_dir.c_str());
if (!err.empty()) { if (!err.empty()) {
std::cerr << err << std::endl; std::cerr << err << std::endl;
} }
@@ -223,9 +249,20 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3],
GLuint texture_id; GLuint texture_id;
int w, h; int w, h;
int comp; int comp;
unsigned char* image = stbi_load(mp->diffuse_texname.c_str(), &w, &h, &comp, STBI_default);
std::string texture_filename = mp->diffuse_texname;
if (!FileExists(texture_filename)) {
// Append base dir.
texture_filename = base_dir + mp->diffuse_texname;
if (!FileExists(texture_filename)) {
std::cerr << "Unable to find file: " << mp->diffuse_texname << std::endl;
exit(1);
}
}
unsigned char* image = stbi_load(texture_filename.c_str(), &w, &h, &comp, STBI_default);
if (image == nullptr) { if (image == nullptr) {
std::cerr << "Unable to load texture: " << mp->diffuse_texname << std::endl; std::cerr << "Unable to load texture: " << texture_filename << std::endl;
exit(1); exit(1);
} }
glGenTextures(1, &texture_id); glGenTextures(1, &texture_id);
@@ -395,7 +432,7 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3],
return true; return true;
} }
void reshapeFunc(GLFWwindow* window, int w, int h) { static void reshapeFunc(GLFWwindow* window, int w, int h) {
int fb_w, fb_h; int fb_w, fb_h;
// Get actual framebuffer size. // Get actual framebuffer size.
glfwGetFramebufferSize(window, &fb_w, &fb_h); glfwGetFramebufferSize(window, &fb_w, &fb_h);
@@ -411,7 +448,7 @@ void reshapeFunc(GLFWwindow* window, int w, int h) {
height = h; height = h;
} }
void keyboardFunc(GLFWwindow* window, int key, int scancode, int action, static void keyboardFunc(GLFWwindow* window, int key, int scancode, int action,
int mods) { int mods) {
(void)window; (void)window;
(void)scancode; (void)scancode;
@@ -440,7 +477,7 @@ void keyboardFunc(GLFWwindow* window, int key, int scancode, int action,
} }
} }
void clickFunc(GLFWwindow* window, int button, int action, int mods) { static void clickFunc(GLFWwindow* window, int button, int action, int mods) {
(void)window; (void)window;
(void)mods; (void)mods;
if (button == GLFW_MOUSE_BUTTON_LEFT) { if (button == GLFW_MOUSE_BUTTON_LEFT) {
@@ -467,7 +504,7 @@ void clickFunc(GLFWwindow* window, int button, int action, int mods) {
} }
} }
void motionFunc(GLFWwindow* window, double mouse_x, double mouse_y) { static void motionFunc(GLFWwindow* window, double mouse_x, double mouse_y) {
(void)window; (void)window;
float rotScale = 1.0f; float rotScale = 1.0f;
float transScale = 2.0f; float transScale = 2.0f;
@@ -494,7 +531,7 @@ void motionFunc(GLFWwindow* window, double mouse_x, double mouse_y) {
prevMouseY = mouse_y; prevMouseY = mouse_y;
} }
void Draw(const std::vector<DrawObject>& drawObjects, std::vector<tinyobj::material_t>& materials, std::map<std::string, GLuint>& textures) { static void Draw(const std::vector<DrawObject>& drawObjects, std::vector<tinyobj::material_t>& materials, std::map<std::string, GLuint>& textures) {
glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_FILL); glPolygonMode(GL_BACK, GL_FILL);
@@ -513,9 +550,11 @@ void Draw(const std::vector<DrawObject>& drawObjects, std::vector<tinyobj::mater
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
std::string diffuse_texname = materials[o.material_id].diffuse_texname; if ((o.material_id < materials.size())) {
if (diffuse_texname.length() > 0) { std::string diffuse_texname = materials[o.material_id].diffuse_texname;
glBindTexture(GL_TEXTURE_2D, textures[diffuse_texname]); if (textures.find(diffuse_texname) != textures.end()) {
glBindTexture(GL_TEXTURE_2D, textures[diffuse_texname]);
}
} }
glVertexPointer(3, GL_FLOAT, stride, (const void*)0); glVertexPointer(3, GL_FLOAT, stride, (const void*)0);
glNormalPointer(GL_FLOAT, stride, (const void*)(sizeof(float) * 3)); glNormalPointer(GL_FLOAT, stride, (const void*)(sizeof(float) * 3));