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

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

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

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

デバッグ

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

C++

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

3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

GLSL

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

Q&A

解決済

2回答

1286閲覧

[opengl ]3D描画で行列計算をシェーダーを使って描画ができない原因が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

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

デバッグ

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

C++

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

3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

GLSL

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

0グッド

0クリップ

投稿2021/04/26 04:13

編集2021/04/26 06:43

提示コードの頂点シェーダーコードなのですが参考サイトを参考にモデル行列計算やすべての行列計算をシェーダーで行いたいのですが画面に正方形の四角い線が描画されません。これはなぜなのでしょうか?そもそもシェーダーでは出来ないのでしょうか?行列をかける順番や処理の内容を参考サイトを参考によく考えましたがどうしても原因がわかりません。

参考サイト

cpp

1#include "DrawTest.hpp" 2 3#include <iostream> 4#include "Shader.hpp" 5 6#include <glm/glm.hpp> 7#include <glm/gtx/transform.hpp> 8#include <glm/gtc/matrix_transform.hpp> 9//コンストラクタ 10DrawTest::DrawTest() 11{ 12 shader = std::make_shared<Shader>("Basic_2D.vert", "Basic_2D.frag"); //シェーダー 13 14 //頂点配列 15 struct Vertex 16 { 17 GLfloat position[2]; 18 }; 19 20 //頂点情報 21 Vertex rectangleVertex[4] = 22 { 23 //頂点、頂点色 24 {-0.5f,-0.5f}, 25 {0.5f,-0.5f}, 26 {0.5f,0.5f}, 27 {-0.5f,0.5f} 28 }; 29 30 //vao 31 glGenVertexArrays(1, &vao); 32 glBindVertexArray(vao); 33 34 //vbo 35 glGenBuffers(1, &vbo); 36 glBindBuffer(GL_ARRAY_BUFFER, vbo); 37 38 39 40 //頂点 41 GLint attrib = shader->getAttribLocation("vertexPosition"); 42 glEnableVertexAttribArray(attrib); 43 glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(Vertex), rectangleVertex, GL_STATIC_DRAW); 44 glVertexAttribPointer(attrib, 2, GL_FLOAT,GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0); 45 shader->setBindAttribVertex("vertexPosition"); 46 47 48 //モデル行列 49 translate = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, -5.0f)); //平行移動 50 rotate = glm::rotate(0.0f, glm::vec3(0.0f, 0.0f, 0.0f)); //回転 51 scale = glm::scale(glm::mat4(), glm::vec3(1.0f, 1.0f, 1.0f)); //拡大縮小 52 53 //ビュー 54 glm::vec3 pos = glm::vec3(0, 0, 50); 55 glm::vec3 center = glm::vec3(0, 0, -1); 56 glm::vec3 up = glm::vec3(0,1,0); 57 58 view = glm::lookAt(pos,center,up); 59 60 //透視射形 61 projection = glm::perspective(glm::radians(90.0f),4.0f / 3.0f ,0.1f,100.0f); 62 63 64 65 66 67 68} 69 70//更新 71void DrawTest::Update() 72{ 73 74 75 76 77 78} 79 80//描画 81void DrawTest::Draw() 82{ 83 shader->setEnable(); 84 85 86 shader->setUniform4f("uFragment", glm::vec4(0.0, 0.0, 1.0, 1.0)); 87 shader->setUniformMatrix4fv("uTranslate", translate); 88 shader->setUniformMatrix4fv("uRotate", rotate); 89 shader->setUniformMatrix4fv("uScale", scale); 90 91 shader->setUniformMatrix4fv("uProjection", projection); 92 shader->setUniformMatrix4fv("uView", view); 93 94 95 96 97 98 99 glDrawArrays(GL_LINE_LOOP, 0, 4); 100 101 shader->setDisable(); 102} 103 104//デストラクタ 105DrawTest::~DrawTest() 106{ 107 glDeleteVertexArrays(1, &vao); 108 glDeleteBuffers(1, &vbo); 109} 110 111

cpp

