2012-05-08 24 views
2

しばらくの間PyOpenGLを喜んで使用した後、私は真剣に立ち往生しています。私はGLSLシェーダとOpenCLプログラムを使用して、GLSLシェーダとOpenCLプログラムのデータを取得するための標準的な方法としてテクスチャを使用して、画像処理にOpenCLプログラムを使用できるPythonパッケージに取り組んでいます。PyOpenGLでpboにテクスチャをコピーする方法は?

pbo(ピクセルバッファオブジェクト)にテクスチャをコピーできないことを除いて、すべてが機能します。 私はOpenCLの/からのテクスチャデータを取得するためにpbo'sを使用しています。これはPyOpenCLですばらしい高速で動作します: pboのOpenCL出力をテクスチャにコピーして表示できます。 cpuをpboに変換します。しかし、GPU上のテクスチャデータをpboに埋め込もうとしていますが、GLSLシェーダで作成した画像をOpenCLにロードして処理する必要があります。

私はこれを行うには、約2の方法を読んだ: 変種1は、テクスチャを結合し、glGetTexImageを(使用して、PBOを結合する) バリアント2はFBO及びPBOおよび使用を結合し、フレームバッファオブジェクトにテクスチャを添付するglReadPixels()

glReadPixels()とglGetTexImage()の両方のPyOpenGLバージョンでは、バインドされたpboを持つときに使用する 'Null'ポインタに問題があることも読んでいます。そのため、OpenGL .raw.GLバリアント。

これらの両方のケースでは、「無効な操作」エラーが表示され、私が間違っていることは実際には分かりません。私pixelbufferのPythonクラスのload_texture()メソッドの2つのバージョン 以下は、私はあまりにも遠くにそれらを削除しませんでした願っています...

バリアント1:

def _load_texture(self, texture): 
     glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, self.id) 
     glEnable(texture.target) 
     glActiveTexture(GL_TEXTURE0_ARB) 
     glBindTexture(texture.target, texture.id) 
     OpenGL.raw.GL.glGetTexImage(texture.target, 0, texture.gl_imageformat, 
            texture.gl_dtype, ctypes.c_void_p(0)) 
     glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0) 
     glDisable(texture.target) 

バリアント2:

def _load_texture(self, texture): 
     fbo = FrameBufferObject.from_textures([texture]) 
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
     texture.target, texture.id, 0) 
     glReadBuffer(GL_COLOR_ATTACHMENT0) 
     glBindFramebuffer(GL_FRAMEBUFFER, fbo.id) 
     glBindBuffer(GL_PIXEL_PACK_BUFFER, self.id) 
     OpenGL.raw.GL.glReadPixels(0, 0, self.size[0], self.size[1], 
            texture.gl_imageformat, texture.gl_dtype, 
            ctypes.c_void_p(0)) 
     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0) 
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
           GL_TEXTURE_RECTANGLE_ARB, 0, 0) 
     glBindFramebuffer(GL_FRAMEBUFFER, 0) 

EDIT(私のPBOのエラーと初期化に関するいくつかの情報を追加):

私はバリアント1のために取得していますエラーは次のとおりです。

OpenGL.error.GLError: GLError(
    err = 1282, 
    description = 'invalid operation', 
    baseOperation = glGetTexImage, 
    cArguments = (
     GL_TEXTURE_RECTANGLE_ARB, 
     0, 
     GL_RGBA, 
     GL_UNSIGNED_BYTE, 
     c_void_p(None), 
    ) 

と私はこのような私のPBOを初期化しています:

self.usage = usage 
    if isinstance(size, tuple): 
     size = size[0] * size[1] * self.imageformat.planecount 
    bytesize = self.imageformat.get_bytesize_per_plane() * size 
    glBindBuffer(self.arraytype, self.id) 
    glBufferData(self.arraytype, bytesize, None, self.usage) 
    glBindBuffer(self.arraytype, 0) 

'self.arraytype' はGL_ARRAY_BUFFER、私は念のためにあらゆる可能性を試してみましたが、GL_STREAM_READはほとんど見えたself.usageです私のタイプの使用には論理的です。 私が典型的に使用しているサイズは1024で1024、4プレーン、1プレーンあたり1バイトです。これは、ホストからピクセルデータを転送するときに問題なく動作します。また

私はプロプライエタリドライバを使用して、GPU上のメモリ3GBのでNVIDIAのGeForce GTX 580を使用して、Kubuntuの11.10日午前、バージョン295.33

私が何をしないのですか?

+0

無効な操作エラーが発生している行を具体的に言うことができますか?バリアント1の – Tim

+0

、glGetTexImageの呼び出し、バリアント2のglReadPixelsの呼び出し。私が得たエラーは、Cコールに渡された値と期待通りのものをリストしています。 私はコードの他の部分でこれらの呼び出しの周りのバインディングの大部分をうまく使いました。だから、エラーはコードではなく何かであると確信しています:) –

+0

エラーのリストを読まれましたか? glGetTexImageのマニュアルページにありますか?それは、無効な操作を生成する可能性のあるすべての可能性を示しています。私は、あなたのケースで本当のものがあるかどうかを知るための十分なコードは見当たりません。 http://www.opengl.org/sdk/docs/man/xhtml/glGetTexImage.xml – Tim

答えて

0

なぜそれがその大きな違いになるのかを実際に理解せずに解決策を見つけました。

私が持っていたコードは、基本的には正しくありましたが、glBufferDataを呼び出す必要がありました。私はすでにと同じです私の元のコードで私のpboを初期化するが、私の推測では、その初期化とテクスチャを読み込む私の試みの間に何とかその間にdisallocatedになることを推測します。

私はそのコールをglGetTexImageコールに近づけただけで、他のものを変更することなく動作します。

奇妙なことに、PyOpenGLに関連している場合は、バグや機能、NVIDIAドライバなどとは何か分かりません。予想される動作であればどこにでも簡単に文書化されているわけではありません。

以下のバリアント1のコードは機能し、高速ですが、バリアント2も同じように処理されても速度は約半分です。

def _load_texture(self, texture): 
    bytesize = (self.size[0] * self.size[1] * 
       self.imageformat.planecount * 
       self.imageformat.get_bytesize_per_plane()) 
    glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, self.id) 
    glBufferData(GL_PIXEL_PACK_BUFFER_ARB, 
       bytesize, 
       None, self.usage) 
    glEnable(texture.target) 
    glActiveTexture(GL_TEXTURE0_ARB) 
    glBindTexture(texture.target, texture.id) 
    OpenGL.raw.GL.glGetTexImage(texture.target, 0, texture.gl_imageformat, 
           texture.gl_dtype, ctypes.c_void_p(0)) 
    glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0) 
    glDisable(texture.target) 
関連する問題