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

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

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

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

C++

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

解決済

OpenGL(GLFW)で、視点移動を上手く行うことができない。

Unity-chan
Unity-chan

総合スコア20

OpenGL

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

C++

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

1回答

0グッド

1クリップ

9821閲覧

投稿2017/01/05 17:14

###前提・実現したいこと
最終的に実現したいことは、モニタ上に描画する画像を切り替え続けつつ、頭部の動きに合わせて視点を移動させることで映像を見回すシステムです。(視界に収まらない程の巨大なスクリーンを見回すといった動作がしたい)OpenGLを用いてこれを実現しようとしています。

「raw画像を読み込み、それをテクスチャに張り付けてそれをモニタ上へ表示する」まで出来ており、"現在実現したいこと"は、「キーボードを用いて視点を移動させることで、テクスチャに張り付けた画像を見回す」ことです。

イメージ説明

###発生している問題

"gluLookAt"で視点移動を行った場合、視界からテクスチャが消える。(視点移動のコードは、Main関数の最後の方に記述する予定)

###該当のソースコード

C++

1//============================================================================= 2// Linker 3//============================================================================= 4 5#pragma comment(lib, "opengl32.lib") 6#pragma comment(lib, "glu32.lib") 7#pragma comment(lib, "glfw3.lib") 8#pragma comment(lib, "glew32.lib") 9 10 11 12//============================================================================= 13// define / include / using 14//============================================================================= 15 16#define GLFW_INCLUDE_GLU // GLFW3で"glu.h"を読み込むように指定 17 18#include <iostream> 19#include <fstream> 20#include <vector> 21#include <cassert> 22#include <GL/glew.h> 23#include <GLFW/glfw3.h> 24 25using std::cerr; 26using std::endl; 27using std::vector; 28using std::ifstream; 29using std::ios; 30 31//============================================================================= 32// variable 33//============================================================================= 34 35const int g_windowWidth = 1920; 36const int g_windowHeight = 1080; 37const int g_pictureWidth = 1920; 38const int g_pictureHeight = 1080; 39GLuint g_texID; 40 41 42 43//============================================================================= 44// Functions Prototype 45//============================================================================= 46 47extern void OnApplicationQuit(); 48extern void KeyCallBack(GLFWwindow *window, int key, int scancode, int action, int mods); 49extern void Display(); 50extern void setupTexture(const char *fileName, const int textureWidth, const int textureHeight); 51 52 53 54//============================================================================= 55// Main Function 56//============================================================================= 57 58int main(){ 59 // --- Initialize OpenGL --- 60 if (!glfwInit()){ 61 cerr << "Can't initialize GLFW." << endl; 62 return -1; 63 } 64 65 // アプリケーション終了時に、GLFWで作成したウィンドウを閉じ、確保したリソースも開放する 66 atexit(OnApplicationQuit); 67 68 69 // OpenGL Version 3.2 Core Profileを選択 70 //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 71 //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 72 //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 73 //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 74 75 76 // フルスクリーンのウィンドウを作成する 77 GLFWwindow *const wHandle(glfwCreateWindow(g_windowWidth, g_windowHeight, "Hello!", glfwGetPrimaryMonitor(), NULL)); 78 if (wHandle == NULL) { 79 cerr << "Can't create GLFW window." << endl; 80 return -1; 81 } 82 83 // ウィンドウを作成した場合、そのウィンドウをアクティブにし、その後キーコールバック関数を登録する 84 glfwMakeContextCurrent(wHandle); 85 glfwSetKeyCallback(wHandle, KeyCallBack); 86 87 88 // モニタとの同期(0の場合は垂直同期オフと同義?) 89 glfwSwapInterval(1); 90 91 92 // 描画範囲の指定 93 glViewport(0, 0, g_windowWidth, g_windowHeight); 94 glMatrixMode(GL_PROJECTION); 95 glLoadIdentity(); 96 glOrtho(0.0f, g_windowWidth, 0.0f, g_windowHeight, -1.0f, 1.0f); 97 98 99 // OpenGL上でテクスチャを生成し、その後そのテクスチャに読み込んだ画像を張り付ける 100 glGenTextures(1, &g_texID); 101 // --- Initialize OpenGL --- 102 103 104 // --- LoadPicture 105 setupTexture("sample2.raw", g_pictureWidth, g_pictureHeight); 106 107 108 // 背景は白色 109 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 110 111 112 // ゲームループ 113 while (glfwWindowShouldClose(wHandle) == GL_FALSE) { 114 // 背景を塗りつぶす 115 glClear(GL_COLOR_BUFFER_BIT); 116 117 // カメラの調整 118 //glLoadIdentity(); 119 //gluLookAt(0.0, 0.0, -5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 120 121 // 描画 122 Display(); 123 124 125 // 新しいバッファに入れ替え 126 glfwSwapBuffers(wHandle); 127 128 129 // イベントが起きるまで待機 130 glfwWaitEvents(); 131 } 132 133 return 0; 134} 135 136 137 138 139//============================================================================= 140// Static Functions 141//============================================================================= 142 143// プログラムが終了する直前に実行する。Add to atexit() 144static void OnApplicationQuit(){ 145 glfwTerminate(); 146} 147 148// キーボードが入力された時の動作 149static void KeyCallBack(GLFWwindow *window, int key, int scancode, int action, int mods){ 150 if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) 151 glfwSetWindowShouldClose(window, GL_TRUE); 152 153 // -- キーボードの入力に応じてgluLookAtの引数を変更する -- 154} 155 156static void setupTexture(const char *fileName, const int textureWidth, const int textureHeight){ 157 // 画像データをロードする 158 ifstream fstr(fileName, ios::binary); 159 assert(fstr); 160 161 162 // テクスチャデータを"textureBuffer配列"に格納する 163 const size_t fileSize = static_cast<size_t>(fstr.seekg(0, fstr.end).tellg()); 164 165 fstr.seekg(0, fstr.beg); 166 167 vector<char> textureBuffer(fileSize); 168 169 fstr.read(&textureBuffer[0], fileSize); 170 171 172 // 画像データとテクスチャiDを結びつける 173 glBindTexture(GL_TEXTURE_2D, g_texID); 174 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, &textureBuffer[0]); 175 176 177 // テクスチャの各種設定 178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 180 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 182} 183 184 185// 描画 186static void Display(){ 187 // テクスチャの頂点配列を定義(画面"左下"から各頂点に対する距離) 188 static const GLfloat textureVertexArray[] = { 189 0, 0, // 左下 190 1920, 0, // 右下 191 1920, 1080, // 右上 192 0, 1080, // 左上 193 }; 194 glVertexPointer(2, GL_FLOAT, 0, textureVertexArray); 195 196 // プロットする画像の頂点を定義(画像"左上"から各頂点に対する距離。[0 - 1.0]) 197 static const GLfloat textureCoordArray[] = { 198 0.0f, 1.0f, // 左上 199 1.0f, 1.0f, // 右上 200 1.0f, 0.0f, // 右下 201 0.0f, 0.0f, // 左下 202 }; 203 glTexCoordPointer(2, GL_FLOAT, 0, textureCoordArray); 204 205 206 // 指定テクスチャの設定開始 207 glBindTexture(GL_TEXTURE_2D, g_texID); 208 209 // 2Dテクスチャと頂点配列の使用を有効にする 210 glEnable(GL_TEXTURE_2D); 211 glEnableClientState(GL_VERTEX_ARRAY); 212 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 213 214 // 描画 215 glDrawArrays(GL_QUADS, 0, 4); 216 217 // 描画が終わったので有効にした機能を無効化 218 glDisable(GL_TEXTURE_2D); 219 glDisableClientState(GL_VERTEX_ARRAY); 220 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 221}

