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

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

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

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

OpenGL ES

携帯電話のような組込み機器のためにデザインされたOpenGLのサブセットです。

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

C++

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

Q&A

解決済

OpenGLのglDeleteBuffersでAccess violation.

kogane1185
kogane1185

総合スコア7

OpenGL

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

OpenGL ES

携帯電話のような組込み機器のためにデザインされたOpenGLのサブセットです。

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

C++

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

1回答

0グッド

0クリップ

2947閲覧

投稿2016/02/28 04:31

編集2016/02/28 04:34

OpenGLを使用してアプリケーションを作成しているのですが、glDeleteBuffersで[Access violation reading location]を吐いてしまいます。
glDeleteBuffers以外は正常に作動しているように見えるのですが、何が原因でglDeleteBuffersができないのでしょうか。

考えられる原因としてWorldがシングルトンでデストラクタが呼ばれる際に、OpenGLのcontextがすでに存在しないからと思っております。もしそうならば、どのようにリソース管理をするのが正しいのでしょうか。
複数のビューに同じ視点違いの同じオブジェクトを描画したいため、すべて一つのcontextにリソースを入れるわけにはいかないのですが……。

lang

1 void GLWidget::paintGL() 2 { 3 // 何行かのシェーダーとビュー行列プロジェクション行列の転送処理。 4 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 5 World::get().draw(); 6 }

lang

1 class World 2 { 3 public: 4 World(const World&) = delete; 5 World& operator=(const World&) = delete; 6 World(World&&) = delete; 7 World& operator=(World&&) = delete; 8 9 static World& get() 10 { 11 static World instance; 12 return instance; 13 } 14 15 void addObject(std::shared_ptr<ObjectBase> object) 16 { 17 _objects.push_back(object); 18 } 19 20 void draw() 21 { 22 for (const auto& object : _objects) 23 { 24 object->draw(); 25 } 26 } 27 28 private: 29 World() = default; 30 ~World() = default; 31 32 std::vector<std::shared_ptr<ObjectBase>> _objects; 33 };

lang

1 class ObjectBase : protected QOpenGLFunctions 2 { 3 public: 4 ObjectBase(); 5 virtual ~ObjectBase(); 6 virtual void initialize() = 0; 7 virtual void draw() = 0; 8 9 protected: 10 GLuint _positionBuffer; 11 GLuint _indexBuffer; 12 }; 13 ObjectBase::ObjectBase() 14 : _positionBuffer(0) 15 , _indexBuffer(0) 16 { 17 initializeOpenGLFunctions(); 18 glGenBuffers(1, &_positionBuffer); 19 glGenBuffers(1, &_indexBuffer); 20 } 21 22 ObjectBase::~ObjectBase() 23 { 24 if (_positionBuffer) 25 { 26 glDeleteBuffers(1, &_positionBuffer); // エラー発生 27 } 28 if (_indexBuffer) 29 { 30 glDeleteBuffers(1, &_indexBuffer); 31 }; 32 }

lang

1 PolygonObject::PolygonObject() 2 : ObjectBase() 3 { 4 } 5 PolygonObject::~PolygonObject() 6 { 7 } 8 void PolygonObject::initialize() 9 { 10 glBindBuffer(GL_ARRAY_BUFFER, _positionBuffer); 11 glBufferData(GL_ARRAY_BUFFER, sizeof(QVector3D)*_vertices.size(), &_vertices.front(), GL_STATIC_DRAW); 12 13 glBindBuffer(GL_ARRAY_BUFFER, _indexBuffer); 14 glBufferData(GL_ARRAY_BUFFER, sizeof(GLuint)*_indices.size(), &_indices.front(), GL_STATIC_DRAW); 15 16 glBindBuffer(GL_ARRAY_BUFFER, 0); 17 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 18 } 19 20 void PolygonObject::draw() 21 { 22 glBindBuffer(GL_ARRAY_BUFFER, _positionBuffer); 23 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); 24 glEnableClientState(GL_VERTEX_ARRAY); 25 glVertexPointer(3, GL_FLOAT, 0, 0); 26 glDrawElements(GL_TRIANGLES, (GLsizei)_indices.size(), GL_UNSIGNED_INT, 0); 27 glDisableClientState(GL_VERTEX_ARRAY); 28 glBindBuffer(GL_ARRAY_BUFFER, 0); 29 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 30 }

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

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

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

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

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

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

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

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

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

回答1

0

ベストアンサー

こんにちは。

他のコントロールできないリソースに依存する場合は、明示的に解放できるようにして、依存先リソースの解放前に解放すると良いと思います。
例えば、下記のような静的関数をWorldクラスに追加して、OpenGLのコンテキスト解放直前に呼び出すなどです。

C++

1static void destroy() 2{ 3 World::get()._objects.clear(); 4}

ところで、ソースの構造的にシングル・スレッドですよね? マルチスレッドならばもう少し対処が必要です。

投稿2016/02/28 05:53

編集2016/02/28 05:54
Chironian

総合スコア23251

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

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

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

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

回答へのコメント

kogane1185

2016/02/28 06:55 編集

回答ありがとうございます。 GLWidgetのデストラクタでdestory関数を呼び出したところ、Access violationエラーは消えました。ありがとうございます。 しかしながら、この場合リソース管理(World)≒GLWidgetになってしまいます。 質問欄に述べた通りGLWidget(GUI上のビューポート)が複数(すなわちcontextが複数)あり、それらがリソースを管理している単一のWorldを参照している形にしたいのですが、何か良い解決策はありますでしょうか。 私がマルチスレッドプログラミングに詳しくないので、なんとも言えませんが出来れば今後マルチスレッド化したいと考えています。
Chironian

2016/02/28 07:31

Worldシングルトン内に参照カウンタを設けて、GLWidgetをコンストラクトする度に+1、デストラクトする度に-1し、0になったらdectroy()のような処理ではどうでしょうか?

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

ただいまの回答率
86.02%

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

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

質問する

関連した質問

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

OpenGL

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

OpenGL ES

携帯電話のような組込み機器のためにデザインされたOpenGLのサブセットです。

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

C++

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