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

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

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

GLFWは、OpenGLを使用してアプリ開発を行うためのフレームワークです。Macにも対応しているマルチプラットフォームであることが特徴。ウィンドウ管理、解像度切り替え、入力管理などの機能を持ちます。

OpenGL

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

GLSL

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

Q&A

解決済

1回答

3998閲覧

GLFWで矩形が描画されない

honjoriki

総合スコア81

GLFW

GLFWは、OpenGLを使用してアプリ開発を行うためのフレームワークです。Macにも対応しているマルチプラットフォームであることが特徴。ウィンドウ管理、解像度切り替え、入力管理などの機能を持ちます。

OpenGL

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

GLSL

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

0グッド

1クリップ

投稿2018/09/25 02:41

編集2018/09/25 02:47

##わからないこと
現在、床井研究室(http://marina.sys.wakayama-u.ac.jp/~tokoi/)の資料を見ながらOpenGLを勉強しております。

そこで見ていたGLFWでのOpenGL入門(http://marina.sys.wakayama-u.ac.jp/~tokoi/GLFWdraft.pdf)第5章、矩形の表示ができません。コンパイルまでは通るのですが、図形表示までの処理がされていない様子です。

main

1#include <cstdlib> 2#include <iostream> 3#include <fstream> 4#include <vector> 5#include <memory> 6#include <GL/glew.h> 7#include <GLFW/glfw3.h> 8#include "Shape.h" 9 10 11// シェーダオブジェクトのコンパイル結果を表示する 12// shader: シェーダオブジェクト名 13// str: コンパイルエラーが発生した場所を示す文字列 14GLboolean printShaderInfoLog(GLuint shader, const char *str) 15{ 16 // コンパイル結果を取得する 17 GLint status; 18 glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 19 if (status == GL_FALSE) std::cerr << "Compile Error in " << str << std::endl; 20 // シェーダのコンパイル時のログの長さを取得する 21 GLsizei bufSize; 22 glGetShaderiv(shader, GL_INFO_LOG_LENGTH , &bufSize); 23 if (bufSize > 1) 24 { 25 // シェーダのコンパイル時のログの内容を取得する 26 std::vector<GLchar> infoLog(bufSize); 27 GLsizei length; 28 glGetShaderInfoLog(shader, bufSize, &length, &infoLog[0]); 29 std::cerr << &infoLog[0] << std::endl; 30 } 31 return static_cast<GLboolean>(status); 32} 33 34// プログラムオブジェクトのリンク結果を表示 35// program: プログラムオブジェクト名 36GLboolean printProgramInfoLog(GLuint program) 37{ 38 // リンク結果取得 39 GLint status; 40 glGetProgramiv(program, GL_LINK_STATUS, &status); 41 if(status == GL_FALSE) std::cerr << "Link Error." << std::endl; 42 43 // シェーダのリンク時のログの長さを取得 44 GLsizei bufSize; 45 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufSize); 46 47 if(bufSize > 1) { 48 //シェーダのリンク時のログの内容を取得する 49 std::vector<GLchar> infoLog(bufSize); 50 GLsizei length; 51 glGetProgramInfoLog(program, bufSize, &length, &infoLog[0]); 52 std::cerr << &infoLog[0] << std::endl; 53 } 54 55 return static_cast<GLboolean>(status); 56} 57 58 59// プログラムオブジェクトを作成する 60// vsrc: バーテックスシェーダのソースプログラムの文字列 61// fsrc: フラグメントシェーダのソースプログラムの文字列 62 63GLuint createProgram(const char *vsrc, const char *fsrc) 64{ 65 // 空のプログラムオブジェクトを作成する 66 const GLuint program(glCreateProgram()); 67 68 if(vsrc != NULL) { 69 // バーテックスシェーダのシェーダオブジェクトを作成 70 const GLuint vobj(glCreateShader(GL_VERTEX_SHADER)); 71 glShaderSource(vobj, 1, &vsrc, NULL); 72 glCompileShader(vobj); 73 74 // バーテックスシェーダのシェーダオブジェクトをプログラムオブジェクトに組み込む 75 if(printShaderInfoLog(vobj, "vertex shader")) 76 glAttachShader(program, vobj); 77 glDeleteShader(vobj); 78 } 79 80 if(fsrc != NULL) { 81 // フラグメントシェーダのシェーダオブジェクトを作成 82 const GLuint fobj(glCreateShader(GL_FRAGMENT_SHADER)); 83 glShaderSource(fobj, 1, &fsrc, NULL); 84 glCompileShader(fobj); 85 86 // フラグメントシェーダのシェーダオブジェクトをプログラムオブジェクトに組み込む 87 if(printShaderInfoLog(fobj, "fragment shader")) 88 glAttachShader(program, fobj); 89 glDeleteShader(program); 90 } 91 92 // プログラムオブジェクトをリンクする 93 glBindAttribLocation(program, 0, "position"); 94 glBindFragDataLocation(program, 0, "fragment"); 95 glLinkProgram(program); 96 97 // 作成したプログラムオブジェクトを返す 98 if(printProgramInfoLog(program)) 99 return program; 100 101 // プログラムオブジェクトが作成できなければ0を返す 102 glDeleteProgram(program); 103 return 0; 104} 105 106 107 108 109// シェーダのソースファイルを読み込んだメモリを返す 110// name: シェーダのソースファイル名 111// buffer: 読み込んだソースファイルのテキスト 112bool readShaderSource(const char *name, std::vector<GLchar> &buffer) 113{ 114 //ファイル名がNULLなら 115 if(name == NULL) { 116 return false; 117 } 118 // ソースファイルを開く 119 std::ifstream file(name, std::ios::binary); 120 if(file.fail()) { 121 // 開けなかった 122 std::cerr << "Error: Can't open source file: " << name << std::endl; 123 return false; 124 } 125 126 // ファイルの末尾に移動して現在位置を得る 127 file.seekg(0L, std::ios::end); 128 GLsizei length = static_cast<GLsizei>(file.tellg()); 129 130 // ファイルサイズのメモリ確保 131 buffer.resize(length + 1); 132 133 // ファイルを先頭から読み込む 134 file.seekg(0L, std::ios::beg); 135 file.read(buffer.data(), length); 136 buffer[length] = '\0'; 137 138 if(file.fail()) { 139 // うまく読み込めなかった 140 std::cerr << "Error: Could not read source file: " << name << std::endl; 141 file.close(); 142 return false; 143 } 144 145 // 読み込み成功 146 file.close(); 147 return true; 148} 149 150 151// シェーダのソースファイルを読み込んでプログラムオブジェクトを作成する 152// vert:バーテックスシェーダのソースファイル名 153// frag:フラグメントシェーダのソースファイル名 154GLuint loadProgram(const char *vert, const char *frag) 155{ 156 // シェーダのソースファイルを読み込む 157 std::vector<GLchar> vsrc; 158 const bool vstat(readShaderSource(vert, vsrc)); 159 std::vector<GLchar> fsrc; 160 const bool fstat(readShaderSource(frag, fsrc)); 161 162 // プログラムオブジェクトを作成 163 return vstat && fstat ? createProgram(vsrc.data(), fsrc.data()) : 0; 164} 165 166// 矩形の頂点の位置 167constexpr Object::Vertex rectangleVertex[] = 168{ 169 { -0.5f, -0.5f }, 170 { 0.5f, -0.5f }, 171 { 0.5f, 0.5f }, 172 { -0.5f, 0.5f } 173}; 174 175 176int main() 177{ 178 // GLFW初期化 179 if(glfwInit() == GL_FALSE) { 180 std::cerr << "Can't initialize GLFW" << std::endl; 181 182 return 1; 183 } 184 185 // プログラム終了時の処理を登録 186 atexit(glfwTerminate); 187 188 // OpenGL Version 3.2 Core Profile を選択 189 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 190 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 191 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 192 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 193 194 // window生成 195 GLFWwindow *const window(glfwCreateWindow(640, 480, "Hello", NULL, NULL)); 196 if(window == NULL) { 197 std::cerr << "Can't create GLFW window" << std::endl; 198 return 1; 199 } 200 //windowをOpenGLの処理対象にする 201 glfwMakeContextCurrent(window); 202 203 // GLEW初期化 204 glewExperimental = GL_TRUE; 205 if(glewInit() != GLEW_OK) { 206 std::cerr << "Can't initialize GLEW" << std::endl; 207 return 1; 208 } 209 210 // 垂直同期のタイミングを待つ 211 glfwSwapInterval(1); 212 213 // 背景色指定 214 glClearColor(1.0f, 1.0f, 1.0f, 0.0f); 215 216 // プログラムオブジェクトの作成 217 const GLuint program(loadProgram("point.vert", "point.frag")); 218 219 // 図形データを作成する 220 std::unique_ptr<const Shape> shape(new Shape(2, 4, rectangleVertex)); 221 222 // windowが開いている間繰り返す 223 while(glfwWindowShouldClose(window) == GL_FALSE) { 224 // windowの消去 225 glClear(GL_COLOR_BUFFER_BIT); 226 227 // シェーダプログラムの使用開始 228 glUseProgram(program); 229 230 //ここで描画処理を行う 231 shape->draw(); 232 233 234 // カラーバッファの入れ替え 235 glfwSwapBuffers(window); 236 237 // イベントを取り出す 238 glfwWaitEvents(); 239 } 240}

Object

1#pragma once 2#include <GL/glew.h> 3 4// 図形データ 5class Object { 6 // 頂点配列オブジェクト名 7 GLuint vao; 8 // 頂点バッファオブジェクト名 9 GLuint vbo; 10 11public: 12 13 // 頂点属性 14 struct Vertex { 15 // 位置 16 GLfloat position[2]; 17 }; 18 19 //コンストラクタ 20 // size: 頂点の位置の次元 21 // vertexcount: 頂点の数 22 // vertex: 頂点属性を格納した配列 23 Object(GLint size, GLsizei vertexcount, const Vertex *vertex) 24 { 25 // 頂点配列オブジェクト 26 glGenVertexArrays(1, &vao); 27 glBindVertexArray(vao); 28 29 // 頂点バッファオブジェクト 30 glGenBuffers(1, &vbo); 31 glBindBuffer(GL_ARRAY_BUFFER, vbo); 32 glBufferData(GL_ARRAY_BUFFER, 33 vertexcount * sizeof(Vertex), vertex, GL_STATIC_DRAW); 34 35 // 結合されている頂点バッファオブジェクトを in 変数から参照できるようにする 36 glVertexAttribPointer(0, size, GL_FLOAT, GL_FALSE, 0, 0); 37 glEnableVertexAttribArray(0); 38 } 39 40 // デストラクタ 41 virtual ~Object() 42 { 43 // 頂点配列オブジェクトを削除 44 glDeleteBuffers(1, &vao); 45 46 // 頂点バッファオブジェクトを削除 47 glDeleteBuffers(1, &vbo); 48 } 49 50private: 51 52 // コピーコンストラクタによるコピー禁止 53 Object(const Object &o); 54 55 // 代入によるコピー禁止 56 Object &operator=(const Object &o); 57 58 59public: 60 61 // 頂点配列オブジェクトの結合 62 void bind() const 63 { 64 // 描画する頂点配列オブジェクトを指定する 65 glBindVertexArray(vao); 66 } 67};

Shape

1#pragma once 2#include <memory> 3 4// 図形データ 5#include "Object.h" 6 7// 図形の描画 8class Shape 9{ 10 // 図形データ 11 std::shared_ptr<const Object> object; 12 13protected: 14 15 // 図形に扱う頂点の数 16 const GLsizei vertexcount; 17 18public: 19 20 // コンストラクタ 21 // size: 頂点の位置の次元 22 // vertexcount: 頂点の数 23 // vertex: 頂点属性を格納した配列 24 Shape(GLint size, GLsizei vertexcount, const Object::Vertex *vertex) 25 : object(new Object(size, vertexcount, vertex)) 26 , vertexcount(vertexcount) 27 { 28 // 本体はない 29 } 30 31 // 描画 32 void draw() const 33 { 34 // 頂点配列オブジェクトを結合 35 object->bind(); 36 37 // 描画の実行 38 execute(); 39 } 40 41 // 描画の実行 42 virtual void execute() const 43 { 44 // 折れ線で描画する 45 glDrawArrays(GL_LINE_LOOP, 0, vertexcount); 46 } 47};

vertexShader

1#version 150 core 2in vec4 position; 3void main() 4{ 5 gl_Position = position; 6} 7

fragmentShader

1#version 150 core 2out vec4 fragment; 3void main() 4{ 5 fragment = vec4(1.0, 0.0, 0.0, 1.0); 6}

これまでも何度か、記述の順番が違うなどの理由でエラーを出してきたのですが、今回ばかりはどうにもわかりません。よろしくお願いします。

Terminal

1$ c++ main.cpp -g -std=c++11 -I/usr/local/include -L/usr/local/lib -lglfw -lglew -framework OpenGL -framework CoreVideo -framework IOKit -framework Cocoa

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

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

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

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

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

guest

回答1

0

ベストアンサー

macOS 10.14にHomebrewでGLEW 2.1.0、GLFW 3.2.1をインストールして、ご提示の「○○くんのために一所懸命書いたものの結局○○くんの卒業に間に合わなかったGLFW による OpenGL 入門」に従ってプロジェクトを作り、ソースコードはご質問者さんのものをそのまま使ったところ、確かに描画されませんでした...

このとき、Xcodeの出力欄に「Link Error.」と表示されたのですが、ご質問者さんの場合は何かメッセージは表示されましたでしょうか?
私の場合ですと、フラグメントシェーダーを生成・アタッチする部分に下記のような修正を加えたところ、とりあえず赤い四角が現れるようになりました(ただし、最初にウインドウをちょっとドラッグして動かしてやらないと描画されないという謎の現象がありましたが...)。

C++

1 if(fsrc != NULL) { 2 // フラグメントシェーダのシェーダオブジェクトを作成 3 const GLuint fobj(glCreateShader(GL_FRAGMENT_SHADER)); 4 glShaderSource(fobj, 1, &fsrc, NULL); 5 glCompileShader(fobj); 6 7 // フラグメントシェーダのシェーダオブジェクトをプログラムオブジェクトに組み込む 8 if(printShaderInfoLog(fobj, "fragment shader")) 9 glAttachShader(program, fobj); 10 // glDeleteShader(program); // ここで関数に渡すべきなのは、プログラムオブジェクトではなく... 11 glDeleteShader(fobj); // シェーダーオブジェクトの方ではないでしょうか? 12 }

投稿2018/09/30 04:22

Bongo

総合スコア10807

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

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

honjoriki

2018/10/01 00:25

ありがとうございます。単純に私のタイプミスだと思います。私の環境はコマンドラインでコンパイル・実行しているのですが、特にエラー情報は出力されませんでした。ウインドウをドラッグしないと描画されない現象も今の所は確認できておりません。環境によって実行処理が変わってしまうのでしょうか...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問