また、各画像またはテクスチャをロードした直後にOpenGL glBindtexture()を使用してバインドを実行するため、各SceneObjectインスタンスにテクスチャIDを保存するだけで済みます。ワーカースレッドでロードを実行しようとすると、プログラム全体がクラッシュしました。
OpenGLコンテキストは、一度に1つのスレッドでのみアクティブにできます。一般に、マルチスレッドのOpenGL操作は、正しく行うために、通常、大きな悪夢になります。あなたの場合、あなたがやろうとしていることは、リソースのロードを委任することです。昔は、バッファオブジェクトが存在する前は、ヘルパーコンテキストを作成し、その「リスト」をメインコンテキストと共有することでこれを行っていました。
今日はもっと良いものがあります:バッファオブジェクト。バッファオブジェクトを使用すると、非同期でOpenGLにデータを送信できます。それはのようなものに沿っています
glGenBuffers(...);
glBindBuffer(...);
glBufferData(..., size, usage);
void *p = glMapBuffer(...);
memcpy(p, data, size);
glUnmapBuffer(...);
glTexImage / glDrawPixels / etc.
理解しておくべき重要な部分は、glMapBufferによって割り当てられたアドレス空間がスレッド間で共有されるということです。したがって、メインスレッドのOpenGLコンテキストに、バッファオブジェクトをマップし、割り当てを使用してワーカースレッドにシグナルを送信するように指示できます。次に、ワーカースレッドがデータを入力し、終了時にOpenGLコンテキストスレッドにシグナルを送信してマップを解除します。
マルチスレッド用に編集
したがって、これを行うには、両側にいくつかの信号ハンドラーを実装します(擬似コード)
signal OpenGLThread::mapPixelBufferObjectForWrite(ImageLoader il):
glGenBuffers(1, &self.bufferId)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, self.bufferId)
glBufferData(GL_PIXEL_UNPACK_BUFFER, il.unpackedImageSize, NULL, GL_STATIC_DRAW)
BufferObjectMapping map(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY))
send_signal(target_thread = workerthread, target_signal_handler = workerthread::loadImageToBuffer(map, il), signal_on_finish = self.unmapPixelBufferObjectWriteFinishedGenTexture(map))
signal IOThread::loadImageToBuffer(BufferObjectMapping map, ImageLoader il):
/* ... */
signal OpenGLThread::unmapPixelBufferObjectWriteFinishedGenTexture(BufferObjectMapping map, ImageLoader il):
if(map.mapping_target == GL_PIXEL_UNPACK_BUFFER)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, self.bufferId)
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER)
glGenTextures(1, &il.textureId)
glBindTexture(il.target, il.textureId)
for mipmaplevel in il.levels
glTexImage2D(il.target, mipmaplevel, il.internalformat, il.width, il.height, il.border, il.format, il.type, mipmaplevel.offset)