Me gustaría renderizar una escena con una textura inicialmente vacía. Para hacerlo, utilizo un Objeto Framebuffer al que adjunto una textura 2d vacía y un buffer de profundidad. Después de la configuración, como para las pruebas, dibujo un cuadrángulo simple en la escena. Cada vértice tiene un color diferente, así que eventualmente espero un cuadrante interpolado por colores en la textura. Luego uso esa textura que contiene el quad y la mapeo en otro quad. Así que, evetually, tengo un quad en mi Framebuffer predeterminado que tiene una textura que contiene un quad de color. Espero que esto no sea demasiado confuso ...OpenGL: Problemas con Renderizar a Textura y Objeto Framebuffer
De todos modos, me falta algo aquí, ya que lo que obtengo no es más que una textura gris. Básicamente seguí las instrucciones this que son bastante sencillas. Sin embargo, no puedo entender lo que me falta aquí. Estaría agradecido si alguien pudiera darme una pista.
Gracias Walter
este es el código que tengo hasta ahora: // crear el objeto memoria intermedia de trama 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();
Resultado esperado:
- Textura con un quad de color sobre un fondo amarillo
- que la textura se mapea en otro quad
Resultado real:
- Una textura gris
- textura éxito puede ser asignada por el otro quad
EDIT: He echado de menos mencionar el tratamiento de errores. Así es como compruebo los errores. Incluye los casos adicionales sugeridos por Paul S. Gracias por eso.
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: Este es el método que utilizo para comprobar si hay errores GL-
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;
}
}
¿Qué versión de OpenGL utiliza? Las funciones de objeto framebuffer no tienen ningún sufijo de proveedor, por lo que estoy dispuesto a creer en 3.0 - 3.3, pero soy sospechoso. Recuerde que existen grandes diferencias entre la funcionalidad básica de OpenGL 3, GL_ARB_framebuffer_object y GL_EXT_framebuffer_object. ¡No son iguales! Además, llamar simplemente glCheckFramebufferStatus() no es suficiente. Asegúrese de manejar los errores normales de OpenGL también con glGetError() –
Su suposición es correcta. Estoy usando OpenGL 3.1. Debería haber mencionado eso antes. Gracias por la sugerencia glGetError(). Incluí eso en mi código. Agregué el método a las listas de códigos de arriba. Creo que verifico todos los errores posiblemente disparados por OpenGL 3.1, ¿no? Revisé todo el código para detectar errores, pero parece que no hay nada. – Walter
Tengo cada vez más sospechas de que no es la aplicación la que contiene errores, pero puede haber alguna biblioteca o extensión faltante o mal configurada, respectivamente. No estoy seguro si eso es de alguna ayuda, pero este es mi sistema: Windows 7, OpenGL 3.1, NVidia Quadro FX 3700. Estoy usando GLEW 1.5.7, SDL 1.2, GL_EXT_framebuffer_object, GL_EXT_texture3D, GL_ARB_draw_buffers ... Any ideas son apreciadas – Walter