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

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

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

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

OpenGL ES

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

Qt

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

C++

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

Q&A

解決済

1回答

3314閲覧

OpenGLのglDeleteBuffersでAccess violation.

kogane1185

総合スコア7

OpenGL

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

OpenGL ES

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

Qt

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

C++

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

0グッド

0クリップ

投稿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 }

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

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

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

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

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

guest

回答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

総合スコア23272

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

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

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()のような処理ではどうでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問