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

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

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

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

C++

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

GLSL

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

Q&A

解決済

1回答

409閲覧

並行移動のZ軸とnear far の関係が知りたい

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

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

C++

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

GLSL

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

0グッド

0クリップ

投稿2020/09/16 00:57

編集2020/09/16 01:36

平行移動のZ軸とnear far の関係について知りたいです。
質問1、平行移動のZ軸をマイナスやプラスすると手間になったり奥になったりと色々すると思いますが自分のコードでは表示されるか表示されないかの二通りになってしまいます、またnear far ですがそれとこのnear far はどういう関係なのでしょうか?キー入力を実装して十字キーでプラス、マイナスする動きを実装しましたがやはり表示されるかされないかのどちらかです。
参考サイトは原理に迫っていますが自分はとりえず関係というかパラメーターに意味が知りたいです。

参考サイト: https://tokoik.github.io/GLFWdraft.pdf (167ページ)

イメージ説明

cpp

1#include "Game.hpp" 2#include <iostream> 3//#include "stdafx.h" 4#include <iostream> 5#include <string> 6#include <fstream> 7#include <sstream> 8#include "Vector.hpp" 9 10 11//透視投影変換行列を作る 12void Game::create_maxtri_mp(float top, float bottom, float left, float right, 13 float near, float far, float result[4][4]) 14{ 15 result[0][0] = (2 * near) / (right - left); 16 result[0][1] = 0; 17 result[0][2] = (right + left) / (right - left); 18 result[0][3] = 0; 19 20 result[1][0] = 0; 21 result[1][1] = (2 * near) / (top - bottom); 22 result[1][2] = (top + bottom) / (top - bottom); 23 result[1][3] = 0; 24 25 result[2][0] = 0; 26 result[2][1] = 0; 27 result[2][2] = -(far + near) / (far - near); 28 result[2][3] = -(2 * far + near) / (far - near); 29 30 result[3][0] = 0; 31 result[3][1] = 0; 32 result[3][2] = -1; 33 result[3][3] = 0; 34} 35 36 37//コンストラクタ 38Game::Game() 39{ 40 mIsRunLoop = true; 41 42} 43 44//メインループ 45bool Game::RunLoop() 46{ 47 if (mIsRunLoop == true) 48 { 49 Update(); 50 GenerateOutput(); 51 } 52 else { 53 return false; 54 } 55 return true; 56 57} 58 59 60 61//シェーダを実装する 62bool Game::Shader() 63{ 64  //割愛 65 66 glBindAttribLocation(program, 0, "position"); 67 68 69 glLinkProgram(program); 70 //使わなくなったシェーダーオブジェクトを削除 71 glDeleteShader(out_frag); 72 glDeleteShader(out_vert); 73 glUseProgram(program); 74 75 76 //シェーダーに値を渡す 77///////////////////////////////////////////////////////////////////////////////////////////////////////////// 78//***************************************************************************** 79 80/////////////////////////////////////////////////////////////////////////////////////// 81 float mp[4][4]; 82 create_maxtri_mp(1.0f, -1.0f, -1.0f, 1.0f, 0.1f, 0.00000001f, mp);//透視行列を作成 83////////////////////////////////////////////////////////////////////////////////////// 84 85 86 const GLfloat rot[4][4] = { 87 {1,0,0,0}, 88 {0,1,0,0}, 89 {0,0,1,0}, 90 {0,0,0,1} 91 }; 92 93 //頂点シェーダー 94 glUniformMatrix4fv(glGetUniformLocation(program, "scale"), 1, GL_TRUE, &scale[0][0]); 95 glUniformMatrix4fv(glGetUniformLocation(program, "rotate"), 1, GL_TRUE, &rot[0][0]); 96 glUniformMatrix4fv(glGetUniformLocation(program, "move"), 1, GL_TRUE, &move[0][0]); 97 98 99 glUniformMatrix4fv(glGetUniformLocation(program, "MP"), 1, GL_TRUE, &mp[0][0]); 100 //***************************************************************************** 101 //////////////////////////////////////////////////////////////////////////////////////////////////////////////// 102 glUseProgram(program); 103 104 105 106 return true; 107} 108 109 110 111 112//初期化 113bool Game::Initialization() 114{ 115 //画面初期化 関係 116 /////////////////////////////////////////////////////////////////////////////////////////////////////////// 117 //glfwの初期化に失敗 118 if (glfwInit() != GL_TRUE) 119 { 120 printf("glfwInit()失敗\n"); 121 int _c = getchar(); 122 123 return 0; 124 } 125 126 //コンテキストを作成 127 Window = glfwCreateWindow(640, 400, "Hello", NULL, NULL); 128 129 //OpenGLコンテキストの作成に失敗 130 if (Window == NULL) 131 { 132 printf("glfCreateWindow()失敗\n"); 133 int c = getchar(); 134 135 return 0; 136 } 137 138 //コンテキストをOpenGLの描画対象にする。 139 glfwMakeContextCurrent(Window); 140 141 //glewを初期化する。 142 glewExperimental = GL_TRUE; 143 if (glewInit() != GLEW_OK) 144 { 145 printf("glewInit() の初期化に失敗しました。"); 146 return 0; 147 } 148 149 //OpenGLバージョン指定 150 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 151 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 0); 152 153 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 154 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 155 156 //垂直同期のタイミングを待つ 157 glfwSwapInterval(1); 158 /////////////////////////////////////////////////////////////////////////////////////////////////////////// 159 160 161 162 if (Shader() == true)//シェーダーを読み込む 163 { 164 printf("シェーダーを読み込む\n"); 165 } 166 167 168 glGenVertexArrays(1, &vbo); 169 glBindVertexArray(vbo); 170 glGenBuffers(1, &vbo); 171 glBindBuffer(GL_ARRAY_BUFFER, vbo); 172 glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex), Vertex, GL_STATIC_DRAW);/////// 173 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 174 glEnableVertexAttribArray(0); 175 //glEnableClientState(GL_VERTEX_ARRAY);//クライアントで頂点を有効にする。 176 177 178 179 180 181 mIsRunLoop = true; 182 return mIsRunLoop; 183} 184 185//アップデート 186void Game::Update() 187{ 188 if (glfwGetKey(Window, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(Window) != GL_FALSE) 189 { 190 mIsRunLoop = false; 191 } 192 193 if (glfwGetKey(Window, GLFW_KEY_UP) == GLFW_PRESS) 194 { 195 printf("UP: %.2f\n",move[2][3]); 196 move[2][3] = move[2][3] - 0.003f; 197 198 }else if (glfwGetKey(Window, GLFW_KEY_DOWN) == GLFW_PRESS) 199 { 200 printf("DOWN: %.2f\n", move[2][3]); 201 move[2][3] = move[2][3] + 0.003f; 202 } 203 else 204 { 205 206 } 207} 208//描画アップデート 209void Game::GenerateOutput() 210{ 211 glClearColor(1.0f, 0.0f, 0.0f, 1.0f); 212 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 213 glUseProgram(program); 214 215 216 glUniformMatrix4fv(glGetUniformLocation(program, "rotate"), 1, GL_FALSE, &move[0][0]); 217 218 glDrawArrays(GL_POLYGON, 0, 18); 219 220 221 222 glViewport(0, 0, WIDTH, HEIGHT); 223 glfwSwapBuffers(Window); 224 glfwPollEvents(); 225 226}

