2009-10-17 7 views
1

Cela devrait être très simple, mais il est consommé plusieurs heures de mon temps, et je n'ai aucune idée de ce qui se passe.OpenGL avec RTF FBO, mélange quand il ne devrait pas

Je rends un quad plein écran plat à une texture, puis relis le résultat avec glGetTexImage. C'est lié à GPGPU, donc je veux que la valeur alpha se comporte comme si c'était l'une des trois autres. J'utilise un FBO, format de texture GL_RGBA32F_ARB, carte NVidia sur un MacBook Pro avec 10.5, si c'est important.

Je ne récupère la couleur correcte que si l'alpha que je spécifie est un; avec toute autre valeur, il semble se fondre avec ce qui est déjà dans le framebuffer, même si j'ai explicitement désactivé GL_BLEND. J'ai également essayé d'activer le mélange et d'utiliser glBlendFunc(GL_ONE, GL_ZERO) mais le résultat final est le même. Je peux effacer le framebuffer à zéro avant le rendu, ce qui le corrige, mais je veux comprendre pourquoi c'est nécessaire. Comme deuxième test, le rendu de deux quads qui se chevauchent donne un résultat fusionné, quand je veux juste revenir à la couleur originale à 4 canaux. Sûrement le quad de couleur solide devrait écraser complètement les pixels dans le framebuffer? Je suppose que j'ai mal compris quelque chose de fondamental. Merci.

const size_t res = 16; 
GLuint tex; 
glGenTextures(1, &tex); 
glBindTexture(GL_TEXTURE_2D, tex); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, 
    res, res, 0, GL_RGBA, GL_FLOAT, 0); 
glBindTexture(GL_TEXTURE_2D, 0); 

GLuint fbo; 
glGenFramebuffersEXT(1, &fbo); 
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); 
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 
    GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0); 
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); 

glViewport(0, 0, res, res); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glOrtho(0, res, 0, res, -1, 1); 

glClearColor(0,0,0,0); 
glClear(GL_COLOR_BUFFER_BIT); 

//glEnable(GL_BLEND); 
//glBlendFunc(GL_ONE, GL_ZERO); 
glDisable(GL_BLEND); 
glDisable(GL_DEPTH_TEST); 

glColor4f(0.2, 0.3, 0.4, 0.5); 

for (int i=0; i<2; ++i) { 
    glBegin(GL_QUADS); 
    glVertex2i(0,0); 
    glVertex2i(res, 0); 
    glVertex2i(res, res); 
    glVertex2i(0, res); 
    glEnd(); 
} 

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 

std::vector<float> tmp(res*res*4); 
glBindTexture(GL_TEXTURE_2D, tex); 
glGetTexImage(GL_TEXTURE_2D, 0, 
    GL_RGBA, GL_FLOAT, &tmp.front()); 
const float * const x = &tmp.front(); 
cerr << x[0] << " " << x[1] << " " << x[2] << " " << x[3] << endl; 
// prints 0.3 0.45 0.6 0.75 

glDeleteTextures(1, &tex); 
glDeleteFramebuffersEXT(1, &fbo); 

Répondre

1

Pas vraiment une bonne réponse, cependant, certaines choses à noter:

  • Qu'est-ce que vous observez ne regarde pas vraiment le mélange. Pour un, votre back-buffer est initialement rgba = 0, donc l'alpha-blending contre lui donnerait 0, pas 0.2 0.3 0.4 0.5 comme vous pouvez l'observer. Mon inclination était que vous définissiez en quelque sorte le même tampon de texture que la texture et attachement framebuffer. Ceci est indéfini dans la spécification (section 4.4.3). Dans l'extrait de code que vous fournissez, vous faites un glBindTexture(GL_TEXTURE_2D, 0) cependant, ce qui devrait vous assurer que ce n'est pas le cas ... Je vais le laisser ici au cas où vous l'auriez manqué.
Questions connexes