1#ifndef ___DRAWTEST_HPP 2#define ___DRAWTEST_HPP 3 4 5#include <iostream> 6#include <glew/include/GL/glew.h> 7 8#include <glm/gtx/matrix_transform_2d.hpp> 9#include <glm/glm.hpp> 10 11 12class Shader; 13class DrawTest 14{ 15public: 16 DrawTest(); //コンストラクタ 17 ~DrawTest(); //デストラクタ 18 19 void Update(); //更新 20 void Draw(); //描画 21 22private: 23 24 std::shared_ptr<Shader> shader; //シェーダークラス 25 26 27 GLuint vao; //VertexArrayObject 28 GLuint vbo; //VertexBufferObject 29 30 31 glm::mat4 scale; //拡大縮小 32 glm::mat4 rotate; //回転 33 glm::mat4 translate; //平行移動 34 35 36 37 glm::mat4 view; //ビュー 38 glm::mat4 projection; //射形 39 40 41}; 42 43#endif 44

glsl

1#extension GL_ARB_explicit_attrib_location: enable 2 3//頂点情報 4layout(location = 0) in vec2 vertexPosition; //頂点座標 5//layout(location = 1) in vec4 vertexColor; //頂点カラー 6 7//フラグメントに転送 8layout(location = 2) out vec4 vFragment; //頂点カラー 9 10 11 12uniform mat4 uScale; //スケール 13uniform mat4 uRotate; //回転 14uniform mat4 uTranslate; //平行移動 15 16uniform mat4 uProjection; //透視行列 17uniform mat4 uView; //ビュー行列 18 19 20 21 22uniform vec4 uFragment; //色 23 24 25 26 27 28 29 30 31void main() 32{ 33 vec4 vertex = vec4(vertexPosition,-20.0,1.0); //頂点座標 34 mat4 model = uTranslate * uRotate * uScale; //モデル行列 35 36 37 38 gl_Position = (uProjection * uView * model) * vertex; 39 //gl_Position = vec4(position,0.0,1.0); //座標 40 41 42 43 44 vFragment = uFragment; //カラー 45}

glsl

1#extension GL_ARB_explicit_attrib_location: enable 2 3 4layout(location = 2) in vec4 vfragment; 5 6 7//出力 8out vec4 fragment; 9 10void main() 11{ 12 13 fragment = vfragment; 14 //fragment = vec4(0.0,0.0,1.0,1.0); 15 16}

cpp

