OpenGL: Problème avec Render to Texture & amp; Objet Framebuffer
J'aimerais effectuer le rendu d'une scène à un vide au début de la texture. Pour ce faire, j'utilise un Objet Framebuffer à laquelle j'attache un vide de texture 2d et un tampon de profondeur. Après la mise en place, comme pour les tests, j'en tire un simple quad dans la scène. Chaque sommet a une couleur différente, j'ai donc éventuellement s'attendre à une couleur interpolée de quad dans la texture.
J'utilise ensuite que la texture contenant le quad et la carte sur un autre quad. Donc evetually, j'ai un quad dans mon défaut Framebuffer qui a une texture contenant une couleur quad. J'espère que ce n'est pas trop confus...
De toute façon, je dois être en manque de quelque chose ici, car ce que je reçois est rien, mais un gris texture. En gros, j'ai suivi cette instructions qui sont assez directe. Cependant, je ne peux pas tout à fait comprendre ce que je suis en manque ici. Je vous serais reconnaissant si quelqu'un pouvait me donner un indice.
Merci
Walter
C'est le code que j'ai pour l'instant:
//création d'un frame buffer object
glGenFramebuffers(1, &frameBufferObject);
//create depth buffer
glGenRenderbuffers(1, &depthAttachment);
//create empty texture
int width = 512;
int height = 512;
int numberOfChannels = 3;
GLuint internalFormat = GL_RGB;
GLuint format = GL_RGB;
unsigned char* texels = new unsigned char[width * height * numberOfChannels];
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, texels);
glGenerateMipmap(GL_TEXTURE_2D);
delete[] texels;
texels = NULL;
//activate & bind empty texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
//attach empty texture to framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
//define render targets (empty texture is at GL_COLOR_ATTACHMENT0)
glDrawBuffers(1, GL_COLOR_ATTACHMENT0);
//attach depth buffer
glBindRenderbuffer(GL_RENDERBUFFER, depthAttachment);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthAttachment);
//use framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferObject);
//draw the colored quad into the initially empty texture
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
//store attibutes
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//reset viewport
glViewport(0, 0, width, height);
//make background yellow
glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
//draw quad into texture attached to frame buffer object
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glVertex2f(0.0f, 100.0f); //top left
glColor4f(1.0f, 0.0f, 0.0f, 1.0f); glVertex2f(0.0f, 0.0f); //bottom left
glColor4f(0.0f, 1.0f, 0.0f, 1.0f); glVertex2f(100.0f, 0.0f); //bottom right
glColor4f(0.0f, 0.0f, 1.0f, 1.0f); glVertex2f(100.0f, 100.0f); //top right
glEnd();
//restore attributes
glPopAttrib();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
//use default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
//clear default framebuffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//draw the scene
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor4f(1.0, 1.0, 1.0, 1.0);
//begin texture mapping
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBegin(GL_QUADS);
glNormal3d(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 50.0f, -100.0f); //top left
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 0.0f, -100.0f); //bottom left
glTexCoord2f(1.0f, 1.0f); glVertex3f(50.0f, 0.0f, -100.0f); //bottom right
glTexCoord2f(1.0f, 0.0f); glVertex3f(50.0f, 50.0f, -100.0f); //top right
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
//swap buffers (I forgot to mention that I use SDL)
SDL_GL_SwapBuffers();
Résultat attendu:
- De Texture avec la couleur de quad sur un fond jaune
- Que la texture est mappé sur un autre quad
Résultat réel:
- Gris texture
- Texture peut être mappé sur l'autre quad
EDIT: j'ai manqué de mentionner l'erreur de manipulation. C'est comment j'ai vérifier les erreurs. Il comprend les cas supplémentaires Paul S a suggéré. Merci pour cela.
GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE:
return;
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
throw FramebufferIncompleteException("An attachment could not be bound to frame buffer object!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
throw FramebufferIncompleteException("Attachments are missing! At least one image (texture) must be bound to the frame buffer object!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
throw FramebufferIncompleteException("The dimensions of the buffers attached to the currently used frame buffer object do not match!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
throw FramebufferIncompleteException("The formats of the currently used frame buffer object are not supported or do not fit together!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
throw FramebufferIncompleteException("A Draw buffer is incomplete or undefinied. All draw buffers must specify attachment points that have images attached.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
throw FramebufferIncompleteException("A Read buffer is incomplete or undefinied. All read buffers must specify attachment points that have images attached.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
throw FramebufferIncompleteException("All images must have the same number of multisample samples.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS :
throw FramebufferIncompleteException("If a layered image is attached to one attachment, then all attachments must be layered attachments. The attached layers do not have to have the same number of layers, nor do the layers have to come from the same kind of texture.");
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
throw FramebufferIncompleteException("Attempt to use an unsupported format combinaton!");
break;
default:
throw FramebufferIncompleteException("Unknown error while attempting to create frame buffer object!");
break;
}
EDIT 2: C'est la méthode que j'utilise pour vérifier GL-erreurs
checkForGLErrors(string sourceFile, int line)
GLenum error = glGetError();
ostringstream o;
switch(error) {
case GL_NO_ERROR:
return;
break;
case GL_INVALID_ENUM:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Invalid enum!"<<endl;
throw GLErrorException(o.str());
break;
case GL_INVALID_VALUE:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Invalid value!"<<endl;
throw GLErrorException(o.str());
break;
case GL_INVALID_OPERATION:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Invalid operation!"<<endl;
throw GLErrorException(o.str());
break;
case GL_STACK_OVERFLOW:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Stack overflow!"<<endl;
throw GLErrorException(o.str());
break;
case GL_STACK_UNDERFLOW:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Stack underflow!"<<endl;
throw GLErrorException(o.str());
break;
case GL_OUT_OF_MEMORY:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Out Of memory!"<<endl;
throw GLErrorException(o.str());
break;
case GL_TABLE_TOO_LARGE:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Table too large!"<<endl;
throw GLErrorException(o.str());
break;
default:
o<<"OpenGL Error in "<<sourceFile<<" at line "<<line<<": Unknown error!"<<endl;
throw GLErrorException(o.str());
break;
}
}
source d'informationauteur Walter
Vous devez vous connecter pour publier un commentaire.
J'ai résolu ce problème.
Voici donc ce que je fais. Peut-être il ya certains des meilleurs /moyens plus intelligents pour le faire, mais il fonctionne parfaitement bien maintenant. N'hésitez pas à suggérer des adaptations...
Je n'ai pas l'erreur de manipulation de sous. Vous pouvez trouver que dans cette question.
Comme vous le voyez, je me suis débarrassé de le tampon de profondeur de l'attachement. J'ai pensé que je n'en ai pas vraiment besoin pour mon travail. Dès que j'ai réellement pu dessiner des choses, j'ai ajouté de la projection orthogonale. Sans cela, le dessin d'une texture résultats assez maladroite images...
Espère que ce sera utile pour quelqu'un il y
Walter
Bizarre, à la fois glDrawBuffers et glFramebufferTexture2D ne ressemble pas aux spécifications! Le premier prend un tableau de GLenum, et pas un GLenum (vérifier les mises en garde: il peut être silencieusement coulé!). Et le deuxième seulement prendre 4 arguments sur les specs!
EDIT:
J'attends de ce qui se passe:
Voici un extrait de code que j'utilise pour vérifier le tampon de trame d'état. Il utilise l'EXT version des organisations confessionnelles et est en Objective-C (d'où le @"" chaînes de caractères), mais il devrait être évident. Il vient après j'ai appelé glBindFramebuffer, glFramebufferTexture2D & glDrawBuffers.
Le problème est probablement le tampon de profondeur, que les conducteurs ont tendance à être assez pointilleux à ce sujet. Pour ce test, vous n'avez pas besoin de profondeur de sorte que vous pouvez supprimer le tampon de rendu des trucs si c'est à l'origine de problèmes.
Une autre note, la texture n'a pas besoin d'être lié et active pour le rendu. Vous pourriez reporter le code jusqu'à ce que vous voulez l'utiliser pour le rendu de votre image finale.