###試したこと
"gluLookAt"で用いられているのは3次元座標となっているので、"Display関数"で定義する頂点配列を3次元のものに置き換えようと試みました。結果として画像が表示されなくなったのですが、"gluLookAt"の設定が悪いのかテクスチャのプロットが悪いのかがわかりませんでした。

###補足情報(言語/FW/ツール等のバージョンなど)
〇開発環境
IDE
Visual Studio 2013 Express for Windows Desktop

OpenGLのツールキット
GLFW3

〇参考サイト
GLFW導入(NuGetは未使用)
http://marina.sys.wakayama-u.ac.jp/~tokoi/GLFW.pdf

テクスチャ(glfw3用に少し改変した)
http://nn-hokuson.hatenablog.com/entry/2014/02/05/001602

視点
http://www.natural-science.or.jp/article/20091110211125.php

頂点配列(3次元のテクスチャ貼り付け方法)
http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20080829

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答1

0

ベストアンサー

ざっと見て思いついたことです。

「カメラの調整」のところで、MatrixModeを設定していません。
設定していないという事は、最後に設定されたままになっています。glMatrixModeを呼んでいるのは一箇所のみのようですので、おそらくGL_PROJECTIONになっているでしょう。
ですので、glOrthoで設定したマトリクスがgluLookAt(の前のglLoadIdentity)で設定するマトリクスで上書きされていると思われます。

ビューマトリクスを設定する前に、MatrixModeをGL_MODELVIEWにしてください。

c

1 // カメラの調整 2 glMatrixMode(GL_MODELVIEW); 3 glLoadIdentity(); 4 gluLookAt(0.0, 0.0, -5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

あともう一点。

glOrthoで指定しているFarクリップ値の値が「1.0」、カメラの位置が「0.0, 0.0, -5.0」、頂点が(Z値を指定していないので)「x, y, 0.0」の位置になっていて、カメラと頂点との距離が「5.0」になるので、デプスバッファの範囲外になり、デプステストが有効であれば表示されません。

もっとも、GL_DEPTH_TESTの設定がされていないので、デプステストのデフォルト値は無効のようなので、現状のままでも表示されると思いますが、一応適切な値を設定する事をお薦めします。

投稿2017/01/06 16:02

katsuko

総合スコア3255

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Unity-chan

2017/01/09 12:32

回答ありがとうございます! 仰る通りカメラの視点移動が正常に動作しなかったのは、モデルビューモードに設定していないことが原因でした。 カメラと頂点のパラメータを正確に理解しておらず、そのような設定となってしまいました。質問外の誤りまで指摘して頂き本当にありがとうございます。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

OpenGL

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

C++

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