1#include "Shader.hpp" 2 3#include <iostream> 4#include <fstream> 5#include <string> 6#include <vector> 7 8#include <glm/gtc/type_ptr.hpp> 9 10//コンストラクタ 11Shader::Shader(const char* vert, const char* frag) 12{ 13 program = loadProgram(vert,frag); 14 if (program == 0) 15 { 16 std::cerr << "シェーダープログラム作成エラー"<<std::endl; 17 exit(1); 18 } 19 20 21 22 23 //std::cout<< program << std::endl; 24 25} 26 27//シェーダーをロード 28GLuint Shader::loadProgram(const char* vert, const char* frag) 29{ 30 std::vector<GLchar> vsrc; 31 const bool vstat = ReadShaderSource(vert, vsrc); 32 33 std::vector<GLchar> fsrc; 34 const bool fstat = ReadShaderSource(frag, fsrc); 35 36 37 if (vstat && fstat) 38 { 39 return CreateProgram(vsrc.data(), fsrc.data()); 40 } 41 else { 42 return 0; 43 } 44} 45 46 47 48//シェーダーファイルを読み込む 49bool Shader::ReadShaderSource(const char* name, std::vector<GLchar>& buffer) 50{ 51 if (name == NULL) 52 { 53 return false; 54 } 55 56 57 std::ifstream file(name, std::ios::binary); 58 if (file.fail()) 59 { 60 std::cerr << "ソースファイルが読み込めません: " << name << std::endl; 61 file.close(); 62 return false; 63 } 64 65 file.seekg(0L, std::ios::end); 66 GLsizei length = static_cast<GLsizei>(file.tellg()); 67 buffer.resize(length + 1); 68 69 file.seekg(0L, std::ios::beg); 70 file.read(buffer.data(), length); 71 buffer[length] = '\0'; 72 73 if (file.fail()) 74 { 75 std::cerr << "ソースファイルを読み込めません: " << name << std::endl; 76 file.close(); 77 78 return false; 79 } 80 81 file.close(); 82 return true; 83} 84 85 86//シェーダーエラーログを取得 87GLboolean Shader::CompileInfoLog(GLuint shader,const char* str) 88{ 89 GLint status; 90 91 //コンパイル結果 92 glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 93 if (status == GL_FALSE) 94 { 95 std::cerr <<"Compile Error: " << str << std::endl; 96 } 97 98 //エラーログの長さを得る 99 GLsizei bufSize; 100 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &bufSize); 101 102 if (bufSize > 1) 103 { 104 std::vector<GLchar> infoLog(bufSize); 105 GLsizei length; 106 glGetShaderInfoLog(shader, bufSize, &length, &infoLog[0]); 107 108 std::cerr<< &infoLog[0] << std::endl; 109 } 110 111 112 113 return (GLboolean)status; 114} 115 116 117 118 119//プログラムオブジェクト作成 120GLuint Shader::CreateProgram(const char* vsrc, const char* fsrc) 121{ 122 const GLuint program = glCreateProgram(); //シェーダープログラムを作成 123 124 //std::cout << program << std::endl; 125 126 if (vsrc != NULL) 127 { 128 const GLuint vobj = glCreateShader(GL_VERTEX_SHADER); 129 glShaderSource(vobj, 1, &vsrc, NULL); 130 glCompileShader(vobj); 131 132 CompileInfoLog(vobj, vsrc); 133 134 glAttachShader(program, vobj); 135 glDeleteShader(vobj); 136 137 } 138 else { 139 std::cout << "頂点シェーダー読み込み失敗" << std::endl; 140 } 141 142 if (fsrc != NULL) 143 { 144 const GLuint fobj = glCreateShader(GL_FRAGMENT_SHADER); 145 glShaderSource(fobj, 1, &fsrc, NULL); 146 glCompileShader(fobj); 147 148 CompileInfoLog(fobj, fsrc); 149 150 glAttachShader(program, fobj); 151 glDeleteShader(fobj); 152 } 153 else { 154 std::cout << "フラグメントシェーダー読み込み失敗" << std::endl; 155 156 } 157 158 glLinkProgram(program); 159 160 ProgramInfoLog(program); 161 162 163 return program; 164} 165 166//プログラムのエラーを表示 167GLboolean Shader::ProgramInfoLog(GLuint program) 168{ 169 GLsizei bufSize; 170 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufSize); 171 172 if (bufSize > 1) 173 { 174 std::vector<GLchar> infoLog(bufSize); 175 176 GLsizei length; 177 glGetProgramInfoLog(program, bufSize, &length, &infoLog[0]); 178 std::cerr<<"Program Info Log: "<< infoLog.data() <<std::endl; 179 180 return false; 181 } 182 else 183 { 184 return true; 185 } 186} 187 188 189 190 191//locationを取得 192GLint Shader::getAttribLocation(const char* str) 193{ 194 return glGetAttribLocation(program,str); 195} 196 197 198 199//頂点シェーダーに属性変数を関連ずける 200void Shader::setBindAttribVertex(const char* str) 201{ 202 GLint n = glGetAttribLocation(program, str); 203 204 //エラー処理 205 if (n == -1) 206 { 207 std::cerr <<"setBindAttribVertex(): "<< n << std::endl; 208 } 209 else 210 { 211 glBindAttribLocation(program, n, str); 212 } 213} 214 215 216//フラグメントシェーダーに属性変数を関連ずける 217void Shader::setBindAttribFragment(const char* str) 218{ 219 GLint n = glGetAttribLocation(program, str); 220 221 //エラー処理 222 if (n == -1) 223 { 224 std::cerr << "setBindAttribFragment(): " << n << std::endl; 225 } 226 else 227 { 228 glBindFragDataLocation(program, n, str); 229 } 230} 231 232//有効にする 233void Shader::setEnable() 234{ 235 glUseProgram(program); 236 237} 238 239//無効にする 240void Shader::setDisable() 241{ 242 glUseProgram(0); 243 244} 245 246 247// ######################################################### Uniform 設定 248 249//vec1 250void Shader::setUniform1f(const char* name, const float vec) 251{ 252 const GLuint object = glGetUniformLocation(program, name); 253 glUniform1f(object,vec); 254} 255 256//vec2 257void Shader::setUniform2f(const char* name, const glm::vec2 vec) 258{ 259 const GLuint object = glGetUniformLocation(program, name); 260 glUniform2f(object,vec.x,vec.y); 261} 262 263//vec3 264void Shader::setUniform3f(const char* name, const glm::vec3 vec) 265{ 266 const GLuint object = glGetUniformLocation(program, name); 267 glUniform3f(object,vec.x, vec.y,vec.z); 268} 269 270//vec4 271void Shader::setUniform4f(const char* name, const glm::vec4 vec) 272{ 273 const GLuint object = glGetUniformLocation(program,name); 274 glUniform4f(object, vec.x, vec.y, vec.z, vec.w); 275} 276 277 278//行列2 279void Shader::setUniformMatrix2fv(const char* name, const glm::mat2 m) 280{ 281 const GLuint object = glGetUniformLocation(program, name); 282 glUniformMatrix2fv(object,1,false,glm::value_ptr(m)); 283} 284 285//行列3 286void Shader::setUniformMatrix3fv(const char* name, const glm::mat3 m) 287{ 288 const GLuint object = glGetUniformLocation(program, name); 289 glUniformMatrix3fv(object, 1, false, glm::value_ptr(m)); 290} 291 292//行列4 293void Shader::setUniformMatrix4fv(const char* name, const glm::mat4 m) 294{ 295 const GLuint object = glGetUniformLocation(program, name); 296 glUniformMatrix4fv(object, 1, false, glm::value_ptr(m)); 297 298} 299 300//デストラクタ 301Shader::~Shader() 302{ 303 304} 305

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

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

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

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

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

