2012-09-30 28 views
9

FBO kullanımı geniş ve karmaşık etkilerin çok daha kolay olmasına yardımcı oluyor. FBO'yu kurdum ve ona çiziyorum, daha sonra FBO dokulu dörtlü, herhangi bir problem olmadan, basit ekran işleme renk gölgelendiricisini bile test ediyorum. Ama FBO’ya verdiğim her şey bir sebepten ötürü tersine döndü. Eğer stok ekranına FBO yaparsam her şey normaldir ve sprite için herhangi bir rotasyon yapmıyorum bile.Çizim FBO - sprite yukarı ve aşağı tersi

FBO yaratma

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 kullanım

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)); 
} 

Sonuç: : gri tonlama shader ile with FBO Sonucu

FBO olmadan Render:

OpenGL en pencere sistemlerinden farklı, sol alt köşedeki kaynağı vardır, çünkü bu olur: yorumlardan Toplu

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

Şunlara bakın: http://www.java-gaming.org/index.php?topic=24126.0 Özellikle bu kısım: 'Doku kökenleri ve pencere kökenleri OpenGL'nin sol alt köşesidir. 'Sorun olabilir mi? :) – Jite

+0

Benim kötü). Yani basit bir şekilde z-ekseni üzerinde 180.0f'ye sprite döndürmek yeterli midir? – Aristarhys

+2

nope, fbo'yu çizerken y koordinatlarını çevirmeniz gerekir. Görüntüyü de yansıtacağından, 180 ° döndürmeyin. – kritzikratzi

cevap

4

Kökeni sol üst köşede, kullanın.

Basitçe, FBO'yu doğru çizmek için doku koordinatlarının sol üstteki 0,1'den 0,1'e, sağ altta ise 1,0'a düştüğünden emin olun, ya da dördünü dikey olarak ters çevrilmiş dokuya çizin.

İlgili konular