hpp

1#ifndef ___GMAE_H_ 2#define ___GMAE_H_ 3 4#define WIDTH 640 5#define HEIGHT 400 6 7#include "stdio.h" 8#include <fstream> 9#include <sstream> 10#include <iostream> 11 12 13 14#include "GLEW/include/GL/glew.h" 15 16#include "gl/GL.h" 17#include "GLFW/include/GLFW/glfw3.h" 18#include "Vector.hpp" 19//#include "Vector.hpp" 20 21 22 23class Game 24{ 25public: 26 Vector3 cv; 27 28 Game(); 29 30 bool Initialization(); 31 32 bool RunLoop(); 33 34 void Update(); 35 void GenerateOutput(); 36 37 38private: 39 bool mIsRunLoop;//メインループ 40 41 42 Vector3 pos; 43 44 45 //頂点バッファー 46 GLfloat Vertex[6][3] = 47 { 48 {-0.5, 0.5, 1.0}, 49 {-0.5, -0.5, 1.0}, 50 {0.5, -0.5, 1.0}, 51 52 {-0.5, 0.5, 1.0}, 53 {0.5, 0.5, 1.0}, 54 {0.5, -0.5, 1.0} 55 }; 56 57 58 //スケール行列 59 const GLfloat scale[4][4] = { 60 {1,0,0,0}, 61 {0,1,0,0}, 62 {0,0,1,0}, 63 {0,0,0,1} 64 }; 65 66 67 //回転 68 float r = 1; 69 const GLfloat rotate[4][4] = { 70 (pos.x * pos.x +(1 - cos(r)) + cos(r)), 71 (pos.x * pos.y +(1 - cos(r)) + pos.z * sin(r)) 72 ,(pos.x * pos.z +(1 - cos(r)) - pos.y * sin(r)),0, 73 74 75 (pos.x * pos.x +(1 - cos(r)) + sin(r)), 76 (pos.y * pos.y +(1 - cos(r)) + cos(r)), 77 (pos.y * pos.z +(1 - cos(r)) + pos.x * sin(r)),0, 78 79 80 (pos.x * pos.z + (1 - cos(r)) - pos.z * sin(r)), 81 (pos.y * pos.z +(1 - cos(r)) - pos.x * sin(r)), 82 (pos.z * pos.z + (1 - cos(r)) + cos(r)),0, 83 }; 84 85 86 //平行移動 87 float mx = 0; 88 float my = 0; 89 float mz = -2; 90 GLfloat move[4][4] = 91 { 92 1,0,0,mx, 93 0,1,0,my, 94 0,0,1,mz, 95 0,0,0,1, 96 }; 97 98 GLuint vbo = 0;//頂点配列バッファオブジェクト名 99 GLuint vao = 0;//頂点バッファオブジェクト名 100 101 GLFWwindow* Window = nullptr;//OpenGLコンテキスト 102 103 GLuint program = 0; 104 bool Shader();//シェーダ読み込み 105 void Compile_log(GLuint Shader);//シェーダーコンパイルログ 106 void Link_log(GLuint Shader);//シェーダーリンクログ 107 108 void GetShader_Log(GLuint shader_type,GLuint Log_type); 109 110 111 void create_maxtri_mp(float top, float bottom, float left, float right, 112 float far, float near, float result[4][4]); 113 114 115 //行列の掛け算 4 x 4 116 void matrix_mul(const float a[4][4],const float b[4][4], float r[4][4]) 117 { 118 //r[0][0] = 119 } 120 121}; 122 123 124 125#endif 126

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

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

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

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

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