YT0014

2021/04/26 05:03

参考サイト等、URLに関しては、Markdown機能のリンクをお使いください。
退会済みユーザー

退会済みユーザー

2021/04/26 05:48

文章を修正しました。
fluid_love

2021/04/26 06:40

「Shader.hpp」のコードを見せていただくことは可能でしょうか? 1回ビルドしてみたいです
退会済みユーザー

退会済みユーザー

2021/04/26 06:44

提示しましたがヘッダーファイルは文字数の関係で載せられませんでした。
guest

回答2

0

ベストアンサー

私もOpenGLを今日初めて触ったので,詳しいことはよくわかりませんが,行列の計算が怪しいようです.

元のコードの平行移動回転拡大縮小行列を全て単位行列にして,カメラの位置を常識的な値にして,shader(vert)のz座標を-20.0から0にすると添付画像の結果になりました.

なので,行列の計算に問題があると思います.

*色は白に変えてます.

cpp

1 2 translate = glm::mat4(1);//glm::translate(glm::mat4(1), glm::vec3(0.0f, 0.0f, 0.1f)); //平行移動 3 rotate = glm::mat4(1);// glm::rotate(0.0f, glm::vec3(0.0f, 0.0f, 0.0f)); //回転 4 scale = glm::mat4(1);// glm::scale(glm::mat4(1), glm::vec3(1.0f, 1.0f, 1.0f)); //拡大縮小 5 6 //ビュー 7 glm::vec3 pos = glm::vec3(0, 0, 1); 8 glm::vec3 center = glm::vec3(0, 0, -1); 9 glm::vec3 up = glm::vec3(0, 1, 0); 10 11 view = glm::lookAt(pos, center, up); 12

GLSL

1 2 vec4 vertex = vec4(vertexPosition,-20.0,1.0); //-20.0を0.0に 34 vec4 vertex = vec4(vertexPosition,0.0,1.0); 5

イメージ説明


あとはお好みで,translateとかrotateとかを使ってください.

cpp

1 2 translate = glm::translate(glm::mat4(1), glm::vec3(1.0f, 0.0f, 0.0f)); //平行移動 3

x軸方向にずらすと↓になりました.
期待通りの動きだと思います.

イメージ説明

投稿2021/04/26 09:34

fluid_love

総合スコア21

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

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

退会済みユーザー

退会済みユーザー

2021/04/26 09:44

glm::translate(glm::mat4(1), glm::vec3(1.0f, 0.0f, 0.0f)); ですが第一引数は何をしているかわかりますでしょか?調べましたがリファレンスに詳しい説明がなく困っています?
fana

2021/04/26 09:53

普通にドキュメントに引数の意味が書いてあるが? > Input matrix multiplied by this translation matrix. って.
退会済みユーザー

退会済みユーザー

2021/04/26 09:56

失礼しました。自分のミスです。
guest

0

