2009-06-21 29 views
32

OpenGL ESのテクスチャにシーンを描画するためのコードを見つけるのが難しかったです(特にiPhoneの場合)。OpenGL ESテクスチャレンダリング

  1. OpenGL ESでどのようにシーンをテクスチャにレンダリングするのですか?
  2. OpenGL ESでレンダリング対象となることができるテクスチャを作成するには、どのパラメータを使用する必要がありますか?
  3. このレンダリングされたテクスチャを他のプリミティブに適用することに何か影響はありますか?

答えて

43

これは私がやっている方法です。

私は(私はAppleのTexture2Dクラスを使用しますが、あなたがしたい場合は、OpenGLのテクスチャIDを使用することができます)テクスチャ変数を定義し、フレームバッファ:

Texture2d * texture; 
GLuint textureFrameBuffer; 

そして、いくつかの点で、私はテクスチャを作成、フレームバッファを作成し、レンダバッファを添付します。このあなたは一度だけ、それを実行する必要があります。

texture = [[Texture2D alloc] initWithData:0 
          pixelFormat:kTexture2DPixelFormat_RGB888 
          pixelsWide:32 
          pixelsHigh:32 
          contentSize:CGSizeMake(width, height)]; 

// create framebuffer 
glGenFramebuffersOES(1, &textureFrameBuffer); 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer); 

// attach renderbuffer 
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture.name, 0); 

// unbind frame buffer 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 

私はテクスチャにレンダリングするたびに、私は:あなたの質問3について

glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer); 

... 
// GL commands 
... 

glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 

を、それはそれだ、あなたのようにテクスチャを使用することができますそれが他のテクスチャであれば。

+0

Marco、レンダリングする必要のあるテクスチャごとにフレームバッファとレンダバッファを保持するのに必要なオーバーヘッドはどれくらいですか?私は、アプリケーションが描画する必要があるいくつかの大きなテクスチャを持っており、glFramebufferTexture2DOESを使って別のフレームバッファを単一の "余分な"フレームバッファに接続しています。それぞれのために別々のフレームバッファを保持する方が良いでしょうか? –

+0

initWithData:... callがスクロールせずに収まるようにコードを編集してください。 – nornagon

+0

さて、編集しました、今よく見えます。 –

9

シーンをテクスチャにレンダリングするには、テクスチャに関連付けられたフレームバッファを使用する必要があります。ここで私はそれを簡単にするために作成された方法は次のとおりです。

void glGenTextureFromFramebuffer(GLuint *t, GLuint *f, GLsizei w, GLsizei h) 
{ 
    glGenFramebuffers(1, f); 
    glGenTextures(1, t); 

    glBindFramebuffer(GL_FRAMEBUFFER, *f); 

    glBindTexture(GL_TEXTURE_2D, *t); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *t, 0); 

    GLuint depthbuffer; 
    glGenRenderbuffers(1, &depthbuffer);  
    glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, w, h); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer); 

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 
    if(status != GL_FRAMEBUFFER_COMPLETE) 
     NSLog(@"Framebuffer status: %x", (int)status); 
} 

あなたは簡単にフレームバッファとテクスチャを作成することができます。

あなたが後であなたの引き分けに_textureにシーンをレンダリングするために_framebuffer使用することができます
GLuint _texture, _framebuffer; 
GLsizei w,h; 
float scale = [UIScreen mainScreen].scale; 
w = self.view.bounds.size.width * scale; 
h = self.view.bounds.size.height * scale; 
glGenTextureFromFramebuffer(&_texture, &_framebuffer, w, h); 

メソッド:

glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); 
//draw here the content you want in the texture 
//_texture is now a texture with the drawn content 

//bind the base framebuffer 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 
//or if you use GLKit 
[view bindDrawable]; 
//draw normaly 

これで、テクスチャで何かできます。いくつかの後処理(ぼかし、咲き、影など)をしたい場合、あなたはできる!

+0

こんにちは、どこから '_renderToTextureBuffer'を取得しましたか? –

+0

_renderToTextureBufferは_framebufferです。私はそれを修正します。 – Anthony

+0

クール、それは私が考えていたものです。実際の例でこれを持っていますか?これを自分のコードに追加しようとしますが、テクスチャを描画する方法についてはわかりません '//ここでテクスチャに必要なコンテンツを描画します' VBOと 'glDrawArrays()'でこれを行うことはできますか? ? –