guest

回答1

0

ベストアンサー

create_maxtri_mp(1.0f, -1.0f, -1.0f, 1.0f, 0.1f, 0.00000001f, mp);//透視行列を作成

nearとfarの値の関係が
near > far
になっているように見えますが,これは意図通りでしょうか?

投稿2020/09/16 01:53

fana

総合スコア11645

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

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

退会済みユーザー

退会済みユーザー

2020/09/16 02:20 編集

create_maxtri_mp(1.0f, -1.0f, -1.0f, 1.0f, 0.00000001f, 1.0f, mp); に編集しましたが表示されません。それと十字キーで値を触れるように設定したあと見えた場所にmzの値を設定して実行すると表示されなくなります。
fana

2020/09/16 02:20

(労力とか情報とかの理由により) 詳細な値までチェックできませんが, nearとfarというのは,普通は(?) perspectiveな投影であれば視野台形の奥行方向の範囲を決めるための値です. 「カメラ(視点)座標系での奥行がnear~farの範囲にあるやつだけを描画対象とする」という. より詳細に言えば… 透視投影変換によって, 【カメラ座標系における奥行が near ~ far である範囲】 を, 【OpenGLが仕様として「なんやかんや計算した結果の座標が最終的にこの範囲にあるやつだけを描画するぜ!」 と決めている正規化座標だか何だかいう範囲のZ方向の範囲(0~1なのか-1~1なのか,詳細覚えてませんが)】 に変換する といった話です.
退会済みユーザー