お使いのglmのバージョン等(?)によって異なってくるのかもしれませんので,確かなことは言えませんが…
各マトリクスの内容が妥当でないならば,当然ながら,それを乗じた結果も妥当ではないでしょう.

私の手元の環境では以下のようなことになるように見えるので,このあたりを確認されてみてはいかがでしょうか.
(私が使っているglmは,ver 0.9.9.7 である模様)

//モデル行列
translate = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, -5.0f)); //平行移動
rotate = glm::rotate(0.0f, glm::vec3(0.0f, 0.0f, 0.0f)); //回転
scale = glm::scale(glm::mat4(), glm::vec3(1.0f, 1.0f, 1.0f)); //拡大縮小

(1) glm::mat4() がどのような内容になるのか?
私が持っているglmのヘッダを見ると,この記述は #if ディレクティブ次第で結果が異なるように見えます.
この記述で単位行列が得られるのであれば問題無いと思いますが,私の環境ではどうやら要素が全0になってしまうようです.
(これが全0になる場合,translateなどが全0になってしまいます.)

(2) glm::rotate(0.0f, glm::vec3(0.0f, 0.0f, 0.0f)); で大丈夫ですか?
この記述,この形のオーバーロードが見つからず,コンパイルが通せませんでした.

translateやrotateと同様に最初の引数にマトリクスを与える形のオーバーロードは存在しますので,第1引数としてglm::mat4(1.0)を追加してやればコンパイルが通せましたが,その結果のrotateの要素値はnanだらけになりました.
glm::vec3(0.0f, 0.0f, 0.0f) では,**引数として不正だからではないか?**と推測します.

投稿2021/04/26 09:04

編集2021/04/26 09:09
fana

総合スコア11634

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

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

退会済みユーザー

退会済みユーザー

2021/04/26 09:08

#include <glm/glm.hpp> #include <glm/gtx/transform.hpp> #include <glm/gtc/matrix_transform.hpp> の三つをインクルードすれば(2)のコンパイルエラーは通ります。 またカメラの位置の関係で画面に見えていないと思われるのでそれを確認するためー5やー10といった値でz軸を触りました。質問ですがGLSLの掛け算の指摘がありませんがここは正しいのでしょうか?
fana

2021/04/26 09:20

ヘッダインクルードによりコンパイルが通ることはわかりました. (結局 gl::mat4(1.0) を第1引数に追加してもらえるだけみたいです) GLSLで乗じるかどうかよりも前に,まずは, translate, rotate, scale 等のマトリクス群の要素値が妥当なことを確認されてはどうでしょうか. (デバッガで見るとかすればわかるでしょうし.) それらが全て妥当な要素値を持っているとすれば,この回答は間違いであるとわかりますし, どれかが変なのであれば,そこを直せばうまくいくようになるのかもしれませんし.
fana

2021/04/26 10:06

使ってる関数の第一引数の意味も把握しないままにBA選んでるけども,結局ご自身でマトリクスの内容確認したんですか? ・glm::mat4() で良いのかダメなのか ・glm::vec3(0.0f, 0.0f, 0.0f) は不正なんじゃないか? みたいな話にはまともな反応が欲しいのだが…
退会済みユーザー

退会済みユーザー

2021/04/26 10:11

glm::vec3(0.0f, 0.0f, 0.0f) は関係ありませんでした。しかし拡大縮小はglm::vec3(1.0,1.0,1.0);という形にして等倍にする必要があります。glm::mat4();では全部が0の値なので掛け算で何をしても0なのでこれが原因でした。対処法はglm:mat4(1),glm::vec3(0.0,0.0,0.0);とすべきです。
fana

2021/04/26 10:35

> glm::mat4();では全部が0 やっぱそちらでも glm::mat4() だと全0になっちゃってるのですね. 「glm::mat4()」 って書いたら何になるの? ってのは字面から不明瞭だから,そこに疑問が湧くのが普通だと思うので, 何はともあれ,そういうことを真っ先に確認すべきだと思いますぞ. うまく動くとか動かんとか言う前の段階として. > glm::vec3(0.0f, 0.0f, 0.0f) は関係ありませんでした。 そもそもの引数の意味的に考えて glm::rotate() に (0,0,0) を渡すという行動があり得ないと思うけど… あえて怪しい値を与えるような冒険しなくてもいいんじゃないかなー.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問