2011-08-25 21 views
20

OpenGL 2Dテクスチャをゼロで初期化する必要があります。0でテクスチャを効率的に初期化するには?

なぜですか? OpenCLでこのテクスチャにレンダリングします。概ね、レンダリングステージは、次のとおり

  1. OpenCLの(それは透明黒画素含まれて)ゼロで初期化し、RGBAテクスチャを作成する:いくつかのオブジェクトが表示され、このテクスチャに書き込む画素の計算色を
  2. OpenGL:透明なピクセルに環境マッピングを追加して最終的な画像を表示する

したがって、実際のテクスチャデータをglTexImage2dに渡す必要はありません。しかし仕様によると、data = NULLを渡すと、テクスチャメモリは割り当てられますが初期化されません。

0で満たされ、glTexImage2Dに渡されるクライアント側メモリを割り当てることは、私が考えることができる1つのみですが、非常に良い選択肢ではありません。

編集:私は実際にはアルファコンポーネント(RGBはとにかくオーバーライドされます)を初期化したいと思いますが、これで状況がさらに簡単になるとは思えません。

答えて

32

は、これを行うには、いくつかの方法があります。

1:

効率を最大にするため
std::vector<GLubyte> emptyData(width * height * 4, 0); 
glBindTexture(GL_TEXTURE_2D, texture); 
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, &emptyData[0]); 

は、あなたがこれを呼び出すとするときの間にいくつかの時間を残す必要があります。テクスチャの幅と高さを考えるとOpenCLがその作業を開始するとき。

2:FBOに取り付け、glClearBufferを使用します。

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); 
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0); //Only need to do this once. 
glDrawBuffer(GL_COLOR_ATTACHMENT0); //Only need to do this once. 
GLuint clearColor[4] = {0, 0, 0, 0}; 
glClearBufferuiv(GL_COLOR, 0, clearColor); 

これは、CPU-GPU DMAが実行されていないため、これは高速であるようです。しかし、FBOのバインディングとバインド解除は、非効率性をもたらす可能性があります。それではまた、そうではないかもしれません。それをプロファイルして確かめてください。

これは、レンダーターゲットとして使用できるイメージ形式でのみ機能することに注意してください。圧縮されたテクスチャではありません。

3:データstandard pixel transfersによって提供することができる画像形式については、こののみ動作することを

glClearTexImage(texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor); 

注:考えると、十分なドライバーは、新しいARB_clear_texture拡張子を使用することができます。圧縮されていない形式なので

+0

'glClearBuffer'について聞いたことがありません。これは非常に新しいバージョンからですか? 'glClear'よりも利点がありますか(または後者は廃止予定ですか?) –

+1

@Christian:ClearBufferの主な利点は、特定のバッファをクリアできることです。フレームバッファ内に複数のバッファがあり、複数のレンダーターゲットがある場合は、異なるバッファを異なる色にクリアすることができます。まったく何かをクリアしないでください。 'glClear'ではこれを行うことはできません。すべてのバッファを同じクリアカラーにクリアします。 'glClear'は非推奨ではなく、' glClearBuffer'はGL 3.0から来ています(拡張子はありません)。 –

+1

glClearTexImageは、glTexImage *またはglTexStorage *への呼び出しを使用して、テクスチャストレージが以前に割り当てられている場合にのみ機能することに注意してください。 glBindTextureを使用してテクスチャを作成するだけでは不十分です。しかしこれはglTexSubImage2Dにも当てはまります。 – rdb

1

おそらく、テクスチャを最初のパスのレンダリングターゲットとして設定し、黒色のプリミティブを描画することができます。ラムとグラフィックカードの間にメモリ転送がないので、速度が速くなる可能性があります。

+0

グッドポイント。しかし、この方法でα= 0に設定することはできますか?私は実際にアルファだけを初期化したい、私はRGBコンポーネントを気にしない。 – jirkamat

+3

glClearColorとglClearを使う方が良いかもしれません。 glClearColorはアルファを受け入れます。 – neodelphi

5

ちょうどいいね:新しいGL_ARB_clear_texture(コアの4.4)拡張は、この問題を具体的に解決します。

+0

これは当てはまりますが、警告の言葉:あなたはこれを明確にプロファイルしたいと思っています。私のシステムでは、glClearTextureはフレームバッファとglClear/glClearBufferを使うよりもずっと遅いです。 – Jagoly

+0

@Jagolyは、GPUタイマークエリを使用して適切にプロファイルしましたか? – Ancurio

+0

いいえ、フレームタイムを使用しています。しかし、少し遅くなるだけではありません。 clearTexture(2つの呼び出し、rgb8 + 24bit深度)は、クリアよりも3倍以上長くかかりました。私はすでにフレームバッファをセットアップしていました。差は深度のみ(5倍)でさらに大きかった。 – Jagoly

0
  1. glTexSubImageは、画像全体が充填されている:

    GLfloat* pData = new GLfloat[1024*768*4]; 
    memset(pData, 0x00, 1024*768*4*sizeof(GLfloat)); 
    glBindTexture(GL_TEXTURE_2D, m_ImageTex); 
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 768, GL_RGBA, GL_FLOAT, pData); 
    glBindTexture(GL_TEXTURE_2D, 0); 
    delete pData; 
    
  2. 使用ピクセルバッファがGPUからデータをコピーするために、この方法は、より速く、より良い

    Iです。 init PBO

    glGenBuffers(1, &m_PixelBuffer); 
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_PixelBuffer); 
    glBufferData(GL_PIXEL_UNPACK_BUFFER, SCREEN_WIDTH*SCREEN_HEIGHT*4*sizeof(GLfloat), NULL, GL_STATIC_DRAW); 
    GLfloat* pData = nullptr; 
    pData = (GLfloat*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); 
    memset(pData, 0x00, 1024*768*4*sizeof(GLfloat)); 
    glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); 
    

    ii。

    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_PixelBuffer); 
    glBindTexture(GL_TEXTURE_2D, m_ImageTex); 
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGBA, GL_FLOAT, NULL); 
    glBindTexture(GL_TEXTURE_2D, 0); 
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); 
    
関連する問題