退会済みユーザー

2020/09/16 02:22

なるほど。しかし表示されない理由は理由はわかりますでしょうか?頂点描画をしているのでzの値を触れば近くなるはずなのですが?w
fana

2020/09/16 02:27

以前に他の質問への回答だかコメントで書きましたが, あなたは全てのマトリクスと頂点の値を(CPU側のコードで)持っているので, 「(GLの設定だのシェーダへの転送だの何だのが全てうまくいっていると仮定したときに)シェーダが行っているハズの計算」の結果 をCPU側のコードで検算なりすることが可能なはずです. なので, とりあえず(OpenGLとは無関係に)最終的に計算される座標値がどうなるのかを確認すると良いでしょう. その結果座標を 「正規化座標だが何だか」の直方体の範囲と比較して見れば,何が起こっているのかを把握する手がかりとなるのではないでしょうか.
fana

2020/09/16 02:33

バーテックスシェーダに書かれている計算式を,単にそのままCPU上でやってみるだけのコンソールアプリケーションでも別途作ってみて, そこで move のマトリクスの要素とかをいろいろ変えて試してみるとよいのではないかと. そういう確認専用のコードみたいなを持っておけば,今後も役に立つでしょう.
退会済みユーザー

退会済みユーザー

2020/09/16 02:35

なるほど、ありがとうございます。質問ですがa * b * c;という4x4の行列の掛け算はa * b * cというそのままでいいのでしょうか?
fana

2020/09/16 02:42

(何の確認なのかよくわからないですが…) 良いんじゃないですか? というか,あなたが「こういう計算をしているハズだ」という計算をまずはCPU上で試そう,という話の上では, (その試してみるためのコードを全部自前で用意するならば,行列の要素レベルでの計算を実装するハズですから) そこらへんは問題にならないですよね. シェーダコード内の a * b のような記述のことであれば,まぁ普通に2つの行列を乗じるという意味になるだろうと思います.(そうじゃないと困る)
退会済みユーザー

退会済みユーザー

2020/09/16 04:13

再度質問です悪いのですが3つの行列の掛け算とはどうするのでしょうか? 2つの行列の掛け算については調べて出てきて答え合わせも自分できるので大丈夫なのですが 3つとなるとどうすればいいのでしょうか?https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12153279307 サイトはちょっと説明が難しくてわかりません。どうすればいいのでしょうか?自分は(a * b) * c と想定しました。
fana

2020/09/16 04:33

a*b*c = (a*b)*c = a*(b*c) 掛ける方向 ( a*b と b*a は違う)さえ間違わなければ,どこの*から計算してもOK.
退会済みユーザー

退会済みユーザー

2020/09/16 05:33

度々質問ですが。サイトの[行列入門]単元ですが行列x頂点 =変換された頂点とありますがありますが横x縦とある場合はどっちがa でどっちがb なのでしょうか? a * bという式を作る際にどっちがどっちなのかわかりません。 教えてくれますでしょうか? http://www.opengl-tutorial.org/jp/beginners-tutorials/tutorial-3-matrices/
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問