提示コードの下部のコメント部内部ですが。頂点インデックスに対応した場合での法線とUV座標の設定方法がわかりません。頂点インデックスの実装はできているのですが法線やUV座標がおかしいため以下の画像のうなライティングになってしまいます。提示サイトを参考にOBJローダーを作成したのですが
どうすればUV座標、法線を正しく設定できるのでしょうか?OBJファイルはブレンダーで作成しました。
試したこと
試しにインデックスの値を使わず直接法線と。UVを設定。
ブレンダーでテクスチャを設定してインポート
github: https://github.com/Shigurechan/GL/tree/2d0637094ec1ec58d84288422b3e9db3b88e97d8
参考サイト:http://www.opengl-tutorial.org/jp/beginners-tutorials/tutorial-7-model-loading/
Mode.cpp
#include "../header/Model.hpp" #include <iostream> #include <sstream> #include <fstream> #include <assert.h> #include <vector> #include <assimp/Importer.hpp> #include <assimp/scene.h> #include <assimp/postprocess.h> #include <glm/glm.hpp> #include <GL/glew.h> #include "../lib/stb/stb_image.h" #include "../header/Resource.hpp" #include "../header/Camera.hpp" #include "../header/Window.hpp" #include "../header/Camera.hpp" FrameWork::D3::Object::Object(ObjFile o) : Render() { //shader->Input(FrameWork::LoadShader("Shader/3D/Phong.vert")->data(), FrameWork::LoadShader("Shader/3D/Phong.frag")->data()); shader->Input(FrameWork::LoadShader("Shader/3D/BasicMono_3D.vert")->data(), FrameWork::LoadShader("Shader/3D/BasicMono_3D.frag")->data()); //shader->Input(FrameWork::LoadShader("Shader/3D/BasicTexture_3D.vert")->data(), FrameWork::LoadShader("Shader/3D/BasicTexture_3D.frag")->data()); obj = o; //オブジェクトファイル glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eao); //頂点 GLint attrib = shader->getAttribLocation("vertexPosition"); glEnableVertexAttribArray(attrib); glVertexAttribPointer(attrib, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *)0); shader->setBindAttribLocation("vertexPosition"); /* //法線 attrib = shader->getAttribLocation("vertexNormal"); glEnableVertexAttribArray(attrib); glVertexAttribPointer(attrib, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *)(obj.vertex.size() * sizeof(obj.vertex[0]))); shader->setBindAttribLocation("vertexNormal"); */ /* attrib = shader->getAttribLocation("vertexUV"); glEnableVertexAttribArray(attrib); glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)(obj.vertex.size() * sizeof(obj.vertex[0]))); shader->setBindAttribLocation("vertexUV"); */ //printf("%d\n",obj.uv.size()); glBufferData(GL_ARRAY_BUFFER, obj.vertex.size() * sizeof(obj.vertex[0]), NULL, GL_STATIC_DRAW); //頂点 //glBufferData(GL_ARRAY_BUFFER, obj.vertex.size() * sizeof(obj.vertex[0]) + obj.normal.size() * sizeof(obj.normal[0]), NULL, GL_STATIC_DRAW); //頂点 glBufferSubData(GL_ARRAY_BUFFER, 0, obj.vertex.size() * sizeof(obj.vertex[0]), obj.vertex.data()); //頂点データ // glBufferSubData(GL_ARRAY_BUFFER, obj.vertex.size() * sizeof(obj.vertex[0]), obj.normal.size() * sizeof(obj.normal[0]), obj.normal.data()); //法線データ glBufferData(GL_ELEMENT_ARRAY_BUFFER, obj.vertexIndex.size() * sizeof(unsigned int), obj.vertexIndex.data(), GL_STATIC_DRAW); //頂点インデックス //Transform setRotate(glm::vec3(1, 1, 1),0); //回転 setPosition(glm::vec3(0, 0, 0)); //座標 setScale(glm::vec3(1, 1,1)); //スケール // glGenTextures(1, &textureID); //テクスチャIDの生成 // glBindTexture(GL_TEXTURE_2D, textureID); //IDバインド /* //テクスチャ生成 FrameWork::TextureFile file = FrameWork::LoadTexture("Assets/debug_texture.png"); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, file.size.x, file.size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, file.fileData); // テクスチャの補間設定 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glGenerateMipmap(GL_TEXTURE_2D); */ //バインド解除 glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); // glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } void FrameWork::D3::Object::Renderer() { //shader->setEnable(); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eao); // glBindTexture(GL_TEXTURE_2D, textureID); //IDバインド //glActiveTexture(GL_TEXTURE0); //テクスチャ有効 //描画 shader->setUniformMatrix4fv("uTranslate", getMatTranslation()); shader->setUniformMatrix4fv("uRotate", getMatRotate()); shader->setUniformMatrix4fv("uScale", getMatScale()); shader->setUniformMatrix4fv("uViewProjection",FrameWork::Camera::getViewProjection()); glDrawElements(GL_TRIANGLES, obj.vertexIndex.size(), GL_UNSIGNED_INT,(void*)0); //描画 //バインド解除 glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //glBindTexture(GL_TEXTURE_2D, 0); //shader->setDisable(); } FrameWork::D3::Object::~Object() { } // ##################################### .objファイル読み込み ##################################### void FrameWork::D3::LoadObj(const char *fileName, ObjFile &attribute) { ObjFile obj; std::vector<int> vertexIndex; std::vector<int> uvIndex; std::vector<int> normalIndex; std::vector<glm::vec3> vertex; std::vector<glm::vec2> uv; std::vector<glm::vec3> normal; FILE *file = fopen(fileName, "r"); if (file == NULL) { std::cerr << ".OBJファイルが開けません: " << fileName << std::endl; assert(0); } else { while (true) { char line[500]; int res = fscanf(file, "%s", line); if (res == EOF) { break; } if (strcmp(line, "v") == 0) { glm::vec3 vert; fscanf(file, "%f %f %fn", &vert.x, &vert.y, &vert.z); vertex.push_back(vert); obj.vertex.push_back(vert); } else if (strcmp(line, "vt") == 0) { glm::vec2 u; fscanf(file, "%f %fn", &u.x, &u.y); //u.y = 1.0f - u.y; // obj.uv.push_back(u); uv.push_back(u); } else if (strcmp(line, "vn") == 0) { glm::vec3 norm; fscanf(file, "%f %f %fn", &norm.x, &norm.y, &norm.z); obj.normal.push_back(norm); normal.push_back(norm); } else if (strcmp(line, "f") == 0) { std::string vertex1, vertex2, vertex3; unsigned int v[3], u[3], n[3]; int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%dn", &v[0], &u[0], &n[0], &v[1], &u[1], &n[1], &v[2], &u[2], &n[2]); if (matches != 9) { printf("File can't be read by our simple parser : ( Try exporting with other optionsn"); assert(0); } vertexIndex.push_back(v[0]); vertexIndex.push_back(v[1]); vertexIndex.push_back(v[2]); obj.vertexIndex.push_back(v[0] - 1); obj.vertexIndex.push_back(v[1] - 1); obj.vertexIndex.push_back(v[2] - 1); uvIndex.push_back(u[0]); uvIndex.push_back(u[1]); uvIndex.push_back(u[2]); obj.uvIndex.push_back(u[0] - 1); obj.uvIndex.push_back(u[1] - 1); obj.uvIndex.push_back(u[2] - 1); normalIndex.push_back(n[0]); normalIndex.push_back(n[1]); normalIndex.push_back(n[2]); obj.normalIndex.push_back(n[0]); obj.normalIndex.push_back(n[1]); obj.normalIndex.push_back(n[2]); } } //////////////////////////////////////////////////////////////////////////////////// for( unsigned int i = 0; i < vertexIndex.size(); i++ ) { // Get the indices of its attributes // unsigned int vi = vertexIndex[i]; unsigned int ui = uvIndex[i]; unsigned int ni = normalIndex[i]; // glm::vec3 v = vertex[ vi - 1 ]; glm::vec2 u = uv[ ui - 1]; glm::vec3 n = normal[ ni- 1]; //obj.vertex.push_back(v); //obj.uv.push_back(u); //obj.normal.push_back(n); } } ////////////////////////////////////////////////////////////////////////////////// attribute = obj; }
あなたの回答
tips
プレビュー