質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

Q&A

解決済

2回答

1956閲覧

opengl テクスチャの表示がおかしい原因が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

0グッド

0クリップ

投稿2021/10/18 02:08

編集2021/10/19 08:15

提示コードですがコンストラクタでテクスチャを設定して、void Renderer()関数部で描画しているのですがテクスチャが正しく描画されない理由が知りたいです。テクスチャは以下のようなものです。表示結果は以下の通りです。

確認したこと

テクスチャのサイズとチャンネル数を確認して指定
シェーダーファイルでUV座標と頂点座標が送られているか確認

Gtihub

https://github.com/Shigurechan/GL

イメージ説明
イメージ説明

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/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); // printf("%d\n",obj.vertexIndex.size()); // printf("%d\n",obj.vertex.size()); //頂点 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("vertexUV"); glEnableVertexAttribArray(attrib); glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)(sizeof(GLfloat) * 3)); shader->setBindAttribLocation("vertexUV"); glBufferData(GL_ARRAY_BUFFER, obj.vertex.size() * sizeof(GLfloat) * 11, obj.vertex.data(), GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, obj.vertexIndex.size() * sizeof(unsigned int), obj.vertexIndex.data(), GL_STATIC_DRAW); setRotate(glm::vec3(1, 1, 1),0); //回転 glGenTextures(1, &textureID); //テクスチャIDの生成 glBindTexture(GL_TEXTURE_2D, textureID); //IDバインド glEnable(GL_TEXTURE_2D); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //テクスチャ生成 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バインド glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * 8 * obj.vertex.size(), obj.vertex.data()); glActiveTexture(GL_TEXTURE0); //テクスチャ有効 //Transform setPosition(glm::vec3(0, 0, -50)); //座標 setScale(glm::vec3(30, 30, 30)); //スケール //描画 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); vertex.push_back(vert); } else if (strcmp(line, "vt") == 0) { glm::vec2 u; fscanf(file, "%f %fn", &u.x, &u.y); std::vector<int> vertexIndex; uv.push_back(u); } else if (strcmp(line, "vn") == 0) { glm::vec3 norm; fscanf(file, "%f %f %fn", &norm.x, &norm.y, &norm.z); 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]); obj.vertexIndex.push_back(v[1]); obj.vertexIndex.push_back(v[2]); //obj.uvIndex.push_back(u[0]); //obj.uvIndex.push_back(u[1]); //obj.uvIndex.push_back(u[2]); uvIndex.push_back(u[0]); uvIndex.push_back(u[1]); uvIndex.push_back(u[2]); 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 v = vertexIndex[i]; unsigned int u = uvIndex[i]; unsigned int n = normalIndex[i]; // Get the attributes thanks to the index glm::vec3 ve = vertex[ v - 1 ]; glm::vec2 uu = uv[ u - 1 ]; glm::vec3 no = normal[ n - 1 ]; // Put the attributes in buffers obj.vertex.push_back(ve); obj.uv.push_back(uu); obj.normal .push_back(no); } attribute = obj; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

stdio

2021/10/18 04:12

画像を見ただけですが、OBJファイルとopenglの座標系とUV座標系があっているか知りたいです。 そんな感じに表示されるのは座標系の何かしらがミスっている可能性が高いです。
episteme

2021/10/18 07:27

これまでのあなたの質問を振り返ってみるに あなた「なんにも考えずにわからんこと垂れ流してる」だけじゃネーノ? って印象。 # 「考えましたがわかりません」は考えてないと同義やぞ。
fana

2021/10/19 01:21

まず,(書き捨てのプログラムでもいいから) (1)まず単純な1個の面にテクスチャを貼った物を表示することを実現してみる (2)複数の面に個別のテクスチャを貼るようなことをやってみる といったことを行い, (3)その結果を踏まえて,その毎度出てくる FrameWork とやらに見合う形での機能実装を行う. ↓ それができたならば,データの出所がOBJファイルだろうが何だろうがもはや問題にならない. 既に実装済みの機能(3)を使うのに見合う形でファイル由来のデータを加工するだけの話だからだ. (3)は自身で仕様を定めて実装したのだから,それを用いるためにはどのようなデータを用意すれば良いのか?なんてことは自明であるハズ.
fana

2021/10/19 01:26 編集

…といったような手順を踏んでいるならば, ファイルからの読込結果データ(上記(3)で用いられるデータ)の中身をチェックしてみれば? っていうだけの話になる. もしも,(3)のような実装自体が現在存在しないのであれば, ・テクスチャを貼る実装 ・OBJファイルから読み込む という2つの要素を同時にやるんじゃなくて,前記のように段階を踏むと良いであろう.
guest

回答2

0

ベストアンサー

別の問題として頂点バッファのデータがうまく渡せていないようです。
これはRenderDocを使ってみるとすぐわかりますので、ぜひ自分でもやってみてください。
RenderDocはLinuxかWindowsであれば使えると思います。

https://github.com/Shigurechan/GL/blob/0ce76a7d1c833455ee0d0472d9795f22a9c573c0/source/Model.cpp#L41

glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)(sizeof(GLfloat) * 3));

バッファ上に位置用データとuv用データ分けて置く場合は、最後の引数にはuv用データの開始オフセット (位置用データ全体のバイトサイズ) を指定する必要があります。
バッファ上に各頂点ごとに位置とuvを交互に配置する場合はstrideを頂点ごとのデータのバイトサイズに変える必要があります。

