2012-09-30 40 views
9

FBOの使い方は広く、複雑なエフェクトをはるかに簡単にするのに役立ちます。私はFBOを設定して描画し、FBOのテクスチャ付きクワッドを問題なくレンダリングし、単純なスクリーン処理カラーシェーダをテストします。しかし、私がFBOにレンダリングするものは何らかの理由で逆さまになりました。在庫画面FBOにレンダリングするとすべて正常で、スプライトの回転も行われません。FBOへの描画 - 上下反転の問題

FBO作成

typedef struct tex 
{ 
dim2i size; // int width, int height 
GLuint id; 
} tex; 

typedef struct fbo 
{ 
GLuint frame_buffer; 
tex buffer_tex; 
}fbo; 

void set_fbo(fbo* res, int width, int height) 
{ 
GLint tex_size; 
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &tex_size); 
GLint render_buffer_size; 
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &render_buffer_size); 
LOGI("Max render buffer size: %d, max texture size: %d", render_buffer_size, tex_size); //max render buffer size: 3838, max texture size: 2048 
glGenFramebuffers(1, &res->frame_buffer); 
GLuint depth_buffer; 
glGenRenderbuffers(1, &depth_buffer); 
glGenTextures(1, &res->buffer_tex.id); 
res->buffer_tex.size.w = width; 
res->buffer_tex.size.h = height; 
glBindTexture(GL_TEXTURE_2D, res->buffer_tex.id); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, res->buffer_tex.size.w, res->buffer_tex.size.h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); 
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_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, res->buffer_tex.size.w, res->buffer_tex.size.h); 
glBindFramebuffer(GL_FRAMEBUFFER, res->frame_buffer); 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, res->buffer_tex.id, 0); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer); 
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) 
    LOGE("BUFFER OK"); 
else 
    LOGE("BUFFER NOT OK"); 
//BUFFER OK 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 
glBindTexture(GL_TEXTURE_2D, 0); 
} 

FBOの使用

static fbo FBO; 
static decor DECOR; //shield quad 
static decor SCREEN_DECOR;// FBO textured quad 

void on_surface_changed(int width, int height) 
{ 
set_fbo(&FBO, width, height); 
... 
} 

void on_draw() 
{ 
glBindFramebuffer(GL_FRAMEBUFFER, FBO.frame_buffer); 
set_render_color(YELLOW); //glClearColor(...) 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
draw_decor(&DECOR, get_shader(SPRITE_SIMPLE_SHADER), *get_proj(ORTHO_PROJ)); 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 
set_render_color(BLACK); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
draw_decor(&SCREEN_DECOR, get_shader(SPRITE_SIMPLE_SHADER), *get_proj(ORTHO_PROJ)); 
} 

結果:グレースケールのシェーダと with FBO 結果: with grayscale shader

FBOずにレンダリング:

OpenGLは最もウィンドウシステムとは異なり、左下隅に起源を持っているので、これが起こる:コメントから集約

void on_draw_simple() 
{ 
set_render_color(YELLOW); //glClearColor(...) 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
draw_decor(&DECOR, get_shader(SPRITE_SIMPLE_SHADER), *get_proj(ORTHO_PROJ)); 
} 

without FBO

+8

これを参照してください:http://www.java-gaming.org/index.php?topic=24126.0 特にこの部分は: 'テクスチャの起源とウィンドウの起源はOpenGLの左下です.'問題かもしれませんか? :) – Jite

+0

私の悪い)。だから簡単な方法はz軸上で180.0fにスプライトを回転させるだけですか? – Aristarhys

+2

いいえ、fboを描画するときにy座標を反転する必要があります。これはあなたのイメージを反映するので、180°回転しないでください。 – kritzikratzi

答えて

4

原点は左上隅にあります。

テクスチャの座標が左上の0,1から右下の1,0になるようにして、FBOを正しく描画するか、テクスチャを垂直に反転させて四角形を描画してください。

関連する問題