https://github.com/Shigurechan/GL/blob/0ce76a7d1c833455ee0d0472d9795f22a9c573c0/source/Model.cpp#L45
https://github.com/Shigurechan/GL/blob/0ce76a7d1c833455ee0d0472d9795f22a9c573c0/source/Model.cpp#L86
このあたりでglBufferDataとglBufferSubDataでバッファ上にデータをコピーしてますがこれは位置用データだけになってると思います。

投稿2021/10/19 13:01

tkaaad97

総合スコア64

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/10/21 09:23 編集

質問ですがこれらのコードをどうやって変更すればいいのでしょうか? https://github.com/Shigurechan/GL/blob/0ce76a7d1c833455ee0d0472d9795f22a9c573c0/source/Model.cpp#L45 https://github.com/Shigurechan/GL/blob/0ce76a7d1c833455ee0d0472d9795f22a9c573c0/source/Model.cpp#L86 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * 3 * obj.vertex.size(), obj.vertex.data()); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * 2 * obj.uv.size(), obj.uv.data()); glBufferData(GL_ARRAY_BUFFER, obj.vertex.size() * sizeof(GLfloat) * 3, obj.vertex.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, obj.uv.size() * sizeof(GLfloat) * 2, obj.uv.data(), GL_STATIC_DRAW); このようにしたのですが上手く描画さません。
tkaaad97

2021/10/21 11:46

上記のコードだと位置データとuvデータどちらもバッファ先頭から書き込まれる感じなので問題あると思います。 頂点バッファの前の方に位置データ、後ろの方にuvデータを配置することにします。 まずglBufferDataでバッファのサイズだけ指定して初期化し、次にglBufferDataを2回呼び出して位置データとuvデータを書き込みます。これは描画時に毎回呼ぶ必要はありませんのでモデルロード時に一回だけ呼べばいいはずです。 コードは下の感じになると思います。 glBufferData(GL_ARRAY_BUFFER, obj.vertex.size() * sizeof(obj.vertex[0]) + obj.uv.size() * sizeof(obj.uv[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.uv.size() * sizeof(obj.uv[0]), obj.uv.data()); それからuv属性指定する部分は下の感じでオフセット指定することになると思います。 glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)(obj.vertex.size() * sizeof(obj.vertex[0])));
退会済みユーザー

退会済みユーザー

2021/10/21 12:14

なるほど。以下のうにしたのですが上手く描画されません。テクスチャは描画されるのですが位置がおかしく表示がおかしいです。これはどうすればいいのでしょうか? attrib = shader->getAttribLocation("vertexUV"); glEnableVertexAttribArray(attrib); //glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)(sizeof(GLfloat) * 3 * obj.vertex.size())); glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)(obj.vertex.size() * sizeof(obj.vertex[0]))); shader->setBindAttribLocation("vertexUV"); glBufferData(GL_ARRAY_BUFFER, obj.vertex.size() * sizeof(obj.vertex[0]) + obj.uv.size() * sizeof(obj.uv[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.uv.size() * sizeof(obj.uv[0]), obj.uv.data()); //glBufferData(GL_ARRAY_BUFFER, obj.vertex.size() * sizeof(GLfloat) * 3, obj.vertex.data(), GL_STATIC_DRAW); //glBufferData(GL_ARRAY_BUFFER, obj.uv.size() * sizeof(GLfloat) * 2, obj.uv.data(), GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, obj.vertexIndex.size() * sizeof(unsigned int), obj.vertexIndex.data(), GL_STATIC_DRAW); setRotate(glm::vec3(1, 1, 1),0); //回転 glGenTextures(1, &textureID); //テクスチャIDの生成 glBindTexture(GL_TEXTURE_2D, textureID); //IDバインド glEnable(GL_TEXTURE_2D);
tkaaad97

2021/10/21 13:32

objファイルの構造知らなかったのですがあとはcx20さんが指摘されているあたりの対応が必要になりそうです。 objファイルのポリゴン情報では位置、uv、法線でそれぞれインデックスを別々に扱っていますがOpenGLではこういうことはできませんのでデータを並べなおす必要があります。glDrawArrayを使う方法のほうが簡単そうです。
退会済みユーザー

退会済みユーザー

2021/10/22 02:47 編集

なるほど。質問ですが並び治すとはインデックスをどうすればいいのでしょうか?一つにまとめるということでしょうか?その場合どうやって一つにまとめるのでしょうか?
guest

0

前回の続きになりますが・・

参考にしていると思われるライブラリのOBJLoaderが頂点インデックスを考慮した作りになっていません。
もし対応するとしたら、下記の個所について対応が必要です。

https://github.com/opengl-tutorials/ogl/blob/master/common/objloader.cpp#L91-L108

対応方法が分からないようであれば glDrawElements() でなく glDrawArrays() を使った方が無難かと思います。

投稿2021/10/18 14:39

cx20

総合スコア4633

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/10/19 08:19

なるほど、提示コードのように修正しましたができません、これはなぜでしょうか?
cx20

2021/10/19 14:20

元となっているコードが opengl-tutorial のものかと思いますので、今一度チュートリアルの解説を読まれると良いかと思います。 ■ チュートリアル7:モデルのロード http://www.opengl-tutorial.org/jp/beginners-tutorials/tutorial-7-model-loading/ 呼び出し側のコードについてはこちらを参照下さい。 ■ ogl/tutorial07_model_loading/ https://github.com/opengl-tutorials/ogl/tree/master/tutorial07_model_loading
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問